想象你拿起一个 3×3 的取景框,去打量一张刚冲洗出来的 7×7 全家福。每框住 9 个格子,你就把里面的“明暗值”合成一个数字记在本子上,然后移动取景框继续下一个位置。最后得到的那张“数字记录表”,就是卷积神经网络中的特征图。这里有两个问题一直困扰着初学者:第一,取景框每次该平移几格?第二,照片边缘那些框不满九格的位置,要不要硬凑?第一个问题由步长(stride)回答,第二个问题由填充(padding)回答。它们看似只是两个数字,却决定了特征图的尺寸大小、边缘信息的保留程度,以及整个网络的“视野”变化规律。这篇文章,我们沿着“取景框扫描照片”这条主线,把 stride 与 padding 彻底看通透。

岗位关联

对 AI 从业者而言,stride 与 padding 是你写网络结构时绕不开的“地基参数”。能精确计算特征图尺寸、诊断维度报错、设计上采样下采样结构,是从“能跑通模型”迈向“会设计模型”的分水岭。

目录
  1. 可视化演示
  2. 填充模式辨析
  3. 步长作用机制
  4. 特征图尺寸计算
  5. 转置卷积调参
  6. 感受野与信息
  7. 网络架构实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示Stride与Padding的核心机制,通过全局/局部/动态/静态四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Stride与Padding:same same与valid填充模式深 步长对特征图分辨率的精确影响 核心机制可视化 Stride与Padding整体架构与关键组件

填充模式辨析

当你拿着 3×3 的取景框扫一张 7×7 的照片时,会立刻发现一个尴尬:取景框只能在照片内部平移,最外圈那一层像素永远无法成为取景框的“中心”。也就是说,无论你怎么扫,照片边缘一圈的信息都会在卷积过程中被丢弃。填充(padding)就是解决这个问题的工具——它给照片外面贴一圈“白边”,让取景框移向边缘时,依然能框到一个完整的 3×3 视野。

白边怎么贴,分成两种主流模式。第一种是 valid 模式:不贴任何白边,取景框完全在照片内部移动,边缘信息直接丢弃,输出尺寸必然小于输入。第二种是 same 模式:按需贴白边,让取景框的视野恰好能覆盖到照片的每一个角落,在 stride=1 时输出与输入尺寸相同,因此叫"same"(相同)。这里的 padding 值不是乱填的,它由卷积核大小决定。

same 模式要贴多少白边,有一个很简单的公式:只要在四周各补上卷积核一半宽度的格子就行。比如 3×3 的卷积核,四周各补 1 格;5×5 的卷积核,四周各补 2 格。这样无论取景框移动到哪个像素上,框内都能凑满完整的格子。

把照片想象成一张要裱起来的画,padding 就是师傅在画四周加的那圈卡纸边。裱得太多,画框显得笨重;裱得太少,取景框扫到边缘就“架空”。valid 相当于不裱,边缘直接舍弃;same 相当于裱到刚好合适,让每寸画面都能被取景框完整光顾一遍。

Psame=F−12\displaystyle P_{same} = \frac{F - 1}{2}
  1. F卷积核边长:取景框是 F×F 的正方形框框,F=3 就是“三格乘三格”。
    F=3\displaystyle F = 3
  2. F−1额外需要的对称格数:以中心格为基准,左右两侧各需要 F−1 格才能让框完整。
    F−1=2\displaystyle F - 1 = 2
  3. 除以 2平均分给两侧:把需要的 2 格分给上下左右,每侧恰好 1 格。
    F−12=1\displaystyle \frac{F - 1}{2} = 1

步长作用机制

取景框除了“边缘够不够”的问题,还有一个“走多快”的问题:每扫完一个位置,往右平移几格再停下?这个“平移格数”就是步长 stride。stride=1 是逐格扫描,信息一个不漏;stride=2 是每次跳两格,扫描速度翻倍,但很多格子根本不会被框住,像是巡逻时“走马观花”。

从直觉上看,移动跨度越大,同样面积的照片上停留的位置就越少。7×7 的照片、3×3 的取景框、不贴边的情况下,stride=1 能停 25 个位置,得到 5×5 的输出;stride=2 只能停 9 个位置,得到 3×3 的输出。也就是说,输出记录表的分辨率随步长增大而下降,信息在采样过程中变稀疏了。

那么步长变大有什么好处?第一,计算量直线下降,网络跑得更快;第二,每个输出值对应的输入区域更宽,有利于捕捉大范围结构。但代价是细节丢失。这也是为什么几乎所有 CNN 都刻意在浅层用 stride=1 保细节,在深层才用 stride=2 快速降分辨率。步长为 s 时,输出一个像素对应的输入覆盖长度有一个直观公式:

就像在田野里用探测器采样:步子跨得大,探测器来回能覆盖的“条纹”范围更宽,但脚下没踩到的田埂自然也就观察不到了。步长就是在“看得广”和“看得细”之间拨动的一根杠杆。

L=(k−1)×s+1\displaystyle L = (k - 1) \times s + 1
  1. k−1框内间隔数:3×3 取景框首尾之间隔着 2 个间隔。
    k−1=2\displaystyle k - 1 = 2
  2. ×(s)间隔被步长拉大:每跳一格,框内覆盖的范围就向外多延伸 s 格。
    (k−1)×s=2s\displaystyle (k - 1) \times s = 2s
  3. +1加回自身所占的格子:间隔之外,取景框自身还占着 1 格。
    L=(k−1)×s+1\displaystyle L = (k - 1) \times s + 1

特征图尺寸计算

前面几节都在定性讨论取景框的行为,但真正设计网络时,我们需要一个精确公式:给定输入尺寸、卷积核大小、padding 和 stride,输出到底多大?这就像你用取景框扫照片前,先要数清楚“这张照片能摆下多少个取景位置”。

核心公式只有一行,它统一了普通卷积的输出尺寸计算:

这个公式是整个卷积尺寸计算的核心工具。设计网络时,你可以通过调整 P 和 S 精确控制特征图的大小:想保持尺寸就设 stride=1 并用 same padding;想减半就设 stride=2;想微调就用公式反推出需要的 padding 值。值得注意的是,当 S 较大时,padding 的“补偿”作用有限——它只是在边界上多腾出一些位置,并不能抵消步长带来的整体缩减。

Wout=⌊Win−F+2PS⌋+1\displaystyle W_{out} = \left\lfloor \frac{W_{in} - F + 2P}{S} \right\rfloor + 1
  1. W_in输入边长:照片一边的格子数,比如 7。
    Win=7\displaystyle W_{in} = 7
  2. −F减去取景框占的宽度:取景框本身要占 F 格,能继续平移的空间只剩 W_in−F 格。
    Win−F=4\displaystyle W_{in} - F = 4
  3. +2P加回两侧白边:上下或左右各补 P 格,可平移空间增大到 W_in+2P−F。
    Win−F+2P=6\displaystyle W_{in} - F + 2P = 6
  4. ÷S看按步长能切几段:把可平移空间按 S 格一份切开,得到的是“窗口间隔数”。
    Win−F+2PS=3\displaystyle \frac{W_{in} - F + 2P}{S} = 3
  5. ⌊⌋ 向下取整切不满一格的丢弃:如果除不尽,多余的空隙不足以再停一次,直接舍掉。
    ⌊Win−F+2PS⌋=3\displaystyle \left\lfloor \frac{W_{in} - F + 2P}{S} \right\rfloor = 3
  6. +1窗口数 = 间隔数+1:从 0 号位置开始数,间隔有 3 段,窗口就有 4 个。
    Wout=4\displaystyle W_{out} = 4

转置卷积调参

打开发散思维:前面我们一直在“扫描照片”,但如果反过来,想从一张小尺寸的特征图“放大”回大尺寸的图,该怎么办?转置卷积登场了。它像是把取景框的用途倒过来——不再从大照片里提取小记录,而是从小记录里“展开”成大照片,因此也叫“反卷积”或“上采样卷积”。

转置卷积的输出尺寸计算公式和普通卷积长得不一样,它把 stride 和 padding 的角色调换了过来:

注意,转置卷积绝不是普通卷积的“逆运算”。它只能恢复特征图的形状尺寸,却无法恢复卷积过程中被压缩掉的像素值。它更像“把一张邮票大小的缩略图放大成海报”——海报的边框尺寸能算准,但海报上的细节是重新“想象”出来的,不是原照片的逐像素还原。在设计生成模型或语义分割解码器时,这一点会被反复验证。

Wout=(Win−1)×S−2P+F\displaystyle W_{out} = (W_{in} - 1) \times S - 2P + F
  1. W_in−1记录间的间隔数:小特征图里有 W_in 个格子,它们之间有 W_in−1 个缝隙。
    Win−1=1\displaystyle W_{in} - 1 = 1
  2. ×S每个缝隙被放大成 S 格:stride 越大,缝隙被拉得越宽,放大倍数越高。
    (Win−1)×S=2\displaystyle (W_{in} - 1) \times S = 2
  3. −2P扣除两侧留白:padding 在这里的作用相反,它会抵消掉一部分外扩范围。
    −2P=−2\displaystyle -2P = -2
  4. +F再加上取景框本身的宽度:最后一格周围还要容纳一个卷积核的跨度。
    Wout=2−2+3=3\displaystyle W_{out} = 2 - 2 + 3 = 3

感受野与信息

连续堆叠多层卷积时,“每一层输出上的一个像素,到底对应原始输入的哪一片区域?”这个区域大小就是感受野。用取景框的比喻来说:第一层取景框只有 3×3,看的是照片局部;但如果第二层取景框踩在第一步的结果上,它间接看到的原始区域就变大了。

stride 在这里起到“加速器”作用。每当我们用一个 stride=2 的卷积层,下一层的每个像素就能跳过更多原始像素,感受野增长得比 stride=1 快得多。层层叠加后,感受野呈近似线性增长,计算式是一个递推公式:

感受野大了,模型能看到更大范围的上下文,但也意味着输出分辨率更低、细节信息被压缩得更厉害。这就像你用望远镜看远处的大山:镜头看得越远越全,近处的一草一木反而越模糊。设计网络时,这是个永远要在“全局理解”和“细节保真”之间做权衡的过程,而 stride 和 padding 就是这套权衡的调节旋钮。

Rl=Rl−1+(kl−1)×∏i=1l−1si\displaystyle R_l = R_{l-1} + (k_l - 1) \times \prod_{i=1}^{l-1} s_i
  1. R_l−1上一层已经积累的感受野:它是递推的起点,代表“已经看到的区域”。
    Rl−1\displaystyle R_{l-1}
  2. k_l−1本层卷积核带来的额外跨度:每一层的新卷积核都会把视野向外扩一点。
    (kl−1)\displaystyle (k_l - 1)
  3. ∏s_i前面所有层步长的乘积:这是总下采样倍数,决定了本层扩大的视野被“放大”了多少倍。
    ∏i=1l−1si\displaystyle \prod_{i=1}^{l-1} s_i

网络架构实践

前面讲的都是理论,现在落到真实网络设计。你会发现,几乎所有经典 CNN 都在自觉地使用 stride 与 padding 的搭配:浅层用 stride=1 + same padding 保持细节,深层用 stride=2 降分辨率提效率。整个网络的“下采样倍数”,其实就是所有 stride 的乘积:

理解了总下采样倍数,很多架构设计就变得顺理成章。残差网络(ResNet)在做恒等映射时,需要让跳跃连接(skip connection)两端的特征图尺寸严格一致,这时要么调整 padding 值,要么在捷径分支插入一个 stride=2 的 1×1 卷积来对齐尺寸。U-Net 这类对称结构中,下采样用了 stride=2 的卷积,上采样则用步长为 2 的转置卷积,二者一降一升,正好保证了编码器与解码器的特征图尺寸能逐级拼接。可以说,stride 与 padding 不只是一个卷积层的参数,更是整个网络空间结构的地基与骨架。

---

DownRatio=∏i=1Lsi\displaystyle \text{DownRatio} = \prod_{i=1}^{L} s_i
  1. ∏对整个网络逐层连乘:每一层的步长都参与最终的缩放倍数。
    ∏i=1L\displaystyle \prod_{i=1}^{L}
  2. s_i第 i 层的步长:stride=1 不改变尺寸,stride=2 让尺寸减半。
    si=2\displaystyle s_i = 2
  3. DownRatio总下采样倍数:例如三层 stride=2,特征图整体缩小 8 倍。
    DownRatio=2×2×2=8\displaystyle \text{DownRatio} = 2 \times 2 \times 2 = 8

AI 应用场景

目标检测中的多尺度特征金字塔

阶段:CNN 特征提取 / 多尺度检测头

解决的问题:一张图里有大有小的目标,传统方法要么缩放到固定尺寸再检测,要么用滑动窗口暴力枚举,效率低且尺度覆盖不完整。现代检测网络用 stride 的层级差异天然构造不同尺度的特征图,一次前向传播同时获得全局与局部信息。

具体案例:YOLOv8 的主干网络用 stride=2 卷积逐级下采样,分别得到 80×80、40×40、20×20 三档分辨率的特征图,大特征图负责检测小物体,小特征图负责检测大物体。每个尺度的特征图再配合对应的 anchor 或 anchor-free 头完成定位与分类。

语义分割中的上采样恢复

阶段:解码器 / 特征上采样

解决的问题:分割任务要求对每个像素分类,但编码器不断用 stride=2 压缩尺寸,特征图变得又小又粗,直接插值回去会丢失边缘。转置卷积通过 stride 与 padding 的公式精确控制上采样倍率,把低分辨率特征恢复到原图大小,恢复过程本身还可训练。

具体案例:U-Net 解码器使用步长为 2 的转置卷积,把 16×16 的特征图逐级恢复到 256×256,同时通过跳跃连接把编码器同尺寸的特征图拼接进来,弥补 stride 下采样造成的细节损失,最终输出逐像素的类别概率图。

图像超分辨率重建

阶段:生成后处理 / 像素重排

解决的问题:把低分辨率图放大为高清图,需要控制上采样倍率且不能出现棋盘格伪影。直接堆叠大 stride 转置卷积容易产生不均匀重叠,业界常用“亚像素卷积”技巧,把 stride 隐含在通道重排中,让上采样更平滑。

具体案例:以 ESPCN 为代表的超分模型,在最后一层将通道数为 r² 的特征图重排为 r 倍宽高的图像,其中 r 就是上采样倍率。相比直接使用 stride=r 的转置卷积,这种方法计算更高效、伪影更少。

Python 演示

python33 行
import numpy as np def conv2d_manual(image, kernel, stride=1, padding=0):    '''手动实现带 stride 和 padding 的二维卷积'''    h, w = image.shape    kh, kw = kernel.shape    image_padded = np.pad(image, padding, mode='constant', constant_values=0)    oh = (h + 2 * padding - kh) // stride + 1    ow = (w + 2 * padding - kw) // stride + 1    output = np.zeros((oh, ow))    for i in range(oh):        for j in range(ow):            h0 = i * stride            w0 = j * stride            roi = image_padded[h0:h0 + kh, w0:w0 + kw]            output[i, j] = np.sum(roi * kernel)    return output def same_padding(kernel_size):    '''计算 same 模式下的 padding 量'''    return (kernel_size - 1) // 2 if __name__ == '__main__':    image = np.arange(49, dtype=float).reshape(7, 7)    kernel = np.array([[1, 0, -1], [1, 0, -1], [1, 0, -1]], dtype=float)     out_valid = conv2d_manual(image, kernel, stride=1, padding=0)    out_same = conv2d_manual(image, kernel, stride=1, padding=same_padding(3))    out_stride2 = conv2d_manual(image, kernel, stride=2, padding=0)     print('valid, stride=1 :', out_valid.shape)    print('same,  stride=1 :', out_same.shape)    print('valid, stride=2 :', out_stride2.shape)
目的:用 NumPy 从零实现一个支持 stride 与 padding 的卷积函数,直观验证输出尺寸公式与三种配置的差异。
  1. np.pad(image, padding, mode='constant', constant_values=0)这就是“给照片贴白边”,白边的值是 0,不掺入任何真实信息
  2. oh = (h + 2 * padding - kh) // stride + 1用输出尺寸公式算出输出高度,// 正是向下取整
  3. roi = image_padded[h0:h0 + kh, w0:w0 + kw]像取景框一样从当前扫描位置框出卷积核大小的区域
  4. np.sum(roi * kernel)框内像素与卷积核逐点相乘再求和,也就是“把框里 9 个格子的特征浓缩成一个数字”

常见误区

误区名字既然叫 "same",那无论 stride 设多大,输出特征图的尺寸都应该和输入一样大吧?我 stride=2 照样输出 7×7,结果一跑就报维度错误。

正解same 只在 stride=1 时才严格保持输入输出同尺寸。当 stride=2 时,same 的含义是“取景框能完整覆盖到边缘”,输出尺寸约等于输入的一半,确切地说是 ceil(输入/2)。“same“指”边界被完整照顾“,而不是”尺寸完全不变”。

为何常见:"same"这个名字太容易望文生义,加上大多数入门教程都用 stride=1 举例,导致学习者形成了刻板印象。

误区反正 padding 是往四周补格子,那我只要不停调大 padding,特征图不就能无限变大吗?多补几圈白边,输出岂不是比输入还大?

正解在 stride 和 kernel 不变时,增大 padding 确实会增加输出尺寸,但输出尺寸由整个公式共同决定。当 stride 较大时,padding 往往只是在“弥补”步长搬走的边界空间,输出可能不变甚至缩小。另外 padding 补的是 0,不携带信息,不可能凭空创造特征。

为何常见:初学者容易只盯住单一变量,忽略了 "+2P" 与除以 stride 之间的相互制约关系。

误区转置卷积既然带“转置”两个字,听起来就是卷积的逆运算,那我用它不就能把特征图还原成原始输入图片吗?逐像素无损还原不是梦。

正解转置卷积只能保证输出形状符合上采样后的尺寸,数值并不是原始图像。普通卷积是“多对一”信息浓缩,转置卷积是“一对多”的信息散布,信息量根本不对等,无法无损还原。它能恢复“尺寸的壳”,但内容全靠卷积核重新生成。

为何常见:“转置”一词带有数学矩阵逆的联想,让人误以为它像矩阵求逆一样能完美回退。

误区stride=2 能把特征图减半,计算又快、感受野又大,那我干脆所有层都用 stride=2,模型又轻又能看清全图,岂不是最优解?

正解步长越大,特征图分辨率下降越剧烈,纹理、边缘等细节信息丢失得越严重。真正的好网络总是“渐进式”下采样:浅层保持 stride=1 捕捉细节,深层才用 stride=2 扩大视野。一上来就大步长,模型只能看到模糊的轮廓,学不出精确特征。

为何常见:人们容易只看到 stride 提速和扩大感受野的好处,却忽略了信息保留的代价,这就是“免费午餐”思维在作祟。

面试题

Q1. 当 stride=1 时,使用 padding 保持输出尺寸与输入相同的模式是?

单选题 · easy

  • A.valid padding
  • B.full padding
  • C.same padding← 正确答案
  • D.zero padding

答案:C。same padding 在 stride=1 时恰好补足边界,使输出与输入同尺寸;valid padding 是不补边,输出会更小,其他两个选项是常见的干扰项。

Q2. 7×7 输入、3×3 卷积核、stride=1、padding=0,输出尺寸是?

单选题 · easy

  • A.5×5← 正确答案
  • B.6×6
  • C.7×7
  • D.3×3

答案:A。代入公式 (7−3+0)/1+1=5,输出 5×5。这就像 7 格长的照片用 3 格取景框逐格扫描,首尾之间只能停 5 个不重叠的位置。

Q3. 输入 7×7、卷积核 3×3、stride=2、padding=1,输出尺寸是?

单选题 · mid

  • A.2×2
  • B.3×3
  • C.4×4← 正确答案
  • D.5×5

答案:C。代入公式 ⌊(7+2−3)/2⌋+1=⌊6/2⌋+1=4,输出 4×4。这里 padding 补 1 格把可平移空间从 4 增至 6,再被 stride=2 切成 3 段,加 1 得 4。

Q4. 下列关于 padding 的说法,正确的是?

多选题 · mid

  • A.padding 可以保留边缘信息← 正确答案
  • B.padding 总使输出变大← 正确答案
  • C.padding 消除所有边缘损失
  • D.padding 增加可训练参数

答案:AB。padding 给边缘补白边,使取景框能覆盖到边缘像素,所以 A 正确;在其他参数不变时,padding 增加输出尺寸,B 也正确。但它补的是 0,无法真正消除边缘信息损失,也不增加卷积核的可训练参数,故 C、D 错误。

Q5. 转置卷积中,输入 2×2、卷积核 3×3、stride=2、padding=1,输出尺寸是?

单选题 · mid

  • A.2×2
  • B.3×3← 正确答案
  • C.4×4
  • D.5×5

答案:B。代入转置卷积公式 (2−1)×2−2+3=3,输出 3×3。转置卷积用小图“展开”成大图,stride 在这里控制放大倍数,padding 则抵消一部分外扩。

Q6. 关于 same padding,以下哪项描述正确?

单选题 · mid

  • A.stride=1 时输出与输入同尺寸← 正确答案
  • B.stride=2 时输出与输入同尺寸
  • C.padding 只加在输入左侧
  • D.padding 大小不必指定

答案:A。same padding 的核心效果是 stride=1 时输入输出同尺寸;stride=2 时输出约为输入一半。padding 在上下左右均匀添加,且大小由卷积核决定而非随意省略。

Q7. 采用 stride=2 的卷积层代替池化层,有哪些影响?

多选题 · hard

  • A.特征图分辨率减半← 正确答案
  • B.感受野加速扩大← 正确答案
  • C.细节信息完全不丢失
  • D.计算量保持不变

答案:AB。stride=2 使输出尺寸减半,同时感受野按步长乘积加速增长,所以 A、B 正确。但大步长采样必然丢失部分细节,C 错误;输出分辨率减半反而使计算量大幅下降,D 也错误。

Q8. 计算特征图尺寸时,除不尽的结果如何处理?

单选题 · easy

  • A.四舍五入
  • B.向下取整← 正确答案
  • C.向上取整
  • D.随机取整

答案:B。卷积尺寸公式使用向下取整,因为窗口必须是完整可见才能计算,多余的空隙不足以停一个取景框。四舍五入或向上取整会凭空多出一个不完整的窗口。

Q9. 关于转置卷积与普通卷积的关系,正确的是?

单选题 · hard

  • A.是卷积的严格逆运算
  • B.能恢复原始像素值
  • C.形状可恢复但值不一定← 正确答案
  • D.与卷积完全无关

答案:C。转置卷积能按公式恢复上采样后的形状尺寸,但数值是学习出来的,不是原始输入的逐像素还原。卷积是“多对一”浓缩,信息一旦浓缩就无法无损展开。

Q10. 在 ResNet 中调整 stride 与 padding 需要关注什么?

多选题 · hard

  • A.跳跃连接两端尺寸对齐← 正确答案
  • B.总下采样倍数保持一致← 正确答案
  • C.padding 必须严格对称
  • D.stride 只能取 1

答案:AB。残差网络的跳跃连接要求两端特征图“逐元素相加”,因此尺寸必须对齐,A 正确;设计整体网络时总下采样倍数要保持稳定,B 正确。padding 对称是默认做法但非硬性规定,stride 也完全可以取 2 来做下采样,C、D 错误。