參數(shù)的更新
神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí)目的是找到使損失函數(shù)的值盡可能小的參數(shù),解決這個問題的過程稱為最優(yōu)化(optimization)
梯度下降法在每次迭代時,需要使用所有的訓(xùn)練數(shù)據(jù),這給求解大規(guī)模數(shù)據(jù)的優(yōu)化問題帶來了挑戰(zhàn)。
1.SGD
使用參數(shù)的梯度,沿梯度方向更新參數(shù),并重復(fù)這個步驟多次,從而逐漸靠
近最優(yōu)參數(shù),這個過程稱為隨機(jī)梯度下降法(stochastic gradient descent),
簡稱SGD。SGD是一個簡單的方法,不過比起胡亂地搜索參數(shù)空間,也算是“聰
明”的方法。
隨機(jī)梯度下降用單個訓(xùn)練樣本的損失來近似平均損失。隨機(jī)梯度下降法用單個訓(xùn)練數(shù)據(jù)即可對模型參數(shù)進(jìn)行一次更新,大大加快了收斂速率。該方法也非常適用于數(shù)據(jù)源源不斷到來的在線更新場景。
SGD的策略是:朝著當(dāng)前所在位置的坡度最大的方向前進(jìn)。
用右邊的值更新左邊的值。
SGD是朝著梯度方向只前進(jìn)一定距離的方法。
class SGD:
def __init__(self,lr=0.01):
self.lr = lr
def update(self, params, grads):
for key in params.keys():
params[key] -= self.lr*grads[key]
參數(shù) params 和 grads (與之前的神經(jīng)網(wǎng)絡(luò)的實(shí)現(xiàn)一樣)是字典型變量,按 params['W1'] 、 grads['W1'] 的形式,分別保存了權(quán)重參數(shù)和它們的梯度。
SGD的缺點(diǎn)
如果函數(shù)的形狀非均向,比如呈延伸狀,搜索的路徑就會非常低效。SGD低效的根本原因是,梯度的方向并沒有指向最小值的方向。
1.1 小批量梯度下降法
為了降低隨機(jī)梯度的方差,從而使得迭代算法更加穩(wěn)定,也為了充分利用高度優(yōu)化的矩陣運(yùn)算操作,在實(shí)際應(yīng)用中我們會同時處理若干訓(xùn)練數(shù)據(jù),該方法被稱為小批量梯度下降法(Mini-Batch Gradient Descent)。
注意:
(1)如何選取參數(shù)批量數(shù)據(jù)的個數(shù)m?在不同的應(yīng)用中,最優(yōu)的m通常會不一樣,需要通過調(diào)參選取。一般m取2的冪次時能充分利用矩陣運(yùn)算操作,所以可以在2的冪次中挑選最優(yōu)的取值,例如32、64、128、256等。
(2)如何挑選m個訓(xùn)練數(shù)據(jù)?為了避免數(shù)據(jù)的特定順序給算法收斂帶來的影
響,一般會在每次遍歷訓(xùn)練數(shù)據(jù)之前,先對所有的數(shù)據(jù)進(jìn)行隨機(jī)排序,然后在每
次迭代時按順序挑選m個訓(xùn)練數(shù)據(jù)直至遍歷完所有的數(shù)據(jù)。
(3)如何選取學(xué)習(xí)速率α?為了加快收斂速率,同時提高求解精度,通常會
采用衰減學(xué)習(xí)速率的方案:一開始算法采用較大的學(xué)習(xí)速率,當(dāng)誤差曲線進(jìn)入平
臺期后,減小學(xué)習(xí)速率做更精細(xì)的調(diào)整。最優(yōu)的學(xué)習(xí)速率方案也通常需要調(diào)參才
能得到。
隨機(jī)梯度下降無法準(zhǔn)確察覺出梯度的微笑變化,就很可能繞彎路或者停下來。
解決之道:慣性保持和環(huán)境感知
2.Momentum
想象一下紙團(tuán)在山谷和鞍點(diǎn)處的運(yùn)動軌跡,在山谷中紙團(tuán)受重力作用沿山道滾下,兩邊是不規(guī)則的山壁,紙團(tuán)不可避免地撞在山壁,由于質(zhì)量小受山壁彈力的干擾大,從一側(cè)山壁反彈回來撞向另一側(cè)山壁,結(jié)果來回震蕩地滾下;如果當(dāng)紙團(tuán)來到鞍點(diǎn)的一片平坦之地時,還是由于質(zhì)量小,速度很快減為零。紙團(tuán)的情況和隨機(jī)梯度下降法遇到的問題簡直如出一轍。直觀地,如果換成一個鐵球,當(dāng)沿山谷滾下時,不容易受到途中旁力的干擾,軌跡會更穩(wěn)更直;當(dāng)來到鞍點(diǎn)中心處,在慣性作用下繼續(xù)前行,從而有機(jī)會沖出這片平坦的陷阱。因此,有了動量方法,模型參數(shù)的迭代公式為
(6.3)
(6.4)
當(dāng)前梯度相當(dāng)于加速度,當(dāng)前的v要依賴于上一時刻的v和加速度。這里新出現(xiàn)了一個變量v,對應(yīng)物理上的速度。式(6.3)表示了物體在梯度方向上受力,在這個力的作用下,物體的速度增加這一物理法則。
class Momentum:
def __init__(self, lr=0.01, momentum=0.9):
self.lr = lr
self.momentum = momentum
self.v = None
def update(self, params, grads):
if self.v is None:
self.v = {}
for key, val in params.items():
self.v[key] = np.zeros_like(val)
for key in params.keys():
self.v[key] = self.momentum*self.v[key] - self.lr*grads[key]
params[key] += self.v[key]
沿山谷滾下的鐵球,會受到沿坡道向下的力和與左右山壁碰撞的彈力。向下的力
穩(wěn)定不變,產(chǎn)生的動量不斷累積,速度越來越快;左右的彈力總是在不停切換,
動量累積的結(jié)果是相互抵消,自然減弱了球的來回震蕩。
3.AdaGrad
慣性的獲得基于歷史信息,除了從歷史信息獲得慣性,還能對周圍環(huán)境進(jìn)行感知。
我們希望更新頻率低的參數(shù)可以擁有較大的更新步幅,而更新頻率高的參數(shù)的步幅可以減小。
AdaGrad采用了學(xué)習(xí)率衰減的思想,為參數(shù)的每個元素適當(dāng)?shù)卣{(diào)整學(xué)習(xí)率。
AdaGrad方法采用“歷史梯度平方和”來衡量不同參數(shù)的梯度的稀疏性,取值越小表明越稀疏。
其中 表示(t+1)時刻的參數(shù)向量
的第i個參數(shù),
表示k時刻的梯度向量
的第i個維度(方向)。另外,分母中求和的形式實(shí)現(xiàn)了退火過程,這是很多優(yōu)化技術(shù)中常見的策略,意味著隨著時間推移,
是以前所有梯度的平方和,也就是說,以前的梯度大的(變動大的),它的學(xué)習(xí)速率
越來越小,從而保證了算法的最終收斂。
AdaGrad會記錄過去所有梯度的平方和。因此,學(xué)習(xí)越深入,更新的幅度就越小。實(shí)際上,如果無止境地學(xué)習(xí),更新量就會變?yōu)?,完全不再更新。為了改善這個問題,可以使用RMSProp 方法。RMSProp方法并不是將過去所有的梯度一視同仁地相加,而是逐漸地遺忘過去的梯度,在做加法運(yùn)算時將新梯度的信息更多地反映出來。這種操作從專業(yè)上講,稱為“指數(shù)移動平均”,呈指數(shù)函數(shù)式地減小過去的梯度的尺度。
h保存了以前的所有梯度值的平方和。
class AdaGrad:
def __init__(self,lr=0.01):
self.lr = lr
self.h = None
def update(self,params,grads):
if self.h is None:
self.h = {}
for key,val in params.items():
self.h[key] = np.zeros_like(val)
for key in params.keys():
self.h[key] += grads[key] * grads[key]
params[key] -= self.lr * grads[key] / (np.sqrt(self.h[key]) + 1e-7)
4. Adam
Momentum參照小球在碗中滾動的物理規(guī)則進(jìn)行移動,AdaGrad為參數(shù)的每個元素適當(dāng)?shù)卣{(diào)整更新步伐。Adam 方法將兩者結(jié)合。
一方面,Adam記錄梯度的一階矩(first moment),即過往梯度與當(dāng)前梯度的平均,這體現(xiàn)了慣性保持;另一方面,Adam還記錄梯度的二階矩(second moment),即過往梯度平方與當(dāng)前梯度平方的平均,這類似AdaGrad方法,體現(xiàn)了環(huán)境感知能力,為不同參數(shù)產(chǎn)生自適應(yīng)的學(xué)習(xí)速率。一階矩和二階矩采用類似于滑動窗口內(nèi)求平均的思想進(jìn)行融合,即當(dāng)前梯度和近一段時間內(nèi)梯度的平均值,時間久遠(yuǎn)的梯度對當(dāng)前平均值的貢獻(xiàn)呈指數(shù)衰減。
其中β 1 ,β 2 為衰減系數(shù),m t 是一階矩,v t 是二階矩。
如何理解一階矩和二階矩呢?一階矩相當(dāng)于估計(jì) :由于當(dāng)下梯度 是隨機(jī)
采樣得到的估計(jì)結(jié)果,因此更關(guān)注它在統(tǒng)計(jì)意義上的期望;二階矩相當(dāng)于估計(jì)
,這點(diǎn)與AdaGrad方法不同,不是 從開始到現(xiàn)在的加和,而是它的期望。它
們的物理意義是,當(dāng)||m t ||大且v t 大時,梯度大且穩(wěn)定,這表明遇到一個明顯的大
坡,前進(jìn)方向明確;當(dāng)||m t ||趨于零且v t 大時,梯度不穩(wěn)定,表明可能遇到一個峽
谷,容易引起反彈震蕩;當(dāng)||m t ||大且v t 趨于零時,這種情況不可能出現(xiàn);當(dāng)||m t ||趨于零且v t 趨于零時,梯度趨于零,可能到達(dá)局部最低點(diǎn),也可能走到一片坡度極緩的平地,此時要避免陷入平原(plateau)。另外,Adam方法還考慮了m t ,v t 在零初始值情況下的偏置矯正。具體來說,Adam的更新公式為
其中,,
參考書籍:《百面機(jī)器學(xué)習(xí)》、《深度學(xué)習(xí)入門 基于Python的理論與實(shí)現(xiàn)》