LSTM 分类交叉熵验证精度保持不变

LSTM categorical crossentropy validation accuracy remains constant

我最近一直在做一些 LSTM 网络,我想预测一个单热编码输出(2 类 目前,我已经尝试过二元交叉熵,我的问题仍然是相同)给定 5 个特征和 14 个回溯步骤(批量大小为 1)。我正在使用 TimeseriesGenerator:

generator = TimeseriesGenerator(scaled_train, train_targets, length=LOOKBACK, batch_size=BATCH_SIZE)
validation_generator = TimeseriesGenerator(scaled_test, test_targets, length=LOOKBACK, batch_size=BATCH_SIZE)

训练目标如下(下图,分布):

array([[1., 0.],
       [0., 1.],
       [1., 0.],
       ...,
       [1., 0.],
       [1., 0.],
       [1., 0.]], dtype=float32)

0    1  
0.0  1.0    1619
1.0  0.0    1545
dtype: int64

和功能/scaled_train 像这样:

array([[0.22189629, 0.21121072, 0.21790398, 0.19933957, 0.41803716],
       [0.2106806 , 0.21783771, 0.2197984 , 0.2237905 , 0.18050205],
       [0.21885786, 0.21532436, 0.21933581, 0.19678948, 0.16397564],
       ...,
       [0.2104257 , 0.20155003, 0.22193512, 0.20173967, 0.12319585],
       [0.2070304 , 0.19911522, 0.21276043, 0.19141927, 0.11876491],
       [0.19873079, 0.18909128, 0.20785918, 0.19083925, 0.1407046 ]])

测试数据的格式相同。

模型也超级简单:

model = Sequential()

model.add(LSTM(100, input_shape=(LOOKBACK, scaled_train.shape[1])))
model.add(Dense(2, activation='softmax'))

model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

这是拟合输出:

基本上,当我进行预测时,一半时间 returns 是 > 0.5,另一半时间是 < 0.5。合身指标非常稳定。我还尝试使用多个 LSTM 层来复杂化我的网络,但没有成功。我还尝试将另一个加载到数据集只是为了尝试,但它没有改变任何东西。我的发电机可能出了问题。

我做错了什么?

谢谢!

尝试重塑目标数据以使用 binary_crossentropy:

targets_binary=np.array([np.where(index==1)[0][0] for index in train_targets])

因此,您将拥有像 [0,1,0]

这样的真实标签,而不是像 [[1., 0.],[0., 1.], [1., 0.]] 这样的单热编码向量

最后一层应该是:

model.add(Dense(1, activation='sigmoid'))

(batch size is 1)

尝试将其更改为 32 之类的值。

以下线程包含一些关于选择小批量大小的合理参考。以及为什么批量大小为 1 会导致 GD 不收敛的一些解释。

https://www.reddit.com/r/MachineLearning/comments/8im43v/d_theoretically_does_batch_size1_will_give_the/

您可能要记住的另一个问题是该问题是否可以由人类解决...人类是否能够识别数据中的某些特征,这些特征将 class 证明一些示例为显然在 class 0 与 class 1 中?您是否可以考虑在输出与标签具有有意义相关性的地方手动实现序列上的某些功能?在某些情况下,可用的输入数据根本不足以驱动相关性。即输出过程不能用输入解释。例如,如果您有给定股票的价格时间序列,那么您不太可能能够以任何合理的准确性预测下一个价格,因为确定输出的过程不仅仅由这些先前的数据点捕获.

  1. 批量大小也可能导致此问题。每批中的一个样本可能无法为模型的梯度提供优化和捕获问题的良好方向。尝试增加批量大小。

  2. 如果我们查看二元交叉熵损失值,它们似乎在最小值附近徘徊。如本 post 中所述,这可能是学习率较高的原因,但不太可能 https://towardsdatascience.com/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0

  3. 最后,考虑到二元分类器在显示的最低损失值 (0.6926) 下的准确度为 0.5095,似乎该模型真的很难解决手头的问题,大约 42,602参数。因此,尝试使用具有扁平化 14*5 特征和具有更高批量大小的密集层的快速且更简单的模型。可能会给出一些具有明确特征重要性的直觉。

  4. 如果以上所有都不能帮助损失或准确性,则可能是由于以下两个原因:

  • 噪声数据
  • 我们试图预测一些无法从提供的输入数据中推断出来的东西。例如。尝试根据 14 天的地理位置来预测此人是男性还是女性。无论我们如何对这个训练集进行特征化,位置和性别之间几乎没有任何相关性。 (与 Pedro 的建议非常相似)

我的建议:

  1. 确保您正确地框定了问题。如果您将随机噪声作为输入数据集或只是没有模式的值,您的模型将无法学习任何东西。数据集中缺少模式和数据 scientist/machine 学习工程师无法看到模式是两码事,应该考虑到这一点。您的数据是否正确输入并适合您的问题?这真的是分类问题还是回归问题?如果您可以正确且轻松地回答所有这些问题,请继续执行后续步骤。
  2. 降低学习率。有可能,默认学习率对于您的问题来说太高了,网络根本无法收敛。 Keras 中 Adam 的默认学习率值为 0.001。尝试用 0.00010.00001 替换它。非常大的学习率加上 batch_size 为 1 可能会导致您的网络无法 learn/converge。
  3. 您还可以将 batch_size 增加到 8/16 并检查行为是否发生变化。您可以同时执行第 2 步和第 3 步,尽管我个人会在此时从第 3 步开始,以确保为神经网络的收敛提供“帮助”的程度。
  4. 14 == timesteps真的足够解决您的问题吗?更改此参数很可能会影响您的结果;如果您的网络难以学习,增加时间步数可能会有帮助。