У меня есть сценарий построения модели LSTM, приспособления к ней для обучения данных, прогнозирования по некоторым тестовым данным. (и просто для забавных сюжетных прогнозов на данных о поездах, поскольку они должны быть близки к данным о поездах, просто чтобы узнать, хорошо ли построена моя модель)
1) Первая проблема заключается в том, что прогнозы на тесте и данные о поездах совершенно разные, в зависимости от того, предсказываю ли я сначала поезд или тест.
2) Вторая проблема может быть связана с первой, поэтому каждый раз, когда я запускаю свой скрипт, прогнозы на тестовых данных совершенно разные. Я знаю, что в нейронных сетях есть какая-то случайность, но, как вы можете видеть на моих полученных графиках, она полностью отличается:
edit1: я пытался установить «stateful = False» как это было предложено в комментариях, но безуспешно.
edit2: я обновил скрипт и графики и предоставил некоторые базовые c синусоидальные образцы данных в новом коде. Проблемы все еще существуют даже в этом простом примере
результирующих графиков прогнозов с сохранением состояния = False
Я получил входной сигнал X в виде синусоиды с 100 временных шагов и случайная амплитуда и частота. Моя цель у соотносится с Х (на каждом временном шаге) и в этом случае также является синусоидой. Форма моих данных:
X_train.shape = (100, 1, 1)
y_train.shape = (100,)
X_test.shape = (100, 1, 1)
y_test.shape = (100,)
Я использую сеть LSTM, пытаясь согласовать полную синусоидальную волну, поэтому размер партии = 100, и прогнозирую каждую точку тестового сигнала, поэтому размер партии для предсказание = 1. Также я вручную сбрасываю состояние LSTM после каждой эпохи, как упомянуто здесь: https://machinelearningmastery.com/use-different-batch-sizes-training-predicting-python-keras/
Для построения своей сети я следовал «правилам keras» как упомянуто здесь: Задержка эха греха - не может воспроизвести результат Tensorflow в Keras
Я знаю базовые c подходы к решению проблем, как предложено здесь: Неправильные предсказания с Нейронная сеть LSTM , но у меня ничего не сработало.
Я благодарен за любую помощь по этому вопросу, а также за то, что я задавал лучшие вопросы, на случай, если я что-то не так сделал, потому что это мой первый пост здесь стек.
Спасибо вам всем! Вот мой пример кода:
import numpy as np
import matplotlib.pyplot as plt
from keras import models, layers, optimizers
from keras.callbacks import Callback
# create training sample data
Fs = 100 # sample rate
z = np.arange(100)
f = 1 # frequency in Hz
X_train = np.sin(2 * np.pi * f * z / Fs)
y_train = 0.1 * np.sin(2 * np.pi * f * z / Fs)
# create test sample data
f = 1 # frequency in Hz
X_test = np.sin(2 * np.pi * f * z / Fs) * 2
y_test = 0.2 * np.sin(2 * np.pi * f * z / Fs)
# convert data into LSTM compatible format
y_train = np.array(y_train)
y_test = np.array(y_test)
X_train = X_train.reshape(X_train.shape[0], 1, 1)
X_test = X_test.reshape(X_test.shape[0], 1, 1)
# build and compile model
model = models.Sequential()
model.add(layers.LSTM(1, batch_input_shape=(len(X_train), X_train.shape[1], X_train.shape[2]),
return_sequences=False, stateful=False))
model.add(layers.Dense(X_train.shape[1], input_shape=(1,), activation='linear'))
model.compile(optimizer=optimizers.Adam(lr=0.01, decay=0.008, amsgrad=True), loss='mean_squared_error', metrics=['mae'])
# construct a class for keras callbacks, to make sure the cell state is reset after each epoch
class ResetStatesAfterEachEpoch(Callback):
def on_epoch_end(self, epoch, logs=None):
self.model.reset_states()
reset_state = ResetStatesAfterEachEpoch()
callbacks = [reset_state]
# fit model to training data
history = model.fit(X_train, y_train, epochs=20000, batch_size=len(X_train),
shuffle=False, callbacks=callbacks)
# re-define LSTM model with weights of fit model to predict for 1 point, so also re-define the batch size to 1
new_batch_size = 1
new_model = models.Sequential()
new_model.add(layers.LSTM(1, batch_input_shape=(new_batch_size, X_test.shape[1], X_test.shape[2]), return_sequences=False,
stateful=False))
new_model.add(layers.Dense(X_test.shape[1], input_shape=(1,), activation='linear'))
# copy weights to new model
old_weights = model.get_weights()
new_model.set_weights(old_weights)
# single point prediction on train data
y_pred_train = new_model.predict(X_train, batch_size=new_batch_size)
# single point prediction on test data
y_pred_test = new_model.predict(X_test, batch_size=new_batch_size)
# plot predictions
plt.figure()
plt.plot(y_test, 'r', label='ground truth test',
linestyle='dashed', linewidth=0.8)
plt.plot(y_train, 'b', label='ground truth train',
linestyle='dashed', linewidth=0.8)
plt.plot(y_pred_test, 'g',
label='y pred test', linestyle='dotted',
linewidth=0.8)
plt.plot(y_pred_train, 'k',
label='y pred train', linestyle='-.',
linewidth=0.8)
plt.title('pred order: test, train')
plt.xlabel('time steps')
plt.ylabel('y')
plt.legend(prop={'size': 8})
plt.show()