每步的Keras多步LSTM批处理火车分类

时间:2018-10-18 07:48:50

标签: python keras time-series classification lstm

问题

如何在Keras中为单标签多类分类批量训练LSTM的多步LSTM,在每个时间步上> 2类?

当前错误

每个目标批次都是一个形状为(batch_size, n_time_steps, n_classes)的3维数组,但Keras希望使用2维数组。

示例/上下文

假设我们有N个股票以及每天和每个股票的每日收盘价:m个特征以及“买入”,“持有”,“卖出”三个动作之一。 如果每只股票有30天的数据量,我们可以训练LSTM来预测(每天针对每只股票)每项操作,如下所示。

对于每批大小为n << N的样本,X_train将具有(n, 30, m)的形状,即n样本,30个时间步长和m特征。一键编码后,“购买”,“持有”和“出售” Y_train将具有(n, 30, 3)的形状,该形状是3维数组。

问题是Keras由于期望Y_train是二维的而出现了错误。

这是一个代码段:

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)

2 个答案:

答案 0 :(得分:3)

如果查看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类根据需要。

答案 1 :(得分:1)

您需要像这样添加更改LSTM层:

{ this.state.userName === "admin" && <SubMenu />; }

此参数执行以下操作:

  

return_sequences:布尔值。是返回输出序列中的最后一个输出还是完整序列。

我将完全诚实地说我不确定为什么会这样,我的LSTM有点生锈,因为我认为应该是相反的方式,但是我能够使您的代码像这个。如果有人想弄清楚为什么这行得通,那就太好了。