摘要
Inception 模块之所以把 1×1、3×3、5×5 卷积(再加上 3×3 池化)并排放在同一个层里,是为了在同一张特征图上同时捕获细粒度纹理、局部结构与更大范围的上下文,并用 1×1 卷积做“瓶颈”把高维特征先压缩、再送入较大的卷积核,从而在计算预算不变的前提下近似“最优稀疏结构”。这种设计让 GoogLeNet 只用 7 M 参数就击败了当年的 VGG‑16(138 M),并成为后续 EfficientNet、MobileNet 等轻量模型的思想源头。 (UvA 深度学习教程, Medium)
文章目录
-
设计初衷:多尺度感受野与稀疏近似
-
三条并行卷积核的作用与权衡
-
1×1 卷积的双重角色:降维 + 跨通道学习
-
计算消耗与参数量分析
-
实战案例:用 PyTorch 搭建一个最小可运行的 Inception Block
-
小结与延伸阅读
1 设计初衷:多尺度感受野与稀疏近似
-
多尺度假设:不同大小的卷积核对同一输入区域观察范围不同——1×1 看单像素通道间关系,3×3 聚焦局部纹理,5×5 覆盖更大上下文。让它们并行,相当于一次性“投票”多种尺度的判别证据。(UvA 深度学习教程, Medium, Medium)
-
稀疏结构近似:理论工作(Arora 等)指出最优 CNN 应为局部稀疏图;Inception 用数个致密卷积分支去“覆盖”这种稀疏连接,同时借助 1×1 瓶颈避免计算爆炸,达到“深而不贵”。
2 三条并行卷积核的作用与权衡
分支 | 典型通道数 | 主要贡献 | 代价 | 何时最关键 |
---|---|---|---|---|
1×1 | 少 | 跨通道交互、线性组合、降维 | 极低 | 整个网络、所有分支前后 |
3×3 | 中 | 大多数物体局部形状 | 中 | 中高层,感受野随深度增长 |
5×5 | 少 | 捕获更大纹理、对抗尺度变化 | 高 | 高层;在 v3 后常被两次 3×3 或 1×7+7×1 取代 |
Inception v1 论文建议:随着层次加深,3×3 与 5×5 所占比例可以逐渐增加,以匹配特征图空间稀疏度的提升。
3 1×1 卷积的双重角色
-
维度减小(瓶颈):把 C_in 通道压到 k (k≪C_in)后再做 3×3 / 5×5;例如 k = 1/4·C_in,可令 5×5 分支的 FLOPs 减到原来的 1/16。(MachineLearningMastery.com, Cross Validated)
-
非线性映射:加 ReLU/BN 后,相当于在像素级做一次“微型 MLP”,让不同通道特征重组,为后续大核卷积提供更有判别力的输入。(MachineLearningMastery.com)
4 计算消耗与参数量分析
假设输入特征图尺寸为 28×28×192:
-
朴素并行(无瓶颈)
-
3×3 (192→128):28²·128·3² ≈ 18 M FLOPs
-
5×5 (192→32):28²·32·5² ≈ 20 M FLOPs
-
-
加 1×1 瓶颈(192→32/8)
-
1×1 降维:28²·32·192 ≈ 4.8 M
-
后接 3×3:28²·128·3² ≈ 10 M
-
降维 + 5×5 :4.8 M + 28²·32·5² ≈ 6.3 M
-
总开销从 ~38 M 降到 ~21 M(≈45% 节省),且参数量亦同比下降。(Medium, MachineLearningMastery.com)
5 实战案例:PyTorch 实现与可视化
import torch
import torch.nn as nn
class MiniInception(nn.Module):
def __init__(self, in_channels):
super().__init__()
# 1×1 branch
self.b1 = nn.Conv2d(in_channels, 16, kernel_size=1)
# 1×1 → 3×3 branch
self.b3 = nn.Sequential(
nn.Conv2d(in_channels, 24, 1),
nn.ReLU(inplace=True),
nn.Conv2d(24, 32, 3, padding=1)
)
# 1×1 → 5×5 branch
self.b5 = nn.Sequential(
nn.Conv2d(in_channels, 4, 1),
nn.ReLU(inplace=True),
nn.Conv2d(4, 8, 5, padding=2)
)
# 3×3 max‑pool → 1×1
self.pool = nn.Sequential(
nn.MaxPool2d(3, stride=1, padding=1),
nn.Conv2d(in_channels, 8, 1)
)
def forward(self, x):
outs = [self.b1(x), self.b3(x), self.b5(x), self.pool(x)]
return torch.cat(outs, dim=1)
# demo
x = torch.randn(1, 64, 28, 28)
net = MiniInception(64)
y = net(x)
print(f"Input shape : {x.shape}\nOutput shape: {y.shape}")
输出:
Input shape : torch.Size([1, 64, 28, 28])
Output shape: torch.Size([1, 64, 28, 28])
可以看到:
-
四个分支的特征在通道维拼接后仍保持 28×28 空间维度,对下游层来说就是同一张“多尺度融合”特征图。
-
通道总数 = 16 + 32 + 8 + 8 = 64,与输入一致,因此不会在堆叠后引起通道爆炸。(UvA 深度学习教程)
6 小结与延伸阅读
-
并行不同卷积核让网络“一层同时看四种尺度”,提高了表达力;
-
1×1 瓶颈保证了这种表达力不会带来计算和参数失控;
-
后续 Inception v2/v3 用“两个 3×3 替代 5×5”与卷积分解继续减算力;v4/Res‑Inception 则引入残差;Xception/MBConv 把深度可分离卷积极致化,均可视为同一多尺度思想的延伸。(Medium, Medium, MachineLearningMastery.com)
推荐阅读
Szegedy et al., Going Deeper with Convolutions, 2014.
UvA Deep Learning Notebook Tutorial 5:Inception, ResNet and DenseNet.
Jason Brownlee, A Gentle Introduction to 1×1 Convolutions, MachineLearningMastery.
这些资料详细讨论了 Inception 演化、1×1 卷积数学推导及更多代码示例,可进一步加深理解。