У меня возникли проблемы с тем, чтобы заставить модель LSTM в Керасе тренироваться на последних 4 временных шагах, а затем просто прогнозировать следующие 2 временных шага.
Я уверен, что это возможно, но думаю, что я просто путаю некоторые из keras api.
Здесь - это книга Google Colab, которая генерирует некоторые поддельные данные, изменяет X и Y для передачи в модель, а затем обучает модель.
Если я установлю X_N_TIMESTEPS
равным Y_N_TIMESTEPS
, он будет работать нормально - так, например, используйте последние 4 временных шага, чтобы предсказать следующие 4.
Но я пытаюсьбыть немного более общим и иметь возможность тренироваться, скажем, на последних 4 шагах, а затем прогнозировать следующие 2. Функция make_xy()
изменяет данные так, как мне кажется.Например,
X.shape=(1995, 4, 3)
Y.shape=(1995, 2, 3)
Я думаю, что мне не хватает, чтобы сказать последнему слою Dense()
, что я хочу, чтобы он выводил всего 2 раза.Я получаю следующую ошибку:
ValueError: Ошибка при проверке цели: ожидается, что плотность_1 будет иметь форму (4, 3), но получен массив с формой (2, 3)
Какой тип подсказывает, что последний плотный слой не знает, я просто хочу 2 временных шага, хотя это то, что я передаю как значения Y.
Я нашел это , которое указывало, что, возможно, я мог бы передать output_dim последнему плотному слою, но я получаю ошибку, если пытаюсь сказать, что мне нужно использовать keras api v2, и когда япосмотрите на документы по Плотным Я думаю, API с тех пор, должно быть, немного изменилось.
Вот весь код (в случае, если он предпочтительнее ссылки на colab):
import numpy as np
import pandas as pd
from numpy import concatenate
from matplotlib import pyplot
from keras.models import Sequential
from keras.callbacks import Callback
from keras.layers import LSTM, Dense, Activation
import matplotlib.pyplot as plt
# %matplotlib inline
# define some variables
N_FEATURES = 3
X_N_TIMESTEPS = 4
Y_N_TIMESTEPS = 2
N_DATA_ORIG = 3000
N_ROLLING = 1000
N_DATA = N_DATA_ORIG - N_ROLLING
# make some noisy but smooth looking data
data = np.sqrt(np.random.rand(N_DATA_ORIG,N_FEATURES))
df_data = pd.DataFrame(data)
df_data = df_data.rolling(window=N_ROLLING).mean()
df_data = df_data.dropna()
df_data = df_data.head(N_DATA)
print(df_data.shape)
data = df_data.values
print(data.shape)
print(df_data.head())
# plot the normal healthy data
fig, ax = plt.subplots(num=None, figsize=(14, 6), dpi=80, facecolor='w', edgecolor='k')
size = len(data)
for x in range(data.shape[1]):
ax.plot(range(0,size), data[:,x], '-', linewidth=1)
def make_xy(data,x_n_timesteps,y_n_timesteps,print_info=True):
''' Function to reshape the data into model ready format, either for training or prediction.
'''
# get original data shape
data_shape = data.shape
# get n_features from shape of input data
n_features = data_shape[1]
# loop though each row of data and reshape accordingly
for i in range(len(data)):
# row to start on for x
xi = i
# row to start on for y
yi = i + x_n_timesteps
x = np.array([data[i:(i+x_n_timesteps),]])
y = np.array([data[yi:(yi+y_n_timesteps),]])
# only collect valid shapes
if (x.shape == (1,x_n_timesteps,n_features)) & (y.shape == (1,y_n_timesteps,n_features)):
# if initial data then copy else concatenate
if i == 0:
X = x
Y = y
else:
X = np.concatenate((X,x))
Y = np.concatenate((Y,y))
if print_info:
print('X.shape={}'.format(X.shape))
print('Y.shape={}'.format(Y.shape))
return X, Y
# build network
model = Sequential()
model.add(LSTM(10,input_shape=(X_N_TIMESTEPS,N_FEATURES),return_sequences=True))
model.add(LSTM(10,return_sequences=True))
model.add(Dense(N_FEATURES))
model.compile(loss='mae', optimizer='adam')
# print model summary
print(model.summary())
# reshape data for training
print(f'... reshaping data for training ...')
X, Y = make_xy(data,X_N_TIMESTEPS,Y_N_TIMESTEPS)
# fit model
model.fit(X, Y)