← 返回文章

结构笔记 / 6 分钟

Inception:分支为什么能汇合

从 torch.cat 出发,理解多尺度分支、空间尺寸和通道数。
深度学习PyTorchInception

从汇合处往回看

第一次面对 Inception,结构图里同时出现多种卷积和池化路径,很容易把注意力放在分支数量上。真正让我理清它的,是先找到代码中的汇合位置:

outputs = [branch1(x), branch2(x), branch3(x), branch4(x)]
return torch.cat(outputs, dim=1)

torch.cat(..., dim=1) 说明这些路径不是互相替代,而是分别处理同一个输入,最后把结果沿通道维度放在一起。先理解汇合规则,再回头逐条阅读分支,复杂结构就变成了几个可以单独检查的小问题。

先写出每条路径的形状

假设输入是 [N, C, H, W]。当拼接维度是 1 时,批次、高度和宽度必须一致,只有通道数可以不同:

branch1: [N, 16, H, W]
branch2: [N, 24, H, W]
branch3: [N, 24, H, W]
branch4: [N, 16, H, W]
output:  [N, 80, H, W]

这里的 80 不是模型自动猜出来的,它来自四条分支通道数之和。下一层卷积的 in_channels 必须与这个结果一致。

卷积核不同,空间尺寸仍要一致

不同感受野并不等于不同输出尺寸。卷积核、padding 和 stride 共同决定高度和宽度。阅读实现时,我会把每条分支的关键参数列出来,而不是只看卷积核名字。

对于 stride 为 1 的卷积,常见目标是通过 padding 保持空间尺寸。池化分支也需要检查 padding,否则某条路径少一行或一列,最终会在 torch.cat 处暴露问题。

用最小输入验证结构

完整训练太慢,不适合用来确认一次形状判断。更直接的做法是构造一个小批次,只运行一次前向传播:

x = torch.randn(2, 3, 32, 32)
y = model(x)
print(x.shape, y.shape)

如果需要定位具体分支,可以暂时分别打印分支输出。这样验证的是结构是否成立,而不是模型是否训练得好。

这段实现能说明什么

torch.cat 能证明多条路径如何汇合,也能帮助检查尺寸和通道。它不能单独证明 Inception 在某项任务上一定优于普通 CNN。性能判断仍然需要相同数据划分、训练流程和清楚标注的实验结果。

对我来说,读懂 Inception 的关键不是记住结构图,而是建立一个可重复的方法:从汇合处确认规则,逐条记录形状,再用最小前向传播验证。