问题
如何在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)
答案 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有点生锈,因为我认为应该是相反的方式,但是我能够使您的代码像这个。如果有人想弄清楚为什么这行得通,那就太好了。