卷积尺寸这事儿,实际上跟切西瓜、切披萨挺像的,但得搞清楚,切多了要么切少了,大脑里的神经网络就完蛋了。 想象一下你手里有个张着大口的西瓜,那是个高 $H$、宽 $W$ 的二维矩阵。

这时候你拿一把刀,不是随意挥两下,而是要沿着特定的路径去瓢取里面的瓜肉,取到了一定数量,然后把这些瓢好的肉拼凑成一个新的形状。

这个“瓢取”的过程,在深度学习里就叫卷积 kernel。 让西瓜变大变小,得看刀如何切 要是你直接拿一把刀,一刀下去,把整块西瓜都切了,那新西瓜肯定就是个点,要么是一串点,高度和宽度都归零了,直接当个数字处理完就没了,这显然不中。你得沿着对角线让刀走,这样既不会切掉忒靠近边缘的瓜皮,也不会把中间的瓜肉切得忒碎。

这个“走对角线”的过程,实际上就是卷积核的步长(Stride)。

要是步长设得忒大,中间那层瓜肉就被切了;设得忒小,别看中间留着,但四周切出来的碎块可能忒多,害得新西瓜变得又胖又扁,边缘信息都丢光了。 这就好比图像处理里的 padding(填充)。我们在图片四周加了一圈白边,不是为了填充真数据,而是为了给卷积核留出空间,避免切到下边缘的时候切到骨头(边界效应)。加完白边后,再让卷积核沿着预设路径走一次,就能拿到一个略微大一点的输出窗口。

要是走完了,发现输出窗口比输入窗口还大,那就直接砍掉两边,对齐回来。 故此,卷积核的宽度(Output Width)和步长(Stride)之间有个好办的除法关系:$Output Width = Input Width - Kernel Width + 1 times (1 - Step Size)$。

这个公式看着数学符号挺冷冰冰的,实际上是个好办的加减乘除,就像算账一样。 步长不同,输出形状就不同 步长实际上是个管住节奏的旋钮。

要是你把步长设得跟核的宽度一样大,那输出出来的就是个方阵,中间是纯数据,四周全是白边,这玩意儿在卷积里叫“零填充”,一般不推荐用,出于边缘信息忒脏。

要是你把步长设得比核的宽度小,比如步长是 1,输出就是全 1;步长是 2,输出就是中间全是数据,四周也是全 1。 比如拿一个 3x3 的卷积核去卷积一个 5x5 的图像。

要是步长是 1,输出出来的就是全 1 的 5x5 矩阵。

这时候,别看计算量不大,但数据量一倍长,对模型过拟合是个风险。

要是步长是 2,输出就是中间 3x3 全是原始数据,边缘全是 1。

这时候输出少了一半,但边缘信息保留了。 还有一种特殊情况,就是步长刚好等于核的宽度。

比如核是 5x5,步长也是 5。

这就意味着每次只取一行(要么一列),数据量减半,并且输出形状的长和高都会减半。

这种配置在早期的网络里见过,目前用得少,出于模型参数数量少了,但信息量也少了,训练效果反而可能变差。 输出宽度是奇数,对模型影响最大 这里有个务必强调的:输出的宽度(Output Width)务必是奇数。

为啥?出于卷积核是中心对称的,你从中间往左、往右各取一段,是等效的。

要是你算出个偶数宽度的输出,比如 4,那意味着中间两个位置的数据彻底重叠了,并且两边数据也彻底重叠了。

这就好比在计算 5 个数字求和时,要是没加小数点,结局都是 1.0。 举个例子。假设你有一个 6x6 的图像,卷积核是 2x2,步长是 1。

这时候输出宽度应当是 $6 - 2 + 1 = 5$。出于 5 是奇数,中间那个位置的数据只被计算了一次,贼清楚。但要是你的卷积核是 3x3,步长也是 1,输入是 6x6,输出宽度就是 $6 - 3 + 1 = 4$。

这时候中间两个位置的数据就被重复计算了两次,两边各一次。

这会害得输出矩阵不均匀,有的位置数值大,有的位置数值小,破坏了数据的纯净性。 实际上要是输入图像是奇数宽,比如 7x7,卷积核 3x3,步长 1,输出宽度就是 $7 - 3 + 1 = 5$。

这样中间的数据只被计算一次,两边各一次,输出宽度保持不变,只是数据量变小了。 像素对齐和边缘处理 之故此要求输出宽度是奇数,还有一个更深层的直觉缘由:像素对齐。人类看图片时,是沿着 4 条线(横竖各一条)来定义网格的。卷积核一般也是定义在网格上的。

要是输出宽度是偶数,比如 4,意味着输出矩阵的尺寸和网格对齐的方式不一致,这在实际应用中挺难解释,也增添了大量不必要的计算。 故此,在写代码的时候,一定要确保算出来的输出宽度是奇数。

要是算出来是偶数,要么调整步长,要么调整核的大小,要么调整输入的大小。 最终总结一下,卷积尺寸的核心逻辑就三条:第一步,用核的宽度减去步长的倍数,再加上 1;第二步,要是算出来是偶数,那肯定出错了,要么改步长,要么改核,要么改输入;第三步,输出务必是奇数,这样中间才干净利落。至于步长取多少,得看你的策略:步子迈大,数据量小,适合小模型;步子迈小,数据量大,适合大模型。别死磕奇数,有时候为了效率,哪怕略微碰到偶数,也能先跑起来,等训练稳了再调回来。 卷积尺寸这事儿,看着像个公式,实际上就是个关于数据量的分配游戏。切多了边缘碎,切少了中间空,如何把数据最干净利落地塞进模型里,还是得靠人用直觉和经验去瞎琢磨,毕竟没人能写出完美的网络架构。