Configuración de datos para LSTM y alimentación de salida de capas densas a LSTM

Estoy tratando de averiguar la syntax adecuada para el modelo que estoy tratando de ajustar. Es un problema de predicción de series de tiempo, y quiero usar algunas capas densas para mejorar la representación de las series de tiempo antes de enviarlas al LSTM.

Aquí hay una serie ficticia con la que estoy trabajando:

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'] = dxshift(1) d['l2_x'] = dxshift(2) d.fillna(0, inplace = True) d["y"] = np.sin(.1*dx*np.sin(d.l1_x))*np.sin(d.l2_x) plt.plot(dx, dy) 

introduzca la descripción de la imagen aquí

Primero, colocaré un LSTM sin capas densas que lo preceden. Esto requiere que yo reformule los datos:

 X = d[["x", "l1_x", "l2_x"]].values.reshape(len(d), 3,1) y = dyvalues 

¿Es esto correcto?

Los tutoriales hacen que parezca que una única serie de tiempo debe tener 1 en la primera dimensión, seguida por el número de pasos de tiempo (1000), seguido por el número de covariables (3). Pero cuando hago eso el modelo no comstack.

Aquí compilo y entreno el modelo:

 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, restre_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(dx, dy) plt.plot(dx, yhat) 

¿Cómo es que no puedo hacer que la modelo se vista en exceso? ¿Es porque he reformulado mis datos mal? Realmente no se vuelve más excesivo cuando uso más nodos en el LSTM.

introduzca la descripción de la imagen aquí

(Tampoco tengo claro qué significa ser “con estado”. Las redes neuronales son solo modelos no lineales. ¿A qué parámetros se refieren los “estados” y por qué querríamos restablecerlos?)

¿Cómo interpongo capas densas entre la entrada y el LSTM? Finalmente, me gustaría agregar un montón de capas densas, básicamente para hacer una expansión básica en x antes de que llegue a la LSTM. Pero un LSTM quiere una matriz 3D y una capa densa escupe una matriz. ¿Qué hago aquí? Esto no funciona:

 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 

Para la primera pregunta, estoy haciendo lo mismo, no recibí ningún error, por favor comparta su error.

Nota : le daré un ejemplo utilizando la API funcional, lo que da un poco más de libertad (opinión personal)

 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 _________________________________________________________________ 

Para su segundo problema, hay dos métodos:

  1. Si está enviando datos sin realizar una secuencia, que está atenuada como (batch, input_dims) , entonces use este método RepeatVector , que repite los mismos pesos por n_steps , que no es más que rolling_steps en 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 ================================================================= 
  1. Si está enviando la secuencia de (seq_len, input_dims) , entonces puede TimeDistributed , que repite los mismos pesos de capa densa en toda la secuencia.

{

 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 ================================================================= 

Nota : al hacerlo, return_sequence dos capas, en la primera capa utilicé return_sequence , que devuelve la salida en cada paso de tiempo, que se usa en la segunda capa, donde se devuelve la salida solo en el último time_step .