卷积神经网络对错误分类具有很高的置信度

数据挖掘 机器学习 Python 神经网络 美国有线电视新闻网
2022-03-06 13:38:41

我正在通过 CNN 做一个关于手语识别的项目。

我的数据集

每个字母表有 300 张图像,空间有一个特殊符号。图像取自三个人。每个图像都有以白色背景为中心的手。分辨率为 640*480。所以总共有 27 个标签和 8100 张图像。

样本图像

代码

我在 PyTorch 中使用预训练的 AlexNet,并根据项目的需要更改了全连接层。我正在训练 10 个 epoch。批量大小为 32。损失函数为 Negative Log Likelihood Loss,优化器为 Adam。

AlexNet(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
    (1): ReLU(inplace=True)
    (2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (4): ReLU(inplace=True)
    (5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
    (6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (7): ReLU(inplace=True)
    (8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (9): ReLU(inplace=True)
    (10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (11): ReLU(inplace=True)
    (12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
  (classifier): Sequential(
    (0): Linear(in_features=9216, out_features=1024, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=1024, out_features=512, bias=True)
    (4): ReLU()
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=512, out_features=27, bias=True)
    (7): LogSoftmax()
  )
)

问题

我面临的问题是,该模型对没有手势或包含错误手势的图像给出了 90-100% 的非常高的置信度。我尝试添加 dropout 层,训练更多的 epoch,但似乎没有什么能解决这个问题。模型有问题还是需要更改/更新数据集?

1个回答

由于您的模型似乎在正确的手势上做得很好,我认为没有任何问题。您可以将模型输出解释为置信度度量是一种常见的误解。考虑以下示例。

假设您有一个二元分类器,并且您学会区分标记为 0 的一个类中的 -1 和 0 之间的数字和标记为 1 的另一个类中的 0 和 1 之间的数字。您的训练数据在这些区间中并且被正确标记。你的分类器最终会是这样的

y=σ(wx)

σ作为 sigmoid 函数。当你训练时,你会很快学会w>0. 训练得越多,规模越大|w|将成为直到你得到接近 0 的东西x[1,0)和接近 1 的东西x(0,1]. 到目前为止一切都很完美和正常。

现在你传递数字x=10到模型。该查询没有意义,因为这x不属于模型训练的任何类,与训练数据无关。没有理由假设该模型会给出任何有用的输出x=10. 但是,该模型仍然会超级自信10(0,1]因此x=10该模型将输出一个比任何训练示例更接近 1 的值。这显然是不正确的。

我希望这能澄清将分类器输出解释为置信度可能会非常误导。如果这些类在特征空间中靠得很近,并且您使用一个介于训练数据之间的示例进行查询,那么您可以将其视为这样,但对于未在训练数据中表示的输入,您将获得的数字不会'根本没有任何意义。

在您的应用程序中,您可以将反例引入训练数据并将它们标记为“其他”,但这也是有风险的。如果您真的需要置信度度量,请查看贝叶斯神经网络(例如Bayes-By-BackpropDropoutBatch norm)、其他贝叶斯方法或bootstrapping