1. AlexNet架构
第一次看论文中给出的架构图,或多或少都会很懵逼,因为整个网络是由上下两个部分组成的,与我们平时所见的神经网络架构不同。
最左边的是输入图片,中间 5 层是经过卷积层处理后得到的 feature map,最右边 3 层是全连接层的输出。给上图加上神经网络各层后,可得到下面的图片。
作者是将 AlexNet 分为了两部分,如上图所示,上面的部分由 训练,下面的部分由 训练。
上面的图不好理解,可以“压缩”为一张图,如下图所示。(实际上,作者也在一块 GPU 上做了实验,只是修改了部分结构)
2. 创新点
AlexNet 的创新点如下面的思维导图所示,接下来简单地介绍下每种技术。
2.1 ReLU
使用 ReLU 作为 CNN 的激活函数,验证了其效果在较深的网络中超过了 Sigmoid,成功解决了 Sigmoid 在网络较深时的梯度弥散问题。
说明:
首先,激活函数的发展:线性激活函数 → 非线性激活函数(如Sigmoid、Tanh) → 非饱和的非线性激活函数(ReLU 及其变体)。
ReLU 是一个激活函数,而且是一个非饱和的非线性激活函数,因此,需要知道:(1)什么是激活函数;(2)何为线性、非线性;(3)何为饱和、非饱和。参考资料如下:
- 激活函数:
- 线性、非线性:
https://www.zhihu.com/question/484469783(李钢蛋)- 饱和、非饱和:
- 关于 ReLU:
https://zhuanlan.zhihu.com/p/427473958
2.2 双GPU
作者设计的全连接层太大了,95% 的参数都在全连接层上,导致网络放不到 GPU 中去,所以作者使用了两块 GPU。
AlexNet 分布在两块 GPU上,每块 GPU 的显存中储存了一半的神经元的参数。因为 GPU 之间通信方便,可以互相访问显存,而不需要通过主机内存,所以同时使用多块 GPU 是非常高效的。同时,AlexNet 的设计让GPU 之间的通信只在网络的某些层进行,控制了通信的性能损耗。使用两块 GPU 加速了神经网络的训练。
但从现在的角度来说,完全没有必要使用两块 GPU。因为现在我们通常不会把全连接层设计的太大,且现在的 GPU 性能已经得到了很大的提升。
为什么深度学习中使用 GPU 而不是 CPU?
参考链接:https://www.run.ai/guides/gpu-deep-learning
(简单来说,GPU 可以并行操作)
2.3 局部响应归一化(LRN)
ReLU 不需要归一化来防止饱和,但 Alex 认为他的这个 LRN 有利于泛化。后来 VGG 作者在论文[1]中通过对比实验证明了 LRN 并无泛化作用,今天我们也不使用 LRN 了。
附:
- [1] K. Simonyan and A. Zisserman. Very deep convolutional networks for large-scale image recognition. In ICLR, 2015.
2.4 重叠池化
在此之前,使用最多的是平均池化。平均池化的优点是能很好地保留背景,但它的缺点也很明显,就是容易使得图片变模糊。因此,作者考虑使用最大池化,这就很好的避免了平均池化的缺点。同时,作者在最大池化的基础上引入了重叠的概念,即让池化步长小于池化窗口的大小,从而产生重叠的部分。作者认为这样可以减轻过拟合,虽未证实这个观点,现在也不再使用这个重叠的池化,但最大池化的效果得到了很好的证明。
附参考资料:
2.5 端到端
论文中的原话如下图所示。
附参考资料:
- 简单来说,由原始图像经过中间的神经网络得到最后的输出。不对原始图像做处理,也不关心神经网络干了啥事。
2.6 降低过拟合
由于 AlexNet 太大了,以至于即使像 ImageNet 这么大的数据集,也会产生严重的过拟合现象。因此,降低过拟合是作者的一大工作重点。作者使用了两种方法降低过拟合:数据增强、Dropout。
那什么是过拟合呢?参考资料:
在介绍这两种方法前,先说说作者在输入端是如何裁剪图片的。
作者提到,他们的系统要求输入的是同维的图片,但 ImageNet 中的图片大小不同。他们先裁剪短边,使其为 256。对长边而言,从中心裁 256,这样就相当于在原始图片的中间位置裁了一个 256 * 256 大小的图片。举个例子,如下图所示:
原文中提到了两种处理过拟合的方法:数据增强、Dropout
2.6.1 数据增强
最常用、最简单的方法就是做数据增强,也就是扩充数据集。如下图所示,做数据增强后,
原本过拟合的曲线渐渐拉直了,明显降低了过拟合。作者使用了两种数据增强方法。
(1) 随机裁剪 + 水平反转
- 在 256 * 256 * 3 的图像上,随机裁剪,裁剪的窗口大小为 224 * 224,如图 1 所示;
- 对图像做水平反转,再随机裁剪,如图 2 所示。
综上,一张图片再经过上述的两步操作后变为 32 * 32 * 2,共 2048 张图片,由此,训练集大小变为原来的 2048 倍。
需要指出的是,这些图片是高度相似的。即使高度相似,这步操作也是必须的,因为主要矛盾是过拟合。由于增大了数据集,所以减轻了过拟合。
(2) 对 RGB 三通道的颜色和光照进行变换
作者之所以这样操作,是因为抓住了一个重要特征:物体的特性不会随着光照强度、颜色的变化而变化。如下原文:
具体做法:对 RGB 三通道的颜色和光照进行了变换,使用了 PCA 方法,求出了 RGB 3 * 3 协方差矩阵的特征值和特征向量,在主成分上对颜色加了随机的变换,这样一张图就可以变成很多张图。
附:
附:比较有意思的 一点是,作者在 GPU 上训练模型,在 CPU 上做模型增强。如下原文所示:
意思是说,用 Python 代码在 CPU 上完成的,当 GPU 在训练上一轮时,下一轮的数据增强已经做好了,不需要存放在硬盘上,存放在内存上和显存上就可以了。
但需要指出的是,即使是数据增强,我们一般也是在 GPU上进行,因为 GPU 处理图片会比 CPU 快,否则在 CPU上做数据增强很可能造成效率瓶颈。
2.6.2 Dropout
什么是 Dropout,原理是什么?参考资料:
Dropout 是作者的导师给他的建议,当然,Dropout 也是他们课题组提出的,相关的论文[2]也是发表于 2012 年。
[2] G.E. Hinton, N. Srivastava, A. Krizhevsky, I. Sutskever, and R.R. Salakhutdinov. Improving neural networks by preventing co-adaptation of feature detectors. arXiv preprint arXiv:1207.0580, 2012.
- 视频地址:https://www.bilibili.com/video/BV1yt4y157vD/。介绍了 AlexNet 的一些趣事。
为什么Dropout可以降低过拟合?
在论文[2]中,作者提出了两个 Dropout 可以降低过拟合的原因。
(1) 防止神经元之间的共适应
每次都以 0.5 的概率失活一半的神经元,这样神经元之间的依赖就会减轻,迫使它去学习更鲁棒的特征。
(2) 做模型平均
每次随机失活一半的神经元,导致网络结构变化,就类似在训练不同的网络。整个 Dropout 的过程就相当于对很多个不同的神经网络取平均,而取平均则有可能让一些“相反的”拟合互相抵消,从而达到整体上减少过拟合。
需要指出的是使用 Dropout 也是有缺点的,它使得收敛所需的时间变为原来的 2 倍。
后来,Hinton 的课题组做了些研究,在论文[3]中证明了 Dropout 不是在做模型融合,也就是上节提到的模型平均,而是等效于一个
- [3] Srivastava N, Hinton G, Krizhevsky A, et al. Dropout: A simple way to prevent neural networks from overfitting[J]. The Journal of Machine Learning Research, 2014, 15(1): 1929-1958.
3. 实验
3.1 Details of learning
3.1.1 随机梯度下降
梯度下降是什么?举个例子,就是从山顶找一条最短的路走到山脚最低的地方。但是因为选择的方向不同,我们找到的最低点可能不是真正的最低点,所以问题在于两点:(1)如何选择方向;(2)如何向下走。
在机器学习中,有时候需要对原始的模型构建损失函数,然后通过优化算法对损失函数进行优化,以便寻找到最优的参数,使得损失函数的值最小。而在求解机器学习参数的优化算法中,使用较多的就是基于梯度下降的优化算法。在 AlexNet 这篇论文后,随机梯度下降成为机器学习中最主流的优化算法。
简言之,优化算法使用来求解损失函数参数的,而梯度下降是其中的一种优化算法。
参考资料:
3.1.2 权重衰减(weight decay)
权重衰减也叫 正则化,
参考资料:
3.1.3 momentum
在训练网络时,一开始会对网络进行权值初始化,但这个初始化一般不是最合适的,因此可能就会出现损失函数在训练的过程中出现局部最小值的情况,而没有达到全局最优的状态。momentum 的出现可以在一定程度上解决这个问题。在 AlexNet 这篇论文后,momentum 动量用得越来越多。
参考资料:
3.1.4 学习率
作者将学习率初始化为 0.01,在训练过程中,当验证误差不下降了,就手动的把它降低 10 倍,如下图中蓝线所示,呈阶梯型下降。但为什么下降 10 倍,而不是其他倍数?什么时候下降?这些都是很难把握的。后来,这种方法由于太复杂,渐渐被其他方法替代了。
ResNet 中使用的方法是,训练 120 轮,每 30 轮下降 0.1,现在我们也更倾向于这种做法。具体做法是,将学习率初始化为 0,让其线性上升,再使用平滑一点的曲线来下降学习率,如 cos 函数,如下图中紫线所示。
3.2 Results
作者在本部分想说的事就是他在几个不同版本的 ImageNet 数据集上做了实验,实验结果都表明 AlexNet 的错误率最低。以其中一个实验为例,如下图所示,可以看到 CNN 完胜传统的方法,也是从 AlexNet 开始,CNN 开始得到机器学习界的重视,此后就开始它在计算机视觉领域的高光之路。
实验结果中最重要的就是这个 4096 维向量。
最后得到的这个 4096 维向量,具有丰富的语义信息,如果两张图片的 4096 向量特别接近的话,那么这两张图片中的物体可能是同一个物体。
以大象为例,可以看出,右侧图片中大象的姿势与左侧图片中大象的姿势并不相同,即使这样,匹配的 5 张图片也与测试集中的那张相似,这也从侧面说明了这个 4096 维的向量的确具有丰富的语义信息。
作者还提到,直接使用 4096 维的向量进行对比效率非常低,但可以通过自动编码器将这些向量压缩为短二进制代码,然后再比较。
有意思的是,两块 GPU 提取到的特征不同,如下图所示。
4. AlexNet的局限性
4.1 有其然,无其所以然
有很多点,作者只是说明了效果好,但没有解释为什么效果好,比如 LRN、重叠池化等。
4.2 深度对模型性能的影响
作者在 Discussion 中提到,如果减少中间的任意一层,就会造成 2% 的误差。
作者由此推断出,神经网络的深度很重要。但这个因果关系有点牵强,仅凭 %2 的损失并不能说明深度一定是性能的决定因素,因为很有可能是参数没有设置好。实际上,AlexNet 能在去掉一些层后,通过修改中间参数,还是有办法达到接近的性能的。
这个推断后来由 2013 年的 ImageNet 竞赛冠军 ZFNet[4]验证出来。
附:
- [4] M. D. Zeiler and R. Fergus. Visualizing and understanding convolutional neural networks. In ECCV, 2014.
4.3 全程无监督
无论是预训练还是训练,作者使用的数据集都是有标签的。
4.4 全连接层设计得太大
前面提到过,95% 的参数都在全连接层上,导致全连接层太大,无法放到一块 GPU 中去。
5. 收获
经验上的收获
- 激活函数可能更倾向于选 ReLU
- 池化,根据情况选最大池化还是平均池化
- 降低过拟合:数据增强、Dropout
- 优化损失函数参数时,更倾向于随机梯度下降,并搭配 weight decay 和 momentum
- 学习率可能会参考 ResNet,然后使用 cos 等函数平滑减小其值
- 由人类能看懂的像素,通过中间网络的特征提取后,变成了机器能看懂的向量,然后用于搜索或分类
- 直接使用 4096 维的向量进行对比效率非常低,但可以通过自动编码器将这些向量压缩为短二进制代码,然后再比较
- 后续的研究可能更倾向于无监督学习
总结