论文原文:https://proceedings.neurips.cc/paper/2012/hash/c399862d3b9d6b76c8436e924a68c45b-Abstract.html
提出了AlexNet网络,训练了一个非常大很深的卷积神经网络去分类ImageNet,得到了ILSVRC-2012的冠军。使用了dropout进行了过拟合的处理。在处理过程中对比删除了参数量占比仅1%的卷积部分,效果明显下降。
1 图像数据集及预处理
主要使用了ImageNet2010作为训练和测试集,同时也在ImageNet2012上进行了测试。
预处理主要是将各种尺寸的图片,先将短边缩小为256,然后再在中心裁剪出256*256大小的图片,未对图像进行其他预处理,仅从每个像素中减去了训练集的平均激活值(意思是计算所有图片像素的R值,然后求平均,图片上的每个像素R值减去这个平均值)。网络是在原始像素RGB值上进行训练的。
2 架构
网络架构图如下图所示:
2.1 ReLu 非线性函数
使用了非饱和非线性的函数ReLu(\(f(x)=max(0,x)\))替代了饱和非线性的函数tanh(\(f(x)=(1+e^{-x})^-1\))。分别使用合适的学习率在同等的网络中学习以达到仅0.25的错误率,用ReLu所花费的时间比tahn快六倍。
2.2 使用多GPU进行训练
用了两个GPU训练,把一层中的神经元均分到两个GPU中。还设计了一个巧思:GPU只在某些层进行交流。例如,第3层的卷积核接收来自第2层所有特征图的输入。然而,第4层的卷积核仅接收来自同一GPU上第3层特征图的输入。
2.3 局部响应归一化
ReLU(线性整流单元)具备一项重要特性:无需通过输入归一化来防止神经元饱和。在此网络中发现局部响应归一化层有助于泛化。若用 \(a_{x,y}^i\) 表示在位置 (x,y)处应用卷积核 i 并经ReLU非线性激活后得到的神经元激活值,则其响应归一化后的激活值 b_{x,y}^i 可由以下表达式计算得出:
\(b_{x,y}^i=a_{x,y}^i/(k+\alpha \sum_{j=max(0,i-n/2)}^{min(N-1,i+n/2)}(a_{x,y}^j)^2)^{\beta}\)
其中,求和运算针对同一空间位置上n个”相邻”卷积核映射进行,而N表示该卷积层中卷积核的总数量。积核映射的排列顺序本质上是任意的,且通常在训练开始前就已确定。取超参数\(k=2,n=5,\alpha = 10^{-4},\beta = 0.75\),将局部响应归一化层放在某些ReLu非线性函数之后。
2.4 重叠池化
让步进stride=2,kernel size=3,就是步进值小于卷积核的尺寸,这样的话每次卷积都会重叠一部分,作者说发现这样可以抑制过拟合。
2.5 整体架构
前面五个卷积层,后面三个全连接层,最后一层全连接层的输出被送入一个1000路softmax分类器,该分类器会生成一个覆盖1000个类别标签的概率分布。此网络通过最大化多项式逻辑回归目标函数进行优化,这等价于最大化训练样本在预测分布下对应真实标签的对数概率平均值。
3 减少过拟合
使用了两种方式来防止过拟合。
3.1 数据增强
最常用的数据增强形式是保持标签不变人为的增大数据集。GPU训练前面的图像时,CPU不断地进行图像地增强,然后再将增强后的图片用GPU训练,同步进行减少时间。
采用了两种图像增强方式:
1.第一种数据增强方法是通过图像平移与水平翻转来生成新样本。从256*256的图像尺寸中随机截取224*224大小的图像并获取其水平翻转(这使得训练集扩大了2048倍),测试集进行测试时,先获取其五个位置的截取(四个角部分和一个中心部分)及其它们的翻转(一共十张图片),然后通过网络的softmax层平均这十个patch的预测结果作为总的结果。
2.第二种数据增强方法是通过调整训练图像RGB通道的强度值来生成新样本。对ImageNet训练集中的所有RGB像素值进行了主成分分析(PCA)。对每张训练图像,我们叠加计算得到的主成分向量,其幅值为对应特征值乘以一个从均值为零、标准差为0.1的高斯分布中采样的随机变量。因此,对于每个RGB图像像素点\([I_{xy}^R, I_{xy}^G, I_{xy}^B]\),叠加以下扰动分量:
\([p_1, p_2, p_3][\alpha_1 \lambda_1, \alpha_2 \lambda_2, \alpha_3 \lambda_3]^T\)
这儿的\(p_i\)和\(\lambda_i\)是RGB像素值的\(3 \times 3\)协方差矩阵的第i个特征向量和特征值,\(a_i\)是前面提到的随机变量。每个αᵢ仅在特定训练图像的所有像素中使用一次,直到该图像再次被用于训练时才会重新采样。该方案较好地捕捉了自然图像的一个重要特性,即物体识别结果对照明强度和颜色变化具有不变性。这一方案使分类任务的Top-1错误率降低了1%以上。(第2种数据增强方式巴拉一堆看不懂一点,看不懂的可以看这个https://blog.csdn.net/m0_56494923/article/details/146438076)
3.2 Dropout
Dropout——每个隐藏层的神经元都有0.5的概率被设置成0,神经元不会再参与前向和后向传播。因此,每当输入数据传入时,神经网络都会采样不同的架构,但这些架构均共享权重参数,这就相当于结合了不同的网络。该技术有效降低了神经元间的复杂共适应效应,因为单个神经元无法依赖特定其他神经元的存在。在测试阶段,会启用所有神经元,但将其输出值乘以0.5——这是对指数级数量dropout网络产生的预测分布几何平均的一种合理近似。(训练时,该神经元只有50%的概率参与运算,其期望贡献为\(0.5 \times\)神经元输出,测试时,若直接使用全部神经元,其贡献为\(1 \times\)神经元输出,是训练时期望值的两倍,所以测试时要通过乘以0.5,使测试时的期望输出与训练时一致。)
4 学习的细节
使用了动量移动平均和权重衰减:
\(v_{i+1}:=0.9 \cdot v_i -0.0005 \cdot \epsilon \cdot w_i – \epsilon \cdot \langle \frac{\partial L}{\partial w} |_{w_i} \rangle_{D_i}\) \(w_{i+1}:=w_i+v_{i+1}\)用均值为0,标准差为0.01的高斯分布初始权重。并用常量1初始化第二,四,五卷积层和全连接隐藏层的偏置,这种初始化方式通过向ReLU神经元提供正向输入,有效加速了模型早期阶段的学习进程。其他层的偏置初始化为0。在所有网络层使用统一的学习率,并在训练过程中手动调整该参数。遵循的启发式策略是:当验证错误率在当前学习率下不再下降时,将学习率除以10。
5 结果
说了一下跑的模型结果,在ImageNet2010上进行测试后(下图第三行)超越了平均了六个稀疏模型的结果(下图第一行),也超越了平均了两个分类器的结果的模型(下图第二行)。
在ImageNet2012上进行了测试,把测试集和验证集交换测试,分别对比了以前的最优结果(第一行),和使用一个CNN层(第二行),5个CNN层(第三行),1个在ImageNet 2011 Fall release进行预训练后的CNN层,把这个CNN层接在了前面5个CNN的最后一个池化层后(第四行),和平均了两个在ImageNet 2011 Fall release进行预训练后的CNN层,同时平均了前面的5个CNN层(第五行),结果如下图:
5.1 定性分析
该网络已经学习了各种频率和方向选择的核,以及各种颜色的斑点。下图为在第一个卷积层上的核,GPU 1上的卷积核主要表现出颜色无关特性,而GPU 2上的卷积核则显著呈现颜色敏感特性。
在下图中的左侧面板,定性的评估了八个测试图片网络计算的前五个预测,即使对象不在图片的正中央,也可以得到很好的预测(比如第一张图mite)。但是有一部分错误分类是因为图片的焦点具有模糊性。
在下图中的右侧面板,给了来自于测试集的五张图片和它们对应在训练集的六张图片,使用欧几里得距离来测量它们4096维度的特征激活向量,这个距离小则模型认为两张图片相似,下面的每个类别的欧几里得距离都能说明同一类别的不同图像相似,尽管它们在像素对应级别上完全不同(比如每张图花的朝向,大象和狗的动作都不一样)。
利用两个4096维实值向量之间的欧氏距离计算相似度是低效的,但通过训练一个自编码器将这些向量压缩成短二进制代码可以提高效率。这种方法的图像检索效果应显著优于基于原始像素的自编码器方案[14]。后者由于未利用图像标签信息,往往仅能检索出边缘模式相似(而非语义相关)的图像结果。
核心代码
self.net = nn.Sequential(
nn.Conv2d(in_channels=3, out_channels=96, kernel_size=11, stride=4), # (b x 96 x 55 x 55)
nn.ReLU(),
nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2), # section 3.3
nn.MaxPool2d(kernel_size=3, stride=2), # (b x 96 x 27 x 27)
nn.Conv2d(96, 256, 5, padding=2), # (b x 256 x 27 x 27)
nn.ReLU(),
nn.LocalResponseNorm(size=5, alpha=0.0001, beta=0.75, k=2),
nn.MaxPool2d(kernel_size=3, stride=2), # (b x 256 x 13 x 13)
nn.Conv2d(256, 384, 3, padding=1), # (b x 384 x 13 x 13)
nn.ReLU(),
nn.Conv2d(384, 384, 3, padding=1), # (b x 384 x 13 x 13)
nn.ReLU(),
nn.Conv2d(384, 256, 3, padding=1), # (b x 256 x 13 x 13)
nn.ReLU(),
nn.MaxPool2d(kernel_size=3, stride=2), # (b x 256 x 6 x 6)
)
# classifier is just a name for linear layers
self.classifier = nn.Sequential(
nn.Dropout(p=0.5, inplace=True),
nn.Linear(in_features=(256 * 6 * 6), out_features=4096),
nn.ReLU(),
nn.Dropout(p=0.5, inplace=True),
nn.Linear(in_features=4096, out_features=4096),
nn.ReLU(),
nn.Linear(in_features=4096, out_features=num_classes),
)
self.init_bias() # initialize bias
def init_bias(self):
for layer in self.net:
if isinstance(layer, nn.Conv2d):
nn.init.normal_(layer.weight, mean=0, std=0.01)
nn.init.constant_(layer.bias, 0)
# original paper = 1 for Conv2d layers 2nd, 4th, and 5th conv layers
nn.init.constant_(self.net[4].bias, 1)
nn.init.constant_(self.net[10].bias, 1)
nn.init.constant_(self.net[12].bias, 1)
学到的知识总结
PCA颜色增强可以试试用在医学图像上面(数据量小的任务)。
局部响应归一化(尽管现在不怎么用了)。
dropout在训练集和测试集中的处理。
定性分析的部分可以整一整,发现很多都用欧几里得距离来作为特征提取相似度的说明。