Created
December 14, 2022 21:16
-
-
Save nilsleh/d3c35985ab23a3ada433d0cd4b5a0d7e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import pandas as pd | |
from darts import TimeSeries | |
from darts.dataprocessing.transformers import Scaler | |
from darts.models import TFTModel | |
from darts.datasets import AirPassengersDataset | |
from darts.utils.timeseries_generation import datetime_attribute_timeseries | |
from darts.utils.likelihood_models import QuantileRegression | |
import pytorch_lightning as pl | |
from pytorch_lightning.callbacks import ModelCheckpoint | |
import warnings | |
warnings.filterwarnings("ignore") | |
import logging | |
logging.disable(logging.CRITICAL) | |
def main(): | |
# before starting, we define some constants | |
num_samples = 200 | |
figsize = (9, 6) | |
lowest_q, low_q, high_q, highest_q = 0.01, 0.1, 0.9, 0.99 | |
label_q_outer = f"{int(lowest_q * 100)}-{int(highest_q * 100)}th percentiles" | |
label_q_inner = f"{int(low_q * 100)}-{int(high_q * 100)}th percentiles" | |
# Read data | |
series = AirPassengersDataset().load() | |
# we convert monthly number of passengers to average daily number of passengers per month | |
series = series / TimeSeries.from_series(series.time_index.days_in_month) | |
series = series.astype(np.float32) | |
# Create training and validation sets: | |
training_cutoff = pd.Timestamp("19571201") | |
train, val = series.split_after(training_cutoff) | |
# Normalize the time series (note: we avoid fitting the transformer on the validation set) | |
transformer = Scaler() | |
train_transformed = transformer.fit_transform(train) | |
val_transformed = transformer.transform(val) | |
series_transformed = transformer.transform(series) | |
# create year, month and integer index covariate series | |
covariates = datetime_attribute_timeseries(series, attribute="year", one_hot=False) | |
covariates = covariates.stack( | |
datetime_attribute_timeseries(series, attribute="month", one_hot=False) | |
) | |
covariates = covariates.stack( | |
TimeSeries.from_times_and_values( | |
times=series.time_index, | |
values=np.arange(len(series)), | |
columns=["linear_increase"], | |
) | |
) | |
covariates = covariates.astype(np.float32) | |
# transform covariates (note: we fit the transformer on train split and can then transform the entire covariates series) | |
scaler_covs = Scaler() | |
cov_train, cov_val = covariates.split_after(training_cutoff) | |
scaler_covs.fit(cov_train) | |
covariates_transformed = scaler_covs.transform(covariates) | |
quantiles = [ | |
0.01, | |
0.05, | |
0.1, | |
0.15, | |
0.2, | |
0.25, | |
0.3, | |
0.4, | |
0.5, | |
0.6, | |
0.7, | |
0.75, | |
0.8, | |
0.85, | |
0.9, | |
0.95, | |
0.99, | |
] | |
input_chunk_length = 24 | |
forecast_horizon = 12 | |
work_dir = "./work_dir" | |
my_model = TFTModel( | |
input_chunk_length=input_chunk_length, | |
output_chunk_length=forecast_horizon, | |
hidden_size=64, | |
lstm_layers=1, | |
num_attention_heads=4, | |
dropout=0.1, | |
batch_size=128, | |
n_epochs=1, | |
add_relative_index=False, | |
add_encoders=None, | |
likelihood=QuantileRegression( | |
quantiles=quantiles | |
), # QuantileRegression is set per default | |
# loss_fn=MSELoss(), | |
random_state=42, | |
model_name="my_model", | |
work_dir=work_dir, | |
save_checkpoints=True | |
) | |
checkpoint_callback = ModelCheckpoint( | |
dirpath=work_dir, | |
save_top_k=1, | |
monitor="val_loss", | |
mode="min", | |
every_n_epochs=1, | |
) | |
trainer = pl.Trainer( | |
default_root_dir=work_dir, | |
callbacks=[checkpoint_callback], | |
max_epochs=1 | |
) | |
my_model.fit( | |
series=train_transformed, | |
future_covariates=covariates_transformed, | |
val_series=train_transformed, | |
val_future_covariates=covariates_transformed, | |
trainer=trainer, | |
) | |
previous = my_model.model.output_layer.weight | |
my_model.model.load_from_checkpoint("ckpt_path") | |
after = my_model.model.output_layer.weight | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment