【问题标题】:Face classification CNN in Keras does not train properlyKeras 中的人脸分类 CNN 没有正确训练
【发布时间】:2018-11-12 21:31:24
【问题描述】:

我对机器学习相当陌生,这是我在 StackOverflow 上的第一篇文章。 我想训练一个 CNN,使它能够将我的脸与其他人区分开来。 我的模型在前 3 个 epoch 之后就停止了改进。

我在机器学习的在线数据库中找到了一些人脸,然后对它们进行居中、灰度和裁剪。我对我的网络摄像头从我脸上拍摄的照片做了同样的事情。

NN 的数据如下所示:

|输入 |输出 | | |---------------------- |-------- |--- | |我的脸| 0 | 1 | |别人的脸| 1 | 0 |

到目前为止一切顺利。

然后我尝试使用以下结构训练 CNN:

model= Sequential()

# sort out the input layer later
model.add(Conv2D(32,3,3, activation='relu', input_shape=(100,100,3)))
model.add(MaxPooling2D((2,2)))

model.add(Conv2D(12,3,3, activation='relu'))
model.add(MaxPooling2D((2,2)))

model.add(Flatten())
model.add(Dense(600, activation='relu'))
model.add(Dense(60, activation='relu'))
#model.add(Dropout(p=0.2))
model.add(Dense(2, activation='softmax'))
model.summary()
epochs = 100
lrate = 0.01
decay = lrate/epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
#%%
model.compile(loss='categorical_crossentropy', optimizer="adam", metrics=['accuracy'])

我尝试了不同的优化器(sdg、adam、rmsprop),并对 CNN 的其他参数进行了一些尝试,但每次模型在前几个 epoch 之后都停止减少损失。

Epoch 1/100
2176/2176 [==============================] - 55s 25ms/step - loss: 1.8043 - acc: 0.8869
Epoch 2/100
2176/2176 [==============================] - 56s 26ms/step - loss: 1.7037 - acc: 0.8943
Epoch 3/100
2176/2176 [==============================] - 57s 26ms/step - loss: 1.7037 - acc: 0.8943
Epoch 4/100

对于这个例子,在 epoch 2 之后损失没有改善。

你知道为什么会这样吗?

【问题讨论】:

  • 每个类有多少个样本?
  • 我有 2941 个负样本。这些是多个随机人的多张照片。比如 294 个人,每 10 张照片,以及我自己的 308 张照片
  • 除了类不平衡,正如 Merlin1896 所暗示的那样,您可以尝试使用更复杂的非Sequential 模型。
  • 所以,给定你的数字,最愚蠢的分类器可以通过总是投票给负样本来达到 90.5% 的准确率。尝试在损失函数中添加一些类权重(这是keras的fit函数的参数)
  • 看来你在做某事。我尝试将拆分从 10:90 减少到 50:50。现在每个时期的损失是恒定的 50%。所以没有更新权重,对吧?我现在就试试班级重量的事情

标签: python tensorflow keras face-recognition convolutional-neural-network


【解决方案1】:

这里发生了不同的事情。

类不平衡

正如 cmets 中已经讨论过的,您的训练集包含 2941 个负样本(来自其他人的面孔)和 308 个正样本(上面有您的面孔的图像)。因此,总是投票给负类的分类器在 3249 个样本中得到了 2941 个正确,即 90.5%。 阅读您的训练准确度分数时应牢记此信息,因为您的 89.4% 表明您的网络没有学到任何有价值的东西。

你可以尝试什么:

  1. 过采样少数类
  2. 欠采样多数类
  3. 在损失函数中使用权重

关于这个主题有大量的文献和教程,所以看看周围吧。

模型容量/网络设计

您在 cmets 中提到,使用平衡的训练数据后,损失仍然没有减少。这表明您的模型的容量不够高,或者您的模型不是为该任务设计的。

图像处理任务存在许多不同的网络结构,具体取决于任务的具体内容。例如,用于进行逐像素分类和实例分割的网络(如Mask RCNN)看起来与设计用于进行人脸识别的网络(如FaceNet)不同。即使我们只专注于一项任务(在此/您的情况下:人脸识别),您发现的网络结构也会看起来非常不同。

那是什么意思?为特定任务构建神经网络并非易事,而且要预测哪些结构适用于哪个任务并不容易。为了找到合适的结构,通常需要进行大量的试验和错误。

模型容量描述了您的模型有多“强大”。对此没有严格的定义,但您可以这样想:不同的任务可能更难或更容易解决。某个模型只能解决“足够简单”的问题,而在更困难的问题上,该模型只会表现出较差的性能。模型容量通常与网络设计/结构密切相关。

这对你有什么帮助?好吧,看看不同的网络结构,它们执行与您的目标相同的任务,并了解为什么使用某些构建块以及它们有什么用处。然后你可以尝试重建这些结构并进行试验。一个好的起点可能是thisthis 人脸识别教程。

【讨论】:

  • 感谢您的广泛回答。我一定会从你的帖子中尝试一些东西,如果我发现一些有用的东西,我会回到这里
猜你喜欢
  • 2019-01-25
  • 2021-04-26
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
  • 2018-01-08
  • 2020-01-19
  • 1970-01-01
相关资源
最近更新 更多