Keras卷积层负维度错误求助:修改模型架构后报错
我有一个多输入的深度学习模型,修改架构后一直报错:
'conv2d_5/convolution'(操作:'Conv2D')因从4中减去5导致负维度大小,输入形状为[?,4,80,64], [5,5,64,64]
我刚接触机器学习,对参数理解有限,恳请大家帮忙。我的模型代码如下:
model_img = Sequential(name="img") # Cropping model_img.add(Cropping2D(cropping=((124,126),(0,0)), input_shape=(376,1344,3))) # Normalization model_img.add(Lambda(lambda x: (2*x / 255.0) - 1.0)) model_img.add(Conv2D(16, (7, 7), activation="relu", strides=(2, 2))) model_img.add(Conv2D(32, (7, 7), activation="relu", strides=(2, 2))) model_img.add(Conv2D(32, (5, 5), activation="relu", strides=(2, 2))) model_img.add(Conv2D(64, (5, 5), activation="relu", strides=(2, 2))) model_img.add(Conv2D(64, (5, 5), activation="relu", strides=(2, 2))) # 报错的层 model_img.add(Conv2D(128, (3, 3), activation="relu")) model_img.add(Conv2D(128, (3, 3), activation="relu")) model_img.add(Flatten()) model_img.add(Dense(100)) model_img.add(Dense(50)) model_img.add(Dense(10)) model_lidar = Sequential(name="lidar") model_lidar.add(Dense(32, input_shape=(360,))) model_lidar.add(Dropout(0.1)) model_lidar.add(Dense(10)) model_imu = Sequential(name='imu') model_imu.add(Dense(32, input_shape=(10, ))) model_imu.add(Dropout(0.1)) model_imu.add(Dense(10)) merged = Merge([model_img, model_lidar, model_imu], mode="concat") model = Sequential() model.add(merged) model.add(Dense(16)) model.add(Dropout(0.2)) model.add(Dense(1))
首先咱们得搞明白问题根源:你报错的那个Conv2D(64, (5,5))层,它接收的输入特征图高度已经只有4了,而5x5的卷积核需要至少5个像素的高度才能进行卷积运算,4-5直接得到负数,所以模型抛出了维度错误。下面给你两种简单可行的解决办法:
办法一:给Conv2D层加上padding='same'参数
这个参数会让模型自动在输入特征图的边缘补零,保证卷积运算能正常进行,还能尽量保留特征图的尺寸信息。你只需要修改出问题的那一层,甚至可以给前面所有Conv2D层都加上这个参数,避免后续再踩同样的坑:
model_img.add(Conv2D(64, (5, 5), activation="relu", strides=(2, 2), padding='same'))
办法二:缩小卷积核尺寸或者减少卷积层
既然输入高度只剩4,那就换个更小的卷积核,比如3x3,这样4-3=1,足够进行卷积:
model_img.add(Conv2D(64, (3, 3), activation="relu", strides=(2, 2)))
或者你也可以考虑删掉这一层Conv2D,减少特征图的压缩幅度,让后面的卷积层有足够的尺寸空间。
小技巧:提前计算特征图尺寸
新手很容易忽略这个,你可以用这个公式手动算每一层Conv2D后的特征图大小:输出尺寸 = (输入尺寸 - 卷积核尺寸 + 2*padding) // 步长 + 1
比如你的输入图像经过裁剪后高度是376-124-126=126,然后每一层步长都是2,算到第五层Conv2D时高度就变成4了,这时候用5x5卷积核且不加padding的话,自然就会出问题。提前算一遍能帮你避开很多这类错误~
因传感器问题未能完成训练,但感谢下方两个解答,模型现已正常运行。
内容的提问来源于stack exchange,提问作者IsmaelSad

