深度≥5的卷积神经网络模型构建报错问题咨询
CNN模型depth≥5时触发Negative dimension size错误
问题重现
用于动态创建CNN的代码如下:
def create_model(depth): model = models.Sequential() model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(128, 130, 1))) model.add(layers.MaxPooling2D((2, 2))) for _ in range(depth): model.add(layers.Conv2D(64, (3, 3), activation='relu')) model.add(layers.MaxPooling2D((2, 2))) model.add(layers.Flatten()) model.add(layers.Dense(128, activation='relu')) model.add(layers.Dense(2, activation='softmax')) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy']) return model
当执行model=create_model(5)(即depth≥5)时,会触发如下ValueError:
Negative dimension size caused by subtracting 3 from 2 for '{{node conv2d_224/Conv2D}} = Conv2D[...]' with input shapes: [?,2,2,64], [3,3,64,64].
depth<5时模型创建正常,≥5时报错。
错误原因
问题出在特征图尺寸的迭代缩小,默认的Conv2D使用padding="VALID"(无填充),每一步卷积和池化都会让特征图尺寸持续缩小:
初始输入:(128, 130, 1)
- 第一次Conv2D(3,3)后:(128-3+1, 130-3+1) = (126, 128)
- 第一次MaxPooling2D(2,2)后:(126//2, 128//2) = (63, 64)
每一轮
depth循环的尺寸变化:- 先Conv2D(3,3):尺寸变为
(w-2, h-2)(因为3-1=2) - 再MaxPooling2D(2,2):尺寸减半(向下取整)
- 先Conv2D(3,3):尺寸变为
逐轮计算后:
- depth=1后:(30, 31)
- depth=2后:(14, 14)
- depth=3后:(6, 6)
- depth=4后:(2, 2)
当depth=5时,进入第5轮循环,第一步要对(2,2)的特征图执行3x3卷积。由于padding="VALID",卷积核尺寸(3x3)大于输入特征图尺寸(2x2),计算输出尺寸时会得到负数,直接触发维度错误。
解决方法
可以从以下几个方向修复:
- 限制depth最大值:将depth的上限设为4,避免特征图过小;
- 修改卷积填充方式:把Conv2D的
padding参数设为"SAME",自动填充边缘,保证卷积后尺寸与输入一致:model.add(layers.Conv2D(64, (3, 3), activation='relu', padding="SAME")) - 调整卷积核/池化参数:在后期循环中使用更小的卷积核(比如1x1),或者减少池化次数;
- 增大输入尺寸:如果允许,将输入图像尺寸调大,让多轮迭代后特征图仍能容纳3x3卷积核。
内容的提问来源于stack exchange,提问作者Dheeman Kumar
相关产品推荐
相关产品推荐

