精读《AlexNet-ImageNet Classification with Deep Convolutional Neural Networks》
\quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad \quad @author 差分曼彻斯特1 \quad \quad 2021.05.15 \quad
文章目录
前期知识储备(Pre-knowledge reserve) \quad
论文总览(Summary of papers) \quad
学习目标(Learning objectives) \quad
一、论文导读 \quad
1.1 论文研究背景 \quad
CV领域常见的数据集:
ILSVRC(ImageNet Large Scale Visual Recognition Challenge): \quad
\quad \quad 大规模图像识别挑战赛。是近年来机器视觉领域最受追捧也是最具权威的学术竞赛之一,代表了图像领域的最高水平。ImageNet数据集是ILSVRC竞赛使用的是数据集,由斯坦福大学李飞飞教授主导,包含了超过1400万张全尺寸的有标记图片。ILSVRC比赛会每年从ImageNet数据集中抽出部分样本,以2012年为例,比赛的训练集包含1281167张图片,验证集包含50000张图片,测试集为100000张图片。 \quad
比赛项目涵盖: \quad
(1)图像分类与目标定位(CLS-LOC); \quad
(2)目标检测(DET); \quad
(3)视频目标检测(VID); \quad
(4)场景分类(Scene); \quad
强大的计算资源——GPU \quad
高性能计算资源使得大型神经网络可以快速训练,AlexNet使用设备:两块GTX 580 3GB GPUs(并行,可互相读写)(作者经过实验发现:在单GPU上训练AlexNet近似一半的网络结构速度比双GPU训练整个网络慢) \quad
1.2 论文研究成果及意义 \quad
研究成果: \quad
AlexNet在ILSVRC 2012以超出第二名10.9个百分点的Top5 erro夺冠 \quad
∙ \bullet ∙SIFT+FVS:ILSVRC 2012分类任务第二名 \quad
∙ \bullet ∙ 1CNN:训练一个AlexNet \quad
∙ \bullet ∙ 5CNNs:训练5个AlexNet取平均值 \quad
∙ \bullet ∙ 1CNN*:在最后一个池化层之后,额外添加第六个卷积层,并使用ImageNet 2011(秋)数据集上进行预训练 \quad
∙ \bullet ∙ 7CNNs*:两个预训练微调,与5CNNs取平均值 \quad
研究意义: \quad
∙ \bullet ∙ 拉开卷积神经网络统治CV的序幕 \quad
∙
\bullet
∙ 加速计算机视觉应用落地
\quad
二、论文精读 \quad
2.1 摘要 \quad
1.在ILSVRC 2010的120万张图片上训练深度卷积神经网络,获得最优结果,top-1和top-5 error分别为37.5%和17%; \quad
2.该网络(AlexNet)由5个卷积层和3个全连接层构成,共计6000万参数,65万个神经元; \quad
3.为加快训练,采用非饱和激活函数——ReLU,采用GPU进行训练; \quad
4.为减轻过拟合,采用Dropout; \quad
5.基于以上模型及技巧,在ILSVRC 2012以超出第二名10.9个百分点的成绩夺冠。 \quad
2.2 AlexNet网络结构 \quad
2.2.1 网络连接方式 \quad
conv1 → \rightarrow →ReLU → \rightarrow →Pool → \rightarrow →LRN \quad conv2 → \rightarrow →ReLU → \rightarrow →Pool → \rightarrow →LRN \quad conv3 → \rightarrow →ReLU \quad conv4 → \rightarrow →ReLU \quad
conv5 → \rightarrow →ReLU → \rightarrow →Pool \quad
特征图变化过程: \quad
卷积输出特征图大小计算: \quad
F 0 = ⌊ F ( i n ) − k + 2 p s ⌋ + 1 F_0=\lfloor\frac{F_(in) -k+2p}{s}\rfloor+1 F0=⌊sF(in)−k+2p⌋+1 \quad
每一级的输出,有多少个卷积和就有多少个通道 \quad
每层连接参数数量计算公式: \quad
f i × ( k s × k s ) × k n + k n f_i\times(k_s\times k_s)\times k_n+k_n fi×(ks×ks)×kn+kn \quad
f i f_i fi:每层输入特征图通道数; \quad k s k_s ks:该层卷积核尺寸大小; \quad k n k_n kn:该层卷积核个数 \quad
从上图可以看出,第一个FC层的Parameres最多,故可得出全连接层参数太过庞大。 \quad
2.2.2 AlexNet网络结构特点 \quad
1.Training on MultipleGPUs(在多GPU上进行训练):使用两块GTX 580 3GB GPUs(并行,可互相读写)。 \quad
2.ReLU Nonlineraity(非线性激活函数): f ( x ) = m a x { 0 , x } f(x)=max\lbrace0,x\rbrace f(x)=max{0,x}开创性地使用了不饱和非线性单元——ReLU(Rectified Linear Units),使训练速度提升很多、防止梯度消失(弥散)、使网络具有稀疏性(注意这里还提到了 f ( x ) = ∣ t a n [ h ( x ) ] ∣ f(x)=\lvert tan[h(x)]\rvert f(x)=∣tan[h(x)]∣这个函数,但不能提升训练速度,只能防止过拟合)。 \quad
几种激活函数对比如下: \quad
∙ \bullet ∙Sigmoid: y = 1 1 + e − x y=\frac{1}{1+e^{-x}} y=1+e−x1 梯度公式: y ′ = y × ( 1 − y ) y'=y\times(1-y) y′=y×(1−y) \quad
∙ \bullet ∙Tanh: f ( x ) = ∣ t a n [ h ( x ) ] ∣ f(x)=\lvert tan[h(x)]\rvert f(x)=∣tan[h(x)]∣ \quad
∙ \bullet ∙ReLU: f ( x ) = m a x { 0 , x } f(x)=max\lbrace0,x\rbrace f(x)=max{0,x} \quad
3.Local Response Normalization(LRN局部响应归一化):对于某个点,其归一化所选择的点为周围同一个位置不同特征图(feature map)的n个值(前n/2个,后n/2个,不足n/2的话到达0或N-1即可),然后再代入下面的公式(其中 k k k , n n n , α \alpha α , β \beta β 为超参数),可以使不同的kernel产生的输出(即不同的feature map)相互竞争,这一步提高了较多正确率,有助于AlexNet泛化能力的提升,受真实神经元侧抑制(lateral inhibition)启发。 \quad
侧抑制(lateral inhibition):细胞分化变为不同时,它会对周围细胞产生抑制信号,阻止它们向相同方向分化,最终表现为细胞命运的不同。
\quad
k = 2, n = 5, α = 1 0 − 4 \alpha=10^{-4} α=10−4, and β = 0.75 \quad
i:通道channel \quad j:代表i-j的像素值平方求和 \quad x,y:像素的位置 \quad a:代表feature map里面i对应像素的具体值 \quad
N:每个feature map里面最内层向量的列数 \quad
4.Overlapping Pooling(带重叠的池化):一般采用的最大池化都是非重叠的,如卷积核大小2 x 2,步长2,AlexNet采用的卷积核大小3 x 3,步长2,根据作者的实验发现这样做效果更好,有效地防止了过拟合。 \quad
常见池化: \quad
5.Dropout,随机失活(这里用于两个全连接层):一种简便的实现模型集成的方法(如果要训练很多个模型太费时),每个输入的网络结构都不相同,这样可以使神经元不单独依赖某些特定的神经元,从而使网络被迫去学习更鲁棒的特征,同时神经元之间权重共享;当测试时,每个神经元的输出均乘以0.5(假设训练时随机失活的概率为0.5)。全连接层的参数占整个网络的绝大部分,所以当加入了dropout之后,迭代次数增大了一倍。 \quad
6.防止过拟合的方法:第一种是数据增强(Data Augmentation):从一张256 x 256的图片中提取五张224 x 224(分别是左上、左下、右上、右下和中间,这也就是为什么上面网络的输入是224 x 224),再加上这五张图片的水平翻转(一共十张图片),测试时同样这样操作(即TTA,test time augmentation),对这十张图片的预测值取均值即可;另一种数据增强方法是利用PCA给每个像素的RGB加上特征值乘上来自于一个均值0标准差0.1的高斯分布的随机值,这样做可以改变图片的光照强度和图片亮度,模型可以学习到这一点变得更强大(具体细节还有待研究)。
三个损失函数的实现代码: \quad
import torch
import torch.nn.functional as F
import matplotlib.pyplot as plt
import numpy as np
x = torch.linspace(-10,10,60)
fig = plt.figure(figsize=(14,4))
ae = fig.add_subplot(131) #sigmod激活函数
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
y = torch.sigmoid(x)
plt.plot(x.numpy(),y.numpy())
plt.ylim((0,1))
ae = fig.add_subplot(132) #tanh激活函数
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
y1 = torch.tanh(x)
plt.plot(x.numpy(),y1.numpy())
plt.ylim((-1,1))
ae = fig.add_subplot(133) # ReLU激活函数
ax = plt.gca()
ax.spines['top'].set_color('none')
ax.spines['right'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
y2 = F.relu(x)
plt.plot(x.numpy(),y2.numpy())
plt.ylim((-1,5))
plt.show()