公式
out = (in + 2 * padding - kernel) / stride + 1
- 输入 (in): 输入图像的尺寸(宽度或高度)。
- 卷积核 (kernel): 卷积核的尺寸(宽度或高度)。
- 填充 (padding): 在输入图像边缘添加的像素数量。
- 步长 (stride): 卷积核在输入图像上滑动的步长。
- 输出 (out): 输出图像的尺寸(宽度或高度)
输出特征图的每个像素对应于卷积核在输入图像上的一次有效滑动(卷积核的所有元素都完全位于输入图像的范围内)。
-
in + 2 * padding:计算填充后的总长度。
-
in + 2 * padding - kernel:计算卷积核中心可以移动的最大距离。这个距离决定了卷积核中心可以放置的位置数量。
-
(in + 2 * padding - kernel) / stride:计算卷积核中心可以放置的位置数量除以步长。这表示有多少次完整的滑动。
floor(...):向下取整,因为我们只考虑完整的滑动。如果滑动不完整(即卷积核部分超出输入图像边界),则不算作一次有效的滑动。 -
+1:加上 1 是因为第一次滑动也产生一个输出。即使 (in + 2 * padding - kernel) / stride 的结果是 0,也意味着至少有一次有效的滑动(即第一次滑动)。
图示解释
用图来解释 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、调整步长或使用其他卷积方式来缓解这种信息丢失。选择哪种方法取决于具体的应用场景和网络设计目标。