在很多機器學(xué)習(xí)和深度學(xué)習(xí)的應(yīng)用中,我們發(fā)現(xiàn)用的最多的優(yōu)化器是 Adam,為什么呢?
下面是 TensorFlow 中的優(yōu)化器:

在 keras 中也有 SGD,RMSprop,Adagrad,Adadelta,Adam 等。
?
我們可以發(fā)現(xiàn)除了常見的梯度下降,還有 Adadelta,Adagrad,RMSProp 等幾種優(yōu)化器,都是什么呢,又該怎么選擇呢?
在 Sebastian Ruder 的這篇論文中給出了常用優(yōu)化器的比較,本文將梳理:
每個算法的梯度更新規(guī)則和缺點
為了應(yīng)對這個不足而提出的下一個算法
超參數(shù)的一般設(shè)定值
幾種算法的效果比較
選擇哪種算法
優(yōu)化器算法簡述
首先來看一下梯度下降最常見的三種變形 BGD,SGD,MBGD,
這三種形式的區(qū)別就是取決于我們用多少數(shù)據(jù)來計算目標(biāo)函數(shù)的梯度,
這樣的話自然就涉及到一個 trade-off,即參數(shù)更新的準(zhǔn)確率和運行時間。
1. Batch gradient descent
梯度更新規(guī)則:
BGD 采用整個訓(xùn)練集的數(shù)據(jù)來計算 cost function 對參數(shù)的梯度:
缺點:
由于這種方法是在一次更新中,就對整個數(shù)據(jù)集計算梯度,所以計算起來非常慢,遇到很大量的數(shù)據(jù)集也會非常棘手,而且不能投入新數(shù)據(jù)實時更新模型
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
我們會事先定義一個迭代次數(shù) epoch,首先計算梯度向量 params_grad,然后沿著梯度的方向更新參數(shù) params,learning rate 決定了我們每一步邁多大。
Batch gradient descent 對于凸函數(shù)可以收斂到全局極小值,對于非凸函數(shù)可以收斂到局部極小值。
2. Stochastic gradient descent
梯度更新規(guī)則:
和 BGD 的一次用所有數(shù)據(jù)計算梯度相比,SGD 每次更新時對每個樣本進行梯度更新, 對于很大的數(shù)據(jù)集來說,可能會有相似的樣本,這樣 BGD 在計算梯度時會出現(xiàn)冗余, 而 SGD 一次只進行一次更新,就沒有冗余,而且比較快,并且可以新增樣本。
for i in range(nb_epochs):
np.random.shuffle(data)
for example in data:
params_grad = evaluate_gradient(loss_function, example, params)
params = params - learning_rate * params_grad
看代碼,可以看到區(qū)別,就是整體數(shù)據(jù)集是個循環(huán),其中對每個樣本進行一次參數(shù)更新。
缺點:
但是 SGD 因為更新比較頻繁,會造成 cost function 有嚴(yán)重的震蕩。

BGD 可以收斂到局部極小值,當(dāng)然 SGD 的震蕩可能會跳到更好的局部極小值處。
當(dāng)我們稍微減小 learning rate,SGD 和 BGD 的收斂性是一樣的。
3. Mini-batch gradient descent
梯度更新規(guī)則:
MBGD 每一次利用一小批樣本,即 n 個樣本進行計算。這樣它可以降低參數(shù)更新時的方差,收斂更穩(wěn)定。另一方面可以充分地利用深度學(xué)習(xí)庫中高度優(yōu)化的矩陣操作來進行更有效的梯度計算。
和 SGD 的區(qū)別是每一次循環(huán)不是作用于每個樣本,而是具有 n 個樣本的批次
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size=50):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad
超參數(shù)設(shè)定值:
n 一般取值在 50~256
缺點:
不過 Mini-batch gradient descent 不能保證很好的收斂性,
learning rate 如果選擇的太小,收斂速度會很慢,如果太大,loss function 就會在極小值處不停地震蕩甚至偏離。
有一種措施是先設(shè)定大一點的學(xué)習(xí)率,當(dāng)兩次迭代之間的變化低于某個閾值后,就減小 learning rate,不過這個閾值的設(shè)定需要提前寫好,這樣的話就不能夠適應(yīng)數(shù)據(jù)集的特點。
此外,這種方法是對所有參數(shù)更新時應(yīng)用同樣的 learning rate,如果我們的數(shù)據(jù)是稀疏的,我們更希望對出現(xiàn)頻率低的特征進行大一點的更新。
電子發(fā)燒友App












評論