上来先说 1 ∗ 1 1*1 1∗1卷积核的作用:
- 特征降维,节省计算量
- 增加模型非线性表达能力
举例:因为bottleneck( 1 ∗ 1 1*1 1∗1卷积核)是在2014年的GoogLeNet中首先应用的,所以我们就拿GoogLeNet来举例。
在GoogLeNet(2014)之前,网络的设计思路是一直在stack(堆叠)层数,当时的假设是网络越deeper,网络的performance越好。到了2014年,GoogLeNet横空出世,GoogLeNet改变了这个假设:除了增加深度,还增加了网络的宽度。GoogLeNet的结构如下:
下面我们一步步来推倒出Inception module的设计,先来看初始版本的Naive Inception module。Naive Inception module就是对同一个输入,用不同大小的卷积核去卷积,然后分别把它们的结果给concatenate(注意这里要求不同卷积操作输出的feature map的大小要相同,不然没法特征拼接呀)起来。但这样有个问题:计算量太大了!
注:上图
3
∗
3
3*3
3∗3卷积的
p
a
d
d
i
n
g
=
1
padding=1
padding=1,
5
∗
5
5*5
5∗5卷积的
p
a
d
d
i
n
g
=
2
padding=2
padding=2(为保证不同卷积操作输出的特征图大小一样,以便于后面的特征拼接)
Naive Inception module的计算量的计算过程如下,可见Naive Inception module的计算量是相当大的(这还只是一层)。
那么我们应该如何减少计算量呢?用的是什么理念和思想呢?
这就不得不提到从2014年一直延续至今的神经网络设计思想:bottleneck。使用bottleneck(即 1 ∗ 1 1*1 1∗1的卷积核)来进行特征降维,减少特征图的层数,从而减少计算量。
bottleneck的过程如下面两张图片所示:
![]() |
![]() |
所以到这里,Naive Inception module就升级为了Inception module。
此时这一个Inception module的计算量为358M ops,相比之前的854M ops,使用“bottleneck”的Inception module的计算量降低了一半多!
done~
有问题欢迎交流~