Upload 3 files
Browse files- config.json +2 -2
- model.safetensors +1 -1
- 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.
|
| 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:
|
| 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,
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 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 |
-
|
| 316 |
-
|
|
|
|
| 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 |
-
|
| 323 |
-
|
|
|
|
|
|
|
|
|
|
| 324 |
|
| 325 |
-
x_ts = torch.tensor(
|
| 326 |
-
y_ts = torch.tensor(
|
| 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
|