首页 > 解决方案 > MNIST 数据集上的可变图像输入分辨率问题(使用 CNN 时)

问题描述

我对 CNN 有点陌生,所以请尽可能纠正我!

我一直在尝试使用 MNIST 数据集进行数字分类。我决定更进一步,将我自己的手写数字传递给模型的预测方法。我知道 MaxPooling2D 层只允许固定的输入分辨率,所以经过一些研究,我使用了 GlobalMaxPooling2D。这解决了可变输入图像分辨率的问题。我现在面临的问题是 predict 方法准确地预测了来自 MNIST 数据集的测试集的图像,但无法预测我自己的手写数字。这是我的模型:

model=Sequential()
model.add(Conv2D(128,(5,5),input_shape=(None,None,1), data_format='channels_last'))
model.add(Dense(80, activation='relu'))
model.add(GlobalMaxPooling2D())
model.add(BatchNormalization())
model.add(Dense(10,activation='softmax'))

该模型的训练准确率为 94.98%,测试准确率为 94.52%。为了预测我自己的手写数字,我使用了分辨率为 200x200 的图像。该模型可以以某种方式预测特定数字,例如 8、6 和 1,但是当我测试任何其他数字时,它仍然会将其分类为 8、6 或 1。谁能指出我哪里出错了?任何帮助表示赞赏!

标签: pythontensorflowopencvconv-neural-networkmnist

解决方案


有几件事可以促成您在此处看到的内容。优化过程不好,优化模型的方式会直接影响模型的性能。优化器的正确选择,学习率,学习率衰减机制,适当的正则化,只是一些名称。除此之外,您的网络非常简单且设计非常糟糕。您没有足够的 Conv 层来利用图像结构并提供可用于执行您要求它执行的操作的良好抽象。你的模型也不够深。

MNIST 本身是一项非常简单的任务,使用线性分类器可以达到您所达到的准确度,甚至可能更好。这表明您没有以任何好的方式利用 CNN 或深度架构功能。如果经过适当的训练,即使是简单的一两个完全连接的层也应该可以提供更好的准确性。

尝试让你的网络更深,使用更多的 CNN 层,然后是 BatchNormalization,然后是 ReLU,并避免快速对输入特征图进行下采样。当您下采样时,您会丢失信息,为了弥补这一点,您通常希望增加下一层的过滤器以补偿由此导致的表示能力下降。换句话说,尝试逐渐减小特征图的维度,同时增加神经元数量。

一开始大量的神经元对您的特定用例来说是浪费的,32/64 可能绰绰有余,随着网络变得更深,更抽象的特征建立在早期层中更原始的特征之上,因此拥有更多后面几层的神经元通常更合理。

早期的层负责创建原始过滤器,在某些时候,更多的过滤器对性能没有帮助,它只会创建一些以前的过滤器已经完成的重复工作。

您看到准确性差异的原因仅仅是因为您最终处于另一个局部最小值!使用相同的精确配置,如果你训练 100 次,你会得到 100 个不同的结果,有些比其他的好,有些比其他的差,永远不会有相同的精确值,除非你通过使用特定种子来使用确定性行为并且只运行中央处理器模式。


推荐阅读