吴教授的CNN课堂:进阶 | 从LeNet到残差网络(ResNe
第二周是关于卷积网络(CNN)进阶部分,学到挺多新东西。因为之前了解过CNN基础后,就大多在用RNN进行自然语言处理方面的研究,很多CNN的最新进展虽有耳闻,但是并不清楚。
特别是各个论文模型又喜欢取一些奇怪的名字(比如昨天读的两篇论文,一个叫NTT,一个叫TMD),如果没读过论文,不了解一些缘由,真是傻傻分不清。
之前看视觉问答时,预处理图片部分需选择训练好的网络,结果一看,一大堆什么VGG、Res、Incept这些看不懂的名词,而且后面还加着16、19、101等数字和V1、V2、V3这样的版本数。结果只能两眼一抹黑,参考别人的论文,瞎选了一个。
闲话不多说,开始吧。
那些曾经辉煌过的Net
在提到之后的ResNet和Inception Net前,最好先回顾一下CNN里面成功架构的发展,这样就可以把握住一条清晰的发展脉络,之后讲解进阶网络的时候也能很快理解。
首先是爷爷级的LeNet-5,因为这大概是20年前提出来的了。是当时尚且青涩,而现在已是深度学习四大天王里的LeCun提出的,LeNet也是取自他名字前半截,5表示只有五层,当时用于处理MNIST这样的手写数字识别。
在基础课里面吴教授也有亲手把整个架构画出来,所以并不是很复杂。分别卷积和池化两次后,然后直接输入全连接网络就可以了。
LeNetLeNet后,因为人工智能寒冬,所以很长时间并没有太大发展。
直到13年的时候,后起之秀Alex Krizhevsky (相信不少人也看过他的博客,听过他有名的Stanford cs231) 提出了AlexNet,在ImageNet比赛上取得了很大的成功,向大家展示了深度学习的力量,从此掀起一次浪潮。
AlexNet和LeNet差别并不是很大,主要不同有以下三点。
- 卷积层过滤器大小的一些变化,网络层数也多了些;
- 使用了ReLU激活函数;
- 在当时用了两个GPU来训练;
在AlexNet展示了深度学习在图像处理上的成功后,大家也就开始不断在其之上完善图像处理的CNN构架。而VGG就是第一个非常简洁又系统化,提出了一套怎么使用更深的网络来训练的网络架构。
VGGVGG的创举之点在于,比起之前那些网络其中参数的混杂,它很有计划和条理地布置了架构中各个层的结构。比如说可以列举出一下几点:
- 卷积层一定用3x3的过滤器,填充用"same",步长选择1;
- 池化层一定用2x2的窗口大小,步长选择2;
- 还有就是把整个网络分成几个大的部分,每部分都是卷积加池化,并且每部分过滤器的个数也有规律的增加,像这样
64 -> 128 -> 256 -> 512 -> 512
。
VGG是当时参赛组(Visual Geometry Group)的名称。一般现在大家用到的都是VGG-16或者VGG-19,16和19也正如所想,分别是对应的VGG版本中的层数。
看上去16和19层好像也很多了,但和之后ResNet这样的动不动就101,152层的巨无霸相比,还是小巫见大巫。
那为什么不也增加VGG的层数呢?
这里要提到深层神经网络训练中的一个大问题了,那就是当层数过大时,会产生所谓的梯度爆炸(Exploding Gradients)和梯度消失(Vanishing Gradients)现象。
打个比方,如果每次的梯度相乘的系数都是小于1的数,假如说0.6, 那么19 层算下来,0.6的19次方就已经是0.00061了,更别提上百层了。这样传播到最底层的时候,能够学习到的参数就很小了,这就是梯度消失。
反过来,梯度爆炸的情况,如果系数大于1,多次累乘后就会得到一个很大的数,也会造成不好的结果。有点像是复利的概念,也就是那个和国王打赌要一棋盘稻子的故事。
梯度爆炸还好解决,可以用梯度修剪(Gradient Clipping)修剪一下就好了。而梯度消失就有点难解决了。
因为这样的问题,所以虽然理论上普通的深处网络是越深学的越好,但是实际上却事与愿违。下图横轴是网络层数,竖轴是训练误差(越小越好)。理论上随着层数增加,误差就减小,但是实际是过了某个点之后,误差反而会增大。
普通网络训练那么ResNet是怎么训练到上百层的呢,难道它就不怕上面的问题吗?
它用一个很简单的方法解决了上面的问题。
残差网络 (ResNet)
有很多很棒的论文,没读之前,看名字觉得很厉害的。但结果一看论文,才发现方法非常之简洁,特别是有一些利用数学知识推导出的简单解决方法,让人不得不一边拍手称赞,一边感叹自己数学渣。
ResNet也是这样子的,看名字很酷炫,但是打开论文一看,才发现原来是这样啊。
ResNet的最主要就是Shortcut(捷径)这个概念。来看看这到底是什么吧,首先假设我们从一个神经网络中取出两层,当做是一个块(block),先不管中间是MLP或者是CNN。
而shortcut就如下图一样,从第一层的输入直接建立一条捷径到第二层的输出,激活函数前。
增加捷径也就是说第二层激活后的输出可以会发生这样的变化。
由
变成
这样子处理之后,我们得到的这一小块就叫做Residual Block(残差块),而把这些块堆叠起来就是我们的残差网络了。很简单吧,像下面这样,一个34层的残差网络。
34层残差网络这样子我们就得到残差网络,那么实际上训练会怎么样呢。
正是我们想要的模型,也非常符合理论。
最后再提一下残差网络背后的原理,为什么这样简单改一下就能够有这么好的表现呢。
原因是捷径的建立,使得每一个残差块可以很容易地学习到恒等函数,也就是f(x)=x。也就是说加入残差块之后,再差也能学会恒等函数,保留信息,把之前的结果直接这样传下去,所以也就不用担心之前提到的梯度消失问题了。
Inception网络
1x1卷积
介绍Inception网络前,先介绍一下其中一个很重要的概念1x1卷积。
初看1x1卷积的概念会觉得很奇怪,这样子每次对一个像素进行卷积有什么用,我们本来不就是想检测局部的特征吗。但是如果理解了通道概念的话,就能很好理解了。
因为,如果说普通的大窗口卷积更注重一个通道内各个特征的互动的话,那么1x1卷积就是只在通道与通道进行卷积运算,加强了通道之间的互动。
这就是第一点,加强了通道与通道之间的交流。用这个就可以只对通道进行一些操作,如用1x1卷积增加通道数,减少通道数,也可以不增不减,但是对之前的通道进行整理。
1x1卷积网络还有一个好处,那就是通过合理运用可以减少整体网络的运算量。
还是来举例子吧,假设有以下一个卷积过程。
正常5x5卷积那么上面这个过程所需要的运算量大约一亿两千万次。
而如果我们巧妙地利用1x1卷积来对通道进行合理处理的话,像下面这样。
利用1x1卷积运算量会变得只有大概一千二百万左右,一下子就缩小了十倍。
什么是Inception网络
有了上面的知识以后,一切就简单多了。Inception网络的核心概念是,既然在选择CNN架构的时候要为了过滤器的窗口大小考虑半天,那么何不把各个尺寸都用上去,最后再把结果接起来就好了呢。
于是就有了下面这样的Inception模块。有用1x1、3x3、5x5各个尺寸的卷积,而且还用到之前讲到的利用1x1卷积减少运算量的技巧。
最后至于整个Inception网络,就像之前残差网络一样,把Inception模块堆叠起来就好了。
当然论文中还有一些次要细节,这里就不多说了。
而且自最初的论文之后,Inception网络也有很多改进,加入了很多技巧,比如之前的残差网络中的技巧。所以现在网上的Inception网络,后面会有V1、V2、V3之类后缀,表示的就是各个版本。
深一点,再深一点(不要想歪)
最后,作为余谈,说说为什么Inception网络要叫做Inception网络。
因为在这篇正经的学术论文里面,作者引用了一个链接,点开后会出现这张图片。