回顾梯度下降:
每一轮都要处理全部样本,样本量太大的话,即使进行了向量化,运行也十分缓慢
使用Mini-batch梯度下降:
将X、Y分成t个小批(batch),分别执行梯度下降。每一个batch执行完都更新W和b,这样一次遍历全部样本后更新了t次W和b而不是一次,这称为一代(epoch)运算。当然我们可以通过循环增加代数来继续运算直到满足要求。
J的变化:
不同于梯度下降法,每次小的迭代中,一个batch被遍历,此时J不一定下降。
但在一代的运算中,J是整体下降的,这与之前的方法结果相同。我们得到的J的图像将会是整体向下的波动图像(即有噪声)。
batch的数目:
只有一个batch时,Mini-batch就是梯度下降法。
而有m(样本数量)个batch时,称为随机梯度下降法,他有很多噪声,平均来看会靠近最小值,但也有可能方向会错,因为这个算法永不收敛,其结果会在最小值附近波动而不是达到它。
batch太大时,问题与梯度下降法相仿,一代运算耗时太长;而batch太小时,失去了向量化带来的加速,效率过低。
使用Mini-batch梯度下降法时,结果也可能在最小值附近波动,这时应当慢慢减小学习率(之后讲授)。
batch数目的选择:
少于2000个样本:直接梯度下降,即1个batch
较大:64-512,最好是2的幂
注意确保你的batch符合CPU/GPU内存
第t(>0)个点的指数加权平均数(移动平均值,指数移动加权平均数)按以下方式计算:
另外:
其意义大致为第t个点之前1/(1-β)项数据(包含第t个)的一个平均,β较大时,显然曲线应当比较平滑,即噪声小。
不断将vt的计算式展开,我们得到以下式子:
排序越靠前的数据,其系数越小,呈一指数型函数下降。且利用等比数列求和,我们容易得到这些系数的和:
n是求和的项数。这样可以看出其和在n较大时接近1,这称为偏差修正(之后讲授)
平均了1/(1-β)项后,系数大概会降低到1/e,此后会快速衰减。因此我们大概也就平均了这么多天的温度。
注意指数加权平均数在迭代中产生,这使得其计算占用内存很少,效率也很不错。
注意到在t较小的时候,用vt来估计前t项数据的均值并不准确,早期我们可以将vt修正后再使用:
注意其分母是我们之前计算的系数的和的形式,因此这个式子实际上是前t项数据的加权平均数。
当然,随着t的增大,分母趋于1,这个修正的作用也就越来越小了。
现有方法的问题:
波动较多,需要很多步迭代才达到最小值。
有的时候我们也希望在纵轴的行进不要太大
解决:
计算梯度的指数加权平均数来更新W和b(vdw是迭代过程,所以这里没有下标):
在纵轴的摆动平均值接近0,横轴方向的运动更快。因为纵轴上,上下摆动是在计算平均值后抵消了,但横轴的移动始终朝向一个方向。这样算法变快了,因为路径更加直接了。
这就称为动量梯度下降法,他的表现往往好于普通的梯度下降法。
实现:
β常常取0.9,一般不需要偏差修正
有的公式删去后面的1-β,但学习率α要相应调整,所以还是算了。
问题仍然是尽量不延缓横轴行进的情况下减小纵轴波动。
类似指数加权平均,算法如下:
原理大致是:
纵轴方向(这里以b为纵轴)我们希望幅度小一点,因此我们希望Sdb较大,相应的,我们当然希望SdW较小
而Sdb和SdW的计算式满足了这一点,db如果较大,那Sdb必然更大,这样之后b会被Sdb衰减,对SdW是同样的道理。
应用算法时,这使得我们可以采用一个更大的学习率。
注意SdW可能接近0,这样W会变得过大,因而我们常常在分母添加一个小量ε,10^-8即可。
它结合了Momentum和RMSprop
同时计算之前的v和S(都初始化为0):
Adam算法中一般要进行偏差修正(t是已计算的数据项数):
更新方式如下:
推荐的设置:
β1:0.9 β2:0999 ε:10^-8
当然也可以自己调整他们
保持学习率不变的话,你的算法可能在最小值附近摆动而不是收敛到最小值,因此我们需要让学习率随着时间衰减。
可以如此设置:
decayrate称为衰减率,epochnum是已进行运算的代数(此前讲过代的概念)
也有一些别的方法,如:
(t是mini-batch的数字)
有时人们也手动控制学习率。
早期人们担心深度学习算法会困在较差的局部最优(梯度下降只能达到局部最优),但事实上,高维情况下,梯度为0的点常常不是局部最优点而是鞍点。
这样问题其实不是局部最优,而是在鞍点附近,你的算法会缓缓走离鞍点,走向更优的点而不是卡在鞍点,而缓慢才是问题。