输入图像尺寸如何影响完全连接层的尺寸和形状?

时间:2019-08-02 18:36:05

标签: machine-learning image-processing neural-network computer-vision image-segmentation

我正在阅读许多说明两件事的教程。

  1. “ [用卷积层替换完全连接的层]将它们转换为采用任何大小的输入和输出分类图的全卷积网络。” Fully Convolutional Networks for Semantic Segmentation, Shelhamer et al.
  2. 传统的CNN无法做到这一点,因为它具有完全连接的层,并且形状由输入图像大小决定。

基于这些陈述,我的问题如下?

  1. 每当我制作FCN时,我只能使其在固定尺寸的输入图像上进行训练和测试。 但是在论文的摘要中,他们指出:“我们的主要见识是建立“完全卷积”的网络,该网络可以接受任意大小的输入,并通过有效的推理和学习产生相应大小的输出。” 可能第一层具有固定数量的权重,并且不同大小的输入图像将无法正确链接到这些权重。
  2. 输入图像大小如何精确确定完全连接的图层?我尝试在线查找,但找不到直接答案。

2 个答案:

答案 0 :(得分:1)

似乎您对图像/特征图的空间尺寸(高度和宽度)和“通道尺寸”(每个像素存储的信息的尺寸)感到困惑。

输入图像可以具有任意的高度和宽度,但始终具有固定的“通道”尺寸= 3;也就是说,每个像素的固定尺寸为3,即每个像素颜色的RGB值。
让我们将输入形状表示为3xHxW(3个RGB通道,按高度H乘以宽度W)。

应用kernel_size=5output_channel=64进行卷积意味着您有64个大小为3x5x5的滤镜。对于每个滤镜,您将获取图像中所有重叠的3x5x5窗口(RGB x 5 x 5像素),并为每个滤镜输出一个数字,该数字是输入RGB值的加权和。对所有64个过滤器执行此操作,将为每个滑动窗口提供64个通道,或者为形状为64x(H-4)x(W-4)的输出特征图。

具有kernel_size=3output_channels=128的附加卷积层将具有128个形状为64x3x3的滤镜应用于输入要素映射为64x(H-4)x(W-4)的所有3x3滑动窗口具有形状为128x(H-6)x(W-6)的输出特征图。

您可以通过类似的方式继续添加卷积甚至池化层。
This post很好地解释了卷积/合并层如何影响要素图的形状。

回顾一下,只要不更改输入通道的数量,就可以对任意 spatial 尺寸的图像应用完全卷积的网络,从而得到不同的输出要素地图的 spatial 形状,但始终具有相同数量的 channels

对于完全连接的(又是内积/线性)层;该层不关心空间尺寸或通道尺寸。完全连接的层的输入被“展平”,然后权重的数量由输入元素的数量(通道和空间组合)和输出的数量确定。
例如,在VGG网络中,当在3x224x224图像上进行训练时,最后一个卷积层将输出形状为512x7x7的特征图,然后将其展平为25,088维矢量,并馈入具有4,096个输出。

如果您要向VGG提供不同空间尺寸的输入图像(例如3x256x256),则最后一个卷积层将输出形状为512x8x8的要素图-请注意,通道尺寸512不变,但空间尺寸从7x7增长到8x8。现在,如果要“展平”此要素贴图,将为完全连接的图层提供32,768尺寸的输入矢量,但是,a,您的完全连接的图层需要25,088的尺寸输入:您将得到RunTimeError。 / p>

如果要使用kernel_size=7output_channels=4096将完全连接的层转换为卷积层,它将对512x7x7输入要素图执行完全相同的数学运算,从而生成一个4096x1x1输出功能。
但是,当您为其提供512x8x8特征图时,它不会产生错误,而是输出4096x2x2输出特征图-调整空间尺寸,固定通道数。

答案 1 :(得分:-1)

  1. 图像在训练和测试期间必须具有预先定义的大小。对于完全连接的层,您可以根据需要拥有任意数量的节点,而该数目并不取决于输入图像的大小或卷积层的输出尺寸。
  2. 输入图像的大小和卷积将确定卷积层的形状以及最终展平的输出,这些输出将馈送到完全连接的层。完全连接的层可以具有任何尺寸,并且不依赖于输入图像。 以下是示例代码。
    model = Sequential()
    model.add(Conv2D(32, (3,3), activation='relu', input_shape=input_shape))
    model.add(BatchNormalization())
    model.add(Conv2D(64, (3,3), activation='relu'))
    model.add(BatchNormalization())
    model.add(Conv2D(128, (3,3), activation='relu'))
    model.add(BatchNormalization())
    model.add(Conv2D(256, (3,3), activation='relu')
    model.add(BatchNormalization())
    model.add(Conv2D(256, (3,3), activation='relu')
    model.add(MaxPooling2D())
    model.add(BatchNormalization())
    model.add(Flatten())
    model.add(Dense(512, activation='sigmoid')) #This is the fully connected layer, whose dimensions are independent of the previous layers