Keras每一步的多步LSTM批量训练分类
Posted
技术标签:
【中文标题】Keras每一步的多步LSTM批量训练分类【英文标题】:Keras multi-step LSTM batch train classification at each step 【发布时间】:2019-03-22 23:39:36 【问题描述】:问题
如何在 Keras 中批量训练多步 LSTM 以实现单标签多类分类,每个时间步超过 2 个类?
当前错误
每个目标批次都是一个形状为 (batch_size, n_time_steps, n_classes)
的 3 维数组,但 Keras 需要一个 2 维数组。
示例/上下文
假设我们有 N 个股票的每日收盘价,以及每个股票的每日收盘价:m 个特征和“买入”、“持有”、“卖出”三个动作之一。 如果每只股票有 30 天的数据,我们可以训练 LSTM 来预测每个动作(每天,每只股票),如下所示。
对于大小为 n X_train 将具有(n, 30, m)
的形状,即n
样本、30 个时间步长和m
特征。在 one-hot 编码后,“购买”、“持有”和“出售”Y_train
将具有 (n, 30, 3)
的形状,这是一个 3 维数组。
问题是 Keras 由于期望 Y_train
是二维的而给出错误。
这是一个代码sn-p:
n_time_steps = 30
n_ftrs = 700
n_neurons = 100
n_classes = 3
batch_size = 256
n_epochs = 500
model = Sequential()
model.add(LSTM(n_neurons, input_shape=(n_time_steps, n_ftrs)))
model.add(Dense(n_classes, activation='sigmoid'))
model.compile(loss='categorical_crossentropy', optimizer='adam',
metrics=['accuracy'])
for e in range(n_epochs):
X_train, Y_train = BatchGenerator()
# Y_train.shape = (256, 30, 3)
model.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=1)
错误
Error when checking target: expected dense_20 to have 2 dimensions,
but got array with shape (256, 30, 3)
【问题讨论】:
您可以尝试将输入形状设置为第一个 LSTM,例如(None, n_time_steps, n_ftrs)
,而不将 return_sequences
设置为 True
?
【参考方案1】:
如果您查看model.summary()
输出,您会意识到问题所在:
Layer (type) Output Shape Param #
=================================================================
lstm_1 (LSTM) (None, 100) 320400
_________________________________________________________________
dense_74 (Dense) (None, 3) 303
=================================================================
Total params: 320,703
Trainable params: 320,703
Non-trainable params: 0
_________________________________________________________________
您可以看到LSTM
层的输出形状是(None, 100)
,这意味着只返回最后一个时间步的输出。结果,Dense
层的输出形状为(None, 3)
,这意味着它将整个输入时间序列(即股票的整个 30 天数据)分类为 3 个类别之一。这不是你想要的。相反,您希望对输入时间序列的每个时间步进行分类。为了实现这一点,正如@VegardKT 建议的那样,您可以将return_sequences=True
传递给LSTM
层,以便在每个时间步都有其输出。让我们看看这次更改后的model.summary()
输出:
Layer (type) Output Shape Param #
=================================================================
lstm_2 (LSTM) (None, 30, 100) 320400
_________________________________________________________________
dense_75 (Dense) (None, 30, 3) 303
=================================================================
Total params: 320,703
Trainable params: 320,703
Non-trainable params: 0
_________________________________________________________________
如您所见,现在LSTM
层给出了每个时间步的输出,因此充当分类器的Dense
层将能够根据需要将这些时间步中的每一个分类为 3 个类之一。
【讨论】:
有见地的评论解释了 return_sequences=True 发生了什么。谢谢。 很好的解释,谢谢@today 如果他们仍然反转了 return_Sequences 的布尔值会不会更有意义? @VegardKT 好吧,我认为不是这样。我这样看:“返回输出序列”。所以很明显,当“return_sequences=True”时,它意味着所有时间步输出(即输出序列)都应该返回(而不仅仅是最后一个时间步的输出)。我编辑了我的答案并使其更清楚。【参考方案2】:您需要像这样添加更改您的 LSTM 层:
model.add(LSTM(n_neurons, input_shape=(n_time_steps, n_ftrs), return_sequences=True))
此参数执行以下操作:
return_sequences:布尔值。是返回输出序列中的最后一个输出,还是返回完整序列。
我将完全诚实地说我不知道为什么会这样,我的 LSTM 有点生锈,因为我相信它应该是相反的,但我能够让你的代码像这样运行这。如果有人想澄清为什么这会很好。
【讨论】:
谢谢。 return_sequences 上的文档可能会更清晰一些,例如简单地说:“return_sequences:布尔值是否准确。如果为真,则返回输出序列中的最后一个输出。如果为假,则返回完整序列”?以上是关于Keras每一步的多步LSTM批量训练分类的主要内容,如果未能解决你的问题,请参考以下文章
Keras 使用真实值作为训练目标的 LSTM 分类器的官方示例?