使用 LSTM 和 CNN 对 Keras 进行故障排除以进行时间序列分类

Posted

技术标签:

【中文标题】使用 LSTM 和 CNN 对 Keras 进行故障排除以进行时间序列分类【英文标题】:Troubleshooting Keras with LSTM and CNN for time series classification 【发布时间】:2021-10-20 09:22:40 【问题描述】:

我一直在尝试复制上一个关于将 LSTM 与 CNN 相结合的问题: How to combine LSTM and CNN in timeseries classification

但是,由于某种原因,我的 val_accuracy 自第一个 epoch 以来一直停留在 0.4166。

有趣的是,无论模型架构如何,这个值都大致相同。这让我觉得某处有问题,但我不知道从哪里开始排除故障。

数据的一些背景:

    具有 3 个可能类别的多元时间序列(5 个时间步长 x 20 个特征)数据。

    训练/验证/测试集的输入形状为 (180000, 5,20) / (60000,5,20) / (60000,5,20)。

    使用 sklearn StandardScaler 对 X 训练集进行标准化,然后在验证集和测试集上进行转换。 y 标签是 one-hot 编码的。

使用 LSTM 和 CNN 的示例模型:

model = keras.Sequential()
model.add(keras.layers.LSTM(200, return_sequences=True, 
                            input_shape=(X_train_scaled.shape[1], X_train_scaled.shape[2]) ))

model.add(keras.layers.Conv1D(200, kernel_size=3, activation = 'relu'))
model.add(keras.layers.GlobalMaxPooling1D())
model.add(keras.layers.Dense(100))
model.add(keras.layers.Dense(y_train.shape[1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['acc'])
    模型上的拟合函数输出:
Epoch 1/20
2828/2828 [==============================] - 115s 40ms/step - loss: 1.0861 - acc: 0.4100 - val_loss: 1.0836 - val_acc: 0.4166
Epoch 2/20
2828/2828 [==============================] - 108s 38ms/step - loss: 1.0837 - acc: 0.4164 - val_loss: 1.0838 - val_acc: 0.4166
Epoch 3/20
2828/2828 [==============================] - 114s 40ms/step - loss: 1.0828 - acc: 0.4184 - val_loss: 1.0833 - val_acc: 0.4165
Epoch 4/20
2828/2828 [==============================] - 111s 39ms/step - loss: 1.0830 - acc: 0.4175 - val_loss: 1.0837 - val_acc: 0.4166
Epoch 5/20
2828/2828 [==============================] - 74s 26ms/step - loss: 1.0834 - acc: 0.4161 - val_loss: 1.0835 - val_acc: 0.4164

编辑: 在更仔细地查看了我的数据后,我现在有这样的东西:

Epoch 1/20
2828/2828 [==============================] - 129s 45ms/step - loss: 0.9560 - acc: 0.5143 - val_loss: 0.9044 - val_acc: 0.5479
Epoch 2/20
2828/2828 [==============================] - 131s 46ms/step - loss: 0.8977 - acc: 0.5520 - val_loss: 0.8937 - val_acc: 0.5527
Epoch 3/20
2828/2828 [==============================] - 116s 41ms/step - loss: 0.8887 - acc: 0.5559 - val_loss: 0.8982 - val_acc: 0.5519
Epoch 4/20
2828/2828 [==============================] - 95s 33ms/step - loss: 0.8820 - acc: 0.5616 - val_loss: 0.8834 - val_acc: 0.5606
Epoch 5/20
2828/2828 [==============================] - 100s 35ms/step - loss: 0.8786 - acc: 0.5624 - val_loss: 0.8823 - val_acc: 0.5580
Epoch 6/20
2828/2828 [==============================] - 82s 29ms/step - loss: 0.8728 - acc: 0.5661 - val_loss: 0.8797 - val_acc: 0.5628
Epoch 7/20
2828/2828 [==============================] - 120s 42ms/step - loss: 0.8723 - acc: 0.5679 - val_loss: 0.8744 - val_acc: 0.5677
Epoch 8/20
2828/2828 [==============================] - 158s 56ms/step - loss: 0.8686 - acc: 0.5670 - val_loss: 0.8733 - val_acc: 0.5679
Epoch 9/20
2828/2828 [==============================] - 146s 51ms/step - loss: 0.8646 - acc: 0.5714 - val_loss: 0.8764 - val_acc: 0.5667
Epoch 10/20
2828/2828 [==============================] - 134s 47ms/step - loss: 0.8632 - acc: 0.5720 - val_loss: 0.8715 - val_acc: 0.5701
Epoch 11/20
2828/2828 [==============================] - 141s 50ms/step - loss: 0.8612 - acc: 0.5734 - val_loss: 0.8721 - val_acc: 0.5694
Epoch 12/20
2828/2828 [==============================] - 151s 53ms/step - loss: 0.8582 - acc: 0.5753 - val_loss: 0.8690 - val_acc: 0.5713
Epoch 13/20
2828/2828 [==============================] - 137s 49ms/step - loss: 0.8554 - acc: 0.5792 - val_loss: 0.8694 - val_acc: 0.5699
Epoch 14/20
2828/2828 [==============================] - 121s 43ms/step - loss: 0.8541 - acc: 0.5779 - val_loss: 0.8709 - val_acc: 0.5691
Epoch 15/20
2828/2828 [==============================] - 134s 47ms/step - loss: 0.8476 - acc: 0.5826 - val_loss: 0.8643 - val_acc: 0.5766
Epoch 16/20
2828/2828 [==============================] - 137s 48ms/step - loss: 0.8453 - acc: 0.5838 - val_loss: 0.8664 - val_acc: 0.5742
Epoch 17/20
2828/2828 [==============================] - 152s 54ms/step - loss: 0.8409 - acc: 0.5872 - val_loss: 0.8716 - val_acc: 0.5683
Epoch 18/20
2828/2828 [==============================] - 150s 53ms/step - loss: 0.8391 - acc: 0.5892 - val_loss: 0.8663 - val_acc: 0.5726
Epoch 19/20
2828/2828 [==============================] - 133s 47ms/step - loss: 0.8341 - acc: 0.5920 - val_loss: 0.8687 - val_acc: 0.5766
Epoch 20/20
2828/2828 [==============================] - 117s 41ms/step - loss: 0.8331 - acc: 0.5913 - val_loss: 0.8643 - val_acc: 0.5764

【问题讨论】:

【参考方案1】:

在模型架构上工作的最初趋势是好的,但在您的案例中,真正的问题很可能在于您的数据集是如何构建的。

您所拥有的恒定准确度很可能是因为网络只预测一个类(实际上您的一个类具有41% 目标分布)。

我的建议是关注数据,而不是模型的架构。从100 单位切换到200 不会解决您的问题;相反,我仍然会做的是默认尝试'adam'优化器并微调学习率。

话虽如此,鉴于您遇到的问题,您是否有足够的时间步长来进行您尝试进行的特定分类? 5 个时间步可能不足以让您的模型在数据集上捕获模式。

所有功能真的有必要吗?您可以尝试使用 RandomForest/XGBoost 来消除对因变量 (y).

真正贡献不大的所有特征

从重复数据集和您要解决的任务开始。确保时间序列数据本身是有意义的,而不是纯粹的噪音。尝试对一小部分数据集进行过拟合,然后才继续进行整个数据集的训练。

【讨论】:

谢谢,结果标签和时间序列在 numpy 重塑过程中完全混淆了。我现在在我编辑的问题中有类似的东西。这是否意味着我在正确的轨道上? 这开始变得有意义了,当人们在 StackOverlfow 上解决其他人的问题时,习惯上赞成/接受他们的回答 是的,它开始有意义了 也许你可以使用更多的时间步数 我不能投票,但我已经接受了答案:)

以上是关于使用 LSTM 和 CNN 对 Keras 进行故障排除以进行时间序列分类的主要内容,如果未能解决你的问题,请参考以下文章

使用Keras与LSTM和RNN进行斗争

使用 Keras 训练 CNN-LSTM 时卡在第一个 epoch

在 keras 中使用带有 LSTM 的 CNN 时,池化层是强制性的吗?

MLP初始化Keras中的LSTM细胞状态

python 时间分布在Keras的CNN + LSTM

keras---cnn---rnn---lstm