如何在 keras 中拟合两个连接 LSTM 的模型?
Posted
技术标签:
【中文标题】如何在 keras 中拟合两个连接 LSTM 的模型?【英文标题】:How do I fit the model of two concatenate LSTM in keras? 【发布时间】:2021-02-22 22:57:36 【问题描述】:您好,我是 keras 的新手,我在 keras 中连接了两个 LSTM。数据集是一个单变量时间序列,由方法滑动窗口分割。然后我将它重塑为 [样本、特征、时间步长] 的 tesor。但是,当我尝试拟合模型时,会出现以下错误。
TypeError:在用户代码中:
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/training.py:806 train_function *
return step_function(self, iterator)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/training.py:796 step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
/usr/local/lib/python3.8/dist-packages/tensorflow/python/distribute/distribute_lib.py:1211 run
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/distribute/distribute_lib.py:2585 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/distribute/distribute_lib.py:2945 _call_for_each_replica
return fn(*args, **kwargs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/training.py:789 run_step **
outputs = model.train_step(data)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/training.py:747 train_step
y_pred = self(x, training=True)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/base_layer.py:985 __call__
outputs = call_fn(inputs, *args, **kwargs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/sequential.py:386 call
outputs = layer(inputs, **kwargs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/base_layer.py:982 __call__
self._maybe_build(inputs)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/engine/base_layer.py:2643 _maybe_build
self.build(input_shapes) # pylint:disable=not-callable
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/utils/tf_utils.py:323 wrapper
output_shape = fn(instance, input_shape)
/usr/local/lib/python3.8/dist-packages/tensorflow/python/keras/layers/merge.py:500 build
del reduced_inputs_shapes[i][self.axis]
TypeError: list indices must be integers or slices, not ListWrapper
我应该如何通过trainX和testX?我想做一些类似这张图片的事情:
LSTMdata
代码如下
trainX = numpy.reshape(trainX, (trainX.shape[0],1, trainX.shape[1]))
testX = numpy.reshape(testX, (testX.shape[0], 1,testX.shape[1]))
model1= Sequential()
model1.add(LSTM(6, input_shape=(1,look_back)))
model2 = Sequential()
model2.add(LSTM(6, input_shape=(1,look_back)))
model = Sequential()
model.add(Concatenate([model1, model1]))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam', metrics = ['mse'])
model.fit([trainX, trainX], trainY, epochs=50, batch_size=1, verbose=1)
【问题讨论】:
你使用的tensorflow版本是什么?你以前在代码中使用过类吗? 检查这个:***.com/questions/52671481/… Tensorflow 2.2.0 中报告了类似的问题,因此可能是 Tensorflow 版本问题。 嗨。感谢您的回答。我有 2.3.1 版本,我没有使用类 查看例如trainX.shape[0]
分隔之前并检查它是什么类型。它应该是一个整数。如果它不是 int,您可以通过例如设置它x=int(trainX.shape[0])
【参考方案1】:
您需要使用Functional API in Keras。
您的具有功能 API 的模型:
from tensorflow.keras.layers import Dense, Concatenate, LSTM, Input, Flatten
from tensorflow.keras.models import Model
look_back = 3200 # just for running the code I used this number
# Model architecture
inputs = Input(shape=(1,look_back),name='Input_1')
lstm1 = LSTM(6, name='LSTM_1')(inputs)
lstm2 = LSTM(6, name='LSTM_2')(inputs)
concatenated = Concatenate( name='Concatenate_1')([lstm1,lstm2])
output1 = Dense(1, name='Dense_1')(concatenated)
model = Model(inputs=inputs, outputs=output1)
现在让我们看看架构:
model.summary()
输出:
Model: "functional_13"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
Input_1 (InputLayer) [(None, 1, 3200)] 0
__________________________________________________________________________________________________
LSTM_1 (LSTM) (None, 6) 76968 Input_1[0][0]
__________________________________________________________________________________________________
LSTM_2 (LSTM) (None, 6) 76968 Input_1[0][0]
__________________________________________________________________________________________________
Concatenate_1 (Concatenate) (None, 12) 0 LSTM_1[0][0]
LSTM_2[0][0]
__________________________________________________________________________________________________
Dense_1 (Dense) (None, 1) 13 Concatenate_1[0][0]
==================================================================================================
Total params: 153,949
Trainable params: 153,949
Non-trainable params: 0
__________________________________________________________________________________________________
此外,我们可以通过检查模型图更好地了解层及其连接
模型图:
from tensorflow.keras.utils import plot_model
plot_model(model)
输出:
现在让我们训练模型:
我用 sklearn 创建了一些虚拟数据来训练模型,一切正常。
训练模型:
from sklearn.datasets import make_blobs
train_x , train_y = make_blobs(n_samples=1000, centers=2, n_features=look_back,random_state=0)
train_x = train_x.reshape(train_x.shape[0], 1, train_x.shape[1])
model.compile(loss='mean_squared_error', optimizer='adam', metrics = ['mse'])
model.fit(train_x, train_y, epochs=5, batch_size=1, verbose=1)
输出:
Epoch 1/5
1000/1000 [==============================] - 2s 2ms/step - loss: 0.0133 - mse: 0.0133
Epoch 2/5
1000/1000 [==============================] - 2s 2ms/step - loss: 1.4628e-13 - mse: 1.4628e-13
Epoch 3/5
1000/1000 [==============================] - 2s 2ms/step - loss: 2.2808e-14 - mse: 2.2808e-14
Epoch 4/5
1000/1000 [==============================] - 2s 2ms/step - loss: 5.2458e-15 - mse: 5.2458e-15
Epoch 5/5
1000/1000 [==============================] - 2s 2ms/step - loss: 1.1384e-15 - mse: 1.1384e-15
<tensorflow.python.keras.callbacks.History at 0x7f5fe4ce9f28>
【讨论】:
嗨。非常感谢。有用 !。使用连接创建此模型和两个 LSTM 的顺序模型之间有一些区别吗?串联有什么作用? 嗨。 YW concatenate layer 是一个连接输入列表的层。 并且,模型通过使用连接层连接 LSTM 层的隐藏状态。 我相信这些链接也很有帮助:lstm return sequences, different ways of building Keras models【参考方案2】:试着这样写:
...
model1= Sequential()
model1.add(LSTM(6, input_shape=(1,look_back)))
model2 = Sequential()
model2.add(LSTM(6, input_shape=(1,look_back)))
concatenated_models = concatenate([model1, model2])
out = Dense(1, activation='softmax', name='output')(concatenated_models)
added_model = Model([model1, model2], out)
added_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
added_model.fit([trainX, trainX], trainY, epochs=50, batch_size=1, verbose=1)
这可能会更好。不是 100% 确定(这里很晚 ;-))
【讨论】:
以上是关于如何在 keras 中拟合两个连接 LSTM 的模型?的主要内容,如果未能解决你的问题,请参考以下文章
用于时间序列预测的 Keras LSTM 神经网络在模型拟合期间显示 nan
将存储在 tfrecord 格式的数据转换为 Tensorflow 中 lstm Keras 模型的输入,并用该数据拟合模型
为啥用于预测的 Keras LSTM 批量大小必须与拟合批量大小相同?