?終于!!!
?終于又有時間學習Deep Learning了?!
30天ML計劃,一起加油!!!
https://blog.csdn.net/weixin_44333889/category_11271153.html《專欄》
在訓練NN的時候,有哪些Optimizers可以優化更快的找到global Minima?
下面我們來看下有哪些方法可以優化求解,
Background
在訓練神經網路的時候,最開始我們是用的Gradient Descent(梯度下降法,GD)來求解,但是會出現很多問題,面臨大量的資料的時候,GD會出現local Minima,而且求解速度會下降,
關于GD+Momentum,可以看這個介紹簡單易懂,
整個技術的發展路線如下:
- SGD 【Cauchy,1847】
- SGD with momentum 【Rumelhart,et al.,Nature’1986】
上面兩個是遠古時期的優化求解方法,其實放到現在來看,依舊還是很有效果,
如下面這些就是SGDM訓練出來的,

目前比較常用的是下面三個Optimizers:
- Adagrad 【Duchi,et al. JMLR’11 2011】
- RMSProp 【Hinton,et al. Lecture slides, 2013】
- Adam 【kingma,et al. ICLR’15 2014】
借用一下李老師(臺大,李宏毅)的PPT,
SGD,stochastic gradient descent,也就是最普通的方法,如下圖所示

SGD就像圖中的更新方式一樣,隨機找到一個起始點,對其求梯度,然后在其梯度的反方向按照
η
\eta
η步長進行更新,找到下一個點,然后在不斷的重復操作,直到找到Minima,
關于SGDM的更新方式如下圖,可以看出,更新方式在SGD的基礎上,增加了Momentum,而這個Momentum則是在一次梯度下降后,按照其算的梯度方向的反方向(圖中 g 1 g^1 g1)和上一個更新方向的延長(圖中 m 1 m^1 m1)的合成方向(圖中 m 2 m^2 m2)的方向進行更新操作的,不斷的進行更新,直到找到最優的解則停止,

Adagrad
Adagrad(自適應梯度演算法),其基本思想是,對每個引數theta自適應的調節它的學習率,自適應的方法就是對每個引數乘以不同的系數,并且這個系數是通過之前累積的梯度大小的平方和決定的,也就是說,對于之前更新很多的,相對就可以慢一點,而對那些沒怎么更新過的,就可以給一個大一些的學習率,
Adagrad演算法:
- 引數設定: ? \epsilon ? 為全域學習率;初始引數 θ \theta θ;較小的常數(超引數,自己設定) δ \delta δ,為了數值穩定大約設定為 1 0 ? 7 10^{-7} 10?7
- 初始化梯度累積變數 r = 0 r=0 r=0
接下來是回圈迭代更新
while 沒有達到停止準則 do
- 從訓練集中采包含 m m m個樣本 { x ( 1 ) , . . . , x ( m ) } \{x^{(1)},...,x^{(m)}\} {x(1),...,x(m)}的小批量,對應目標為 y ( i ) y^{(i)} y(i)
- 計算梯度: g ← 1 m ▽ θ Σ i L ( x ( 1 ) ; θ , y ( i ) ) g \leftarrow \frac{1}{m} \bigtriangledown _\theta\Sigma_i L(x^{(1)};\theta,y^{(i)}) g←m1?▽θ?Σi?L(x(1);θ,y(i))
- 累積平方梯度: r ← r + g ⊙ g r\leftarrow r+g \odot g r←r+g⊙g
- 計算更新: △ θ ← ? ? δ + r ⊙ g \bigtriangleup \theta\leftarrow - \frac{\epsilon}{\delta+\sqrt{r}}\odot g △θ←?δ+r ???⊙g(逐步元素地應用除和求平方根)
- 應用更新: θ ← θ + △ θ \theta\leftarrow \theta+\bigtriangleup \theta θ←θ+△θ
end
(結束優化更新)
以上就為Adagrad演算法的內容,
Python實作代碼:
import numpy as np
class Adagrad:
def __init__(self, learning_rate=0.01):
self.learning_rate = learning_rate # 學習率設定為0.01
self.fg = None
self.delta = 1e-07 # 設定1e-07微小值避免分母為0
def update(self, params, grads): # 更新操作
if self.fg is None:
self.fg = {} # 設為空串列
for key, value in params.items():
self.fg[key] = np.zeros_like(value) # 構造一個矩陣
for key in params.keys(): # 回圈迭代
self.fg[key] += grads[key] * grads[key]
params[key] -= self.learning_rate * grads[key] / (np.sqrt(self.fg[key]) + self.delta)
RMSProp
RMSProp演算法實則為對Adagrad的一個改進,也就是把Adagrad對歷史梯度加和變成了對歷史梯度求均值,再利用這個均值代替Adagrad累加的梯度和對當前梯度進行加權,并用來update更新,
用均值代替求和是為了解決Adagrad的學習率逐漸消失的問題,

(圖片源自網路)
有位大佬的解釋更加清晰,可跳轉此處,
def RMSprop(x, y, step=0.01, iter_count=500, batch_size=4, alpha=0.9, beta=0.9):
length, features = x.shape
data = np.column_stack((x, np.ones((length, 1))))
w = np.zeros((features + 1, 1))
Sdw, v, eta = 0, 0, 10e-7
start, end = 0, batch_size
# 開始迭代
for i in range(iter_count):
# 計算臨時更新引數
w_temp = w - step * v
# 計算梯度
dw = np.sum((np.dot(data[start:end], w_temp) - y[start:end]) * data[start:end], axis=0).reshape((features + 1, 1)) / length
# 計算累積梯度平方
Sdw = beta * Sdw + (1 - beta) * np.dot(dw.T, dw)
# 計算速度更新量、
v = alpha * v + (1 - alpha) * dw
# 更新引數
w = w - (step / np.sqrt(eta + Sdw)) * v
start = (start + batch_size) % length
if start > length:
start -= length
end = (end + batch_size) % length
if end > length:
end -= length
return w
Adam
最后講講Adam(自適應矩估計 Adaptive moment estimation),因為目前是比較強的,下面這些都是由Adam訓練出來的,

看一下Adam和SGDM的準確率對比(源自論文)

由于Adam的提出的地方有一些突兀,并非在論文或會議,能找到的最原始的出處也只有下面了,看一下他的更新方式吧,相當于一個優化引數的更新模塊,

簡單翻譯一下上面的更新步驟:
首先,引數設定: g t 2 = g t ⊙ g t g_t^2=g_t \odot g_t gt2?=gt?⊙gt?,默認測驗的學習率(LR) α = 0.001 \alpha=0.001 α=0.001,各種超引數 β 1 = 0.9 、 β 2 = 0.999 、 ? = 1 0 ? 8 \beta _1=0.9、\beta_2=0.999、\epsilon =10^{-8} β1?=0.9、β2?=0.999、?=10?8
- α \alpha α: 步長(Stepsize)亦或學習率
- β 1 , β 2 ∈ [ 0 , 1 ] \beta _1,\beta _2\in[0,1] β1?,β2?∈[0,1]:矩估計的指數衰減率
- f ( θ ) f(\theta) f(θ):引數 θ \theta θ 的隨機目標函式值
- θ 0 \theta_0 θ0?: 初始引數向量{ m 0 ← 0 m_0 \leftarrow0 m0?←0:(初始化第一權值向量)、 v 0 ← 0 v_0\leftarrow0 v0?←0:(初始化第二權值向量)、 t ← 0 t\leftarrow0 t←0:(初始化時變步長)}
下面為約束,當且僅當 θ t \theta_t θt? 不收斂的時候執行以下操作:
- t ← t + 1 t\leftarrow t+1 t←t+1
- g t ← ▽ θ f t ( θ t ? 1 ) g_t \leftarrow \bigtriangledown _{\theta}f_{t}(\theta_{t}-1) gt?←▽θ?ft?(θt??1) :(獲得新一輪更新的梯度值(引數 t t t 是上次剛更新的步長))
- m t ← β 1 ? m t ? 1 + ( 1 ? β 1 ) ? g t m_t \leftarrow \beta_1\cdot m_{t-1}+(1-\beta_1)\cdot g_t mt?←β1??mt?1?+(1?β1?)?gt?:(更新帶偏差的第一權重估計值)
- v t ← β 2 ? v t ? 1 + ( 1 ? β 1 t ) ? g t 2 v_t\leftarrow\beta_2 \cdot v_{t-1}+(1-\beta_1^t)\cdot{g_t^2} vt?←β2??vt?1?+(1?β1t?)?gt2?:(更新帶偏差的第二原始權重估計值)
- m t ^ ← m t / ( 1 ? β 2 t ) \hat {m_t}\leftarrow m_t / (1-\beta_2^t) mt?^?←mt?/(1?β2t?):(計算偏差校正后的第一權重估計值)
- v t ^ ← v t / ( 1 ? β 2 t ) \hat {v_t}\leftarrow v_t/(1-\beta_2^t) vt?^?←vt?/(1?β2t?):(計算偏差校正后的第二原始權重估計值)
- θ t ← θ t ? 1 ? α ? m t ^ / ( v t ^ + ? ) \theta_t\leftarrow \theta_{t-1}-\alpha \cdot \hat{m_t}/(\sqrt{\hat{v_t}}+\epsilon) θt?←θt?1??α?mt?^?/(vt?^? ?+?):(更新 θ \theta θ 引數值)
到此引數優化結束,
回傳 θ t \theta_t θt? 的值,
Adam 的Python代碼有大佬已經開源了:
- https://github.com/yzy1996/Python-Code/blob/master/Algorithm/Optimization-Algorithm/Adam.py
- https://github.com/sagarvegad/Adam-optimizer/blob/master/Adam.py
如果不想轉鏈接,這里直接附上了:
import math
alpha = 0.01
beta_1 = 0.9
beta_2 = 0.999 # 初始化引數的值
epsilon = 1e-8
def func(x):
return x*x -4*x + 4
def grad_func(x): # 計算梯度
return 2*x - 4
theta_0 = 0 # 初始化向量
m_t = 0
v_t = 0
t = 0
while (1): # 回圈直到它收斂
t+=1
g_t = grad_func(theta_0) # 計算隨機函式的梯度
m_t = beta_1*m_t + (1-beta_1)*g_t # 更新梯度的移動平均線
v_t = beta_2*v_t + (1-beta_2)*(g_t*g_t) # 更新平方梯度的移動平均線
m_cap = m_t/(1-(beta_1**t)) # 計算偏差校正后的估計
v_cap = v_t/(1-(beta_2**t)) # 計算偏差校正后的估計
theta_0_prev = theta_0
theta_0 = theta_0 - (alpha*m_cap)/(math.sqrt(v_cap)+epsilon) # 更新引數
if(theta_0 == theta_0_prev): # 檢查是否收斂
break
總而言之,這個優化器目前是處于機器學習中最強的優化地位,
其實,對于不同的資料集或許會有所偏差,在不同的優化時間段,前中后期,各個優化器的準確率會有所波動,如下(源自論文)準確率測驗圖:

所以,不經感嘆道,搞優化求解,真的是一門玄學啊,老的方法不一定在現在沒有用,新的方法不一定適用于所以場景,找到最適合的方法才是真的有效的,相信在科技如此發達的現在及以后,會有更多的優化求解演算法,推進人類進步,而不僅僅是從硬體上提升運算速度,
Recommend
推薦一本書,對于沒學過最優控制或者最優化方法的小伙伴,會是一個很好地入門書籍,
《最優化計算方法》
真不是打廣告,真誠推薦!!!
References
- https://github.com/Fafa-DL/Lhy_Machine_Learning
?堅持讀Paper,堅持做筆記,堅持學習?!!!
?To Be No.1??哈哈哈哈
學習DeepLearning堅持!30天計劃!!!
打卡 第 4 /30 Day!!!
?創作不易?,過路能?關注、收藏、點個贊?三連就最好不過了
?( ′・?・` )
?
『
Make the choice to be happy. The biggest part of being happy is to simply make up your mind to be a happy person.
』
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/299600.html
標籤:AI
上一篇:核磁共振重建演算法綜述
