優化器 從SGD到 Adam

2021-10-17 14:37:24 字數 2668 閱讀 7806

所有的優化器都是可以套進這個基本框架的。

這裡的e指的是單位矩陣。sgd 沒有動量概念,因為一階動量就是當前梯度,二階梯度就是單位矩陣。

缺點:容易陷入區域性最優。由於sgd只考慮當前時刻的梯度,在區域性最優點的當前梯度為0。由計算公式可知,此時引數不再進行更新,故陷入區域性最優的狀態。

顯而易見,引入歷史梯度值,引入動量(momentum)的概念可以幫助我們跳出鞍點。

咱比如要算 θ

t\theta_t

θt​ 的平均,一般大家就用相加求和/總數的方法。

而ema(指數滑動平均)是指數式的平均。

第一行最重要,方便理解。

當前時刻 v

tv_t

vt​ 等於 衰減因子β

\beta

β 與上乙個時刻的值 vt−

1v_vt−1

​ 的乘積 加上 (1−

β)×θ

t(1-\beta) \times \theta_t

(1−β)×

θt​。這個式子可以遞迴化簡為第二行,也就是把θ

t\theta_t

θt​的歷史做乙個指數的求和,所以很形象的稱為滑動平均。

而對於那些權重小於 1

e\frac

e1​的項,我們可以忽略不記。然後可以數學推導(極限),指數滑動平均肯定有個範圍啊,就是到底與多寬的歷史時刻有關,答案是 11−

β\frac

1−β1

​,所以一般β

=0.999

\beta=0.999

β=0.99

9的時候,就是1000個時刻取指數平均。

此時,我們知道了ema,就可以把 θ

t\theta_t

θt​換成g

tg_t

gt​,目的是引入梯度的歷史值,進而可以計算出梯度的動量(momentum)。

當t比較小的時候,ema會把平均值拉的很小。

所以這裡大家一般都會引入乙個修正因子1−β

t1-\beta^t

1−βt

,我們可以分析,

在sgd上,加入一階動量,還是沒有引入二階動量。

這裡沒有嚴格使用ema,具體為,沒有使用1−β

t1-\beta^t

1−βt

,而是使用了 η

\eta

η,無傷大雅,原理上一致。

同樣使用了一階動量而沒有使用二階動量。沒有使用 (1−

β)×g

t(1-\beta) \times g_t

(1−β)×

gt​,而是**t-1時刻下一時刻梯度,沒有引入當前的觀測值,可以理解為跟著慣性走了一步。

加下來的都是引入二階後的方法。二階動量出現,才說明了自適應學習率的優化演算法時代到來。

如圖,我們希望經常被刺激到的神經元引數更新幅度小一些,那些不經常被用到的神經元更新的慢一點。

有一種歸一化的感覺。對於那些更新幅度很大的引數,通常歷史累計梯度的平方和會很大(可以理解為能量很大),所以希望能量大的更新慢一點,能量小的更新快一點。

所以,如圖式一,計算以往梯度的平方和作為二階動量,梯度本身作為一階動量,就可以得到第二行的式子。此時,二階動量大的引數就會更新的小一點啦。

缺點:隨著時間步的拉長,歷史累計梯度平方和會越來越大,這樣會使得所有維度引數的學習率都不斷減小(單調遞減),無論更新幅度如何。

顯然,一直累計肯定不好,這裡可以想到momentum,利用ema不就好了嗎?

delta 就是乙個小範圍嘛,就是使用了歷史一部分梯度。

momentum 在sgd 基礎上增加了一階動量,adagrad 在sgd 基礎上增加了二階動量, 把一階和二階動量都使用了就是adam。

adam相關的優化器

adam 自出道以來,就一直是最流行的深度學習優化器,哪怕現在其實已經有幾種可能更好用的優化器 如果將 adam 優化出現以來產生的關於優化過程的有趣想法按時間順序排列的話,結果如下 這個來自 andrej karpathy 的笑話或多或少是我深度學習專案的一套流程。除非把具有學習率硬編碼的 直接從...

Pytorch中adam優化器的引數問題

之前用的adam優化器一直是這樣的 alpha optim torch.optim.adam model.alphas config.alpha lr,betas 0.5,0.999 weight decay config.alpha weight decay 沒有細想內部引數的問題,但是最近的工作...

PHP優化 從語言到業務

經常有人說php速度慢,其實語言層面的速度差異和實際的業務相比,不在乙個數量級。業務的瓶頸往往在於io,而不是cpu。單引號和雙引號 單引號不解析字串裡的變數,而雙引號會解析,如果需要大量處理字串,建議用單引號和字串連線符 和 會進行型別轉換,比如 1 和1 用 為真,而 為假,如果型別相同的話,使...