Формирование данных для LSTM и подача вывода плотных слоев в LSTM
Я пытаюсь выяснить правильный синтаксис для модели, которую я пытаюсь соответствовать. Это проблема прогнозирования временных рядов, и я хочу использовать несколько плотных слоев, чтобы улучшить представление временных рядов, прежде чем передать их в LSTM.
Вот фиктивная серия, с которой я работаю:
import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')
import numpy as np
import keras as K
import tensorflow as tf
d = pd.DataFrame(data = {"x": np.linspace(0, 100, 1000)})
d['l1_x'] = d.x.shift(1)
d['l2_x'] = d.x.shift(2)
d.fillna(0, inplace = True)
d["y"] = np.sin(.1*d.x*np.sin(d.l1_x))*np.sin(d.l2_x)
plt.plot(d.x, d.y)
Во-первых, я установлю LSTM без плотных слоев, предшествующих ему. Это требует, чтобы я изменил данные:
X = d[["x", "l1_x", "l2_x"]].values.reshape(len(d), 3,1)
y = d.y.values
Это правильно?
Учебники показывают, что один временной ряд должен иметь 1 в первом измерении, за которым следует количество временных шагов (1000), а затем число ковариат (3). Но когда я делаю это, модель не компилируется.
Здесь я собираю и обучаю модель:
model = K.Sequential()
model.add(K.layers.LSTM(10, input_shape=(X.shape[1], X.shape[2]), batch_size = 1, stateful=True))
model.add(K.layers.Dense(1))
callbacks = [K.callbacks.EarlyStopping(monitor='loss', min_delta=0, patience=5, verbose=1, mode='auto', baseline=None, restore_best_weights=True)]
model.compile(loss='mean_squared_error', optimizer='rmsprop')
model.fit(X, y, epochs=50, batch_size=1, verbose=1, shuffle=False, callbacks = callbacks)
model.reset_states()
yhat = model.predict(X, 1)
plt.clf()
plt.plot(d.x, d.y)
plt.plot(d.x, yhat)
Почему я не могу заставить модель переодеться? Это потому, что я изменил свои данные неправильно? Когда я использую больше узлов в LSTM, на самом деле это не слишком излишне.
(Мне также непонятно, что значит быть "состоящим из состояний". Нейронные сети - это просто нелинейные модели. К каким параметрам относятся "состояния" и зачем их сбрасывать?)
Как мне вставить плотные слои между входом и LSTM? Наконец, я хотел бы добавить несколько плотных слоев, чтобы в основном сделать базовое расширение x
прежде чем он попадет в LSTM. Но LSTM хочет трехмерный массив, а плотный слой выплевывает матрицу. Что мне здесь делать? Это не работает:
model = K.Sequential()
model.add(K.layers.Dense(10, activation = "relu", input_dim = 3))
model.add(K.layers.LSTM(3, input_shape=(10, X.shape[2]), batch_size = 1, stateful=True))
model.add(K.layers.Dense(1))
ValueError: Input 0 is incompatible with layer lstm_2: expected ndim=3, found ndim=2
1 ответ
По первому вопросу, я делаю то же самое, я не получил никакой ошибки, пожалуйста, поделитесь своей ошибкой.
Примечание: я приведу пример использования функционального API, который дает немного больше свободы (личное мнение)
from keras.layers import Dense, Flatten, LSTM, Activation
from keras.layers import Dropout, RepeatVector, TimeDistributed
from keras import Input, Model
seq_length = 15
input_dims = 10
output_dims = 8
n_hidden = 10
model1_inputs = Input(shape=(seq_length,input_dims,))
model1_outputs = Input(shape=(output_dims,))
net1 = LSTM(n_hidden, return_sequences=True)(model1_inputs)
net1 = LSTM(n_hidden, return_sequences=False)(net1)
net1 = Dense(output_dims, activation='relu')(net1)
model1_outputs = net1
model1 = Model(inputs=model1_inputs, outputs = model1_outputs, name='model1')
## Fit the model
model1.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_11 (InputLayer) (None, 15, 10) 0
_________________________________________________________________
lstm_8 (LSTM) (None, 15, 10) 840
_________________________________________________________________
lstm_9 (LSTM) (None, 10) 840
_________________________________________________________________
dense_9 (Dense) (None, 8) 88
_________________________________________________________________
Для вашей второй проблемы есть два метода:
- Если вы отправляете данные без создания последовательности, которая имеет
(batch, input_dims)
, затем использовать можно использовать этот метод RepeatVector, которые повторяют те же веса поn_steps
что ничего кромеrolling_steps
в LSTM.
{
seq_length = 15
input_dims = 16
output_dims = 8
n_hidden = 20
lstm_dims = 10
model1_inputs = Input(shape=(input_dims,))
model1_outputs = Input(shape=(output_dims,))
net1 = Dense(n_hidden)(model1_inputs)
net1 = Dense(n_hidden)(net1)
net1 = RepeatVector(3)(net1)
net1 = LSTM(lstm_dims, return_sequences=True)(net1)
net1 = LSTM(lstm_dims, return_sequences=False)(net1)
net1 = Dense(output_dims, activation='relu')(net1)
model1_outputs = net1
model1 = Model(inputs=model1_inputs, outputs = model1_outputs, name='model1')
## Fit the model
model1.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_13 (InputLayer) (None, 16) 0
_________________________________________________________________
dense_13 (Dense) (None, 20) 340
_________________________________________________________________
dense_14 (Dense) (None, 20) 420
_________________________________________________________________
repeat_vector_2 (RepeatVecto (None, 3, 20) 0
_________________________________________________________________
lstm_14 (LSTM) (None, 3, 10) 1240
_________________________________________________________________
lstm_15 (LSTM) (None, 10) 840
_________________________________________________________________
dense_15 (Dense) (None, 8) 88
=================================================================
- Если вы отправляете последовательность димс
(seq_len, input_dims)
Затем вы можете TimeDistributed, который повторяет одинаковые веса плотного слоя на всей последовательности.
{
seq_length = 15
input_dims = 10
output_dims = 8
n_hidden = 10
lstm_dims = 6
model1_inputs = Input(shape=(seq_length,input_dims,))
model1_outputs = Input(shape=(output_dims,))
net1 = TimeDistributed(Dense(n_hidden))(model1_inputs)
net1 = LSTM(output_dims, return_sequences=True)(net1)
net1 = LSTM(output_dims, return_sequences=False)(net1)
net1 = Dense(output_dims, activation='relu')(net1)
model1_outputs = net1
model1 = Model(inputs=model1_inputs, outputs = model1_outputs, name='model1')
## Fit the model
model1.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_17 (InputLayer) (None, 15, 10) 0
_________________________________________________________________
time_distributed_3 (TimeDist (None, 15, 10) 110
_________________________________________________________________
lstm_18 (LSTM) (None, 15, 8) 608
_________________________________________________________________
lstm_19 (LSTM) (None, 8) 544
_________________________________________________________________
dense_19 (Dense) (None, 8) 72
=================================================================
Примечание: я сложил два слоя, при этом, в первом слое, который я использовал return_sequence
, которые возвращают результат на каждом временном шаге, который используется вторым слоем, где он возвращает результат только в конце time_step
,