【问题标题】:Accuracy in a CNN model never goes high for training and validation setCNN 模型的准确度对于训练和验证集永远不会太高
【发布时间】:2018-12-28 00:23:53
【问题描述】:

我正在KTH 数据集上训练一个 CNN 模型来检测 6 类人类行为。

数据处理

  • 数据集由 599 个视频组成,每个动作有 25 个不同的人执行的 99-100 个视频。我将数据分为 300 个视频用于训练,98 个视频用于验证,200 个视频用于测试集。
  • 我将分辨率降低到 50x50 像素,因此在处理时不会耗尽内存。
  • 我从每个视频的中间提取了 200 帧。
  • 它将像素从 0-255 标准化为 0,1
  • 最后我将一个热编码为类标签。

模型架构

This is my model architecture.
这是NN层的代码。

model = Sequential()
model.add(Conv3D(filters=64,
         kernel_size=(3, 3, 3),
         strides=(1, 1, 1),
         padding='valid',
         activation='relu', 
         input_shape=X_train.shape[1:]))

model.add(MaxPooling3D(pool_size=2,
               strides=(2, 2, 2),
               padding='same'))

model.add(Conv3D(filters=128,
         kernel_size=(3, 3, 3),
         strides=(1, 1, 1),
         padding='valid',
         activation='relu'))

model.add(MaxPooling3D(pool_size=2,
               strides=(2, 2, 2),
               padding='same'))

model.add(Conv3D(filters=256,
         kernel_size=(3, 3, 3),
         strides=(1, 1, 1),
         padding='valid', 
         activation='relu'))

model.add(Conv3D(filters=256,
         kernel_size=(3, 3, 3),
         strides=(1, 1, 1),
         padding='valid',
         activation='relu'))

model.add(MaxPooling3D(pool_size=2,
               strides=(2, 2, 2),
               padding='same'))

model.add(Conv3D(filters=512,
         kernel_size=(3, 3, 3),
         strides=(1, 1, 1),
         padding='valid',
         activation='relu'))

model.add(Dense(4096, activation='relu'))
model.add(Dense(4096, activation='relu'))
#model.add(Dropout(0.5))
model.add(Flatten())
model.add(Dense(6, activation='softmax'))

model.summary()

培训

我的问题是训练和验证的准确性都没有改变,它们基本上从第一个 epoch 就冻结了。这些是训练步骤。 这些是the first 6 epochs,这里是last 6 epochs。 损失看起来like this。 训练损失非常高,验证损失没有改变。 训练看起来like this

我很困惑,模型是 underfitting 还是 overfitting? 我将如何解决这个问题? dropout 会有所帮助吗,因为我无法对视频进行数据增强(我假设是这样)?

我非常感谢任何建议。

【问题讨论】:

  • 对于分类问题,您可以先使用 MNIST 数据集验证您的库和算法。
  • 但这是一个视频数据集,它适用于 MNIST,但不适用于这种类型的数据集。

标签: python machine-learning keras deep-learning conv-neural-network


【解决方案1】:

您正在使用 0-1 帧值并且正在使用 relu。在垂死的 relu 问题模型被冻结并且根本不学习,因为 relu 获得最大值 b/w 0 或者如果没有添加偏差,则权重*输入。您可以做两件事来确保模型正常工作,尽管我不确定您是否会获得良好的准确性,但可以尝试这样做来避免这个垂死的 relu 问题:-

使用 alpha>=0.2 的泄漏 relu。 不要对帧进行归一化,而只是转换为灰度以减少大量训练。 不要从中间取 200 帧,将所有视频分成等量的帧块,并从每个块中取 2,3 个连续帧。还可以尝试添加更密集的层,因为它们有助于分类。

我解决了几乎相同的问题,我所做的是将帧合并在一起后使用 Conv2d,即如果您有 10 个大小为 64、64、3 的帧,而不是执行 conv3d,我在 640、64、3 数据集上执行了 conv2d并在 16 个视频类中实现了 86% 的准确率。

【讨论】:

  • 感谢您的反馈!!我将根据您的建议修改我的模型,如果一切正常,我将发布此问题的解决方案。 :)
  • 太棒了,也可以尝试使用简单的 conv2d,直觉上它应该可以工作,因为连续的帧几乎相同,因此将它们合并在一起然后进行 conv2d 将是有意义的。
【解决方案2】:

这取决于您如何使用 200 帧视频作为训练数据来对动作进行分类。您的训练数据有太多偏差。 由于它是要分类的顺序数据,因此您必须使用基于内存的架构或串联模型。

【讨论】:

  • 您的意思是使用 CNN-LSTM 或 LRCN 模型。这种情况下,CNN和RNN的拼接应该怎么做?
  • 您可以选择混合 CNN-RNN 模型,也可以将连续图像连接成单帧以在 CNN 中使用。例如:将 225 帧组合成具有 15x15 行和列的单个图像。如果要分类的动作时间线在 5 秒以下,我建议选择 25 帧。
猜你喜欢
  • 1970-01-01
  • 2021-07-22
  • 2018-09-18
  • 2017-12-21
  • 1970-01-01
  • 2021-10-13
  • 2022-01-12
  • 2018-08-16
  • 2017-10-14
相关资源
最近更新 更多