神经网络训练优化
一、优化算法
1.1 Batch VS Mini-batch梯度下降法
1.1.1 Mini-batch梯度下降法
1)Batch梯度下降法缺点
将训练集样本放入到 X 特征矩阵和 Y 标签矩阵中能避免在对 m 个样本进行训练时用for循环。虽然向量化能让计算效率大幅度提高,但是当样本数量过多时,计算速度仍然较慢(例如训练集含有1亿个样本)。之前学习的梯度下降法名为Batch梯度下降法,使用此方法对整个训练集进行梯度下降时,必须处理整个训练集才能进行一步梯度下降,然后又需要重新处理整个训练集才能进行下一步梯度下降,当样本数量庞大时,这种方法十分低效。
2)Mini-batch梯度下降法
解决Batch梯度下降法效率低的方法是把训练集划分为多个训练集(这些子训练集被称为Mini-batch),然后对这些子训练集依此进行Batch梯度下降,例如:假设训练集样本总量为五百万,每个子集中含有1000个样本,相当于把训练集拆分成了5000个子集。具体拆分过程:将这五百万个样本的前1000个特征X拿出来作为第一个子训练集(记为X{1}),然后再依此取出后1000个作为X{2}、再后1000个…直到将五百万个样本全部划分好(对目标值Y也做同样处理)。拆分的结果是:含500万个样本的训练集被拆为5000个X{t} 和5000个 Y{t} 的子训练集。其中X{t} 的维度为(nx , 划分力度),Y{t} 的维度为(1,划分力度),这里的划分力度为1000。最后对所有子集依此进行Batch梯度下降。以上过程称为Mini-batch梯度下降法(又名小批量梯度下降法)。事实证明,当需要对一个庞大的训练集进行梯度下降时,Mini-batch梯度下降法相较于Batch梯度下降法效率更快,所以几乎每个从事深度学习研究的人都会用到Mini-batch梯度下降法。
1.1.2 Mini-batch梯度下降法原理
设训练集样本总量为五百万,每个子集含有一千个样本,运行Mini-batch梯度下降的过程如下:
for t = 1,…,5000:
(下列为使用Batch梯度下降对 X{t} 和 Y{t} 执行梯度下降的具体过程)
1)输入X{t}进行正向传播:Z[l] = W[l]X{t}+b[l]、A[l] = g[l](Z[l])
2)得出成本函数:J{t} = L(y^(i),y(i)) (这里的y(i)来自于子训练集中)
3)输入 J{t} 进行反向传播更新 W 和 b
注:for 循环内部的梯度下降过程与之前学的完全一样。
1.2 深入理解Mini-batch
1.2.1 梯度下降的“成本-迭代”函数图像
1)使用Batch梯度下降时,每一次迭代都需要遍历整个训练集,成本函数值会随着迭代次数逐渐下降,如果成本函数时是迭代次数的一个函数,那么函数图像如下:
2)使用Mini-batch梯度下降时,由于每一次的训练都是针对不同的 X{t} 和 Y{t},这就会导致成本函数随着迭代次数的增加虽然总体呈下降趋势,但是过程中有很多起伏(因为每次都相当于在对不同的训练集进行梯度下降,不同的训练集难免训练难度不同,所有成本函数也不同),大致图像如下:
1.2.2 Mini-batch梯度下降
1)两种子集划分方式
Mini-batch指的是训练集划分之后,每个子训练集中含有的样本数量,假设训练集样本数为m:一种极端情况是将整个训练集划分为一个子训练集(Mini-batch=m),这种情况其实就是Batch梯度下降,可得:(X{1} ,Y{1})=(X ,Y);另一种极端情况是将整个训练集划分为m个子训练集(Mini-batch=1),这种情况一般称为随机梯度下降法,可得:(X{t},Y{t})=(X(t),Y(t))
2)两种划分方式对应的最优成本函数寻找方式
下图为成本函数轮廓:
注:蓝色部分对应Batch梯度下降迭代过程,紫色部分为随机梯度下降迭代过程。
假设成本函数最小值在上图中心位置。batch梯度下降法从某处开始,相对噪声小,幅度大,但是当面对大数据量时效率很低(如果训练样本不大,batch梯度下降法运行地很好),batch梯度下降可以沿着蓝线轨迹找到最小值。
而相反在随机梯度下降法中,每次只对一个样本进行梯度下降,大部分时候确实是向着全局最小值靠近,但有时候会远离最小值,因为那个样本恰好指的方向不对,因此随机梯度下降法是有很多噪声的。大体上看,它最终会靠近最小值,不过有时候也会方向错误,因为随机梯度下降法永远不会在达到最小值时停留,而是会一直在最小值附近波动。
3)两种划分方式的缺点
假设使用Batch梯度下降(Mini-batch=m),每次迭代需要处理大量训练样本,该算法的主要弊端在于当训练样本数量巨大的时候,单次迭代耗时太长。如果训练样本不大,batch梯度下降法运行地很好。
相反,如果使用随机梯度下降法,当只需要处理一个样本时,这个方法很好,通过减小学习率,噪声会有所减小。但随机梯度下降的一大缺点是,会失去所有向量化带来的加速,因为一次性只处理了一个训练样本,这样效率过于低下。
综上,实践中最好选择大小适中的mini-batch尺寸,学习率最快。因为一方面你得到了大量向量化,如果mini-batch大小为1000个样本,你就可以对1000个样本向量化,比一次性处理多个样本快得多。另一方面,你不需要等待整个训练集被处理完就可以开始进行后续工作。、
4)mini-batch对应的最优成本函数寻找图像
注:图中绿色部分为mini-batch梯度下降对应的最优成本函数寻找图像。
它虽然不会总朝向最小值靠近,但它比随机梯度下降要更持续地靠近最小值的方向。它也不一定在很小的范围内收敛,如果出现这个问题,可以慢慢减少学习率(在之后会讲到学习率衰减,也就是如何减小学习率)。
1.2.3 Mini-batch数值选择
问:如果mini-batch大小既不是1也不是m,应该取中间值,那应该怎么选择呢?
答:mini-batch是一个重要的超参数,需要找到一个让梯度下降优化算法最高效的大小。首先,如果训练集较小(小于2000个样本),直接使用batch梯度下降法,你就可以快速处理整个训练集。
当样本数目较大时,一般设mini-batch为64到512。考虑到电脑内存设置和使用的方式,如果mini-batch大小是2的n次方,代码会运行地快一些,64就是2的6次方,以此类推,128是2的7次方,256是2的8次方,512是2的9次方(也可将mini-batch的大小设为1024,不过比较少见,64到512的mini-batch比较常见),一般多尝试几个数值,看看梯度下降算法在什么情况下最高效。
需要注意的是mini-batch的设置要确保 X{t} 和 Y{t} 符合CPU/GPU内存,如果你处理的mini-batch和CPU/GPU内存不相符,那么不管用什么方法处理数据,算法的表现都会惨不忍睹。
1.3 动量梯度下降(Momentum)
有一种梯度下降方法叫做动量梯度下降法(Momentum),运行速度几乎总是快于标准的梯度下降算法。其基本的思想就是计算梯度的指数加权平均数,并利用该梯度更新权重。
1.3.1 常规梯度下降法缺点
假设成本函数形状如下图(红点代表函数最小值)。当优化成本函数时,假设从蓝色点开始进行梯度下降(batch或mini-batch下降法),如果进行梯度下降法的一次迭代,也许会指向如下图所示:
以此类推,一步步迭代计算下去,慢慢摆动到最小值,如下图所示:
这种上下摆动减慢了梯度下降法的速度(因为毫无意义),而且无法使用较大的学习率(权重更新公式里面的α就是学习率),如果用较大的学习率可能会导致偏离函数的范围,比如某一步迭代的方向错误,但是正好用了大的学习率,这将会导致(紫色箭头所示):
注:为了避免摆动过大,只能用一个较小的学习率。
所以在纵轴上,你希望学习慢一点,因为你不想要这些摆动;但是在横轴上,你希望加快学习,你希望快速从左向右移,移向最红点(最小值),由此引入动量梯度下降法!
1.3.2 动量梯度下降法
1)步骤:
第一步:在每次迭代过程中,计算 v_dW、v_db(暂时省略上标[l])。计算v_dW = βv_dW + (1-β)dW、v_db = βv_db + (1-β)db,v_dW等同于dW的移动平均数,v_db等同于db的移动平均数(这里没有家偏差修正);
第二步:更新权重与偏置:W:=W -αv_dW、b:=b -αv_db。通过以上方法可减缓梯度下降的摆动幅度。
如下图所示:
2)动量梯度下降法优点
使用动量梯度下降法后,在纵轴方向摆动减小了;而且在横轴方向,由于所有的微分都指向横轴方向,因此横轴方向的平均值仍然较大,经过几次迭代后,你会发现横轴方向运动更快。综上,使用动量梯度下降可以使算法走一条更加直接的路径抵达最小值,如下图红色部分所示:
1.4 Adam算法
Adam算法是一种极其常用的学习算法,被证明能有效适用于不同神经网络,适用于广泛的结构。
1.4.1 算法执行步骤
第一步:初始化v_dW=0,S_dW=0,v_db=0,S_db=0。
在第t次迭代中:
第二步:首先通过mini-batch梯度下降计算dw、db,然后计算 v_dW = β_1v_dW + (1-β_1) dW 和 v_db = β_1v_db + (1-β_1)db (注意这里使用β_1是为了跟RMSprop算法中的β_2区分),然后计算 s_dW =β_2s_dW + (1-β_2)(dW)2 和 s_db = β_2s_db + (1-β_2)(db)2。
第三步:在Adam算法中一般要加上偏差修正,所以有:
v_dW = v_dW/( 1-β_1t)、v_db = v_db/( 1-β_1t)
s_dW = s_dW/( 1-β_2t)、s_db = s_db/( 1-β_2t)
第四步:最后更新权重和偏置:
1.4.2 超参数说明
1)学习率 α 需要多次调试,你可以尝试一系列值,然后看哪个有效。
2)β_1常用的缺省值为0.9,这是 dw 的移动平均数(加权平均数)。
3)β_2推荐使用0.999,这是在计算 (dw)2 以及 (db)2 的移动加权平均值。
4)ε建议取10(-8),但也可以不设置它,因为它并不会影响算法表现。
1.5 学习率衰减
加快算法学习的一个办法是随时间慢慢减少学习率,一般将其称为学习率衰减。
1.5.1 学习率衰减的好处
假设现使用mini-batch梯度下降法,在迭代过程中会有噪音,下降朝向最小值,但是不会精确地收敛,将在最小值附近摆动。由于此时的α是一个较大固定值,将会导致最后算法大幅度在最小值附近摆动(如下图蓝色部分所示)。但如果随着梯度下降逐渐减少学习率α,最后曲线会小幅度在最小值附近摆动。所以慢慢减少α的本质在于,在学习初期能承受较大的步伐,但当开始收敛的时候,小一些的学习率能让你步伐小一些从而更精确(如下图绿色部分所示)。
1.5.2 常见的更新学习率方法
1)公式法(介绍两种公式更新方法)
- 假设使用mini-batch梯度下降法,将训练集拆分成不同的mini-batch后,将第一次遍历训练集的过程叫做第一代(也就是第一步梯度下降),第二次遍历称为第二代依此类推。可以将学习率设为:
α= [ 1 /(1+衰减率 * 代数)]α0
其中代数指第几代遍历训练集,衰减率为手动设置的超参数,α0为更新之前的学习率(刚开始的α0是需要手动设置的超参数,因为这是第一代的学习率)。在训练时多尝试几个超参数,找到合适的值让学习率呈递减趋势。 - 指数衰减:α= 0.95(代数-num)α0,其中α为小于1的值,所以学习率将呈指数下降。
2)手动调整学习率:当模型数量小的时候,如果一次只训练一个模型,也有人会手动调整学习率。
二、调参
2.1 超参调试处理
本节将介绍一套超参调节的指导原则,系统地组织超参调节过程的技巧。
2.1.1 超参数重要等级划分
关于深度学习的难点之一是超参的调整,因为深度学习涉及的超参数很多(例如学习率α、学习率的衰减率、Adam算法中的β1、β2、神经网络层数、隐层的单元数量、mini-bacth的大小等)
事实证明,一些超参数比其他超参数更为重要,所以不同超参数调试的优先级是不一样的。若是按照重要等级分,那么第一等级的是学习率 α,第二等级是Momentum算法的 β(一般取0.9)、隐藏层单元数、mini-batch size,第三等级是神经网络层数、学习率的衰减率,第四等级是Adam算法中的β1、β2(一般不需要调试)。
2.1.2 超参数调试选择
既然知道了这些超参数的重要等级,那么如何选择调试值呢?
1)网格取值的调试方法
设某个算法存在两个超参数:在网格中取样点,然后系统地研究这些数值组合对算法效率的影像,选出效果最好的超参数组合,如下图所示(假设取25对超参组合):
网格取值调试方法有一个问题:假设上图中的一个超参为学习率 α(重要程度为一等级),而另一个超参β不那么重要。此时你实验了五个 β 的值,你会发现无论 α 取何值,结果基本上都一样。所以表面上看上图中有二十五对超参组合,但实际上进行实验的只有五对超参(即α值不同的五对)
2)随机取值的调试方法
设某个算法存在两个超参数:在二维平面中随机选择点,然后用这些随机取的点试验超参数的效果,之所以这么做是因为对于要解决的问题而言,很难提前知道超参数的重要性,这种方式可以避免网格取值中的那种情况(对 α 和 β 进行组合调试)。随机取值的调试方法即使是对 α 和 β 进行组合调试,也会实验25对超参(因为没有哪个超参的值会重复),所以更有机率选出效果较好的超参,如下图:
注:上面讲的是两个参数的情况,而现实中遇到的参数选择远远不止两个,但原理都一样,只需要在更高维度去进行超参组合的调试即可,例如对三个超参进行选择如下图:
2.1.3 小技巧-由粗到精取值
调参是遵循的一个惯例是由粗糙到精细的取值策略:例如采用随机取值的调试方法进行取值之后,也许你会发现某个点效果比较好,那说明这个点周围的其他组合效果也很好,那么现在在这些点组成的小区域中再随机取更多、更密集的点,如下图所示:
2.2 为超参数选择合适的范围
上一节学习到,随机取值的调试方法更有机率选出效果较好的超参组合,但是随机取值并不是在取值范围内随机均匀取值,而是要选择合适的标尺来随机取值。
2.2.1 利用线性刻度尺进行参数选择
假设神经网络层数L的取值范围是[2,4],那么在2-4的数轴上直接均匀取2,3,4比较合理,但是这种取值方式对于某些超参数而言并不适用。
例如,学习率的取值范围是[0.0001,1],假设画一条从0.0001到1的数轴表示取值范围,并且沿着这条数轴均匀取值,那么90%的数值将会落在0.1到1之间,结果就是在0,1到1之间占用了90%的资源,这并不合理。如下图所示:
2.2.2 利用对数刻度尺进行参数选择
改进方法,利用对数尺取代线性尺搜索超参数:
注:之所以名为对数尺是因为0.0001为 10(-4)、0.001为 10(-3)、0.01为 10(-2)…
这样在0.0001到1之间的资源是均匀分布的。在python中实现上述过程的代码为:
r=-4 * np.random.rand();α=10r
上述代码的执行效果为:r的取值范围是[-4,0],那么α取值范围为[10(-4),100]。
现实中常见的情况是超参数的取值范围为[ 10a, 10b],例如上面的例子中a为-4、b为0。你要做的就是在[a,b]区间随即均匀地给 r 取值。
2.2.3 超参数训练的实践
由于计算资源的不同,模型训练的调参方式可分为以下两种:panda 和 caviar。
1) 保姆式照看一个模型(Panda)
像保姆一样每天照看一个模型,不断调节参数。这种情况通常是有庞大的数据集进行训练,但没有许多计算资源或足够的CPU和GPU,此时电脑只能一次试验一个模型或一小批模型。
例如第0天(也就是第一天),你将随机参数初始化后开始训练,然后逐渐观察损失函数J或者数据设置误差,在第1天内逐渐减少,那这一天结束的时候,你可能会感觉训练得不错,如下图:
第二天增加了学习率、填充Momentum和减少了一些变量,发现效果依然不错,然后第三天…如下图:
每天你都会观察它,不断调整参数(可以说是在每天花时间照看此模型)。所以这是一种通过人为照料一个模型的方法,观察它的表现,耐心地调试学习率。这种情况通常是因为计算机没有足够的计算能力,不能在同一时间试验大量模型时才采取的办法。
2) 同时训练多个模型 (Caviar)
另一种方法则是同时训练多种模型。初始化一些超参数,然后让这个模型自己运行,过几天后你会获得像类似下图的学习曲线,竖轴可以代表损失函数、实验误差或数据误差的损失。
与此同时你又可以训练一个有着不同超参数设定的另一个模型,第二个模型也会生成一个不同的学习曲线。同理,你可以试验第三种、第四种、第n种模型…最后选择训练效果最好的那个。
在计算机视觉领域,数据集一般非常庞大,所以同时试验大量的模型是很困难的,所以应用熊猫方式会多一些。你会像对婴儿一样照看一个模型,调试参数。当然,即使是在熊猫方式中,当照看一个模型一段时间后,也可以建立一个不同的模型,如下图:
三、模型评估
3.1 模型评估指标
在训练机器学习模型的时候,无论是调整超参数,还是尝试更好的优化算法,为问题设置一个单一数字评估指标,可以更好更快的评估模型。所谓单实数评估指标就是把所顾及到的多方面指标(例如准确率、召回率)组合成单个指标,从而对模型进行评估。
3.1.1 Precision、Recall、F1-score
在分类任务下,预测值与真实值之间存在四种不同的组合,构成混淆矩阵:
真实值与预测值都是正例那么就叫真正例TP;真实值是正例预测值是假例那么就叫伪反例FN;真实值是假例预测值是正例那么就叫伪正例FP;真实值和预测值都是假例,那么就叫真反例TN。
1)精确率(Precision)
预测值为正例样本中真实结果为正例的比例,例如被分类器标记为猫的例子中,有多少真的是猫
(查不查得准):P(精确率)=TP / (TP+FP)
2)召回率(Recall)
真实值为正例样本中预测结果为正例的比例,对于所有真猫的图片,分类器正确识别出了多少百分比(查不查得全):R(召回率)=TP / (TP+FN)
3)模型评估指标(F1-score):F1 = 2 / (1/P+1/R)
3.1.2 案例分析
下面是分别训练的两个分类器的 Precision、Recall 以及 F1 score:
由上表可以看出,以 Precision 为指标,则分类器 A 的分类效果好;以 Recall 为指标,则分类器 B 的分类效果好。所以在有两个及以上判定指标的时候,很难决定出 A 好还是 B 好。
这里以 Precision 和 Recall 为基础,构成一个综合指标 F1 Score,那么利用 F1 Score 便可以更容易的评判出分类器A的效果更好。
3.2 满足和优化指标
要把所顾及到的多方面指标组合成单实数评估指标有时很困难,这种情况下,一般设立满足和优化指标对模型进行评估。
3.2.1 概念
假设你很看重分类器的准确度(可以是F1-score或者用其他衡量准确度的指标)。但除了准确度之外,还需考虑多长时间来分类一张图。分类器A需要80毫秒,B需要95毫秒,C需要1500毫秒。
可以将准确度和运行时间组合成一个整体评估指标(成本)。比如cost = accuracy-0.5 × runningTime,用这样的公式来组合准确度和运行时间,两个数值的线性加权求和。
你还可以选择一个分类器,能够在满足运行时间的前提下最大限度提高准确度,比如对图像进行分类所需的时间必须小于等于100毫秒。在这种情况下,就说准确度是一个优化指标,因为你想要准确度最大化,运行时间(满足指标)必须足够好。实际情况可能是,只要运行时间少于100毫秒,你的用户就不会在乎运行时间是100毫秒还是50毫秒,甚至更快。
通过定义优化和满足指标,就可以给你提供一个明确的方式,去选择“最好的”分类器。在这种情况下分类器B最好,因为在所有的运行时间都小于100毫秒的分类器中,它的准确度最好。
更一般地说,如果你要考虑N个指标,有时候选择其中一个指标做为优化指标是合理的。所以你想尽量优化那个指标,然后剩下N-1个指标都是满足指标,意味着只要它们达到一定阈值(例如运行时间快于100毫秒),你不在乎它超过那个门槛之后的表现,但它们必须达到这个门槛。
3.2.2 案例分析
假设你正在构建一个语音控制系统来检测唤醒语(比如对于苹果设备,你会说“Hey Siri”)。通过唤醒语可以唤醒这些语音控制设备,所以你可能会在乎唤醒语检测系统的准确性,即当说出唤醒语时,有多大概率可以唤醒设备。
你需要顾及假阳性(false positive)的数量,就是当没有人在说唤醒语时,设备被唤醒的概率。这种情况下,合理组合这两种评估指标可以最大化精确度。所以当某人说出唤醒词时,你的设备被唤醒的概率是一个优化指标,然后必须满足24小时内最多只能有1次假阳性(即平均每天只有一次设备在没人说话时被唤醒)为满足指标。
总结一下,当需要顾及多个指标时(比如有一个优化指标,你想尽可能优化的,然后还有一个或多个满足指标,需要满足的),就可通过满足和优化指标,在观察多个成本大小时,选出"最好的"那个模型。
3.3 贝叶斯最优错误率
3.3.1 比较人类和机器
在过去的几年里,很多科研团队一直在讨论如何比较机器学习系统和人类的表现。首先因为深度学习的进步,使得在许多应用领域出现算法威胁到人类的表现了(比如很多职业被人工智能替代)。其次,当人类试图让机器做人类能做的事情时,可以精心设计机器学习系统的工作流程,让工作流程效率更高,所以比较人类和机器是很自然的。
3.3.2 贝叶斯最优错误率
贝叶斯最优错误率(Bayes optimal),指的是机器永远不会被超越的错误率(即理论上的最小错误率),无论人类再研究多少年,人工智能将永远不会超越贝叶斯错误率。贝叶斯最优错误率产生的原因:深度学习超越了人类的表现,人类已经很难再指导深度学习往继续优化的道路上走了。
总结:在训练模型的时候,通过人的最佳表现就能够大致判断模型是否还有提升空间!