【发布时间】:2019-04-21 22:31:29
【问题描述】:
这个问题在我问过的previous question 中继续。
我已经训练了一个 LSTM 模型来预测一个包含 100 个样本的批次的二进制类(1 或 0),每个样本有 3 个特征,即:数据的形状是 (m, 100, 3),其中 m 是批次数。
数据:
[
[[1,2,3],[1,2,3]... 100 sampels],
[[1,2,3],[1,2,3]... 100 sampels],
... avaialble batches in the training data
]
目标:
[
[1]
[0]
...
]
型号代码:
def build_model(num_samples, num_features, is_training):
model = Sequential()
opt = optimizers.Adam(lr=0.0005, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0001)
batch_size = None if is_training else 1
stateful = False if is_training else True
first_lstm = LSTM(32, batch_input_shape=(batch_size, num_samples, num_features), return_sequences=True,
activation='tanh', stateful=stateful)
model.add(first_lstm)
model.add(LeakyReLU())
model.add(Dropout(0.2))
model.add(LSTM(16, return_sequences=True, activation='tanh', stateful=stateful))
model.add(Dropout(0.2))
model.add(LeakyReLU())
model.add(LSTM(8, return_sequences=False, activation='tanh', stateful=stateful))
model.add(LeakyReLU())
model.add(Dense(1, activation='sigmoid'))
if is_training:
model.compile(loss='binary_crossentropy', optimizer=opt,
metrics=['accuracy', keras_metrics.precision(), keras_metrics.recall(), f1])
return model
对于训练阶段,模型是非有状态的。在预测我使用有状态模型时,迭代数据并输出每个样本的概率:
for index, row in data.iterrows():
if index % 100 == 0:
predicting_model.reset_states()
vals = np.array([[row[['a', 'b', 'c']].values]])
prob = predicting_model.predict_on_batch(vals)
当查看批次结束时的概率时,这正是我在预测整个批次时得到的值(不是一个一个)。但是,我预计当新样本到达时,概率将始终朝着正确的方向发展。实际发生的是概率输出可能会在任意样本上飙升到错误的类别(见下文)。
预测时间内的 100 个样本批次中的两个样本(标签 = 1):
有没有办法实现我想要的(在预测概率时避免极端峰值),或者这是一个既定的事实?
任何解释,建议将不胜感激。
更新
感谢@today 的建议,我尝试在最后一个 LSTM 层上使用return_sequence=True 为每个输入时间步使用隐藏状态输出训练网络。
所以现在标签看起来像这样(形状(100,100)):
[[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
...]
模型总结:
Layer (type) Output Shape Param #
=================================================================
lstm_1 (LSTM) (None, 100, 32) 4608
_________________________________________________________________
leaky_re_lu_1 (LeakyReLU) (None, 100, 32) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 100, 32) 0
_________________________________________________________________
lstm_2 (LSTM) (None, 100, 16) 3136
_________________________________________________________________
dropout_2 (Dropout) (None, 100, 16) 0
_________________________________________________________________
leaky_re_lu_2 (LeakyReLU) (None, 100, 16) 0
_________________________________________________________________
lstm_3 (LSTM) (None, 100, 8) 800
_________________________________________________________________
leaky_re_lu_3 (LeakyReLU) (None, 100, 8) 0
_________________________________________________________________
dense_1 (Dense) (None, 100, 1) 9
=================================================================
Total params: 8,553
Trainable params: 8,553
Non-trainable params: 0
_________________________________________________________________
但是,我得到了一个例外:
ValueError: Error when checking target: expected dense_1 to have 3 dimensions, but got array with shape (75, 100)
我需要解决什么问题?
【问题讨论】:
-
训练准确率是多少?由于您使用的是
LeakyReLU层,您是否尝试过为 LSTM 层设置activation='linear'? -
请不要使用“samples”代替“timesteps”。它们是不同的东西,这会导致混乱。在您的示例中,每个样本(即序列)的形状为
(100, 3),这意味着每个样本由 100 个时间步长组成,其中每个时间步长是长度为 3 的特征向量。此外,“数据的形状为(m, 100, 3),其中m是批次数”有点错误:m是样本数(或者可能是一批中的样本数),而不是批次数。每批可能包含一个或多个样本。 -
我不知道关于概率不应该波动或尖峰并且它们应该随着我们处理更多时间步而单调增加或减少的说法是对还是错。但是您必须考虑到 1) 模型已经在长度为 100 的序列上进行了训练,2) 在查看了所有 100 个时间步之后,它已经被训练为输出正确的标签, 3) 它不会在训练期间为中间时间步生成任何输出。因此,我认为我们不应该期望预测阶段的中间输出具有特定的行为;而最后一个很重要。
-
我想我同意“今天”。我认为这不是问题,但您可以通过创建包含所有 100 个步骤的目标来防止这种情况。而不是
y = [[0],[1],[0],...],使用y = [[0,0,0...],[1,1,1...],[0,0,0...x100], ....]——为此你需要return_sequences=True直到结束。 -
哦,这已经是下面的答案了 :) -- 点赞
标签: python tensorflow machine-learning keras lstm