Conv2dTranspose 产生错误的输出形状
Conv2dTranspose produces the wrong output shape
我目前正在尝试修改 mobilenetv2,以便它检测图像中的某些对象和 returns 标记所述对象位置的热图。为此,热图必须具有与输入图像完全相同的分辨率。
我的方法是构建某种类似 U-Net 的编码器-解码器网络,它利用 Conv2dTranspose 将移动网络的输出缩放回其原始形状,并使用通往每个相应卷积的快捷路径降低分辨率。
第一个对应层之间的第一个连接运行良好,但第二个连接失败,因为它们的输出形状不匹配。正如我预期的那样,第一个 Conv2dTranspose 将分辨率提高了 2 倍。然而,第二个没有。它具有输入形状 (None, 20, 80, 192) 并且应该输出 (None, 40, 160, 144)。不幸的是,实际的输出形状变成了 (None, 36, 156, 144),使得层的串联成为不可能。
如何实现一致的输出形状?我认为这就是 padding='same' 应该保证的?非常感谢您的帮助!
到目前为止,我已尝试更改填充类型、设置 output_padding 参数、步幅和过滤器大小。 None 其中或多或少令人惊讶地以所需的方式影响了输出形状。
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
层需要具有匹配形状的输入,但连接轴除外。得到输入形状:[(None, 40, 160, 144), (None, 36, 156, 144)]
第一个形状是 Conv2dTransposed 输出的期望形状,第二个是实际形状。这些应该相同才能使串联工作。
好吧,我明白了,有时候你只需要暂时离开一个问题。事实证明,我太专注于 Conv2dTranspose 是我完全忽略的罪魁祸首,以至于两者之间还有其他层可能会导致问题。毕竟忘记把普通Conv2d的padding设置成'same'了。正确设置此参数解决了问题,我得到了预期的输出形状。
我目前正在尝试修改 mobilenetv2,以便它检测图像中的某些对象和 returns 标记所述对象位置的热图。为此,热图必须具有与输入图像完全相同的分辨率。
我的方法是构建某种类似 U-Net 的编码器-解码器网络,它利用 Conv2dTranspose 将移动网络的输出缩放回其原始形状,并使用通往每个相应卷积的快捷路径降低分辨率。
第一个对应层之间的第一个连接运行良好,但第二个连接失败,因为它们的输出形状不匹配。正如我预期的那样,第一个 Conv2dTranspose 将分辨率提高了 2 倍。然而,第二个没有。它具有输入形状 (None, 20, 80, 192) 并且应该输出 (None, 40, 160, 144)。不幸的是,实际的输出形状变成了 (None, 36, 156, 144),使得层的串联成为不可能。
如何实现一致的输出形状?我认为这就是 padding='same' 应该保证的?非常感谢您的帮助!
到目前为止,我已尝试更改填充类型、设置 output_padding 参数、步幅和过滤器大小。 None 其中或多或少令人惊讶地以所需的方式影响了输出形状。
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
层需要具有匹配形状的输入,但连接轴除外。得到输入形状:[(None, 40, 160, 144), (None, 36, 156, 144)]
第一个形状是 Conv2dTransposed 输出的期望形状,第二个是实际形状。这些应该相同才能使串联工作。
好吧,我明白了,有时候你只需要暂时离开一个问题。事实证明,我太专注于 Conv2dTranspose 是我完全忽略的罪魁祸首,以至于两者之间还有其他层可能会导致问题。毕竟忘记把普通Conv2d的padding设置成'same'了。正确设置此参数解决了问题,我得到了预期的输出形状。