详解神经网络训练及需要注意的细节(含激活函数选择,预处理,权重,正则化,优化,等)
神经网络训练过程中需要考虑的细节
• 如何从零开始建立神经网络
〓 如何选择激活函数
〓 如何对数据进行预处理
〓 如何初始化权重
〓 如何进行正则化
〓 如何进行梯度检查
• 训练过程哪些动态变化
〓 如何监控学习的过程
〓 如何选择参数的更新法则
〓 如何对超参数进行优化
• 如何评估学习结果
〓 如何评估建立的模型
〓 如何进行模型的集成
从零开始建立神经网络
激活函数
在任意的全连接层或者卷积层中,将输入乘以权重值,然后将这一计算结果输入一个激活函数或非线性单元中。
常见的激活函数
有这么多种激活函数,如何在这些里面选出最合适的呢(+_+)?
• Sigmoid函数
特点:
» 每个输入的元素都被压缩到[0,1]的范围内。
» 某种意义上可视为神经元的饱和放电率(firing rate)。
存在的问题:
» 饱和神经元将导致梯度的消失(梯度变成0)。阻止了梯度的传递~
» 该函数的输出始终是一个非零的数,不是以0为中心,意味着该处的梯度方向只能全是正方向或者全为负方向。这造成梯度更新非常低效地。例如下▼
» 指数exp()的计算代价较高。
• tanh函数
特点:
» 每个输入的元素都被压缩到[-1,1]的范围内。
» 解决了Sigmoid函数的全正数的权值的问题。
存在的问题:
» 饱和神经元仍然会导致梯度的消失(梯度变成0)。阻止了梯度的传递~
• ReLU函数(Rectified Linear Unit)
特点:
» 每个输入的元素都被压缩到[0,+∞)的范围内。负数都变0,非负数还是输入的数。
» 有一半的区域不存在饱和现象(x轴正方向上),这个是很大的优势。
» 计算成本较低,仅仅是简单的max()。
» 收敛速度快(相较于sigmoid()和tanh())。
» 有证据表明,比sigmoid函数更具备生物学上的合理性。
存在的问题:
» 该函数的输出始终是一个非负数的数,不是以0为中心这造成梯度更新非常低效地。(类似sigmoid函数)
» x轴正半轴不会达到饱和,而负半轴却始终饱和。负半轴上梯度的消失阻碍了梯度的传递~该现象称为 dead ReLU▼
» 存在部分ReLU单元会dead
• Leaky ReLU函数
特点:
» 完全不存在饱和状态,梯度可良好地进行传递,不会出现挂掉的问题。
» 计算成本也较低。
» 收敛速度快(相较于sigmoid()和tanh())。
• ELU函数(Exponential Linear Units)
特点:
» 拥有ReLU的全部优点
» 输出的均值还十分接近0。
» 与Leaky ReLU相比,ELU没有在负区间倾斜,而是一个负饱和机制。这使得模型对noise具有更强的鲁棒性。
存在的问题:
» 指数exp()的计算代价较高。
• Maxout函数(Exponential Linear Units)
特点:
» 和其他的激活函数具有完全不同的形式,直接从两组函数种取最大值。
» 因为只是提取两个线性函数的最大值,故作用是泛化ReLU和Leaky ReLU
» 这种方式既不会饱和也不会消亡
存在的问题:
» 会把每个神经元的参数数量翻倍,(原来只有权重W,而现在有W1和W2)
激活函数小结 []( ̄▽ ̄)*
- 一般最好的经验法是是使用ReLU***,大体最标准的。但必须非常谨慎地调整学习速率*。
- 也可以使用***Lealy ReLU/Maxout/ELU***,但实用率较弱,更偏向实验。
- 也用下***tanh***,但别抱太大的希望( ̄▽ ̄)"。
- 一般不会使用***sigmoid***。
数据预处理
有来自训练集的输入数据对神经网络进行训练,但一般需要对这些原始数据进行一个预处理,来加快求解梯度下降求最优解的速度和(可能)提高精度。
预处理的一般步骤
1. 从训练集拿到原始数据
2. 对原始数据进行 中心化 操作(多以0为中心化)
由激活函数知,应尽量让数据是以0为中心分布,才能最快求解梯度下降最优解
3. 再对中心化的数据进行 归一化 操作
尽量让所有特征都在相同值域内,且这些特征贡献相同,较少数据就可实现,提高了精度
具体步骤的实现
• 中心化
概念:仅仅要求平均值为0(样本平均分布在0左右),而不对标准差进行要求。
最常用的方法:x’ = x - μ
说明:
x是未中心化的数据,
x’是经过中心化的数据,
μ是未中心化的数据集中数据的平均值。
• 归一化
概念:将原始数据映射为分布于[0,1]或[1,1]之间的数
最常用的方法:
▶ 最大-最小标准化:[0,1]
说明:
x是未归一化的数据,
x’是经过归一化的数据,
min(X)是未归一化的原始数据集中的最小值,
max(X)是未归一化的原始数据集中的最大值。
▶ Z-score标准化:[0,1]
说明:
x是未归一化的数据,
x’是经过归一化的数据,
μ是未归一化的原始数据集中数据的均值,
σ未归一化的原始数据集中数据的标准差。
权值初始化
在开始训练前,需要确定各个神经元的权值。这是一个很重要的过程,决定了之后训练过程中权值的更新方式和速度。
常用方法:
▶ 小随机数法:(Small random number)
将所有的权重设为一个小的随机数(如从一个标准正太分布中进行抽样,然后通过小一个尺度转换生成权重(较小的)。
例如▼
说明:仅仅对小神经网络起作用,但对结构深一点的则不起作用(因为这是非常小的权重,造成神经网络崩溃;但权重一大,神经网络又会达到饱和)
▶ Xavier初始化:(Xavier initialization)
将所有的权重设为一个随机数(如从一个标准正太分布中进行抽样,然后通过一个尺度转换生成权重),但在尺度转换放缩的倍数由当前层的神经元数量决定!
较好地解决了权值过大过小的问题~但对激活函数是ReLU将不太适用(有一般神经元几乎被砍掉),常常使用这一初始化方法。
批量归一化(BN)
目的:是让我们不用花费大量的时间去刻意去微调参数,是为了解决在训练过程中,中间层数据分布随着参数的更新而分布改变的情况,这就是BN的作用
说明:是在训练开始的时候而不是权值初始化的时候开始进行的,可以使得每一层都能较好的符合基本正态(高斯)分布。通常都会在全连接层或者卷积层与激活函数直接进行一个批处理。可将BN视为网络中的一层(其他层有激活函数层、卷积层、全连接层等)
计算法则:对每一层的输入数据,计算均值和方差,然后对这一批数据进行归一化~归一化公式▼
对象域是同一层的数据
本质原理:在网络的每一层输入的时候,往之中插入一个BN层,表示对这一层的输入数据做一个归一化处理(符合标准正态分布)后,再进入网络的下一层。特点在于,这个归一层是可学习的,学习的目的就是尽量使得随着参数更新而中间层数据的分布随之改变的情况。学习的参数有(γ,β)(γ用来缩放,β同于平移)
通过学习来使得γ等于方差,β等于均值
特点:
• 改善了流经网络的梯度
• 允许选用更高的学习率,
• 减小了对初始化的强依赖性。
• 改善了正则化策略,即减轻了对dropout的依赖
训练过程的动态变化
监控学习过程
Step 1:数据预处理
Step 2:选取网络的架构
Step 3:反复确认损失(loss)是合理的
Step 4:开始训练,先确保可以同较小的数据集拟合地较好
Step 5:对所有的训练数据加上一个小的正则化项,并找到最优的学习率(一般为**[1e-3,1e-5]**之间)来使loss有效减小
学习率太小则loss不会明显减小,学习率太大则loss爆了(NaN)。
超参数选取
采取策略:对任何超参数都执行交叉验证(cross-validation)
╰(‵□′)╯ 交叉验证 是指在训练集上训练,然后在验证集上验证并观察这些超参数的效果如何。
执行步骤:
1. 选择相当分散(如何选取见下)的数据,然后用几个 epoch 的迭代去学习。经过了几个 epoch (++一个epoch表示整个数据集正向并方向训练一次++) 后,就可以知道哪些超参数是ok的,哪些是不行的。应该对这些不行的进行相应的调整。
2. 通过调整后可得到一个比较好的参数取值区间,然后可以在这个区间寻找更加精确的值了。这一步骤可能花费较长的时间来对这一得到的区间进行进一步精确的搜索。
小技巧:若训练一些参数时,在迭代或 epoch 中若花费的代价远远大于初始的代价(如比初始代价的三倍还要大),说明这个选取是行不通的,应该立刻停止。
超参数搜寻的方法:
• 网格搜索法(Grid Search)
对不同的超参数列表进行暴力穷举搜索~
仅对每一个超参数的一组固定值进行采样
对两个超参数的取样情况下▼
• 随机搜索法(Random Search)
从抽样分布中抽取随机的参数组合。
对每一个超参数在一定范围内进行随机值采样采样。如若有两个超参数则需要
小结:在多参数情况下,相比而言随机采样更加的真实,因为它可以体现维度关系。可以得到更多的重要变量的样本,有了更多的重要样本有会得到更多的有用信息。
训练过程中可能出现的问题
Epoch-loss图▼
loss-time图▼
刚开始梯度变化不明显,没有开始学习,但突然开始调整就像刚刚开始学习一样。这是因为初始值没有选好
关键点
经验!通过不断累积经验来发现错误。
神经网络的优化方法
随机梯度下降法-Stochastic Gradient Descent(SGD)
概念:并非计算整个训练集的损失和梯度值,而是在每一次迭代中,仅仅选取一小部分训练样本记为 minibitch (按照惯例,通常取2的幂次方如32,64等个),用这个 minibitch 来计算损失和求当前位置的梯度。
计算公式:
缺点:
虽然解决了每次都要访问所有样本的问题,但是准确度不够,由于样本的随机性导致收敛方向变化大,不能很快收敛到局部最优解!
带有动量的SGD-(Momentum + SGD)
概念:保持一个不随时间变化的速度,并且将估计的梯度加到这个速度上,然后在这个速度的方向上前进,而不是在梯度的方向上前行。还有一个超参数ρ表示对前进方向的阻碍作用。实现的思想是在每一步,采用当前的速度,然后用摩擦系数ρ来对其衰减,之后将之加到梯度上。于是就实现了在速度向量的方向上前行,而不是在原始梯度向量的方向上步行。
计算公式:
特点:
解决了SGD在局部极小值(鞍点)时由于梯度为0而停止运动的问题。(直观理解是哪怕梯度为0,到那时仍然有一个速度,故会继续运行下去。)
Nesterov动量-Nesterov Momentum
概念:是对传统Momentum方法的一种改进,(++待后续理解完毕后再补充,欢迎各位前来讨论~++)
计算公式:
带入后得:
特点:
对凸优化问题上有很好的理论性质
上述三种方式作用图示(o゚v゚)ノ
AdaGrad
概念:区别于之前方法中任何的参数都使用同一个更新速率,当不同的参数不一定都适合于同一个更新速率。即,AdaGrad是自适应来为各个参数分配不同的学习率。
计算公式:
特点:
步长在一个梯度下降很慢的维度下训练会加快,而在另一个梯度下降相较之下较快的维度的方向上训练则会减慢,优化了摆幅过大的现象。
对每个参数,随着训练的时间越长,其对应的学习速率逐渐减慢,即在训练的中后期,梯度会趋近于0而使得训练提前结束。
对凸函数而言效果很好,因为当接近极值点时,学习速率会慢下来最后达到收敛。当对非凸函数会出现很多的问题(如一个局部的极值点便将之卡死,无法继续训练)
RMSProp
概念:是AdaGrad的一个变体,(引入了衰变率β【β通常取0.9或0.99】),让平方梯度按照一定比率下降,见计算公式便可知(>人<;)
计算公式:
特点:
步长在一个梯度下降很慢的维度下训练会加快,而在另一个梯度下降相较之下较快的维度的方向上训练下则会减慢,同Adagrad会使得曲线更加的平缓。
由于引入的衰变量,会减缓学习率的下降速度(相较于Adagrad)~~
上述三种方式作用图示(o゚v゚)ノ
Adam
来源:引入动量模型的速度概念,也引入AdaGrad和RMSProp相求梯度平方的估计值,然后除以梯度平方的实际值。于是这两者合成的就成了Adam算法(≧∇≦)ノ
本质:结合了动量和梯度平凡的思想,应该是更加好的算法。
计算公式:
缺点:
会使得刚开始的步长变得很大,可能会将初始化工作完全搞砸~
克服缺点:通过增加偏置校正项以避免出现初始时步长较大的情况▼
采用无偏估计来对每一步更新,而不是初始就对俩m和n进行估计。
方法~
特点:
Adam 确实是一个比较好的最优化算法,对不同的问题使用 Adam 都能得到很不错的结果。几乎可以用来解决任何问题。
如β1设置为0.99,β2设置为0.999,学习率α设为1e-3(或5e-4),效果很棒!故**一般 Adam 算法是首选。**
上述四种方式作用图示(o゚v゚)ノ
多阶优化函数
一阶优化函数
之前的所有优化函数都是一阶优化函数,仅仅通过分析的是实际函数的一阶偏导。(由于是梯度下降的最优解,但不能一次迈太多,毕竟一旦区间增大,这一逼近就不太有效了)
二阶优化函数
可能会同时考虑函数的一阶偏导和二阶偏导。对于二阶偏导,是可以直接求出最小值点的,这就很ok啦"( ̄y▽, ̄)╭ "
二阶函数的泰勒展开式
选用牛顿步长进行更新来解决临界点的问题
海森矩阵H:就是二阶偏导矩
特点:
• 不需要引入学习率。(二阶偏导可直接到最小值点)
• 但对深度学习是不现实的(海森矩阵是N×N的),而实际中N是非常大的,且又呈平方型增长内存一定存不下。
学习成果的评估
上述所有的优化方法都是针对训练数据的,都是在试图降低训练误差,但实际上我们并不太关心训练误差,我们真正关心的是模型在没有见过的数据上的表现,关心的是如何减少训练误差和测试误差之间的差距,在测试数据上也能表现良好。⇩
模型集成(Model Ensembles)
这是一个快速且简单的方法
过程:
• 对随机选取的多个(多取10个)不同的独立的模型进行分别进行训练
• 然后测试时,对这些模型的预测结果取平均数
优点:
• 能缓解一点过拟合现象。
• 能固定的提高模型一点点的性能(这一点点可能就2%左右)
小技巧~~(略微改变模型的选取方式)
过程:
• 不用独立的对模型进行测试,而是在训练过程中保留多个模型的快照,然后用这些模型来做测试
• 测试后,仍是对这些模型的预测结果取平均数
正则化(Regularization)
如何提高单一模型的效果(减小测试模型的数量模型便可达到较好的测试效果呢)?正则化正是这样一种方法。
概念:
往模型中加入一些成分来防止训练集上数据的过拟合,从而使测试集上表达效果得到较显著的提升
如这一个损失函数▼
方法:
Dropout
概念:
每次在网格中正向传递时,在每一层随机将一部分神经元置为0,这些随机被置0 的神经元都不是完全相同的。即每次经过一层,就算出这一层的值,并随即将这一层的其中一些神经元置为0,然后继续前行。
特征:
发现经过 dropout 后的网络就像是变小了一样,并且仍是正向传播的,每次遍历都是不同的部分。故我们只用到了其中一部分神经元便可有效的表达出训练的效果。
实现:
实际上两行代码便可实现dropout一层之间的操作~~
之所以有效的解释:
• 只能通过零散的特征来进行判断,一定程度上避免了过拟合现象的出现
• 是单一模型中的集成学习
Batch normalization
概念:
在训练中,一个数据点可能和其他不同的数据点出现在不同的Small batch中,对于单个数据点来说,其于训练过程中会如何被正则化具有一定的随机性。但在测试过程中,通过基于全局估计的正则化来抵消这种随机性。
更加通用的正则化策略 (Common Pattern)
概念:
在训练中,给网络添加一些随机性,来防止它的训练数据过拟合化。(从一定程度上扰乱它,防止其完美地你和训练数据)。但在测试的时候,我们应该抵消所有的随机性,来尽可能提高模型的泛化能力。
dropout只能说是该策略的一个实例。
Batch normalization也是符合该策略的。
Data Augmentation
概念:
在训练中,有一个最初的版本,之中既有自己的数据,也有自己的标签。在每一次迭代中,都使用这个版本取更新我们的卷积神经网络。但是,我们可以让其以一某种特定的方式随机地转换图像(镜像,抽取不同尺寸大小裁剪图像,颜色转换[R,G,B]等),但不动标签。然后再用这些随机转换的图像进行训练。然后在测试过程中,通过评估一些固定的裁剪图像来抵消这种随机性。
Step 1:
Step 2:
特点:
适用面特别广,几乎可以用于所有数据处理。
最大池化法
前面讨论过就不再展开说明了
随机深度(Stochastic depth)
概念:
假设有一个很深的网络如下图▼,在训练时,随机从网络中丢弃部分层,只使用部分层来训练。而在训练时,却使用全部的网络~~
较前研,想法很不错,但实际操作不常用
迁移学习(Transfer Learning)
另一种处理过拟合的方法(一种是正则化)
特点:无需大量的样本集也能对卷积层进行训练
对于很少数据集的思想方法:
1. 找到一些卷积神经网络(CNN),先用这个CNN在一个很大的数据集中进行训练,这个很大的数据集有足够多的元素取训练整个网络
2. 然后就尝试把这个从大数据集中训练出的提取特征的能力用到感兴趣的小数据集上(理论上分类会远少于大数据集上的)
3. 修改从最后一层的特征到最后的分类输出之间的全连接层即重新随机初始化这一部分矩阵,冻结前面层产生的权重
4. 然后只需要训练一个线性分类器(仅仅最后一层),让之在感兴趣的小数据上收敛。
对于还算充裕数据集的思想方法:
1. 找到一些卷积神经网络(CNN),先用这个CNN在一个很大的数据集中进行训练,这个很大的数据集有足够多的元素取训练整个网络
2. 然后就尝试把这个从大数据集中训练出的提取特征的能力用到感兴趣的小数据集上(理论上分类会远少于大数据集上的)
3. 微调整个网络,当其在数据集上充分训练之后且在最后一层收敛,可以试着更新整个网络的权值。
通用策略:当对网络进行更新时,需将学习率调低,因为最初的网络的参数可能是在大数据集上收敛的,其泛化能力已经足够强了,对其进行微调便可用来适应自己感兴趣的小数据集。
通过迁移学习,我们应该学会自己去寻找数据集!!!如下:▼
• Caffe
• Caffe
训练如带娃~~
- 斯坦福CS231n计算机视觉-神经网络训练中激活函数的选择
- 斯坦福cs231n学习笔记(7)------神经网络训练细节(激活函数)
- 斯坦福cs231n学习笔记(8)------神经网络训练细节(数据预处理、权重初始化)
- 训练深度神经网络的时候需要注意的一些小技巧
- 斯坦福cs231n学习笔记(10)------神经网络训练细节(训练过程,超参数优化)
- 训练深度神经网络的时候需要注意的一些小技巧
- 论文学习:二值神经网络BNN-用+1或-1限制的权值和激活函数来训练神经网络
- 深度神经网络(DNN)损失函数和激活函数的选择
- 神经网络学习(五)优化方法:激活函数
- 训练深度神经网络的时候需要注意的一些小技巧【转载】
- 训练深度神经网络的时候需要注意的一些小技巧
- 神经网络中的激活函数——加入一些非线性的激活函数,整个网络中就引入了非线性部分,sigmoid 和 tanh作为激活函数的话,一定要注意一定要对 input 进行归一话,但是 ReLU 并不需要输入归一化
- 王小草【深度学习】笔记第三弹--神经网络细节与训练注意点
- 神经网络中的激活函数的作用和选择
- 训练深度神经网络的时候需要注意的一些小技巧
- 斯坦福CS231n计算机视觉-神经网络训练细节(权值初始化、批量归一化、超参数优化)
- 【深度学习】③--神经网络细节与训练注意点
- 神经网络细节与训练注意事项
- 神经网络中激活函数的作用及选择
- 训练深度神经网络的时候需要注意的一些小技巧