吴恩达《深度学习专项》笔记(六):改进梯度下降算法 ...
学习提示一直以来,我们都用梯度下降法作为神经网络的优化算法。但是,这个优化算法还有很多的改进空间。这周,我们将学习一些更高级的优化技术,希望能够从各个方面改进普通的梯度下降算法。
我们要学习的改进技术有三大项:分批梯度下降、高级更新方法、学习率衰减。这三项是平行的,可以同时使用。
分批梯度下降是从数据集的角度改进梯度下降。我们没必要等遍历完了整个数据集后再进行参数更新,而是可以遍历完一小批数据后就进行更新。
高级更新方法指不使用参数的梯度值,而是使用一些和梯度相关的中间结果来更新参数。通过使用这些更高级的优化算法,我们能够令参数的更新更加平滑,更加容易收敛到最优值。这些高级的算法包括gradient descent with momentum, RMSProp, Adam。其中Adam是前两种算法的结合版,这是目前最流行的优化器之一。
学习率衰减指的是随着训练的进行,我们可以想办法减小学习率的值,从而减少参数的震荡,令参数更快地靠近最优值。
在这周的课里,我们要更关注每种优化算法的单独、组合使用方法,以及应该在什么场合用什么算法,最后再去关注算法的实现原理。对于多数技术,“会用”一般要优先于“会写”。
分批梯度下降
这项技术的英文名称取得极其糟糕。之前我们使用的方法被称为"batch gradient descent", 改进后的方法被称为"mini-batch gradient descent"。但是,这两种方法的本质区别是是否把整个数据集分成多个子集。因此,我们认为我的中文翻译“分批梯度下降”、“整批梯度下降”比原来的英文名词或者“小批量梯度下降”等中文翻译要更贴切名词本身的意思。使用mini-batch
在之前的学习中,我们都是用整个训练集的平均梯度来更新模型参数的。而如果训练集特别大的话,遍历整个数据集要花很长时间,梯度下降的速度将十分缓慢。
其实,我们不一定要等遍历完了整个数据集再做梯度下降。相较于每次遍历完所有个训练样本再更新,我们可以遍历完一小批次(mini-batch)的样本就更新。让我们来看课件里的一个例子:
假设整个数据集大小https://www.zhihu.com/equation?tex=m%3D5%2C000%2C000。我们可以把数据集划分成5000个mini-batch,其中每一个batch包含1000个数据。做梯度下降时,我们每跑完一个batch里的1000个数据,就用它们的平均梯度去更新参数,再去跑下一个batch。
这里要介绍一个新的标记。设整个数据集https://www.zhihu.com/equation?tex=X的形状是https://www.zhihu.com/equation?tex=%28n_x%2C+m%29%28m%3D5%2C000%2C000%29,则第个数据集的标记为https://www.zhihu.com/equation?tex=X%5E%7B%5C%7Bi%5C%7D%7D,形状为https://www.zhihu.com/equation?tex=%28n_x%2C+1000%29。
再次总结一下标记:https://www.zhihu.com/equation?tex=x%5E%7B%28i%29%5Bj%5D%5C%7Bk%5C%7D%7D中的上标分别表示和第i个样本相关、和第j层相关、和第k个批次的样本集相关。实际上这三个标记几乎不会同时出现。
使用了分批梯度下降后,算法的写法由
for i in range(m):
update parameters
变成
for i in range(m / batch_size)
for j in range(batch_size):
update parameters
。现在的梯度下降法每进行一次内层循环,就更新一次参数。我们还是把一次内层循环称为一个"step(步)"。此外,我们把一次外层循环称为一个"epoch(直译为'时代’,简称‘代’)",因为每完成一次外层循环就意味着训练集被遍历了一次。
mini-batch 的损失函数变化趋势
使用分批梯度下降后,损失函数的变化趋势会有所不同:
如图所示,如果是使用整批梯度下降,则损失函数会一直下降。但是,使用分批梯度下降后,损失函数可能会时升时降,但总体趋势保持下降。
这种现象主要是因为之前我们计算的是整个训练集的损失函数,而现在计算的是每个mini-batch的损失函数。每个mini-batch的损失函数时高时低,可以理解为:某批数据比较简单,损失函数较低;另一批数据难度较大,损失函数较大。
选择批次大小
批次大小(batch size)对训练速度有很大的影响。
如果批次过大,甚至极端情况下batch_size=m,那么这等价于整批梯度下降。我们刚刚也学过了,如果数据集过大,整批梯度下降是很慢的。
如果批次过小,甚至小到batch_size=1(这种梯度下降法有一个特别的名字:随机梯度下降(Stochastic Gradient Descent)),那么这种计算方法又会失去向量化计算带来的加速效果。
回想一下第二周的内容:向量化计算指的是一次对多个数据做加法、乘法等运算。这种计算方式比用循环对每个数据做计算要快。出于折中的考虑,我们一般会选用一个介于1-m之间的数作为批次大小。
如果数据集过小(m<2000),那就没必要使用分批梯度下降,直接拿整个数据集做整批梯度下降即可。
如果数据集再大一点,就可以考虑使用64, 128, 256, 512这些数作为batch_size。这几个数都是2的次幂。由于计算机的硬件容量经常和2的次幂相关,把batch_size恰好设成2的次幂往往能提速。
当然,刚刚也讲了,使用较大batch_size的一个目的是充分利用向量化计算。而向量化计算要求参与运算的数据全部在CPU/GPU内存上。如果设备的内存不够,则设过大的batch_size也没有意义。
一段数据的平均值
在课堂上,这段内容是从数学的角度切入介绍的。我认为这种介绍方式比较突兀。我将从计算机科学的角度切入,用更好理解的方式介绍“指数加权移动平均”。背景
假设我们绘制了某年每日气温的散点图:
假如让你来描述全年气温的趋势,你会怎么描述呢?
作为人类,我们肯定会说:“这一年里,冬天的气温较低。随后气温逐渐升高,在夏天来到最高值。夏天过后,气温又逐渐下降,直至冬天的最低值。”
但是,要让计算机看懂天气的变化趋势,应该怎么办呢?直接拿相邻的天气的差作为趋势可不行。冬天也会出现第二天气温突然升高的情况,夏天也会出现第二天气温突然降低的情况。我们需要一个能够概括一段时间内气温情况的指标。
移动平均数
一段时间里的值,其实就是几天内多个值的总体情况。多个值的总体情况,可以用平均数表示。严谨地来说,假如这一年有365天,我们用https://www.zhihu.com/equation?tex=t表示这一年每天的天气,那么:
https://www.zhihu.com/equation?tex=t_i%3D%5Cleft%5C%7B%5Cbegin%7Baligned%7D%26%E7%AC%ACi%E5%A4%A9%E7%9A%84%E5%A4%A9%E6%B0%94+%261+%5Cleq+i+%5Cleq+365+%5C%5C%260+%26i%E5%8F%96%E5%85%B6%E4%BB%96%E5%80%BC%5Cend%7Baligned%7D%5Cright.
我们可以定义一种叫做移动平均数(Moving Averages) 的指标,表示某天及其前几天温度的平均值。比如对于5天移动平均数https://www.zhihu.com/equation?tex=ma,其定义如下:
https://www.zhihu.com/equation?tex=ma_i%3D%5Cfrac%7Bt_i%2Bt_%7Bi-1%7D%2Bt_%7Bi-2%7D%2Bt_%7Bi-3%7D%2Bt_%7Bi-4%7D%7D%7B5%7D+%281+%5Cleq+i+%5Cleq+365%29
假如要让计算机依次输出每天的移动平均数,该怎么编写算法呢?我们来看几个移动平均数的例子:
https://www.zhihu.com/equation?tex=ma_5%3D%28t_5%2Bt_4%2Bt_3%2Bt_2%2Bt_1%29%2F5+%5C%5Cma_6%3D%28t_6%2Bt_5%2Bt_4%2Bt_3%2Bt_2%29%2F5+%5C%5Cma_7%3D%28t_7%2Bt_6%2Bt_5%2Bt_4%2Bt_3%29%2F5
通过观察,我们可以发现https://www.zhihu.com/equation?tex=ma_6%3Dma_5%2B%28t_6-t_1%29%2F5,https://www.zhihu.com/equation?tex=ma_7%3Dma_6%2B%28t_7-t_2%29%2F5。
也就是说,在算n天里的m天移动平均数(我们刚刚计算的是5天移动平均数)时,我们不用在n次的外层循环里再写一个m次的循环,只需要根据前一天的移动平均数,减一个值加一个值即可。这种依次输出移动平均数的算法如下:
input temperature
input m
def get_temperature(i):
return temperature if i >= 0 and i < n else 0
ma = 0
for i in range(n):
ma += (get_temperature(i) - get_temperature(i - m)) / m
ma_i = ma
output ma_i
这种求移动平均数的方法确实很高效。但是,我们上面这个算法是基于所有温度值一次性给出的情况。假如我们正在算今年每天温度的移动平均数,每天的温度是一天一天给出的,而不是一次性给出的,上面的算法应该怎么修改呢?让我们来看修改后的算法:
input m
temp_i_day_ago = zeros((m))
def update_temperature(t):
for i in range(m - 1):
temp_i_day_ago = temp_i_day_ago
temp_i_day_ago = t
ma = 0
for i in range(n):
input t_i
update_temperature(t_i)
ma += (temp_i_day_ago - temp_i_day_ago) / m
ma_i = ma
output ma_i
由于我们不能提前知道每天的天气,我们需要一个大小为m的数组temp_i_day_ago记录前几天的天气,以计算m天移动平均数。
上述代码的时间复杂度还是有优化空间的。可以用更好的写法去掉update_temperature里的循环,把计算每天移动平均数的时间复杂度变为。但是,这份代码的空间复杂度是无法优化的。为了算m天移动平均数,我们必须要维护一个长度为m的数组,空间复杂度一定是。
对于一个变量的m移动平均数,的空间复杂度还算不大。但假如我们要同时维护l个变量的m移动平均数,整个算法的空间复杂度就是https://www.zhihu.com/equation?tex=O%28ml%29。在l很大的情况下,m对空间的影响是很大的。哪怕m取5这种很小的数,也意味着要多花4倍的空间去存储额外的数据。空间复杂度里这多出来的这个是不能接受的。
指数加权移动平均
作为移动平均数的替代,人们提出了指数加权移动平均数(Exponential Weighted Moving Average) 这种表示一段时期内数据平均值的指标。其计算公式为:
https://www.zhihu.com/equation?tex=v_i%3D%5Cbeta+v_%7Bi-1%7D+%2B+%281+-+%5Cbeta%29t_i
这个公式直观上的意义为:一段时间内的平均温度,等于上一段时间的平均温度与当日温度的加权和。
相比普通的移动平均数,指数平均数最大的好处就是减小了空间复杂度。在迭代更新这个新的移动平均数时,我们只需要维护一个当前平均数https://www.zhihu.com/equation?tex=v_i,一个当前的温度https://www.zhihu.com/equation?tex=t_i即可,空间复杂度为。
让我们进一步理解公式中的参数。把公式展开可得:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7Dv_i%26%3D%281+-+%5Cbeta%29t_i+%2B+%5Cbeta+v_%7Bi-1%7D+%5C%5Cv_i%26%3D%281+-+%5Cbeta%29t_i+%2B+%281+-+%5Cbeta%29%5Cbeta+t_%7Bi-1%7D+%2B%5Cbeta%5E2+v_%7Bi-2%7D+%5C%5C+v_i%26%3D%281+-+%5Cbeta%29t_i+%2B+%281+-+%5Cbeta%29%5Cbeta+t_%7Bi-1%7D+%2B+%281+-+%5Cbeta%29%5Cbeta+%5E2t_%7Bi-2%7D%2B+%5Cbeta%5E3+v_%7Bi-2%7D+%5C%5C...%5Cend%7Baligned%7D
从这个式子可以看出,之前数据的权重都在以的速度指数衰减。根据https://www.zhihu.com/equation?tex=%281-%5Cepsilon%29%5E%7B%5Cfrac%7B1%7D%7B%5Cepsilon%7D%7D+%5Capprox+%5Cfrac%7B1%7D%7Be%7D,并且我们可以认为一个数到了https://www.zhihu.com/equation?tex=%5Cfrac%7B1%7D%7Be%7D就小到可以忽视了,那么指数平均数表示的就是https://www.zhihu.com/equation?tex=%5Cfrac%7B1%7D%7B1-%5Cbeta%7D天内数据的平均情况。比如https://www.zhihu.com/equation?tex=%5Cbeta%3D0.9表示的是10天内的平均数据,https://www.zhihu.com/equation?tex=%5Cbeta%3D0.99表示的是100天内的平均数据。
偏差矫正
指数平均数存在一个问题。在刚刚初始化时,指数平均数的值可能不太正确,请看:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7Dv_1+%26%3D++%281+-+%5Cbeta%29t_1+%5C%5Cv_2+%26%3D++%281+-+%5Cbeta%29%5Cbeta+t_1+%2B%281+-+%5Cbeta%29t_2%5Cend%7Baligned%7D
让我们把每一项前面的权重加起来。对于https://www.zhihu.com/equation?tex=v_1,前面的权重和是https://www.zhihu.com/equation?tex=%281-%5Cbeta%29;对于https://www.zhihu.com/equation?tex=v_2,前面的权重和是https://www.zhihu.com/equation?tex=%281-%5Cbeta%29%28%5Cbeta%2B1%29。显然,这两个权重和都不为1。而计算平均数时,我们希望所有数据的权重和为1,这样才能反映出数据的真实大小情况。这里出现了权重上的“偏差”。
为了矫正这个偏差,我们应该想办法把权重和矫正为1。观察刚才的算式可以发现,第项的权重和如下:
https://www.zhihu.com/equation?tex=w_i+%3D+%281-%5Cbeta%29%281%2B%5Cbeta%2B%5Cbeta%5E2%2B...%5Cbeta%5Ei%29
根据等比数列求和公式,上式化简为:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7Dw_i+%26%3D+%281-%5Cbeta%29%5Cfrac%7B%281-%5Cbeta%5Ei%29%7D%7B%281-%5Cbeta%29%7D+%5C%5Cw_i+%26%3D+1-%5Cbeta%5Ei%5Cend%7Baligned%7D
为了令权重和为1,我们可以令每一项指数平均数都除以这个和,即用下面的式子计算矫正后的指数平均数https://www.zhihu.com/equation?tex=v_i%27:
https://www.zhihu.com/equation?tex=v_i%27%3D%5Cfrac%7Bv_i%7D%7B1-%5Cbeta%5Ei%7D
但是,在实践中,由于这个和https://www.zhihu.com/equation?tex=1-%5Cbeta%5Ei收敛得很快,我们不会特地写代码做这个矫正。
Momentum
Gradient Descent with Momentum (使用动量的梯度下降) 是一种利用梯度的指数加权移动平均数更新参数的策略。在每次更新学习率时,我们不用本轮梯度的方向作为梯度下降的方向,而是用梯度的指数加权移动平均数作为梯度下降的方向。即对于每个参数,我们用下式做梯度下降:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7DV_%7Bdw%7D%26%3D%5Cbeta+V_%7Bdw%7D%2B+%281-%5Cbeta%29dw+%5C%5CV_%7Bdb%7D%26%3D%5Cbeta+V_%7Bdb%7D%2B+%281-%5Cbeta%29db+%5C%5Cw+%26%3A%3D+w+-+%5Calpha+V_%7Bdw%7D+%5C%5Cb+%26%3A%3D+b+-+%5Calpha+V_%7Bdb%7D%5Cend%7Baligned%7D
也就是说,对于每个参数https://www.zhihu.com/equation?tex=p,我们用它的指数平均值https://www.zhihu.com/equation?tex=v_%7Bdp%7D代替https://www.zhihu.com/equation?tex=dp进行参数的更新。
使用梯度的平均值来更新有什么好处呢?让我们来看一个可视化的例子:
不使用 Momentum 的话,每次参数更新的方向可能变化幅度较大,如上图中的蓝线所示。而使用 Momentum 后,每次参数的更新方向都会在之前的方向上稍作修改,每次的更新方向会更加平缓一点,如上图的红线所示。这样,梯度下降算法可以更快地找到最低点。
在实现时,我们不用去使用偏差矫正。取0.9在大多数情况下都适用,有余力的话这个参数也可以调一下。
RMSProp 和 Adam
课堂上并没有对RMSProp的原理做过多的介绍,我们只需要记住它的公式就行。我会在其他文章中介绍这几项技术的原理。与 Momentum 类似,RMSProp(Root Mean Squared Propagation) 使用了某种移动平均值来平滑梯度的更新。其梯度下降公式如下:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7DS_%7Bdw%7D%26%3D%5Cbeta+S_%7Bdw%7D%2B+%281-%5Cbeta%29dw%5E2+%5C%5CS_%7Bdb%7D%26%3D%5Cbeta+S_%7Bdb%7D%2B+%281-%5Cbeta%29db%5E2+%5C%5Cw+%26%3A%3D+w+-+%5Calpha+%5Cfrac%7Bdw%7D%7B%5Csqrt%7BS_%7Bdw%7D%7D%7D+%5C%5Cb+%26%3A%3D+b+-+%5Calpha+%5Cfrac%7Bdb%7D%7B%5Csqrt%7BS_%7Bdb%7D%7D%7D%5Cend%7Baligned%7D
在编程实现时,我们应该给分母加一个极小值,防止分母出现0。
Adam (Adaptive Moment Estimation) 是 Momentum 与 RMSProp 的结合版。为了使用Adam,我们要先计算 Momentum 和 RMSProp 的中间变量:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7DV_%7Bdw%7D%26%3D%5Cbeta_1+V_%7Bdw%7D%2B+%281-%5Cbeta_1%29dw+%5C%5CV_%7Bdb%7D%26%3D%5Cbeta_1+V_%7Bdb%7D%2B+%281-%5Cbeta_1%29db+%5C%5CS_%7Bdw%7D%26%3D%5Cbeta_2+S_%7Bdw%7D%2B+%281-%5Cbeta_2%29dw%5E2+%5C%5CS_%7Bdb%7D%26%3D%5Cbeta_2+S_%7Bdb%7D%2B+%281-%5Cbeta_2%29db%5E2%5Cend%7Baligned%7D
之后,根据前面的偏差矫正,获得这几个变量的矫正值:
如前文所述,在实现时添加偏差矫正意义不大。估计这里加上偏差矫正是因为原论文加了。https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7DV_%7Bdw%7D%27%26%3D%5Cfrac%7BV_%7Bdw%7D%7D%7B1-%5Cbeta_1%5Et%7D+%5C%5CV_%7Bdb%7D%27%26%3D%5Cfrac%7BV_%7Bdb%7D%7D%7B1-%5Cbeta_1%5Et%7D+%5C%5CS_%7Bdw%7D%27%26%3D%5Cfrac%7BS_%7Bdw%7D%7D%7B1-%5Cbeta_2%5Et%7D+%5C%5CS_%7Bdb%7D%27%26%3D%5Cfrac%7BS_%7Bdb%7D%7D%7B1-%5Cbeta_2%5Et%7D+%5C%5C%5Cend%7Baligned%7D
最后,进行参数的更新:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7Dw+%26%3A%3D+w+-+%5Calpha+%5Cfrac%7BV_%7Bdw%7D%27%7D%7B%5Csqrt%7BS_%7Bdw%7D%27%7D%2B%5Cepsilon%7D+%5C%5Cb+%26%3A%3D+b+-+%5Calpha+%5Cfrac%7BV_%7Bdb%7D%27%7D%7B%5Csqrt%7BS_%7Bdb%7D%27%7D%2B%5Cepsilon%7D%5Cend%7Baligned%7D
和之前一样,这里的是一个极小值。在编程时添加,一般都是为了防止分母中出现0。
Adam是目前非常流行的优化算法,它的表现通常都很优秀。为了用好这个优化算法,我们要知道它的超参数该怎么调。在原论文中,这个算法的超参数取值如下:
https://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D%5Cbeta_1+%26%3D+0.9+%5C%5C%5Cbeta_2+%26%3D+0.999+%5C%5C%5Cepsilon+%26%3D+10%5E%7B-8%7D%5Cend%7Baligned%7D
绝大多数情况下,我们不用手动调这三个超参数。
学习率衰减
训练时的学习率不应该是一成不变的。在优化刚开始时,参数离最优值还差很远,选较大的学习率能加快学习速度。但是,经过了一段时间的学习后,参数离最优值已经比较近了。这时,较大的学习率可能会让参数错过最优值。因此,在训练一段时间后,减小学习率往往能够加快网络的收敛速度。这种训练一段时间后减小学习率的方法叫做学习率衰减。
其实学习率衰减只是一种比较宏观的训练策略,并没有绝对正确的学习率衰减方法。我们可以设置初始学习率https://www.zhihu.com/equation?tex=%5Calpha_0,之后按下面的公式进行学习率衰减:
https://www.zhihu.com/equation?tex=%5Calpha+%3D+%5Cfrac%7B1%7D%7B1+%2B+DecayRate+%5Cast+EpochNum%7D%5Calpha_0
这个公式非常简单,初始学习率会随着一个衰减率(DecayRate)和训练次数(EpochNum)衰减。
同样,我们还可以使用指数衰减:
https://www.zhihu.com/equation?tex=%5Calpha+%3D+0.95%5E%7BEpochNum%7D%5Calpha_0
或者其他一些奇奇怪怪的衰减方法(k是超参数):
https://www.zhihu.com/equation?tex=%5Calpha+%3D+%5Cfrac%7Bk%7D%7B%5Csqrt%7BEpochNum%7D%7D%5Calpha_0
甚至我们可以手动调学习率,每训练一段时间就把学习率调整成一个更小的常数。
总之,学习率衰减是一条启发性的规则。我们可以有意识地在训练中后期调小学习率。
局部最优值
在执行梯度下降算法时,局部最优值可能会影响算法的表现:在局部最优值处,各个参数的导数都是0。梯度是0(所有导数为0),意味着梯度下降法将不再更新了。
在待优化参数较少时,陷入局部最优值是一种比较常见的情况。而对于参数量巨大的深度学习项目来说,整个模型陷入局部最优值是一个几乎不可能发生的事情。某参数在梯度为0时,既有可能是局部最优值,也可能是局部最差值。不妨设两种情况的概率都是0.5。如果整个模型都陷入了局部最优值,那么所有参数都得处于局部最优值上。假设我们的深度学习模型有10000个参数,则一个梯度为0的点是局部最优值的概率是https://www.zhihu.com/equation?tex=0.5%5E%7B10000%7D,这是一个几乎不可能发生的事件。
所以,在深度学习中,更常见的梯度为0的点是鞍点(某处梯度为0,但不是局部最值)。在鞍点处,有很多参数都处于局部最差值上,只要稍微对这些参数做一些扰动,参数就会往更小的方向移动。因此,鞍点不会对学习算法产生影响。
在深度学习中,一种会影响学习速度的情况叫做“高原”(plateau)。在高原处,梯度的值一直都很小。只有跨过了这段区域,学习的速度才会快起来。这种情况的可视化结果如下:
总而言之,深度学习问题和简单的优化问题不太一样,不用过多担心局部最优值的问题。而高原现象确实会影响学习的速度。
总结
这周,我们围绕深度学习的优化算法,学习了许多提升梯度下降法性能的技术。让我们来捋一捋。
首先,我们可以在处理完一小批数据后就执行梯度下降,而不必等处理完整个数据集后再执行。这种算法叫分批梯度下降(mini-batch gradient descent)。这是一种对梯度下降法的通用改进方法,即默认情况下,这种算法都可以和其他改进方法同时使用。
之后,我们学习了移动平均的概念,知道移动平均值可以更平滑地反映数据在一段时间内的趋势。基于移动平均值,有 gradient descent with momentum 和 RMSProp 这两种梯度下降的改进方法。而现在非常常用的 Adam 优化算法是Momentum 和 RMSProp 的结合版。
最后,我们学习了学习率衰减的一些常见方法。
学完本课的内容后,我认为我们应该对相关知识达到下面的掌握程度:
[*]分批梯度下降
[*]了解原理
[*]掌握如何选取合适的 batch size
[*]高级优化算法
[*]了解移动平均数的思想
[*]了解 Adam 的公式
[*]记住 Adam 超参数的常见取值
[*]未来学习了编程框架后,会调用 Momentum,Adam 优化器
[*]学习率衰减
[*]掌握“学习率衰减能加速收敛”这一概念
[*]在训练自己的模型时,能够有意识地去调小学习率
[*]局部最优值
[*]不用管这个问题
学了这么多技术,不去实践一下可不行。在之后的笔记中,让我们使用高级梯度下降算法,再次挑战小猫分类任务。届时,我们将从头实现一个优化器类,并继承实现不同的优化算法。
周弈帆:吴恩达《深度学习专项》代码实战(六):用 Numpy 实现 Momentum, Adam 等优化算法
本文使用 WPL/s 发布 @GitHub
使用这个插件确实能有效提高 Markdown 在知乎上的编辑效率,但是公式中还是有很多<br>。希望知乎对Markdown 的支持能早日达到能用的程度。
页:
[1]