背景:
标记TensorFlow,因为Keras在它上面运行,这更像是一个普遍的深度学习问题。
我一直在研究Kaggle数字识别器问题,并使用Keras训练CNN模型完成任务。下面这个模型具有我在本次比赛中使用的原始CNN结构,并且表现良好。
def build_model1():
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), padding="Same" activation="relu", input_shape=[28, 28, 1]))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64, (3, 3), padding="Same", activation="relu"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64, (3, 3), padding="Same", activation="relu"))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation="softmax"))
return model
然后我在Kaggle上阅读了一些其他的笔记本并借用了另一个CNN结构(下面复制),它比上面的更好,因为它在获得更好的准确性,更低的错误率,并且在过度拟合训练数据之前需要更多的时代
def build_model2():
model = models.Sequential()
model.add(layers.Conv2D(32, (5, 5),padding ='Same', activation='relu', input_shape = (28, 28, 1)))
model.add(layers.Conv2D(32, (5, 5),padding = 'Same', activation ='relu'))
model.add(layers.MaxPool2D((2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Conv2D(64,(3, 3),padding = 'Same', activation ='relu'))
model.add(layers.Conv2D(64, (3, 3),padding = 'Same', activation ='relu'))
model.add(layers.MaxPool2D(pool_size=(2, 2), strides=(2, 2)))
model.add(layers.Dropout(0.25))
model.add(layers.Flatten())
model.add(layers.Dense(256, activation = "relu"))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(10, activation = "softmax"))
return model
问题:
第二个CNN结构的更好性能背后是否有任何直觉或解释?是什么让堆叠2个Conv2D层比在最大池和丢失之前使用1个Conv2D层更好?或者是否有其他因素导致第二种模型的结果?
感谢你们的时间和帮助。
答案 0 :(得分:6)
这两种方法的主要区别在于后者(2转)在表达非线性变换时具有更大的灵活性而不会丢失信息。 Maxpool从信号中删除信息,丢失力分布式表示,因此有效地使传播信息变得更加困难。如果,对于给定的问题,必须对原始数据应用高度非线性变换,堆叠多个conv(使用relu)将使其更容易学习,就是这样。另请注意,您正在将具有3个最大池的模型与仅具有2个的模型进行比较,因此第二个可能会丢失较少的信息。另一件事是它在末端具有更大的完全连接位,而第一个是微小的(64个神经元+ 0.5辍学意味着你实际上有效地拥有最多32个神经元,这是一个很小的层!)。总结一下: