那些年,我们一起追过的Backbone
来自|CSDN博客 作者|kuweicai
整理|深度学习这件小事
本文仅作学术交流,如有侵权,请联系后台删除。
1943年,心理学家麦卡洛克和数学逻辑学家皮兹发表论文《神经活动中内在思想的逻辑演算》,提出了MP模型。
1960年,Henry J. Kelley 提出 BP(Back propagation),但是还仅仅应用有控制理论中。
1965年,Alexey Grigoryevich Ivakhnenko(开发了数据处理的分组方法)和Valentin Grigor_evich Lapa(控制论和预测技术的作者)在开发深度学习算法方面做出了最早的努力。
经过第一个高潮的发展,大家对深度学习充满了期待,但是结果却远远未达到预期,所以各国政府削减资助,投资人也减少投资, 上世纪70年代,第一个 AI 寒冬到来了,AI 的研究也进入了低谷期。第一次寒冬主要是从理论到数据到算力都不能满足要求。
1979年,Kunihiko Fukushima 开始将 CNN 应用于神经网络中。由于一些人的坚持,深度学习又开始有了巨大发展。
1985年,Rumelhart, Williams, 和 Hinton 证明 BP 在神经网络的作用,由此 BP 才开启了它的神经网络之旅。历史总是惊人的相似,在外界对 AI 抱有巨大希望的时候,泡沫再次破裂了, 第二次 AI 寒冬到来。第二次寒冬主要是受限于数据和算力。
1989年,第一个用于解决实际问题的网络(LeCun1989)由 Yann LeCun 于贝尔实验室提出,用于识别手写数字,当然这个还不是我们所熟知的 LeNet5, 后者是1998年才提出的。
1995年,Dana Cortes 和 Vladimir Vapnik 提出了 SVM 。1997年,Sepp Hochreiter 和 Juergen Schmidhuber 提出了 LSTM。
1999年,当时计算机处理数据的速度开始加快,gpu(图形处理单元)也得到了发展。通过GPU处理图片,在10年的时间里,计算速度提高了1000倍。这为 AI 的第三次繁荣奠定了基础。
第一行是按着如何使网络结构更深的发展思路来进行推进的。
第二行是在玩 module 的概念,当然我们看到第一行和第二行后面是被结合到一起了的。
第三条是按着如何使网络更快,结构更轻量化来进行发展的。这里仅仅只是列出了一些比较经典的网络,而且每种网络都有多个版本。下图是轻量化网络更详细的发展情况。
2012年,AlexNet 的成绩有质的飞跃,这主要是因为和前面的相比,CNN 的引入带来的巨大进步。
2014年,VGGNet 将错误率降到10以下,网络的层数也是突破了个位数,达到16-19层。
2015年,ResNet 首次将错误率降到比人类还低的水平。
网络更大更深,LeNet5 有 2 层卷积 + 3 层全连接层,有大概6万个参数,而AlexNet 有 5 层卷积 + 3 层全连接,有6000万个参数和65000个神经元。
使用 ReLU 作为激活函数, LeNet5 用的是 Sigmoid,虽然 ReLU 并不是 Alex 提出来的,但是正是这次机会让 ReLU C位出道,一炮而红。AlexNet 可以采用更深的网络和使用 ReLU 是息息相关的。
使用 数据增强 和 dropout 来解决过拟合问题。在数据增强部分使用了现在已经家喻户晓的技术,比如 crop,PCA,加高斯噪声等。而 dropout 也被证明是非常有效的防止过拟合的手段。
用最大池化取代平均池化,避免平均池化的模糊化效果, 并且在池化的时候让步长比池化核的尺寸小,这样池化层的输出之间会有重叠和覆盖,提升了特征的丰富性。
提出了LRN层,对局部神经元的活动创建竞争机制,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强了模型的泛化能力。
在当年的 ImageNet 挑战赛上刷新了成绩,而且是较之前的网络取得了非常大的进步。
将错误率降到10以下,网络的层数也是突破了个位数,达到16-19。
选用比较小的卷积核(3x3),而之前无论 AlexNet 还是 LeNet5 都是采用较大的卷积核,比如 11x11, 7x7。而采用小卷积核的意义主要有两点,一是在取得相同的感受野的情况下,比如两个3x3的感受野和一个5x5的感受野的大小相同,但是计算量却小了很多,关于这点原文中有很详细的解释,建议直接看原文;第二点是两层3x3相比一层5x5可以引入更多的非线性,从而使模型的拟合能力更强,这点作者也通过实验进行了证明。其实这里还有一个优点就是采用小的卷积核更方便优化卷积计算,比如Winograd算法对小核的卷积操作有比较好的优化效果。
使用1x1的卷积核在不影响输入输出的维度情况下,通过ReLU进行非线性处理,提高模型的非线性。当然这个并非 VGGNet 首创,最先在 Network In Network中提出。
证明提高网络的深度能提高精度。
在网络结构上与之前的网络结构有比较大的差异,而且深度也达到了22层。在 GoogLeNet 上开始出现了分支,而不是一条线连到底,这是最直观的差异,也被称作 Inception module,如下图所示。从图中可以看到, 每个 module 中采用了不同 size 的 kernel,然后在将特征图叠加,实际上起到了一个图像金字塔的作用,即 所谓的 multiple resolution。
上图中有很多 1x1 的卷积核,这里的1x1的卷积操作与之前讲到是不一样的,这里利用它来改变 output 的 channel, 具体说这里是减少 channel 数,从而达到减少计算的目的。
用 Global Ave Pool 取代 FC。下图可以看到,对于 FC ,超参数的个数为 7x7x1024x1024=51.3M,但是换成 Ave Pool之后,超参数变为0,所以这里可以起到防止过拟合的作用,另外作者发现采用 Ave Pool 之后,top-1的精度提高了大概0.6%。但是需要注意的是,在 GoogLeNet 中并没有完全取代 FC。
采用了辅助分类器。整个模型有三个 output(之前的网络都只有一个 output),这里的多个 output 仅仅在训练的时候用,也就是说测试或者部署的时候仅仅用最后一个输出。在训练的时候,将三个输出的loss进行加权平均,weight=0.3, 通过这种方式可以缓解梯度消失,同时作者也表示有正则化的作用。其实这个思想有点类似于传统机器学习中的投票机制,最终的结果由多个决策器共同投票决定,这个在传统机器学习中往往能提升大概2%的精度。
ResNet 的核心思想是采用了 identity shortcut connection。前面我们提到,已经得出了结论,加深网络深度有助于提高模型精度,那什么不直接干到几千几万层?这里的原因很多,抛开计算资源和数据库的原因,还有一个很重要的原因是梯度消失。在最开始,比如在 LeNet 那个年代,也就几层网络,当网络更深的时候便会出现精度不升反降的现象,后来我们知道是因为梯度下降导致学习率下降甚至停滞,而到了 VGG 和 GoogLeNet 的年代,我们有了 ReLU,有了更好的初始化方法,有了 BN,但是如下面第一幅图所示,当深度达到50多层时,问题又出现了了,所以激活函数或者初始化方法仅仅是缓解了梯度消失,让网络的深度从几层推移到了二十多层,而如何让网络更深,正是 ResNet 被提出的原因。GoogLeNet 中我们提到采用辅助分类器的方式来解决梯度消失的问题,而 ResNet 是另一种思路,虽然这个思路并非由凯明首创,但是确实取得了很好的效果。这个应该比较好理解,因为 shortcut 的存在,因此有 assemble 的效果,如下面第二幅图所示。
下图对比了 VGG-19 和 34层的 ResNet,可以看到 ResNet 的 kernel channel 比 VGG-19 少很多,另一个就是 ResNet 中已经没有 FC 了, 而是用的 Ave Pool,这点在 GoogLeNet 中已经提到过。下面的 VGG-19 的 FLOPs 是 19.6 biliion, 而下面的 34 层的 ResNet 仅仅只有3.6 billion,即使是152层的。另外还可以发现在 ResNet 中只有开头和结尾的位置有 pooling 层,中间是没有的,这是因为 ResNet 中间采用了 stride 为2的卷积操作,取代了 pooling 层的作用。
另外上图中需要注意的是,shortcut 有虚线和实线之分,实际上虚线的地方是因为用了 stride 为2的conv,因此虚线连接的 input 和 output 的 size 是不一样大的,因此没法直接进行 element wise addition,所以虚线表示并非是直接相连,而是通过了一个 conv 去完成了 resize 的操作,是相加的两个输入有相同的 size。
还一点是,之前在 VGG 和 GoogLeNet 中都采用3x3的conv,但是我们看到在 ResNet 中又用回了7x7的 conv。上图中 VGG-19用的4个 3x3, 而 ResNet 用的一个 7x7, 我觉得主要还是因为 ResNet 的 channel 数比较小,因此大的 kernel size 也不会使计算量变的很大(和 VGG-19 的4个 conv 比,计算量更小),而且可以获得较大的感受野。
优化网络结构。比如 Shuffle Net。
减少模型参数。比如 SqueezeNet。
优化卷积操作。这里又可以分为两种,一种是改变卷积操作的过程,比如 MobileNet;另外一种是从算法的角度对卷积进行优化,比如 Winograd。
剔除 FC。比如 SqueezeNet,LightCNN。
多用 1x1 的卷积核,而少用 3x3 的卷积核。因为 1x1 的好处是可以在保持 feature map size 的同时减少 channel。
在用 3x3 卷积的时候尽量减少 channel 的数量,从而减少参数量。
延后用 pooling,因为 pooling 会减小 feature map size,延后用 pooling, 这样可以使 size 到后面才减小,而前面的层可以保持一个较大的 size,从而起到提高精度的作用。
技术交流群邀请函
扫描二维码添加小助手微信(ID : HIT_NLP)
一个算法工程师的日常是怎样的?吴恩达上新:生成对抗网络(GAN)专项课程从SGD到NadaMax,十种优化算法原理及实现