mirror of
https://github.com/wassname/seq2seq-time.git
synced 2026-07-12 12:19:10 +08:00
misc, fix transformer, more plots
This commit is contained in:
@@ -55,7 +55,6 @@ Using sequence to sequence interfaces for timeseries regression
|
||||
<td>1.08</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
<th>MetroInterstateTraffic</th>
|
||||
<td>1.76</td>
|
||||
<td>-0.27</td>
|
||||
|
||||
+900
-10920
File diff suppressed because one or more lines are too long
@@ -19,15 +19,22 @@
|
||||
#
|
||||
# In this notebook we are going to tackle a harder problem:
|
||||
# - predicting the future on a timeseries
|
||||
# - using an LSTM
|
||||
# - by outputing sequence of predictions
|
||||
# - with rough uncertainty (uncalibrated)
|
||||
# - outputing sequence of predictions
|
||||
# - using forecasted information (like weather report, week, or cycle of the moon)
|
||||
#
|
||||
# Not many papers benchmark movels for multivariate regression, much less seq prediction with uncertainty. So this notebook will try a range of models on a range of dataset.
|
||||
#
|
||||
# We do this using a sequence to sqequence interface
|
||||
#
|
||||
# <img src="../reports/figures/Seq2Seq for regression.png" />
|
||||
#
|
||||
#
|
||||
# https://medium.com/@boitemailjeanmid/smart-meters-in-london-part1-description-and-first-insights-jean-michel-d-db97af2de71b
|
||||
#
|
||||
|
||||
# - [ ] tensorboard / wandb
|
||||
# - [ ] show test train
|
||||
# - [ ] val
|
||||
# - [ ] don't overfit
|
||||
# - [ ] TCN
|
||||
|
||||
# OPTIONAL: Load the "autoreload" extension so that code can change. But blacklist large modules
|
||||
# %load_ext autoreload
|
||||
@@ -49,10 +56,11 @@ from torch.autograd import Variable
|
||||
import torch
|
||||
import torch.utils.data
|
||||
|
||||
import xarray as xr
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
plt.rcParams['figure.figsize'] = (12.0, 3.0)
|
||||
plt.rcParams['figure.figsize'] = (10.0, 2.0)
|
||||
plt.style.use('ggplot')
|
||||
|
||||
from pathlib import Path
|
||||
@@ -71,11 +79,19 @@ from seq2seq_time.util import dset_to_nc
|
||||
import logging, sys
|
||||
# logging.basicConfig(stream=sys.stdout, level=logging.INFO)
|
||||
|
||||
# +
|
||||
import holoviews as hv
|
||||
from holoviews import opts
|
||||
from holoviews.operation.datashader import datashade, dynspread
|
||||
hv.extension('bokeh')
|
||||
|
||||
# holoview datashader timeseries options
|
||||
# %opts RGB [width=800 height=200 active_tools=["xwheel_zoom"] default_tools=["xpan","xwheel_zoom", "reset"] toolbar="right"]
|
||||
# -
|
||||
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore")
|
||||
|
||||
# ## Parameters
|
||||
|
||||
@@ -91,15 +107,16 @@ num_workers = 5
|
||||
freq = '30T'
|
||||
max_rows = 5e5
|
||||
datasets_root = Path('../data/processed/')
|
||||
|
||||
|
||||
window_past
|
||||
# -
|
||||
|
||||
# ## Plot helpers
|
||||
|
||||
|
||||
|
||||
# +
|
||||
def plot_prediction(ds_preds, i):
|
||||
"""Plot a prediction into the future, at a single point in time."""
|
||||
def plot_prediction(ds_preds, i, ax=None, title='', std=False, label='pred', legend=False):
|
||||
"""Plot a prediction into the future, at a single point in time."""
|
||||
d = ds_preds.isel(t_source=i)
|
||||
|
||||
# Get arrays
|
||||
@@ -109,18 +126,16 @@ def plot_prediction(ds_preds, i):
|
||||
yt = d.y_true
|
||||
now = d.t_source.squeeze()
|
||||
|
||||
|
||||
plt.figure(figsize=(12, 4))
|
||||
|
||||
plt.scatter(xf, yt, label='true', c='k', s=6)
|
||||
plt.scatter(xf, yt, c='k', s=6, label='true' if legend else None)
|
||||
ylim = plt.ylim()
|
||||
|
||||
# plot prediction
|
||||
plt.fill_between(xf, yp-2*s, yp+2*s, alpha=0.25,
|
||||
facecolor="b",
|
||||
interpolate=True,
|
||||
label="2 std",)
|
||||
plt.plot(xf, yp, label='pred', c='b')
|
||||
if std:
|
||||
plt.fill_between(xf, yp-2*s, yp+2*s, alpha=0.25,
|
||||
facecolor="b",
|
||||
interpolate=True,
|
||||
label="2 std" if legend else None,)
|
||||
plt.plot(xf, yp, label=label)
|
||||
|
||||
# plot true
|
||||
plt.scatter(
|
||||
@@ -131,24 +146,26 @@ def plot_prediction(ds_preds, i):
|
||||
)
|
||||
|
||||
# plot a red line for now
|
||||
plt.vlines(x=now, ymin=0, ymax=1, label='now', color='r')
|
||||
plt.vlines(x=now, ymin=ylim[0], ymax=ylim[1], color='grey', ls='--')
|
||||
plt.ylim(*ylim)
|
||||
|
||||
now=pd.Timestamp(now.values)
|
||||
plt.title(f'Prediction NLL={d.nll.mean().item():2.2g}')
|
||||
plt.xlabel(f'{now.date()}')
|
||||
plt.ylabel('energy(kWh/hh)')
|
||||
plt.legend()
|
||||
plt.xticks(rotation=45)
|
||||
plt.show()
|
||||
|
||||
plt.title(title or f'Prediction NLL={d.nll.mean().item():2.2g}')
|
||||
plt.xticks(rotation=0)
|
||||
if legend:
|
||||
plt.legend()
|
||||
plt.xlabel(f'{now}')
|
||||
plt.ylabel(ds_preds.attrs['targets'])
|
||||
return now
|
||||
|
||||
def plot_performance(ds_preds, full=False):
|
||||
"""Multiple plots using xr_preds"""
|
||||
plot_prediction(ds_preds, 24)
|
||||
plot_prediction(ds_preds, 24, std=True, legend=True)
|
||||
plt.show()
|
||||
|
||||
ds_preds.mean('t_source').plot.scatter('t_ahead_hours', 'nll') # Mean over all predictions
|
||||
n = len(ds_preds.t_source)
|
||||
plt.ylabel('Negative Log Likelihood (lower is better)')
|
||||
plt.ylabel('NLL (lower is better)')
|
||||
plt.xlabel('Hours ahead')
|
||||
plt.title(f'NLL vs time ahead (no. samples={n})')
|
||||
plt.show()
|
||||
@@ -175,10 +192,39 @@ def plot_hist(trainer):
|
||||
df_histe = df_hist.set_index('epoch').groupby('epoch').mean()
|
||||
if len(df_histe)>1:
|
||||
df_histe[['loss/train', 'loss/val']].plot(title='history')
|
||||
plt.show()
|
||||
return df_histe
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ## Datasets
|
||||
|
||||
|
||||
|
||||
# +
|
||||
from seq2seq_time.data.data import IMOSCurrentsVel, AppliancesEnergyPrediction, BejingPM25, GasSensor, MetroInterstateTraffic
|
||||
|
||||
datasets = [BejingPM25, GasSensor, AppliancesEnergyPrediction, MetroInterstateTraffic, IMOSCurrentsVel]
|
||||
datasets
|
||||
# -
|
||||
|
||||
# View train, test, val splits
|
||||
l = hv.Layout()
|
||||
for dataset in datasets:
|
||||
d = dataset(datasets_root)
|
||||
|
||||
p = dynspread(
|
||||
datashade(hv.Scatter(d.df_train[d.columns_target[0]]),
|
||||
cmap='red'))
|
||||
p *= dynspread(
|
||||
datashade(hv.Scatter(d.df_val[d.columns_target[0]]),
|
||||
cmap='green'))
|
||||
p *= dynspread(
|
||||
datashade(hv.Scatter(d.df_test[d.columns_target[0]]),
|
||||
cmap='blue'))
|
||||
p = p.opts(title=f"{dataset}")
|
||||
l += p
|
||||
l.cols(1)
|
||||
|
||||
# ## Lightning
|
||||
|
||||
@@ -262,30 +308,30 @@ models = [
|
||||
# lambda: TransformerAutoR(input_size,
|
||||
# output_size, hidden_out_size=32),
|
||||
lambda: RANP(input_size,
|
||||
output_size, hidden_dim=32,
|
||||
latent_dim=64, n_decoder_layers=4),
|
||||
output_size, hidden_dim=64, dropout=0.5,
|
||||
latent_dim=32, n_decoder_layers=4),
|
||||
lambda: LSTM(input_size,
|
||||
output_size,
|
||||
hidden_size=80,
|
||||
hidden_size=32,
|
||||
lstm_layers=3,
|
||||
lstm_dropout=0.3),
|
||||
lstm_dropout=0.4),
|
||||
lambda: LSTMSeq2Seq(input_size,
|
||||
output_size,
|
||||
hidden_size=64,
|
||||
lstm_layers=2,
|
||||
lstm_dropout=0.25),
|
||||
lstm_dropout=0.4),
|
||||
lambda: TransformerSeq2Seq(input_size,
|
||||
output_size,
|
||||
hidden_size=128,
|
||||
hidden_size=64,
|
||||
nhead=8,
|
||||
nlayers=4,
|
||||
attention_dropout=0.2),
|
||||
attention_dropout=0.4),
|
||||
lambda: Transformer(input_size,
|
||||
output_size,
|
||||
attention_dropout=0.2,
|
||||
attention_dropout=0.4,
|
||||
nhead=8,
|
||||
nlayers=8,
|
||||
hidden_size=128),
|
||||
nlayers=6,
|
||||
hidden_size=64),
|
||||
lambda :TransformerProcess(input_size,
|
||||
output_size, hidden_size=16,
|
||||
latent_dim=8, dropout=0.5,
|
||||
@@ -294,11 +340,7 @@ models = [
|
||||
]
|
||||
# models
|
||||
|
||||
# +
|
||||
from seq2seq_time.data.data import IMOSCurrentsVel, AppliancesEnergyPrediction, BejingPM25, GasSensor, MetroInterstateTraffic
|
||||
|
||||
datasets = [IMOSCurrentsVel, BejingPM25, GasSensor, AppliancesEnergyPrediction, MetroInterstateTraffic]
|
||||
datasets
|
||||
|
||||
# +
|
||||
# GasSensor(datasets_root)
|
||||
@@ -309,25 +351,26 @@ datasets
|
||||
from collections import defaultdict
|
||||
results = defaultdict(dict)
|
||||
|
||||
# +
|
||||
# tmp
|
||||
model = Transformer(input_size,
|
||||
output_size,
|
||||
attention_dropout=0.4,
|
||||
nhead=2,
|
||||
nlayers=4,
|
||||
hidden_size=16)
|
||||
|
||||
x_past, y_past, x_future, y_future = next(iter(dl_val))
|
||||
model(x_past, y_past, x_future, y_future)
|
||||
# -
|
||||
|
||||
from seq2seq_time.metrics import rmse, smape
|
||||
|
||||
for Dataset in datasets:
|
||||
dataset_name = Dataset.__name__
|
||||
dataset = Dataset(datasets_root)
|
||||
ds_train, ds_test = dataset.to_datasets(window_past=window_past,
|
||||
window_future=window_future)
|
||||
|
||||
# Init data
|
||||
x_past, y_past, x_future, y_future = ds_train.get_rows(10)
|
||||
input_size = x_past.shape[-1]
|
||||
output_size = y_future.shape[-1]
|
||||
|
||||
|
||||
# +
|
||||
for Dataset in datasets:
|
||||
dataset_name = Dataset.__name__
|
||||
dataset = Dataset(datasets_root)
|
||||
ds_train, ds_test = dataset.to_datasets(window_past=window_past,
|
||||
ds_train, ds_val, ds_test = dataset.to_datasets(window_past=window_past,
|
||||
window_future=window_future)
|
||||
|
||||
# Init data
|
||||
@@ -341,7 +384,7 @@ for Dataset in datasets:
|
||||
shuffle=True,
|
||||
pin_memory=num_workers == 0,
|
||||
num_workers=num_workers)
|
||||
dl_test = DataLoader(ds_test,
|
||||
dl_val = DataLoader(ds_val,
|
||||
batch_size=batch_size,
|
||||
num_workers=num_workers)
|
||||
|
||||
@@ -353,21 +396,21 @@ for Dataset in datasets:
|
||||
print(dataset_name, model_name)
|
||||
|
||||
# Wrap in lightning
|
||||
patience = 2
|
||||
patience = 3
|
||||
model = PL_MODEL(pt_model,
|
||||
lr=3e-4, patience=patience,
|
||||
lr=3e-3, patience=patience,
|
||||
weight_decay=1e-5).to(device)
|
||||
|
||||
# Trainer
|
||||
trainer = pl.Trainer(
|
||||
gpus=1,
|
||||
min_epochs=2,
|
||||
max_epochs=20,
|
||||
max_epochs=300,
|
||||
amp_level='O1',
|
||||
precision=16,
|
||||
|
||||
limit_train_batches=1000,
|
||||
limit_val_batches=100,
|
||||
limit_train_batches=300,
|
||||
limit_val_batches=30,
|
||||
logger=CSVLogger("../outputs", name=f'{dataset_name}_{model_name}'),
|
||||
callbacks=[
|
||||
EarlyStopping(monitor='loss/val', patience=patience * 2, verbose=True),
|
||||
@@ -375,7 +418,7 @@ for Dataset in datasets:
|
||||
)
|
||||
|
||||
# Train
|
||||
trainer.fit(model, dl_train, dl_test)
|
||||
trainer.fit(model, dl_train, dl_val)
|
||||
|
||||
ds_preds = predict(model.to(device),
|
||||
ds_test,
|
||||
@@ -387,9 +430,9 @@ for Dataset in datasets:
|
||||
print(f'mean_NLL {ds_preds.nll.mean().item():2.2f}')
|
||||
loss = ds_preds.nll.mean().item()
|
||||
|
||||
# Performance
|
||||
# print(plot_hist(trainer))
|
||||
# plot_performance(ds_preds)
|
||||
# Performance TODO tensorboard, wandb
|
||||
print(plot_hist(trainer))
|
||||
plot_performance(ds_preds)
|
||||
|
||||
metrics = dict(
|
||||
rmse=rmse(ds_preds.y_true, ds_preds.y_pred).item(),
|
||||
@@ -408,20 +451,88 @@ for Dataset in datasets:
|
||||
df_results = pd.concat({k:pd.DataFrame(v) for k,v in results.items()})
|
||||
display(df_results)
|
||||
|
||||
# +
|
||||
# File "/media/wassname/Storage5/projects2/3ST/seq2seq-time/seq2seq_time/models/transformer.py", line 54, in forward
|
||||
# outputs = self.encoder(x, mask=mask#, src_key_padding_mask=x_key_padding_mask
|
||||
# File "/media/wassname/Storage5/projects2/3ST/seq2seq-time/seq2seq_time/models/transformer.py", line 54, in forward
|
||||
# outputs = self.encoder(x, mask=mask#, src_key_padding_mask=x_key_padding_mask
|
||||
|
||||
# -
|
||||
|
||||
df_results.xs('nll', level=1).round(2)
|
||||
# # Leaderboard
|
||||
|
||||
# +
|
||||
# ds_preds.to_netcdf(trainer.logger.experiment.log_dir+'/ds_preds2.nc')
|
||||
# -
|
||||
def bold_min(data):
|
||||
'''
|
||||
highlight the maximum in a Series or DataFrame
|
||||
'''
|
||||
attr = 'font-weight: bold'
|
||||
#remove % and cast to float
|
||||
data = data.replace('%','', regex=True).astype(float)
|
||||
if data.ndim == 1: # Series from .apply(axis=0) or axis=1
|
||||
is_min = data == data.min()
|
||||
return [attr if v else '' for v in is_min]
|
||||
else: # from .apply(axis=None)
|
||||
is_min = data == data.min().min()
|
||||
return pd.DataFrame(np.where(is_min, attr, ''),
|
||||
index=data.index, columns=data.columns)
|
||||
|
||||
|
||||
print(f'Negative Log-Likelihood (NLL).\nover {window_future} steps')
|
||||
d=df_results.xs('nll', level=1).T.round(2)
|
||||
d.style.apply(bold_min)
|
||||
|
||||
print(f'Symmetric mean absolute percentage error (SMAPE)\nover {window_future} steps')
|
||||
d=df_results.xs('smape', level=1).T.round(2)
|
||||
d.style.apply(bold_min)
|
||||
# # Plots
|
||||
# # plots
|
||||
# Load saved preds
|
||||
results = defaultdict(dict)
|
||||
for Dataset in datasets:
|
||||
dataset_name = Dataset.__name__
|
||||
for m_fn in models:
|
||||
pt_model = m_fn()
|
||||
model_name = type(pt_model).__name__
|
||||
|
||||
checkpoint_name = f"{dataset_name}_{model_name}"
|
||||
save_dir = Path(f"../outputs")/checkpoint_name
|
||||
fs = sorted(save_dir.glob("**/ds_preds.nc"))
|
||||
if len(fs)>0:
|
||||
ds_preds = xr.open_dataset(fs[-1])
|
||||
results[dataset_name][model_name] = ds_preds
|
||||
|
||||
data_i = 100
|
||||
|
||||
|
||||
|
||||
# Plot mean of predictions
|
||||
for dataset in results.keys():
|
||||
for model in results[dataset].keys():
|
||||
ds_preds = results[dataset][model]
|
||||
plot_prediction(ds_preds, data_i, label=f"{model}")
|
||||
plt.title(dataset)
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
# +
|
||||
dataset='BejingPM25'
|
||||
n = len(results[dataset].keys())
|
||||
|
||||
plt.figure(figsize=(8, 1.5*n))
|
||||
plt.suptitle(f'Plots with confidence for {dataset} ')
|
||||
for i, model in enumerate(results[dataset].keys()):
|
||||
plt.subplot(n, 1, i+1)
|
||||
ds_preds = results[dataset][model]
|
||||
if i==n-1:
|
||||
# The last one has the legend
|
||||
plot_prediction(ds_preds, data_i, title=f"{model}", std=True, legend=True)
|
||||
else:
|
||||
plot_prediction(ds_preds, data_i, title=f"{model}", std=True, )
|
||||
|
||||
# share the x axis
|
||||
locs, _ = plt.xticks()
|
||||
plt.xticks(locs, labels=[])
|
||||
plt.xlabel(None)
|
||||
plt.subplots_adjust()
|
||||
# -
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+25
-18
@@ -26,7 +26,7 @@ class RegressionForecastData:
|
||||
self.df = self.download()
|
||||
self.df_norm, self.scaler = self.normalize(self.df)
|
||||
self.output_scaler = next(filter(lambda r:r[0][0] in self.columns_target, self.scaler.features))[-1]
|
||||
self.df_train, self.df_test = self.split(self.df_norm)
|
||||
self.df_train, self.df_val, self.df_test = self.split(self.df_norm)
|
||||
|
||||
# Check processing
|
||||
self.check()
|
||||
@@ -46,7 +46,8 @@ class RegressionForecastData:
|
||||
|
||||
def split(self, df_norm: pd.DataFrame) -> Tuple[pd.DataFrame, pd.DataFrame]:
|
||||
df_train, df_test = timeseries_split(df_norm)
|
||||
return df_train, df_test
|
||||
df_test, df_val = timeseries_split(df_test, 0.5)
|
||||
return df_train, df_val, df_test
|
||||
|
||||
def check(self) -> None:
|
||||
"""Check the resulting dataframe"""
|
||||
@@ -61,8 +62,9 @@ class RegressionForecastData:
|
||||
def to_datasets(self, window_past: int, window_future: int, valid:bool=False) -> Tuple[Seq2SeqDataSet, Seq2SeqDataSet]:
|
||||
"""Convert to torch datasets"""
|
||||
ds_train = Seq2SeqDataSet(self.df_train, window_past=window_past, window_future=window_future, columns_target=self.columns_target, columns_past=self.columns_past)
|
||||
ds_val = Seq2SeqDataSet(self.df_val, window_past=window_past, window_future=window_future, columns_target=self.columns_target, columns_past=self.columns_past)
|
||||
ds_test = Seq2SeqDataSet(self.df_test, window_past=window_past, window_future=window_future, columns_target=self.columns_target, columns_past=self.columns_past)
|
||||
return ds_train, ds_test
|
||||
return ds_train, ds_val, ds_test
|
||||
|
||||
def __repr__(self):
|
||||
return f'<{type(self).__name__} {self.df.shape if (self.df is not None) else None}>'
|
||||
@@ -76,27 +78,32 @@ class GasSensor(RegressionForecastData):
|
||||
columns_forecast = ['Flow rate (mL/min)', 'Heater voltage (V)']
|
||||
|
||||
def download(self):
|
||||
# TODO cache in faster format
|
||||
url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/00487/gas-sensor-array-temperature-modulation.zip'
|
||||
|
||||
# download if needed
|
||||
# extract_path = self.datasets_root/'gas-sensor-array-temperature-modulation.zip'
|
||||
download_url(url, self.datasets_root)
|
||||
outfile = self.datasets_root / 'gas-sensor-array-temperature-modulation.pk'
|
||||
if not outfile.exists():
|
||||
|
||||
# Load csv's from inside zip
|
||||
zf = zipfile.ZipFile(self.datasets_root / 'gas-sensor-array-temperature-modulation.zip')
|
||||
dfs=[]
|
||||
for f in zf.namelist():
|
||||
if f.endswith('.csv'):
|
||||
now = pd.to_datetime(Path(f).stem, format='%Y%m%d_%H%M%S')
|
||||
df = pd.read_csv(zf.open(f))
|
||||
df.index = pd.to_timedelta(df['Time (s)'], unit='s') + now
|
||||
dfs.append(df)
|
||||
self.df = pd.concat(dfs).dropna(subset=self.columns_target)
|
||||
# Load csv's from inside zip
|
||||
zf = zipfile.ZipFile(self.datasets_root / 'gas-sensor-array-temperature-modulation.zip')
|
||||
dfs=[]
|
||||
for f in zf.namelist():
|
||||
if f.endswith('.csv'):
|
||||
now = pd.to_datetime(Path(f).stem, format='%Y%m%d_%H%M%S')
|
||||
df = pd.read_csv(zf.open(f))
|
||||
df.index = pd.to_timedelta(df['Time (s)'], unit='s') + now
|
||||
dfs.append(df)
|
||||
self.df = pd.concat(dfs).dropna(subset=self.columns_target)
|
||||
|
||||
df = df[[ 'CO (ppm)', 'Humidity (%r.h.)', 'Temperature (C)',
|
||||
'Flow rate (mL/min)', 'Heater voltage (V)', 'R1 (MOhm)']]
|
||||
df = df.resample('0.3S').first()
|
||||
|
||||
df = df[[ 'CO (ppm)', 'Humidity (%r.h.)', 'Temperature (C)',
|
||||
'Flow rate (mL/min)', 'Heater voltage (V)', 'R1 (MOhm)']]
|
||||
df = df.resample('0.3S').first()
|
||||
|
||||
df.to_pickle(outfile)
|
||||
df = pd.read_pickle(outfile)
|
||||
return df
|
||||
|
||||
|
||||
@@ -304,6 +311,6 @@ class IMOSCurrentsVel(RegressionForecastData):
|
||||
columns=['HEIGHT_ABOVE_SENSOR', 'NOMINAL_DEPTH'])
|
||||
df['SPD'] = np.sqrt(df.VCUR**2 + df.UCUR**2)
|
||||
df.dropna(subset=self.columns_target, inplace=True)
|
||||
df = df.resample('30T').first()
|
||||
df = df.resample('30T').first()[:'2015']
|
||||
|
||||
return df
|
||||
|
||||
@@ -31,7 +31,7 @@ class Seq2SeqDataSet(torch.utils.data.Dataset):
|
||||
assert df.index.freq is not None, 'should have freq'
|
||||
assert_no_objects(df)
|
||||
|
||||
self.freq = self.df.index.freq
|
||||
self.freq = df.index.freq
|
||||
self.df = df.dropna(subset=columns_target).ffill()
|
||||
|
||||
self.window_past = window_past
|
||||
|
||||
@@ -48,7 +48,7 @@ class Transformer(nn.Module):
|
||||
|
||||
x = self.enc_emb(x).permute(1, 0, 2)
|
||||
|
||||
B, S, _ = x.shape
|
||||
S, B, _ = x.shape
|
||||
mask = mask_upper_triangular(S, device)
|
||||
|
||||
outputs = self.encoder(x, mask=mask#, src_key_padding_mask=x_key_padding_mask
|
||||
|
||||
@@ -49,7 +49,7 @@ def predict(model, ds_test, batch_size, device='cpu', scaler=None):
|
||||
"y_true": (["t_source", "t_ahead",], y_future),
|
||||
},
|
||||
coords={"t_source": t_source, "t_ahead": t_ahead, "t_behind": t_behind},
|
||||
attrs={'freq': ds_test.freq, "model": str(model), "targets": ds_test.columns_target}
|
||||
attrs={'freq': str(ds_test.freq), "model": str(type(model)), "targets": ds_test.columns_target}
|
||||
)
|
||||
xrs.append(xr_out)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user