这一阵子源于好奇心,我把Google出的Inception系列文章粗略读了一遍,当然这中间还读了这个算法的引子NiN,还有就是这中间有一篇叫做Xception的文章,不过这篇文章似乎是讲深度可分离网络的,之前在做实验和读MobilenetV1的时候稍微接触过,关于它以后再写吧!
首先来讲讲NiN(Network In Network),这篇文章不是来自Google,但它对Inception的产生起了非常重要的作用,打一个不恰当的比方,它相当于Selective Search 对RCNN系列文章的推动一样。好了,废话不多说。NiN的创新点有2个:
1. 采用mlpconv的结构来代替传统的卷积层。所谓mlpconv层其实就是传统的卷积层后面加了两个串联的全连接层,在实际代码中,全连接层是用1x1的卷积层实现的。所以mlpconv=传统conv+1x1conv+1x1conv。再说地通俗点NiN就是在原来的2个传统的卷积层中间又加了2个全连接层来提升网络抽取特征的能力,因为传统的卷积层可以认为是线性模型,局部接收域上的一小块数据跟卷积核加权求和,再激活,它的抽取能力不够;
2. 将原来的最后的全连接层替换成了全局平均池化层。全连接层容易造成过拟合而且非常依赖Dropout技术,再者就是参数量大,如今大部分高性能模型基本在最后放全局平均池化层。
讲完引子NiN,正式进入Inception系列算法,先来说说InceptionV1(GoogLeNet), Inception的文章其实不确切地讲就是在两个卷积层之间做手脚,V1最初的版本是拓宽了网络的宽度,产生了4部分:1x1conv、3x3 conv、5x5 conv、3x3 max pooling,之所以拆成这么多是考虑到了抽取不同尺度特征的问题。随后在V1上的改进是引进了1x1卷积,先来介绍一下它的作用:
1. 实现跨通道的交互和信息整合;
2. 对输出通道进行升、降维。
在这里是用来降维减少计算量的,具体怎么减少参数量的我就不详细介绍了,其他博客有很多讲这个的,其实在NiN就已经提出了1x1卷积的方法,只是到了InceptionV1才得到重视,1x1卷积在残差网络的残差块中也有大量使用,升降维都用到了。接下去的模型我就讲重点部分,论文中的细节我就不多讲了,主要是我自己有些细节也没看懂。
再就是InceptionV2,V2主要结合了当时最新的批量归一化技术(BN),防止过拟合,在训练时加速收敛,我首次接触到BN是在当时用Tensorflow做cafir10分类,效果的确很出色。V2就是将原来V1中的5x5conv换成了两个3x3conv,主要是5x5conv计算量太大,因为两个3x3conv的感受野跟一个5x5conv的感受野是一样的,但计算量小了从5x5→2x3x3。
V3是在V2的基础上运用高数里矩阵相乘的原理对nxn又进行了拆分,变成了1xn和nx1,然后组成了两种并行和串行模块,论文本身串行用的是n=7,并行是n=3, V3其他两个改进是把网络开头的7x7卷积改成了3个3x3卷积,目的还是在感受野不变的情况下降低计算量,然后就是把V2的模块跟新改进的2个模块(并行、串行)堆叠起来形成一个新网络,反正Inception系列算法就是不断拆,拆到满意为止。还有就是提出了缩减模块,通过减少特征图大小来减少计算量,其里面的结构跟Inception模块相似。
V4还有Resnet-InceptionV2 两者性能差不多,但V4训练时收敛速度慢一点,这两个模型是在同一篇论文中提出来的,其实还有个Resnet-InceptionV1,不过它不是重点,只是个过渡角色,这里我不讲。先吐槽一下这篇文章,结构图真的是多,看其他文章我都嫌图太少,这下真是满足了。V4还有Resnet-InceptionV2的区别就是网络的后半部分,后者用了恒等映射,前者没用。两者有一个共同的结构是stem模块,这个模块挺复杂的,不过主要的思想是并行连接,其实这也是残差网络里残差块的思想,所以这也很好解释V4的后半段没有用恒等映射,却跟用了恒等映射的Resnet-InceptionV2性能差不多。两者后半段,其实跟V3差不多,V4的后半段起码跟V3一样,Resnet-InceptionV2因为加了恒等映射去除了Inception模块里的max pooling。(其实我一直没搞明白Inception模块里面的max pooling是用来干嘛的?)
总体Inception系列文章看下来收获还是很大的,不过就是头很大,留下的唯一印象就是拆拆拆。这个系列的文章主要以略读为主,代码我没有去分析,我本身是做图像的,经常在论文中看到这些模型所以就找出来看看,如有讲的不对的地方,恳请大家指正。