卷积神经网络是强大的,同时也是灵活的,我们在设计时往往有很多的选择,比如下边一层我们应该用卷积层还是池化层?卷积层的filter应该选取多少?1乘1还是3乘3?

之前我们看到的不论是LeNet-5,AlexNet,VGG-16,每一层都只能干一件事,比如这一层是卷积,那就不是pooling。而且如果这一层是卷积,那么Filter的长宽和channel都是固定的。看着前人那些超神的网络设置,感觉如何设置网络简直是个玄学。那么网络设置能让机器学习帮我们做吗?Google Inception网络就是一个例子:

Google Inception网络做的事情是在一层网络上你设置多个操作,比如应用3个1*1的filter,然后在应用2个5*5的Same filter,再加一个max pooling filter。它们分别生成了3个,2个,1个channel。它们必须保证长和宽是一样的。然后在channel维度上进行堆叠,形成一个6个channel的输出。经过参数学习,这一层可能只干一件事,比如是max pooling或者一个3*3的Filter的卷积。或者是多种功能的结合。这个由网络自己来学习,不用我们纠结了。

它把原本需要我们人为定义的一些超参数转化成了可以让网络自己学习的参数。那么它带来了一个问题就是计算量的大幅增加。因为它引入了很多需要计算的参数。

如何减少计算量

之前我们说过1*1的filter可以帮助我们减少计算量。现在我们就举一个例子看看。
我们以下图为例,看看它的计算量是多少。

输入维度为 28*28*192,用32个5*5*192的Filter进行卷积运算。可以这么估计计算量:
我们生成的输出是28*28*32,每生成一个元素需要计算 5*5*192次乘法,还有 5*5*192-1次的加法,还有一次ReLU的计算。我们忽略计算量不大的加法和ReLU运算,则总共计算了:28*28*32*5*5*192=120422400次,大概是1.2亿次。只是正向传播一次就是1.2亿的计算量!

那么我们看看引入1*1 Filter后的计算量:
首先我们看第一个1*1*16的filter产生bottle neck 层 28*28*16输出的计算量:
28*28*16*192 = 2408448
接着我们看第二个5*5*32的filter产生28*28*32个输出的计算量:
5*5*16*28*28*32 = 10035200
两次计算量之和为12443648,约等于1240万,比之前的计算量少了90%。
你可能又担心这个bottle neck会不会有信息丢失,影响网络精度,经过试验证明,通过适当配置,它不会影响网络精度。

Inception Module


这个图最下边是一个Inception Module(你可以理解为一层)的输入。最上边是这个Inception Module的channel叠加输出。
我们从左往右看看中间都有哪些操作:

1*1 Filter

保证了输出维度和输入维度在长和宽上一致,filter的channel数是由输入channel数决定,输出维度数是由Filter个数决定。

3*3 Filter

首先是一个1*1的Filter来减少计算量,然后是一个same convolution 3*3 Filter。输出维度数是由Filter个数决定。

5*5 Filter

首先是一个1*1的Filter来减少计算量,然后是一个same convolution 5*5 Filter。输出维度数是由Filter个数决定。

池化层

这一层比较特殊:
1. 用的是same max pooling,pooling之前我们说没有人用padding,但是这里用了,只为为了让输出的维度和其他Filter一样,这样后来才能把各个Fitler输出的channel堆叠起来。
2. 我们知道max pooling是在各个channel上做,它不会减少channel。这样原来有多少channel,它就输出多少channel。加上别的Filter生成的channel,那么就太多了。所以我们在后边再加上一些1*1*n的filter,这样,它就可以生成n个channel的输出。n可以控制,这样就达到了压缩channel的目的。

Inception network

一个Inception network 可以看成是多个Inception Module的堆叠。当然还有一些小的改动,下图是一个示意图:

为什么叫Inception Network

因为是对盗梦空间这部电影的致敬,你要是看过电影,应该能理解。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: