赞
踩
论文根据近几年来的关于训练过程优化的大量的优秀论文,总结整理了一大袋用于提升网络模型性能的技巧,这些技巧包含了数据增广、大批量训练、低精度训练、模型调整、学习率调整策略等等。
下面按照大纲,记录论文总结的方法。
论文选取了ResNet-50、Inception-V3和MobileNet作为baseline model。
其中,ResNet有许多实现版本,论文使用的是这个实现方式Training and investigating Residual Nets。
baseline的训练步骤如图:
其中,训练和测试的不同在于数据预处理的不同,主要为测试时不进行数据增广,区别如下:
1.随即采样一幅图像,像素值取值范围[0,255],解码为32位浮点数类型。
2.随机裁剪矩形区域图像,长宽比在 [3/4, 4/3]范围随机取值,裁剪面积在[8%, 100%]范围随机取值,然后将裁剪区域缩放为224x224的方形图像。
3.以0.5的概率随机水平翻转图像。
4.缩放色调hue,饱和度saturation,明亮度brightness,缩放系数在[0.6,1.4]范围均匀采样。
5.从正态分布 N(0,0.1) 采样参数用于添加PCA噪声.
6.通过减去[123.68, 116.779, 103.939]并除以[58.393, 57.12,57.375]进行数据的归一化RGB通道。(ImageNet)。
1.保持长宽比,缩放图像使短边长度为256像素。
2.在图像中心裁剪出224x224区域。
3.同样通过减去[123.68, 116.779, 103.939]并除以[58.393, 57.12,57.375]进行数据的归一化RGB通道。(ImageNet)
使用Xavier 算法进行卷积层和全连接层的参数初始化。
Xavier初始化的paper:Understanding the difficulty of training deep feedforward neural networks
具体来说,就是公式
https://blog.csdn.net/shuzfan/article/details/51338178 xavier
https://blog.csdn.net/shuzfan/article/details/51347572 MSRAPrelu
每一层的参数都从上式范围内随机均匀抽取,其中 nj 是 第j层的输入通道数。
训练时使用Nesterov Accelerated Gradient(NAG)作为优化器。
https://www.cnblogs.com/guoyaohua/p/8542554.html
数据量大,GPU显存大,大家自然就想用大的Batch Size进行训练,但是大的batch size可能会减慢训练的进程。对于凸优化问题来说,收敛的速度随着batch size的增加而减小。
换句话说,就是训练同样数目的epoch,使用大的batch size会降低模型在验证集上的准确率。
下面是四种对该问题的解决方案:
Linear scaling learning rate是在论文中针对比较大的batch size而提出的一种方法。
在凸优化问题中,随着批量的增加,收敛速度会降低,神经网络也有类似的实证结果。随着batch size的增大,处理相同数据量的速度会越来越快,但是达到相同精度所需要的epoch数量越来越多。也就是说,使用相同的epoch时,大batch size训练的模型与小batch size训练的模型相比,验证准确率会减小。
linear scaling learning rate是一种有效的方法。在mini-batch SGD训练时,梯度下降的值是随机的,因为每一个batch的数据是随机选择的。增大batch size不会改变梯度的期望,但是会降低它的方差。也就是说,大batch size会降低梯度中的噪声,所以我们可以增大学习率来加快收敛。
具体做法很简单,比如ResNet原论文中,batch size为256时选择的学习率是0.1,当我们把batch size变为一个较大的数b时,学习率应该变为 0.1 × b/256。
学习率是神经网络训练中最重要的超参数之一,针对学习率的技巧有很多。Warm up是在ResNet论文中提到的一种学习率预热的方法。由于刚开始训练时模型的权重(weights)是随机初始化的(全部置为0是一个坑),此时选择一个较大的学习率,可能会带来模型的不稳定。学习率预热就是在刚开始训练的时候先使用一个较小的学习率,训练一些epoches或iterations,等模型稳定时再修改为预先设置的学习率进行训练。Resnet论文中使用一个110层的ResNet在cifar10上训练时,先用0.01的学习率训练直到训练误差低于80%(大概训练了400个iterations),然后使用0.1的学习率进行训练。
上述的方法是constant warmup,18年Facebook又针对上面的warmup进行了改进,因为从一个很小的学习率一下变为比较大的学习率可能会导致训练误差突然增大。论文提出了gradual warmup来解决这个问题,即从最开始的小学习率开始,每个iteration增大一点,直到最初设置的比较大的学习率。
所以学习率预热应该是针对上一条学习率扩大来讲的,因为学习率变大之后,较大的初始学习率容易导致数值的不稳定。
换句话说,在学习率预热的想法里,先用较小的学习进行训练,等到训练过程稳定之后再切换到设置的初始学习率。也有的做法是,切换这一个步骤改进为从较小的学习率线性变为设置的初始学习率。
举例来说,设置m个bacth用于预热,设置初始学习率为η。则在预热阶段,第i个batch时,学习率为i∗η/m。
ResNet的每个block的最后一层都有BN层,BN层首先标准化输入,记为x,然后进行尺度变换γx+β。其中,x和γ都是可以学习的参数,通常分别初始为0和1。
Zero γ的想法是,在所有BN层中将γ初始化为0,这样就相当于在训练的初始阶段减少了网络的层数,易于训练。
就是只对卷积层和全连接层的权重进行衰减,而不去正则化所有的biases、BN层的γ和β。
一般的是将weight decay应用在所有可学习的参数上,包括weights和bias。然而,更推荐的做法是,只将L2正则化项应用在weights上来避免过拟合。其他参数,包括BN层里的 γ和β 都是不经过正则化的。
正则化通过在损失函数后加一项惩罚项,是常用的防止模型过拟合的策略。大多数深度学习框架默认会对所有可学习的参数做正则化,包括weight, bias, BN beta和gamma(batch norm中可学习的参数)。我们发现bias, beta, gamma的参数量相对于weight来说非常小,对于AlexNet模型,bias, beta, gamma参数量总和仅占总参数量的0.02%。
因此,bias, beta, gamma不会给模型带来过拟合,如果我们对这些参数进行正则化,增加了计算量,还会让模型损失一些灵活性。经过实验验证,我们发现不对bias, beta, gamma做正则化,模型提高了约1.3%的准确性。
除了这四种方法,另外文中也提出,像LARS这种layer-wise adaptive lr更适合于超大的batch size(beyond 16k)。
一般来讲,神经网络的训练是使用32位float类型(FP32)的,所有的数据和参数都用32位浮点来存储和计算。
最近几年呢,新的计算设备提供了低精度的16位float类型(FP16)的计算能力,于是就有了拿FP16来进行计算的方式。
总的来说呢,用更低的精度进行神经网络的训练,有好处有坏处:
针对缺点,有人提出的解决方案是,在整个训练过程中,用FP16来存储参数、计算梯度,同时留一个32位精度的参数的备份,用于更新参数。
还有一种实用的方案是计算损失函数时,乘以一个数(尺度),将梯度的范围更好地对齐到FP16上。
这里主要讲了ResNet及其变体。
ResNet-B
调整原因:原有的residual block的下采样部分,使用了kernel=1x1和stride=2,忽略掉了3/4的信息,所以改进为kernel=3x3和stride=2。
ResNet-C
调整原因:鉴于卷积操作时,kernel size与计算消耗呈平方关系,因此将输入时的卷积操作的7x7的kernel,改为3个3x3的卷积操作。
ResNet-D
调整原因:与ResNet-B相似,下采样的右边通道同样存在着忽略3/4信息的问题,因此进行改进。实验发现,将卷积改为sride=1,同时在前面加上一个kernel=2x2,stride=2的平均池化层,效果理想。
常用的Learning Rate Decay是Step Decay,即每隔N个Epoch,learning rate乘上一个固定decay系数。
但是Step Decay不好的地方在于学习率衰减的时候,跳跃变化较大,带来了较大的冲量Momentum,引起的训练不稳定需要Optimizer用几个迭代去稳定他。有人就提出使用余弦学习率衰减的方式,Cosine Learning rate decay。公式如下,也很好理解:
但是论文中的结果是这样子的,余弦衰减不一定比步进衰减(Step decay)好:
虽然论文中解释说,当Step Decay方法的学习率已经较小的时候,Cos Decay方法的学习仍比较大,因而能够加速整个训练的过程。但是看图中b,很明显Step Decay再衰减之后,准确率就上来了,说明衰减之前的数量级效用已经不强了,这个时候Cos decay还是那个数量级,所以速度就比Step Decay慢了。显然Step Decay方法60-80个Epoch就达到的水准,要Cos Decay120个Epoch去达到,说服力不强。
但Cosine Decay总归是一个思路,大家都推崇,必然有其优越性,是骡子是马,两种方法都测试下就好了。
在分类问题中,我们的最后一层一般是全连接层,然后对应标签的one-hot编码,即把对应类别的值编码为1,其他为0。这种编码方式和通过降低交叉熵损失来调整参数的方式结合起来,会有一些问题。这种方式会鼓励模型对不同类别的输出分数差异非常大,或者说,模型过分相信它的判断。但是,对于一个由多人标注的数据集,不同人标注的准则可能不同,每个人的标注也可能会有一些错误。模型对标签的过分相信会导致过拟合。
标签平滑(Label-smoothing regularization,LSR)是应对该问题的有效方法之一,它的具体思想是降低我们对于标签的信任,例如我们可以将损失的目标值从1稍微降到0.9,或者将从0稍微升到0.1。标签平滑最早在inception-v2[4]中被提出,它将真实的概率改造为:
所以Label Smoothing就是一种抑制过拟合的手段。
其中,ε是一个小的常数,K是类别的数目,y是图片的真正的标签,i代表第i个类别,q_i是图片为第i类的概率。
总的来说,LSR是一种通过在标签y中加入噪声,实现对模型约束,降低模型过拟合程度的一种正则化方法。
知识蒸馏是指用一个准确率较高的复杂的预训练模型(teacher model)来训练一个结构较为简单的模型(student model),来提升student model的准确率。尽可能压榨teacher model来训练student model,好处既能获取复杂模型的预测能力,又能简化网络结构提高推理速度。
训练时,使用蒸馏损失(distillation loss)来对teacher model和student model的输出差异进行惩罚,辅助学习。
对于给定的输入,假设p为真实的概率分布,z和r分别为student model和teacher model的最后一层全连接层的输出。使用交叉熵Cross Entropy来计算损失,因此整个训练的损失函数为:
其中T是一个超参数,用来平滑整个Loss的。
Mixup是一种新的数据增强的方法。Mixup training,就是每次取出2张图片,然后将它们线性组合,得到新的图片,以此来作为新的训练样本,进行网络的训练,如下公式,其中x代表图像数据,y代表标签,则得到的新的xhat, yhat。:
其中,λ是从Beta(α, α)随机采样的数,在[0,1]之间。在训练过程中,仅使用(xhat, yhat)。
Mixup方法主要增强了训练样本之间的线性表达,增强网络的泛化能力,不过mixup方法需要较长的时间才能收敛得比较好。
分类模型具备更高的准确率之后,再将分类模型作为其他任务的backbone,显然是有帮助的,毕竟分类模型说到底就是一个提取图像特征的过程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。