我是深度学习的初学者,我正在尝试创建一个手写单词分类模型,我创建了一个数据集,它包含71个不同的类,每个类有1000张图像。
问题是,我试图创建一个卷积、最大池化和密集层的不同组合的CNN模型,同时也改变了优化器,但准确性仍然很糟糕。
这是模型、数据集还是我的参数的问题?你有什么建议?
这是我试过的最后一个模型
model = Sequential([
Conv2D(32, kernel_size=(2, 2),activation="relu", input_shape=(143, 75, 1)),
MaxPooling2D(pool_size=(3,3)),
Conv2D(64, kernel_size=(4, 4),activation="relu"),
MaxPooling2D(pool_size=(9,9)),
Flatten(),
Dense(512, activation="relu"),
Dense(128, activation="sigmoid"),
Dense(71, activation="softmax")
])
model.compile(optimizer=Nadam(learning_rate=0.01), loss="categorical_crossentropy", metrics=["accuracy"])
2条答案
按热度按时间eufgjt7s1#
你的模型的问题在于你的池大小。Keras的官方文档是这样描述池化层的
通过在输入的每个通道的输入窗口(由pool_size定义的大小)上取最大值,沿着其空间维度(高度和宽度)对输入进行下采样。窗口沿每个维度移动步幅。
默认情况下,池化层的池大小为
(2,2)
,这意味着在4个元素的矩阵窗口中,仅考虑最大值。如果我们打印您的模型的摘要,我们得到
因此,通过查看这些层及其形状,
conv2d_1(Conv2D)
层输出和max_pooling2d_1(MaxPooling2D)
层输出之间有很大的变化。输出形状从(44,21,64)
变为(4,2,64)
。这是因为您在Dense层之前为Pooling层使用了(9,9)
的池大小。为了理解池大小和池化的效果,考虑下面的输入图像,其大小为
(183,183,3)
。现在,当我们对上面的图像应用2D最大池化,池大小为
(2,2)
时,我们得到以下图像,其空间维度减少到(91,91,3)
。这里图像维度减少了,但图像中的信息被保留了下来。现在,对于相同的输入图像,池大小为
(3,3)
的最大池化输出将是以下尺寸为(61,61,3)
的图像在这里,你几乎可以看到这个词真棒的图像。
当池大小为
(5,5)
时,我们得到的最大池输出为,空间维度为
(36,36,3)
。在这里,您根本看不到任何信息。Why is that ?
因为白色像素是255,黑色像素是0,当你做一个最大池时,你总是取255。现在,因为你使用的是(9,9)
的池大小,在窗口中考虑更多的白色像素沿着黑色像素,并且随着空间维度减少到(20,20,3)
,您会丢失有用的信息,就像池大小为的情况一样(5,5)
. (此处仅显示图像上的池化效果。添加Conv 2D图层时,输出将根据过滤器值而变化。)有了这个,你的模型将无法学习任何东西,尽管你改变了任何其他组件,如优化器或损失函数。
因此,将模型架构更改为如下所示,并重新训练网络
**P.S:**卷积层的内核大小通常是(3,3)或(5,5)。例如,当你有一个卷积层
Conv2D(64, kernel_size=(3, 3))
时,你将有64个过滤器,每个过滤器的大小为(3,3)。另外,不要忘记在将图像输入模型之前将其归一化。Cheers!!!
ybzsozfc2#
找到了解决方案
我的数据集有白色背景和黑色手写的图像,由于我使用的是
MaxPooling2D
层,它只接受白色像素,因为它们的值是255
,黑色像素的值是0
,这就是为什么我必须使用Pillow
库中的invert
方法来反转我的数据集图像。这样做之后,我的精度上升到
0.9887
。我还修复了我使用的模型,感谢@Keerthitheja S.C.的回答。