njeffrie commited on
Commit
f985f51
·
verified ·
1 Parent(s): 4e1f3af

Upload 3 files

Browse files
Files changed (3) hide show
  1. config.json +2 -2
  2. model.safetensors +1 -1
  3. modeling_gluformer.py +25 -18
config.json CHANGED
@@ -10,9 +10,9 @@
10
  "d_fcn": 2048,
11
  "d_model": 512,
12
  "distil": true,
 
13
  "len_pred": 12,
14
  "len_seq": 180,
15
- "len_label": 60,
16
  "model_type": "gluformer",
17
  "n_heads": 12,
18
  "num_dec_layers": 1,
@@ -20,5 +20,5 @@
20
  "num_features": 5,
21
  "r_drop": 0.1,
22
  "torch_dtype": "float32",
23
- "transformers_version": "4.53.3"
24
  }
 
10
  "d_fcn": 2048,
11
  "d_model": 512,
12
  "distil": true,
13
+ "len_label": 60,
14
  "len_pred": 12,
15
  "len_seq": 180,
 
16
  "model_type": "gluformer",
17
  "n_heads": 12,
18
  "num_dec_layers": 1,
 
20
  "num_features": 5,
21
  "r_drop": 0.1,
22
  "torch_dtype": "float32",
23
+ "transformers_version": "4.54.0"
24
  }
model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:dc157c82a48b496db650fda5a6827786dcf7b38cf64b3c48ba38857923c2e649
3
  size 65480616
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:185f3885fbd96c6de6b51a0d3762ca3f6885932768fc862ef03789e0aa9c35d4
3
  size 65480616
modeling_gluformer.py CHANGED
@@ -298,32 +298,35 @@ class Preprocessor:
298
  def unnormalize_glucose(self, glucose):
299
  return (glucose + self.SCALE_1) / (self.SCALE_1 * self.SCALE_2) * (self.UPPER - self.LOWER) + self.LOWER
300
 
301
- def normalize_datetime(self, date):
302
- DAYS_YEAR = 182.5
303
- DAYS_MONTH = 15.5
304
- DAYS_WEEK = 3.5
305
- HOURS_DAY = 12.0
306
- MINUTES_HOUR = 30.0
307
- OFFSET = 1
308
- return np.array([date.timetuple().tm_yday / DAYS_YEAR - OFFSET,
309
- date.day / DAYS_MONTH - OFFSET,
310
- date.weekday() / DAYS_WEEK - OFFSET,
311
- date.hour / HOURS_DAY - OFFSET,
312
- date.minute / MINUTES_HOUR - OFFSET], dtype = float)
313
 
314
  def __call__(self, subject_id, timestamps, glucose_values):
315
- subject_id = torch.tensor([subject_id]).float()
316
- glucose_values = torch.tensor(glucose_values).reshape(1, self.len_seq, 1).float()
 
317
  glucose_values = self.normalize_glucose(glucose_values)
 
318
 
319
  # Model takes any number of inputs to encoder.
320
  # Decoder takes exactly 60 (5 hours of history) previous values with 12 (1 hour) of zeros.
321
  # Timestamps for y are the corresponding timestamp for the 60 values passed into the decoder with 12 future values separated by 5 minutes.
322
- y_timestamps = timestamps[-self.len_label:] + [timestamps[-1] + timedelta(minutes=5 * i) for i in range(self.len_pred)]
323
- decoder_input = torch.cat([glucose_values[:,-self.len_label:,:], torch.zeros(1, self.len_pred, 1).float()], dim=1)
 
 
 
324
 
325
- x_ts = torch.tensor(np.vstack([self.normalize_datetime(date) for date in timestamps])).float().unsqueeze(0)
326
- y_ts = torch.tensor(np.vstack([self.normalize_datetime(date) for date in y_timestamps])).float().unsqueeze(0)
327
  return subject_id, glucose_values, decoder_input, x_ts, y_ts
328
 
329
  class GluformerForTimeSeries(PreTrainedModel):
@@ -348,6 +351,10 @@ class GluformerForTimeSeries(PreTrainedModel):
348
  self.preprocessor = Preprocessor(config.len_seq, config.len_pred, config.len_label)
349
 
350
  def forward(self, subject_id, timestamps, glucose_values):
 
 
 
 
351
  x_id, x_enc, x_dec, x_mark_enc, y_mark_dec = self.preprocessor(subject_id, timestamps, glucose_values)
352
  output, log_var = self.model(x_id, x_enc, x_mark_enc, x_dec, y_mark_dec)
353
  return self.preprocessor.unnormalize_glucose(output), log_var
 
298
  def unnormalize_glucose(self, glucose):
299
  return (glucose + self.SCALE_1) / (self.SCALE_1 * self.SCALE_2) * (self.UPPER - self.LOWER) + self.LOWER
300
 
301
+ def normalize_datetime(self, ts: np.ndarray) -> np.ndarray:
302
+ ts = np.asarray(ts, dtype="datetime64[ns]")
303
+ d, y, m, h = ts.astype("datetime64[D]"), ts.astype("datetime64[Y]"), ts.astype("datetime64[M]"), ts.astype("datetime64[h]")
304
+ return np.stack((
305
+ ((d - y).astype("timedelta64[D]").astype(np.int64) + 1) / 182.5 - 1.0, # day of year
306
+ ((d - m).astype("timedelta64[D]").astype(np.int64) + 1) / 15.5 - 1.0, # day of month
307
+ ((d.astype(np.int64) + 3) % 7) / 3.5 - 1.0, # weekday (Mon=0)
308
+ ((h - d).astype("timedelta64[h]").astype(np.int64)) / 12.0 - 1.0, # hour
309
+ ((ts.astype("datetime64[m]") - h).astype("timedelta64[m]").astype(np.int64)) / 30.0 - 1.0, # minute
310
+ ), axis=-1).astype(float)
 
 
311
 
312
  def __call__(self, subject_id, timestamps, glucose_values):
313
+ batch_size, seq_len = glucose_values.shape
314
+ subject_id = torch.full((batch_size,), subject_id, dtype=torch.float)
315
+ glucose_values = torch.tensor(glucose_values).reshape(-1, self.len_seq, 1).float()
316
  glucose_values = self.normalize_glucose(glucose_values)
317
+ ts = np.asarray(timestamps, dtype=np.int64).reshape(batch_size, -1)
318
 
319
  # Model takes any number of inputs to encoder.
320
  # Decoder takes exactly 60 (5 hours of history) previous values with 12 (1 hour) of zeros.
321
  # Timestamps for y are the corresponding timestamp for the 60 values passed into the decoder with 12 future values separated by 5 minutes.
322
+ nanos_per_interval = np.int64(5 * 60 * 1e9)
323
+ ts_deltas = np.arange(1, self.len_pred + 1, dtype=np.int64) * nanos_per_interval
324
+ ts_deltas = ts_deltas.reshape(1, -1).repeat(batch_size, axis=0)
325
+ y_timestamps = np.concatenate([ts[:, -self.len_label:], ts[:, -1:] + ts_deltas], axis=1)
326
+ decoder_input = torch.cat([glucose_values[:,-self.len_label:,:], torch.zeros(batch_size, self.len_pred, 1).float()], dim=1)
327
 
328
+ x_ts = torch.tensor(self.normalize_datetime(ts)).float()
329
+ y_ts = torch.tensor(self.normalize_datetime(y_timestamps)).float()
330
  return subject_id, glucose_values, decoder_input, x_ts, y_ts
331
 
332
  class GluformerForTimeSeries(PreTrainedModel):
 
351
  self.preprocessor = Preprocessor(config.len_seq, config.len_pred, config.len_label)
352
 
353
  def forward(self, subject_id, timestamps, glucose_values):
354
+ if len(glucose_values.shape) == 1:
355
+ subject_id = subject_id.unsqueeze(0)
356
+ timestamps = timestamps.unsqueeze(0)
357
+ glucose_values = glucose_values.unsqueeze(0)
358
  x_id, x_enc, x_dec, x_mark_enc, y_mark_dec = self.preprocessor(subject_id, timestamps, glucose_values)
359
  output, log_var = self.model(x_id, x_enc, x_mark_enc, x_dec, y_mark_dec)
360
  return self.preprocessor.unnormalize_glucose(output), log_var