深度學習中如何選擇好的優化方法(optimizer)【原理】
除了隨機梯度初始化(SGD),在深度學習中還有很多其他的方法可以對網路進行優化
1. 減少網路收斂時間
2. 除了學習率(learning rate)還有更多其他的引數
3. 比SGD到達更高的分類準確率
一. 自適應學習率
為了更好的理解優化的方法,這裡我們都是用虛擬碼的方式來進行描述。
首先,我們先來看我們最熟悉的SGD的方法
W += -lr * dW
其中我們有三個變數:
1. W:權值矩陣
2. lr:學習率
3. dW:權值W的梯度
其中,我們的學習率是固定的,假設它很足夠小,loss在訓練的過程中就會下降。
(1)Adagrad
Adagrad在網路中會自適應的改變學習率,在引數改變不明顯的時候學習率變化更頻繁,在引數改變明顯的地方學習率變化減弱。我們來看看Adagrad的更新公式:
cache += (dW ** 2)
W += -lr * dW / (np.sqrt(cache) + eps)
注意到的第一個引數是cache,這個引數表示每一個引數梯度平方的總和,會在訓練過程每一次小的mini-batch進行更新。當觀察cache時,我們可以發現哪些引數更新的快,哪些更新的慢。
接著使用lr*dW除以cache的平方(這裡加一個epsilon的原因是為了防止除數為0)。發現,當cache變化的很快時,cache的值會變得很大,接著在下一個公式有效的對學習率進行降低,同樣,當變化的很慢時,學習率會相應的變大。
Adagrad最大的優點在於人們不需要手動的調節學習率——在大多數設定中,初始設定為0.01,然後讓其自動在網路中進行調節。
但是,同樣其缺點也非常的明顯。在每一個mini-batch,梯度按照平方的形式在分母累計。因為梯度會平方(永遠是正數),這個累積會在訓練過程一直增加。我們都知道,當一個很小的數目除以一個很大的數目的時候,結果就會趨近於零,會導致更新非常的小而實際上什麼都學習不到。這也是為什麼我們不經常在深度學習中使用Adagrad的原因。
(2)RMSprop
RMSprop是對於Adagrad的一個改進,可以減少因為cache帶來的學習率單調遞減的問題。主要的方法是採用了指數加權滑動平均(EWMA)。
cache = decay_rate * cache + (1 - decay_rate) * (dW ** 2) W += -lr * dW / (np.sqrt(cache) + eps)
跟Adagrad的更新方式相似,主要的區別在於cache的變化。decay_rate, 經常被設定為0.9。這種滑動平均的方式可以讓cache丟掉老的梯度平方,從而用新的來代替。
所以,在深度學習中,RMSprop比Adagrad更有效,並且收斂速度比SGD更快。是現在第二流行使用的優化方式,接下來介紹最佳的優化方式Adam
(3)Adam
m = beta1 * m + (1 - beta1) * dW
v = beta2 * v + (1 - beta2) * (dW ** 2)
x += -lr * m / (np.sqrt(v) + eps)
其中,m和v的值和SGD的動量很相似,m代表第一時刻的梯度,v代表第二時刻。
W的跟新方式與RMSprop是一樣的,一般情況下,beta1為0.9,beta2為0.999.
二.好的優化方式推薦
有這麼多的優化方式,對於我自己的模型而言,哪一個更好呢?其實,現在還沒有一個明確的答案,最好的方法是,選擇幾個不同的方法在自己的模型上嘗試,找到最適合的。
這裡特別要提醒的是,千萬不要忽略SGD的重要性,你會發現,在AlexNet,VGGNet,SqueezeNet,Inception,ResNet中,都採用的是SGD的方法,為什麼呢?
雖然SGD會比較的慢,但是對於網路來說,引數才是最重要的,如果你不能將優化引數調到最佳的話,你永遠得不到好的準確率。SGD的使用時間將近60年,人們對它會更熟悉。
小tips:如果你可以使用SGD在指定的資料上達到很高的準確率,我建議你就使用SGD儘管會比RMSprop和Adam時間長一些。所以必須要記住的三種優化方式為:
1. SGD
2. RMSprop
3. Adam
一個模型建立時,首先使用SGD,一般情況下,結果會比較好。接著,再使用另外兩種,建議直接使用Adam,因為在大多數情況下Adam會比RMSprop表現的好。