Conv2dTranspose产生错误的输出形状

时间:2019-07-14 17:55:52

标签: python tensorflow keras conv-neural-network mobilenet

我当前正在尝试修改mobilenetv2,以便它检测图像中的某些对象并返回标记该对象位置的热图。为此,必须使热图具有与输入图像完全相同的分辨率。

我的方法是建立类似U-Net的编码器/解码器网络,该网络利用Conv2dTranspose将移动网络的输出缩放到其原始形状,并为每个相应的卷积提供捷径,从而降低分辨率。

第一个对应层之间的第一个串联工作良好,但是第二个失败,因为它们的输出形状不匹配。如我所料,第一个Conv2dTranspose将分辨率提高了2倍。但是第二个没有。它具有输入形状(None,20,80,192),应该输出(None,40,160,144)。不幸的是,实际的输出形状竟然是(None,36,156,144),使得不可能串联这些层。

如何获得一致的输出形状?我以为padding ='same'应该保证什么?非常感谢您的帮助!

到目前为止,我已经尝试过更改填充类型,设置output_padding参数,步幅和过滤器大小。没有一个或多或少会令人惊讶地以期望的方式影响输出形状。

base_model = MobileNetV2(input_shape=(imageShape[0], 
    imageShape[1], 3), include_top=False, weights='imagenet')
conv_layers = get_conv_layers(base_model)

x = base_model.output

c = conv_layers.pop()
c = conv_layers.pop()
x = Conv2DTranspose(filters=c.output_shape[-1],
                    kernel_size=(3, 3), strides=(2, 2), 
                    activation='relu', padding='same', 
                    kernel_initializer='he_normal')(x)
x = concatenate([c.output, x], axis=-1)
x = Conv2D(filters=c.output_shape[-1], kernel_size=(3, 3),
           activation='relu')(x)

c = conv_layers.pop()
x = Conv2DTranspose(filters=c.output_shape[-1],
                    kernel_size=(3, 3), strides=(2, 2), 
                    activation='relu', padding='same',
                    kernel_initializer='he_normal')(x)
x = concatenate([c.output, x], axis=-1)
x = Conv2D(filters=c.output_shape[-1], kernel_size=(3, 3),
           activation='relu')(x)

ValueError:Concatenate层需要输入(除了concat轴以外)具有匹配的形状。得到了输入形状:[[None,40,160,144),(None,36,156,144)]

第一个形状是Conv2dTransposed输出的所需形状,第二个是实际形状。对于串联来说,这些应该是相同的。

1 个答案:

答案 0 :(得分:0)

好,所以我明白了,有时候您只需要在一段时间内摆脱问题即可。原来,我非常关注Conv2dTranspose是罪魁祸首,以致于我完全忽略了两者之间可能存在其他层的问题。毕竟我忘了将普通Conv2d的填充设置为'same'。设置此参数正确解决了问题,并且得到了预期的输出形状。