公式

out = (in + 2 * padding - kernel) / stride + 1

输出特征图的每个像素对应于卷积核在输入图像上的一次有效滑动(卷积核的所有元素都完全位于输入图像的范围内)。

图示解释

用图来解释 in + 2 * padding - kernel 如何计算卷积核中心可以移动的最大距离,以及这个距离如何决定卷积核中心可以放置的位置数量。

为了简化,我们只考虑一维的情况(例如,只考虑宽度)。二维的情况只是在一维的基础上扩展到另一个维度。

情况 1:无填充 (padding = 0)

输入 (in = 6): [ _ _ _ _ _ _ ]
卷积核 (kernel = 3): [ * * * ]

滑动过程:

1.  [ * * * ] _ _ _   中心位置:1
2.  _ [ * * * ] _ _   中心位置:2
3.  _ _ [ * * * ] _   中心位置:3
4.  _ _ _ [ * * * ]   中心位置:4

最大移动距离:4 - 1 = 3
中心位置数量:4
计算:6 + 2 * 0 - 3 = 3
在这个例子中,卷积核中心可以移动的最大距离是 3 个单位。中心位置有 4 个(1, 2, 3, 4)。注意,最大移动距离比中心位置数量少 1。

情况 2:有填充 (padding = 1)

输入 (in = 6): [ _ _ _ _ _ _ ]
填充后: [ # _ _ _ _ _ _ # ] (# 表示填充)
卷积核 (kernel = 3): [ * * * ]

滑动过程:

1.  [ * * * ] _ _ _ _ #   中心位置:0
2.  _ [ * * * ] _ _ _ #   中心位置:1
3.  _ _ [ * * * ] _ _ #   中心位置:2
4.  _ _ _ [ * * * ] _ #   中心位置:3
5.  _ _ _ _ [ * * * ] #   中心位置:4
6.  _ _ _ _ _ [ * * * ]   中心位置:5

最大移动距离:5 - 0 = 5
中心位置数量:6
计算:6 + 2 * 1 - 3 = 5
在这个例子中,由于填充,输入图像“变大”了。卷积核中心可以移动的最大距离是 5 个单位。中心位置有 6 个(0, 1, 2, 3, 4, 5)。

情况 3:步长 (stride = 2)

输入 (in = 6): [ _ _ _ _ _ _ ]
卷积核 (kernel = 3): [ * * * ]

滑动过程:

1.  [ * * * ] _ _ _     中心位置:1
2.  _ _ [ * * * ] _     中心位置:3
3.  _ _ _ _ [ * * * ]   中心位置:5

最大移动距离:5 - 1 = 4
中心位置数量:3
计算:floor((6 + 2 * 0 - 3) / 2) + 1 = floor(3 / 2) + 1 = 1 + 1 = 2。注意这里计算的是输出的维度,也就是中心位置的个数,而不是最大移动距离。最大移动距离仍然是3

在这个例子中,步长为 2,这意味着卷积核每次移动两个单位。中心位置有 3 个(1, 3, 5)。

情况 4:步长 (stride = 3)

输入 (in = 8): [ _ _ _ _ _ _ _ _ ]
卷积核 (kernel = 3): [ * * * ]

滑动过程:

1. [ * * * ] _ _ _ _ _    中心位置:1
2. _ _ _ [ * * * ] _ _    中心位置:4

最大移动距离: 8 + 2 * 0 - 3 = 5

使用 floor + 1 计算输出维度: floor((8 + 2 * 0 - 3) / 3) + 1 = floor(5 / 3) + 1 = floor(1.666...) + 1 = 1 + 1 = 2

Note

当步长不能整除输入尺寸时,确实会导致输入边缘的部分信息没有被完整地用于卷积计算。这并不是一个错误,而是卷积运算的固有特性。可以通过使用 padding、调整步长或使用其他卷积方式来缓解这种信息丢失。选择哪种方法取决于具体的应用场景和网络设计目标。