def main(): num_rows = 100 num_columns = 4 timesteps = 20 d = pd.DataFrame(data=np.random.uniform(size=(num_rows, num_columns)), columns=['A', 'B', 'C', 'D']) print(d.head()) # Use <A, B, C> to predict D. predictors = d[['A', 'B', 'C']] targets = d['D'] # backcast length is timesteps. # forecast length is 1. predictors = np.array([predictors[i:i + timesteps] for i in range(num_rows - timesteps)]) targets = np.array([targets[i:i + 1] for i in range(num_rows - timesteps)])[:, :, None] # noinspection PyArgumentEqualDefault model_keras = NBeatsKeras( input_dim=num_columns - 1, output_dim=1, forecast_length=1, nb_blocks_per_stack=1, backcast_length=timesteps ) # plot_model(model_keras, 'pandas.png', show_shapes=True, show_dtype=True) model_keras.compile(loss='mae', optimizer='adam') model_keras.fit(predictors, targets, validation_split=0.2) num_predictions = len(predictors) predictions = model_keras.predict(predictors) np.testing.assert_equal(predictions.shape, (num_predictions, 1, 1)) d['P'] = [np.nan] * (num_rows - num_predictions) + list(model_keras.predict(predictors).squeeze(axis=(1, 2))) print(d)
def main(): # https://keras.io/layers/recurrent/ num_samples, time_steps, input_dim, output_dim = 50_000, 10, 1, 1 # Definition of the model. model_keras = NBeatsKeras(backcast_length=time_steps, forecast_length=output_dim, stack_types=(NBeatsKeras.GENERIC_BLOCK, NBeatsKeras.GENERIC_BLOCK), nb_blocks_per_stack=2, thetas_dim=(4, 4), share_weights_in_stack=True, hidden_layer_units=64) model_pytorch = NBeatsPytorch(backcast_length=time_steps, forecast_length=output_dim, stack_types=(NBeatsPytorch.GENERIC_BLOCK, NBeatsPytorch.GENERIC_BLOCK), nb_blocks_per_stack=2, thetas_dim=(4, 4), share_weights_in_stack=True, hidden_layer_units=64) # Definition of the objective function and the optimizer. model_keras.compile(loss='mae', optimizer='adam') model_pytorch.compile(loss='mae', optimizer='adam') # Definition of the data. The problem to solve is to find f such as | f(x) - y | -> 0. # where f = np.mean. x = np.random.uniform(size=(num_samples, time_steps, input_dim)) y = np.mean(x, axis=1, keepdims=True) # Split data into training and testing datasets. c = num_samples // 10 x_train, y_train, x_test, y_test = x[c:], y[c:], x[:c], y[:c] test_size = len(x_test) # Train the model. print('Keras training...') model_keras.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=20, batch_size=128) print('Pytorch training...') model_pytorch.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=20, batch_size=128) # Save the model for later. model_keras.save('n_beats_model.h5') model_pytorch.save('n_beats_pytorch.th') # Predict on the testing set (forecast). predictions_keras_forecast = model_keras.predict(x_test) predictions_pytorch_forecast = model_pytorch.predict(x_test) np.testing.assert_equal(predictions_keras_forecast.shape, (test_size, model_keras.forecast_length, output_dim)) np.testing.assert_equal(predictions_pytorch_forecast.shape, (test_size, model_pytorch.forecast_length, output_dim)) # Predict on the testing set (backcast). predictions_keras_backcast = model_keras.predict(x_test, return_backcast=True) predictions_pytorch_backcast = model_pytorch.predict(x_test, return_backcast=True) np.testing.assert_equal(predictions_keras_backcast.shape, (test_size, model_keras.backcast_length, output_dim)) np.testing.assert_equal(predictions_pytorch_backcast.shape, (test_size, model_pytorch.backcast_length, output_dim)) # Load the model. model_keras_2 = NBeatsKeras.load('n_beats_model.h5') model_pytorch_2 = NBeatsPytorch.load('n_beats_pytorch.th') np.testing.assert_almost_equal(predictions_keras_forecast, model_keras_2.predict(x_test)) np.testing.assert_almost_equal(predictions_pytorch_forecast, model_pytorch_2.predict(x_test))
def main(): # Let's consider a setup where we have [sunshine] and [rainfall] and we want to predict [rainfall]. # [sunshine] will be our external variable (endogenous). # [rainfall] will be our internal variable (endogenous). # We assume that rainfall[t] depends on the previous values of rainfall[t-1], ... rainfall[t-N]. # And we also think that rainfall[t] depends on sunshine. # Rainfall is 1-D so input_dim=1. We have just one exo variable so exo_dim=1. # Output_dim is also 1-D. It's rainfall[t]. Therefore, output_dim=1. # We have long sequences of rainfall[t], sunshine[t] (t>0) that we cut into length N+1. # N will be the history. and +1 is the one we want to predict. # N-Beats is not like an LSTM. It needs the history window to be finite (of size N<inf). # here N=time_steps. Let's say 20. # We end of having an arbitrary number of sequences (say 100) of length 20+1. num_samples, time_steps, input_dim, output_dim, exo_dim = 1000, 20, 1, 1, 1 # Definition of the model. # NOTE: If you choose the Keras backend with input_dim>1, you have # to set the value here too (in the constructor). model_keras = NBeatsKeras(input_dim=input_dim, backcast_length=time_steps, forecast_length=output_dim, exo_dim=exo_dim) # from keras.utils.vis_utils import plot_model # plot_model(model_keras, 'exo.png') model_keras.compile(loss='mae', optimizer='adam') rainfall = np.random.uniform(size=(num_samples, time_steps + 1, input_dim)) # predictors. x_rainfall = rainfall[:, 0:time_steps, :] x_sunshine = np.random.uniform(size=(num_samples, time_steps, 1)) # target. y_rainfall = rainfall[:, time_steps:, :] model_keras.compile(loss='mae', optimizer='adam') model_keras.fit([x_rainfall, x_sunshine], y_rainfall, epochs=10) np.testing.assert_equal( model_keras.predict([x_rainfall, x_sunshine]).shape, (1000, 1, 1))
def main(): args = get_script_arguments() if args.task in ['m4', 'dummy']: model = NBeatsNet(backcast_length=10, forecast_length=1, stack_types=(NBeatsNet.GENERIC_BLOCK, NBeatsNet.GENERIC_BLOCK), nb_blocks_per_stack=2, thetas_dim=(4, 4), share_weights_in_stack=True, hidden_layer_units=128) elif args.task == 'kcg': model = NBeatsNet(input_dim=2, backcast_length=360, forecast_length=10, stack_types=(NBeatsNet.TREND_BLOCK, NBeatsNet.SEASONALITY_BLOCK), nb_blocks_per_stack=3, thetas_dim=(4, 8), share_weights_in_stack=False, hidden_layer_units=256) elif args.task == 'nrj': model = NBeatsNet(input_dim=1, exo_dim=2, backcast_length=10, forecast_length=1, stack_types=(NBeatsNet.TREND_BLOCK, NBeatsNet.SEASONALITY_BLOCK), nb_blocks_per_stack=2, thetas_dim=(4, 8), share_weights_in_stack=False, hidden_layer_units=128, nb_harmonics=10) else: raise ValueError('Unknown task.') model.compile(loss='mae', optimizer='adam') train_model(model, args.task, is_test=args.test)
print(np.mean(np.abs(dn.apply_inv(b_val_uni) - dn.apply_inv(y_val_uni)))) b2_val_uni = x_val_uni[:, -1, 0] print(np.mean(np.abs(b2_val_uni - y_val_uni))) print(np.mean(np.abs(dn.apply_inv(b2_val_uni) - dn.apply_inv(y_val_uni)))) # noinspection PyArgumentEqualDefault m = NBeatsNet( stack_types=(NBeatsNet.GENERIC_BLOCK, NBeatsNet.GENERIC_BLOCK, NBeatsNet.GENERIC_BLOCK), nb_blocks_per_stack=3, forecast_length=1, backcast_length=univariate_past_history, thetas_dim=(15, 15, 15), share_weights_in_stack=False, hidden_layer_units=384) m.compile(loss='mae', optimizer='adam') class EvaluateModelCallback(Callback): def on_epoch_end(self, epoch, logs=None): b3_val_uni = m.predict(x_val_uni) print(f'[{epoch}] b3_val_uni.shape=', b3_val_uni.shape) print(np.mean(np.abs(b3_val_uni - y_val_uni))) print(np.mean(np.abs(dn.apply_inv(b3_val_uni) - dn.apply_inv(y_val_uni)))) print('*' * 80) m.fit(x_train_uni, y_train_uni, epochs=20, validation_split=0.1, shuffle=True, callbacks=[EvaluateModelCallback()])