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中的多步时间序列预测

如何处理keras中多变量LSTM的多步时间序列预测

Keras 使用真实值作为训练目标的 LSTM 分类器的官方示例?

如何为LSTM Keras中的多步和多变量准备时间序列数据

Keras 在训练分类 LSTM 序列到序列模型时给出 nan

LSTM 文本分类精度差 Keras