from nbdev.config import get_config
Core Elements for Multi Step Ahead Prediction
Create a dataloader for multi step ahead prediction
We create a prediction dataloader by including the system output with a timeshift to the input. The output is shifted one step so that it is always older than the predicted one.
= get_config().config_file.parent
project_root = project_root / 'test_data/WienerHammerstein' f_path
= get_hdf_files(f_path)
hdf_files = 300
init_sz = ['u']
u = ['y']
y = DataBlock(blocks=(SequenceBlock.from_hdf(u+y,TensorSequencesInput,clm_shift=[0,-1]),
seq =[-1])),
SequenceBlock.from_hdf(y,TensorSequencesOutput,clm_shift=CreateDict([DfHDFCreateWindows(win_sz=500+1,stp_sz=100,clm='u')]),
get_items=ApplyToDict(FuncSplitter(lambda o: 'valid' in str(o))))
splitter= seq.dataloaders(hdf_files,bs=32,shuffle=True) dls_pred
0][0].shape,dls_pred.one_batch()[0][1].shape dls_pred.one_batch()[
(torch.Size([500, 2]), torch.Size([500, 2]))
=1) dls_pred.show_batch(max_n
Create a learner Callback for prediction
Instead of creating a specialized dataloader we can instead create a Callback for the learner to add the historic system output data. This creates more flexibility for the learner and requires only one kind of dataloader per dataset.
PredictionCallback
PredictionCallback (t_offset=1, std=None, mean=None)
Concatenates the optionally normalized system output to the input data for autoregression, assumes 1-tuple as input
Type | Default | Details | |
---|---|---|---|
t_offset | int | 1 | the number of steps output is shifted in the past, shortens the sequence length by that number |
std | NoneType | None | standard deviation of the output tensor |
mean | NoneType | None | mean of the output tensor |
We create a dataloader without system output as input and compare the signals after the callback.
= DataBlock(blocks=(SequenceBlock.from_hdf(u,TensorSequencesInput),
seq
SequenceBlock.from_hdf(y,TensorSequencesOutput)),=CreateDict([DfHDFCreateWindows(win_sz=500,stp_sz=100,clm='u')]),
get_items=ApplyToDict(FuncSplitter(lambda o: 'valid' in str(o))))
splitter= seq.dataloaders(hdf_files,bs=32) dls
Evaluate that a simulation model works with the dataset
= SimpleRNN(1,1)
model =nn.MSELoss()).fit(1) Learner(dls,model,loss_func
epoch | train_loss | valid_loss | time |
---|
and a prediction model which expects a 2d input does not work without the callback
= SimpleRNN(2,1)
model lambda: Learner(dls,model,loss_func=nn.MSELoss()).fit(1)) test_fail(
epoch | train_loss | valid_loss | time |
---|
# dls_pred.show_batch(max_n=1)
# dls.show_batch(max_n=1)
= SimpleRNN(2,1)
model = PredictionCallback(1)
pred_callback
pred_callback.init_normalize(dls.one_batch())= Learner(dls,model,loss_func=nn.MSELoss(),cbs=pred_callback)
lrn 1) lrn.fit(
epoch | train_loss | valid_loss | time |
---|