Deep Learning模型中常見的optimizer優化器演算法總結

BGoodHabit發表於2020-10-01

1. 優化演算法在DL中的挑戰

1.1 優化演算法定義

在一個深度學習問題中,我們首先會定義一個損失函式(loss function),一旦有了損失函式,我們就可以用優化演算法去最小化這個損失函式的loss值。而深度學習中絕大多數目標函式都很複雜,因此,很多優化問題並不存在解析解,而需要使用基於數值方法的優化演算法找到近似解。

1.2 挑戰:區域性最小值與鞍點

x 0 x_0 x0是函式 f ( x ) f(x) f(x)的區域性最小值也就是說在 x 0 x_0 x0附近, f ( x 0 ) f(x_0) f(x0)是最小值,但相對於全域性範圍, f ( x 0 ) f(x_0) f(x0)並不是全域性最小值。而深度學習模型的目標函式可能有若干區域性最優值,當一個優化問題的數值解在區域性最優解附近時,由於目標函式有關解的梯度接近或變為0,最終迭代求得的數值解可能只令目標函式區域性最小化而非全域性最小化。如下圖所示:
在這裡插入圖片描述
除了區域性最優解外,同時,還有一種情況會使得梯度接近或變成0,這個點叫鞍點(saddle point),例如函式 f ( x ) = x 3 f(x)=x^3 f(x)=x3,在 x = 0 x=0 x=0的時候,梯度為0,但該點是一個鞍點,如下圖所示:
在這裡插入圖片描述
雖然在深度學習中,找到目標函式的全域性最優解很難,但是一些常用的優化演算法,在很多實際問題中都能夠訓練出有效的深度學習模型,接下來,會對這幾種優化演算法做一個介紹。

2. 常見的優化演算法

2.1 梯度下降 (gradient descent)

2.1.1 梯度下降演算法可以降低目標函式值原因

首先大多數人可能會有過這樣的疑問:為什麼梯度下降演算法可以降低目標函式值?
讓我們來做一個簡單的推導,假設有一個連續可導函式 f ( x ) f(x) f(x),給定一個足夠小的數 ε \varepsilon ε,根據泰勒展開式,得到以下近似等式:
f ( x + ε ) ≈ f ( x ) + ε f ′ ( x )    ( 1 ) f(x+\varepsilon) \approx f(x)+\varepsilon f^{'}(x) \text{ }\text{ } (1) f(x+ε)f(x)+εf(x)  (1)
這裡 f ′ ( x ) f^{'}(x) f(x)是函式在 x x x處的梯度,一維函式的梯度是一個標量,也稱導數。
ε = − a f ′ ( x ) \varepsilon = -af^{'}(x) ε=af(x),其中常數 a > 0 a>0 a>0,且使得 ∣ a f ′ ( x ) ∣ \begin{vmatrix} a f^{'}(x) \end{vmatrix} af(x)足夠小,則上述等式(1)變換形式如下:
f ( x − a f ′ ( x ) ) ≈ f ( x ) − a f ′ ( x ) 2    ( 2 ) f(x-a f^{'}(x)) \approx f(x) - af^{'}(x)^{2} \text{ }\text{ } (2) f(xaf(x))f(x)af(x)2  (2)
如果導數 f ′ ( x ) ≠ 0 f^{'}(x) \ne 0 f(x)=0,那麼 a f ′ ( x ) 2 > 0 af^{'}(x)^{2} > 0 af(x)2>0,則上述(2)等式變換形式如下:
f ( x − a f ′ ( x ) ) < ≈ f ( x ) f(x-af^{'}(x)) <{\approx} f(x) f(xaf(x))<f(x)
也就是說,通過 x ← x − a f ′ ( x ) x \gets x-af^{'}(x) xxaf(x),來迭代 x x x,函式 f ( x ) f(x) f(x)的值可能會降低。因此在平時訓練深度學習模型時,我們會初始化變數值 x x x,然後設定一個學習率 a a a來不斷迭代 x x x,直到到達停止條件,比如loss值足夠小,或者試驗指標已經不再提高等。
下面通過實現一個簡單的函式來體驗下梯度下降過程,假如我們的目標函式是 f ( x ) = x 2 f(x)=x^2 f(x)=x2,我們知道最小化 f ( x ) f(x) f(x)的解是 x = 0 x=0 x=0,用梯度下降法,假設初始 x = 10 x=10 x=10,並設學習率 a = 0.2 a=0.2 a=0.2,則10次迭代後, x x x的值已經和最優解十分接近了,如下python程式碼演示:

# -*-coding:utf8 -*-
import sys

def gd(rate, epoch=10):
	'''
		y=x*x函式,梯度求解過程驗證
	'''
	x = 10
	results = [x]
	for i in range(epoch):
		x -= rate*2*x
		results.append(x)
	print('epoch %d, x: %f:'%(epoch,x))
	return results

epoch 10, x: 0.060466

如下圖為自變數 x x x的迭代過程圖:
在這裡插入圖片描述

2.1.2 學習率設定

學習率是一個超引數,需要人工設定,如果使用過小的學習率,學習過程較緩慢,需要更多次迭代, x x x才能夠得到較好的解。函式 f ( x ) = x 2 f(x)=x^2 f(x)=x2,若設定學習率 a = 0.05 a=0.05 a=0.05,則10次迭代後,x的值和最優解還存在較大的差距,這是10次後的結果值:
在這裡插入圖片描述

自變數 x x x的迭代過程圖形如下:
在這裡插入圖片描述
相反,如果學習率 a a a設定過大,那麼會出現什麼現象呢?如果學習率過大,上述的假設 ∣ a f ′ ( x ) ∣ \begin{vmatrix} a f^{'}(x) \end{vmatrix} af(x)很小不成立,則最開始的一階泰勒展開公式不再成立,則無法保證迭代 x x x會降低 f ( x ) f(x) f(x)的值,還是以上面的例子為例,假設設定學習率 a = 1.1 a=1.1 a=1.1,則 x x x不斷越過最優解 x = 0 x=0 x=0並逐漸發散。
在這裡插入圖片描述
x x x的迭代變化過程如下圖所示:
在這裡插入圖片描述

2.2 隨機梯度下降 (stochastic gradient descent)

2.2.1 方法

在深度學習中,目標函式通常是訓練樣本資料集中所有樣本的損失函式的平均。假設 f i ( x ) f_i(x) fi(x)是第 i i i個訓練樣本的損失函式, n n n是總樣本數, x x x是模型的引數向量,那麼目標函式定義為:
f ( x ) = 1 n ∑ i = 1 n f i ( x ) f(x) = \frac{1}{n} \sum_{i=1}^{n}f_i(x) f(x)=n1i=1nfi(x)
目標函式在 x x x處的梯度計算為:
∇ f ( x ) = 1 n ∑ i = 1 n ∇ f i ( x ) \nabla f(x) = \frac{1}{n}\sum_{i=1}^{n}\nabla f_i(x) f(x)=n1i=1nfi(x)
如果使用梯度下降,每次自變數迭代的計算開銷為 O ( n ) O(n) O(n),若樣本量 n n n很大時,每次迭代開銷很大。
而隨機梯度下降就是為了減少每次迭代的計算開銷,在隨機梯度下降的每次迭代中,我們隨機均勻取樣一個樣本索引 i ∈ 1 , 2 , . . . , n i \in {1,2,...,n} i1,2,...,n,並計算梯度 ∇ f i ( x ) \nabla f_i(x) fi(x)來迭代 x x x:
x ← x − a ∇ f i ( x ) x \gets x - a\nabla f_i(x) xxafi(x)
所以每次迭代的計算開銷從 O ( n ) O(n) O(n)降低到 O ( 1 ) O(1) O(1)

2.2.2 總結

總結兩點:

  • 學習率過大或過小都是不合理的,平時可以根據經驗和試驗設定一個較合理的值
  • 使用適當的學習率,沿著梯度反方向更新自變數可能降低目標函式值

2.3 批量隨機梯度下降 ( batch gradient descent)

Batch Renormalization: Towards Reducing Minibatch Dependence in Batch-Normalized Models

2.3.1 方法

梯度下降和隨機梯度下降一個計算完整個資料集梯度,再進行引數變數的更新,一個隨機取樣一個樣本計算梯度,再進行引數變數的更新。梯度下降每次更新引數變數計算開銷代價太大,而隨機梯度每次更新引數變數容易受單樣本影響,使得學習過程變得困難,不夠平滑。所以,批量梯度下降是這兩者方法的折中,開銷代價既沒有梯度下降大,學習過程也比隨機梯度方法更加平滑。
從名字可知,批量隨機梯度每次隨機取樣一個批量,也就是平時在訓練深度學習模型過程中的一個batch樣本來計算梯度。

2.4 Momentum

On the importance of initialization and momentum in deep learning

2.4.1 方法

假設我們有一個二維向量輸入的目標函式 f ( x ) = 0.1 x 1 2 + 2 x 2 2 f(x)=0.1x_1^2+2x_2^2 f(x)=0.1x12+2x22,實現這個目標函式的梯度下降,程式碼如下所示:

def function(x1,x2):
	return 0.1 * x1 ** 2 + 2 * x2 ** 2

def gd_f(x1, x2, a):
	return (x1 - a * 0.2 * x1, x2 - a * 4 * x2)

假設我們令學習率 a = 0.4 a=0.4 a=0.4, 引數更新迭代的圖形變化如下:
在這裡插入圖片描述
由於目標函式在 x 2 x_2 x2方向比在 x 1 x_1 x1方向的斜率更大,從圖中也可以看出,梯度下降迭代自變數在 x 2 x_2 x2方向比在 x 1 x_1 x1方向移動幅度更大,為了避免自變數 x 2 x_2 x2方向上目標函式越過最優解,需要調小學習率,但是,在 x 1 x_1 x1方向上,朝最優解移動會變慢。若將學習率再調大一些 a = 0.6 a=0.6 a=0.6,在 x 2 x_2 x2方向上發散,越過最優解,如下圖所示:
在這裡插入圖片描述
而動量(momentum)方法就是解決上述梯度下降問題。數學公式定義為如下:
v t = β v t − 1 + g t v_t = \beta v_{t-1} + g_{t} vt=βvt1+gt
其中 β ∈ ( 0 , 1 ) \beta \in (0,1) β(0,1) v v v叫做 momentum,讓我們對 v v v進行迴圈展開得到如下表示式:
v t = β 2 v t − 2 + β g t − 1 + g t = . . . , = ∑ i = 0 t − 1 β i g t − i v_t = \beta^2v_{t-2} + \beta g_{t-1} + g_{t} = ..., = \sum_{i=0}^{t-1}\beta^i g_{t-i} vt=β2vt2+βgt1+gt=...,=i=0t1βigti
而當時間 t t t達到極限的時候,有如下公式:
∑ i = 0 ∞ β i = 1 1 − β \sum_{i=0}^{\infty}\beta^i =\frac{1}{1-\beta} i=0βi=1β1
而基於momentum方法的梯度更新公式如下:
v t ← β v t − 1 + g t v_t \gets \beta v_{t-1} + g_{t} vtβvt1+gt
x t ← x t − 1 − η v t x_t \gets x_{t-1} - \eta v_t xtxt1ηvt
β = 0 \beta =0 β=0時,就是最初的梯度下降演算法了,基於momentum方法,更新的梯度不再是當前最近一個step t t t計算的梯度,而是根據歷史前時間 t t t步數的梯度加權之後,但離當前時間 t t t越前的時間,由於 β 2 \beta^2 β2指數形式,對當前會產生很小甚至不產生作用,也就是說與當前時間 t t t越近, β i \beta^i βi越大,所以越近的梯度產生較大的比重。上述函式 f ( x ) = 0.1 x 1 2 + 2 x 2 2 f(x)=0.1x_1^2+2x_2^2 f(x)=0.1x12+2x22,momentum方法梯度更新程式碼如下:

def momentum(beta, a, x1, x2, v1, v2):
	v1 = beta * v1 + 0.2 * v1
	v2 = beta * v2 + 4 * v2
	return x1 - eta * v1, x2 - eta * v2, v1, v2

我們還是設學習率 η = 0.6 \eta=0.6 η=0.6 β = 0.5 \beta=0.5 β=0.5,則基於momentum方法的引數更新過程如下圖所示:
在這裡插入圖片描述
我們可以看到,和上述我們使用過的梯度下降演算法一樣的學習率 η = 0.6 \eta=0.6 η=0.6,momentum方法也能夠較好的收斂。

2.4.2 總結

總結三點:

  • 動量法使用了指數加權移動平均的思想,它將過去的梯度做了加權平均,且權重按照時間步指數進行刪減,離當前越近步的梯度權重越大
  • 動量法使得相鄰的自變數更新在方向上更加一致
  • 動量法依賴指數加權移動平均使得自變數的更新方向更加一致,從而降低發散的可能
  • 在動量法中,自變數在各個方向上的移動幅度不僅取決於當前梯度,還取決於過去的各個梯度在各個方向上是否一致

2.5 Adagrad

Adaptive Subgradient Methods for
Online Learning and Stochastic Optimization∗

2.5.1 方法

上述的幾個優化演算法在相同的時間步裡,目標函式對變數的每個元素都使用相同的學習率進行更新迭代。但是,實際情況中,可能會有很多稀疏特徵,訓練模型過程中,出現頻率高的特徵,學習率可能需要慢慢減少,但是一些比較低頻率出現的特徵,可能需要大一點的學習率。所以,Afagrad根據自變數在每個維度的梯度值的大小來調整各個維度上的學習率,從而避免統一的學習率難以適應所有維度的問題
從Adagrad演算法的核心思想出發,在計算各自變數值的時候,我們可以基於批量隨機梯度方法調整如下:

g t = ∂ w l ( y t , f ( x t , w ) ) g_t = \partial_wl(y_t, f(x_t, w)) gt=wl(yt,f(xt,w))
s t = s t − 1 + g t 2 s_t = s_{t-1} + g_t^2 st=st1+gt2
w t = w t − 1 − η s t + ε g t w_t = w_{t-1} - \frac{\eta}{\sqrt{s_t+\varepsilon}}g_t wt=wt1st+ε ηgt
其中 η \eta η是學習率, ε \varepsilon ε是一個很小的常量,比如 1 0 − 6 10^{-6} 106,為了維持數值穩定性,從上面三個公式可以看出,每個自變數的學習率 η s t + ε \frac{\eta}{\sqrt{s_t+\varepsilon}} st+ε η會根據歷史累計梯度的平方進行變化,若之前的歷史累積梯度較大,則學習率會慢慢變小,相反,則會慢慢變大,初始 s 0 = 0 s_0=0 s0=0
接下來,讓我們仍然以目標函式 f ( x ) = 0.1 x 2 + 2 x 2 2 f(x)=0.1x^2+2x_2^2 f(x)=0.1x2+2x22為例,看Adagrad演算法是怎樣對自變數進行迭代的,梯度更新程式碼如下:

import math
eta = 0.4
def adagrad(x1, x2, s1, s2):
	g1, g2, eps = 0.2*x1, 4*x2, 1e-6
	s1 += g1 ** 2
	s2 += g2 ** 2
	x1 -= eta / math.sqrt(s1 + eps) * g1
	x2 -= eta / math.sqrt(s2 + eps) * g2
	return x1, x2, s1, s2

我們還是按照學習率為0.4,adagrad優化演算法圖形如下:
在這裡插入圖片描述
可以看出,由於 s t s_t st的累加效果,自變數隨著時間步拉長,變化幅度越來越小。如果調大學習率為2,自變數更為迅速地逼近了最優解,如下圖所示:
在這裡插入圖片描述

2.5.2 總結

  • Adagrad演算法會根據每個變數的歷史累計梯度,不斷降低(不變)學習率的大小
  • 歷史梯度累積越大,則學習率下降的越快
  • Adagrad演算法對稀疏特徵較有效,當頻率出現較低的特徵在學習過程中需要較大的學習率
  • Adagrad演算法對於學習率降低有點過於極端,如果一開始某個變數的學習率很大,但是一直沒學好,則後面學習率降低很小,很有可能不會再找到最優解

2.6 RMSProp

divide the gradient by a running average of its recent magnitude. COURSERA

2.6.1 方法

由於在Adagrad演算法中,我們是通過對之前時間步 t t t的梯度平方累加而不斷降低學習率。如果學習率在一開始早期迭代沒有到達最佳值,到後面由於學習率太小,可能很難再找到合適的解。
為了解決Adagrad演算法後期迭代學習率過小,而還沒有達到最優解的這種問題,從上述Adagrad公式可以看出,一種方法是最後的 s t s_t st可以求個時間 t t t的平均, s t / t s_t/t st/t,這樣 s t s_t st不會因為時間 t t t的累積,一直在變大,而導致學習率一直在下降。但是這種求平均方式學習過程很緩慢。可以用一個類似的平均方法取代,在前面講解的momentum方法中使用過的指數加權移動平均。RMSProp更新迭代的數學公式如下:
s t ← γ s t − 1 + ( 1 − γ ) g t 2 s_t \gets \gamma s_{t-1} + (1-\gamma)g_t^2 stγst1+(1γ)gt2
x t ← x t − 1 − η s t + ε ⊙ g t x_t \gets x_{t-1} - \frac{\eta}{\sqrt{s_t+\varepsilon}}⊙g_t xtxt1st+ε ηgt
常量 ε > 0 \varepsilon>0 ε>0,用來保證除數不為0或者不會除以很小的數,維持數值穩定。讓我們對 s t s_t st展開,得到如下形式:
s t = ( 1 − γ ) g t 2 + γ s t − 1 = ( 1 − γ ) ( g t 2 + γ g t − 1 2 + γ 2 g t − 2 2 + . . . , ) s_t = (1-\gamma)g_t^2+\gamma s_{t-1}=(1-\gamma)(g_t^2+\gamma g_{t-1}^2 +\gamma^2g_{t-2}^2+...,) st=(1γ)gt2+γst1=(1γ)(gt2+γgt12+γ2gt22+...,)
1 + γ + γ 2 + . . . , = 1 1 − γ 1+\gamma+\gamma^2+...,=\frac{1}{1-\gamma} 1+γ+γ2+...,=1γ1,因此並不是隨著時間增加, s t s_t st一直增加,因為隨著時間增加,梯度按照最近的指數加權平均,可以看做最近時間步 1 1 − γ \frac{1}{1-\gamma} 1γ1的梯度指數加權平均。
還是以函式 f ( x ) = 0.1 x 1 2 + 2 x 2 2 f(x)=0.1x_1^2+2x_2^2 f(x)=0.1x12+2x22為例,迭代程式碼如下:

import math
eta, gamma = 0.4, 0.9
def Rmsprop(x1, x2, s1, s2):
	g1, g2, eps = 0.2 * x1, 4 * x2, 1e-6
	s1 = gamma * s1 + (1 - gamma) * g1 **2
	s2 = gamma * s2 + (1 - gamma) * g2 **2
	x1 -= eta / math.sqrt(s1 + eps) * g1
	x2 -= eta / math.sqrt(s2 + eps) * g2
	return x1, x2, s1, s2

我們還是用學習率為0.4,在Adagrad迭代方法中,後期自變數移動幅度較小,而下圖是RMSProp優化迭代過程,相同的迭代條件下,收斂速度更快。
在這裡插入圖片描述

2.6.2 總結

  • RMSProp演算法和Adagrad演算法十分相近,不同點在於,RMSProp演算法使用指數加權移動平均來調整學習率,保證了學習率並不會一直單調降低
  • 係數 γ \gamma γ決定了累積歷史多久時間步的梯度值更新引數 s t s_t st

2.7 AdaDelta

ADADELTA: AN ADAPTIVE LEARNING RATE METHOD

2.7.1 方法

Adadelta是AdaGrad演算法的一種變體,類似RMSProp演算法,主要針對AdaGrad後期迭代因為學習率降低的太小,可能較難找到最優解問題而做的改進,同時Adadelta沒有學習率這個超引數。
Adadelta保留了兩個狀態變數, s t s_t st儲存了歷史梯度變化情況, Δ x t \Delta x_t Δxt儲存的是歷史自變數變化情況。所以具體數學公式如下:
s t = ρ s t − 1 + ( 1 − ρ ) g t 2 s_t = \rho s_{t-1} + (1-\rho)g_t^2 st=ρst1+(1ρ)gt2

g t ′ = Δ x t − 1 + ε s t + ε g_t^{'}=\frac{\sqrt{\Delta x_{t-1} + \varepsilon}}{\sqrt{s_t+\varepsilon}} gt=st+ε Δxt1+ε
Δ x t = ε Δ x t − 1 + ( 1 − ε ) g t ′ 2 \Delta x_t = \varepsilon \Delta x_{t-1} + (1-\varepsilon)g_t^{{'}^2} Δxt=εΔxt1+(1ε)gt2
x t = x t − 1 − g t ′ x_t = x_{t-1} - g_t^{'} xt=xt1gt
其中 ε \varepsilon ε是一個很小的數值,比如 1 0 − 5 10^{-5} 105,為了維持計算的穩定性。從上面公式可以看出,AdaDelta演算法相比RMSProp演算法的主要區別是用 Δ x \Delta x Δx這個變數來替換RMSProp的超引數學習率 η \eta η。其中 Δ x 0 \Delta x_0 Δx0 s 0 s_0 s0初始化都是0。

2.7.2 總結

  • Adadelta演算法沒有學習率這個超引數,通過計算自變數的指數加權平均來替代學習率
  • Adadelta使用兩個變數來儲存梯度的變化和自變數本身的變化

2.8 Adam

ADAM: A METHOD FOR STOCHASTIC OPTIMIZATIONfang’f

2.8.1 方法

Adam是一個綜合了上述所有優化演算法的一個有效的演算法。目前為止,Adam是在深度學習模型裡使用較多,也是教魯棒的優化器之一。不過Adam演算法也有一些問題,具體可以參考以下兩篇論文:
On the Convergence of Adam and Beyond

Adaptive Methods for Nonconvex Optimization

Adam演算法的使用了動量變數 v t v_t vt和RMSProp演算法中的批量隨機梯度平方的指數加權移動平均變數 s t s_t st。數學公式如下:
v t ← β 1 v t − 1 + ( 1 − β 1 ) g t v_t \gets \beta_1v_{t-1} + (1-\beta_1)g_t vtβ1vt1+(1β1)gt
s t ← β 2 s t − 1 + ( 1 − β 2 ) g t 2 s_t \gets \beta_2 s_{t-1} + (1-\beta_2)g_t^2 stβ2st1+(1β2)gt2
其中 β 1 \beta_1 β1 β 2 \beta_2 β2是一個小於1的正數,一般設定是 β 1 = 0.9 \beta_1=0.9 β1=0.9 β 2 = 0.999 \beta_2=0.999 β2=0.999,初始值 v 0 = s 0 = 0 v_0=s_0=0 v0=s0=0
v t = ( 1 − β 1 ) ∑ i = 1 t β 1 t − i g i v_t = (1-\beta_1)\sum_{i=1}^t\beta_1^{t-i}g_i vt=(1β1)i=1tβ1tigi,將過去各時間步批量隨機梯度權值相加,得到 ( 1 − β 1 ) ∑ i = 1 t β 1 t − i = 1 − β 1 t (1-\beta_1)\sum_{i=1}^t\beta_1^{t-i}=1-\beta_1^t (1β1)i=1tβ1ti=1β1t,當時間 t t t很小時。過去各時間步批量梯度權值之和很小,例如當 β 1 = 0.9 \beta_1=0.9 β1=0.9 v 1 = 0.1 g 1 v_1=0.1g_1 v1=0.1g1,為了避免這樣的影響,除以 1 − β 1 t 1-\beta_1^t 1β1t歸一化因子,修正後如下:
v t ^ = v t 1 − β 1 t \hat{v_t}=\frac{v_t}{1-\beta_1^t} vt^=1β1tvt
s t ^ = s t 1 − β 2 t \hat{s_t} = \frac{s_t}{1-\beta_2^t} st^=1β2tst
Adam演算法用 v t v_t vt s t s_t st來調整每個引數的學習率,如下公式:
g t ′ ← η v t ^ s t ^ + ε g_t^{'} \gets \frac{\eta \hat{v_t}}{\sqrt{\hat{s_t}}+\varepsilon} gtst^ +εηvt^
x t ← x t − 1 − g t ′ x_t \gets x_{t-1} - g_t^{'} xtxt1gt
η \eta η是學習率, ε \varepsilon ε是為了維持數值計算穩定的一個很小的常量,如 1 0 − 8 10^{-8} 108,和AdaGrad、RMSProp以及AdaDelta演算法一樣,每個自變數都有自己的學習率。

2.8.2 總結

  • Adam演算法集合了許多優化演算法的特性,是一個較魯棒的優化演算法
  • Adam相對於RMSPro演算法,在時間 t t t步上,用歷史所有時間 t t t步的批量隨機梯度指數加權移動平均來替代當前時間 t t t的梯度 g t g_t gt
  • Adam演算法y也使用了偏差修正,保證了在剛開始,時間步 t t t很小的時候,指數加權權重之和較小問題

3. 參考資料

Optimization and Deep Learning

相關文章