轉載出處:http://www.2cto.com/kf/201612/572613.html
常見算法
SGD
1 | x+= -learning_rate*dx |
Momentum
Momentum可以使SGD不至於陷入局部鞍點震盪,同時起到一定加速作用。
Momentum最開始有可能會偏離較遠(overshooting the target),但是通常會慢慢矯正回來。
1 2 | v = mu*v - learning_rate*dx x+= v |
Nesterov momentum
基本思路是每次不在x位置求dx,而是在x+mu*v處更新dx,然後在用動量公式進行計算
相當於每次先到動量的位置,然後求梯度更新
vt=μvt?1?ε▽f(θt?1+μvt?1)
θt=θt?1+vt
計算▽f(θt?1+μvt?1)不太方便,做如下變量替換:?t?1=θt?1+μvt?1 ,並帶回上述公式可以得到
vt=μvt?1+ε▽f(?t?1)
?t?1=?t?1?μvt?1+(1+μ)vt
1 2 3 | v_prev = v v = mu*v-learning_rate*dx x += -mu*v_prev+( 1 +mu)*v |
AdaGrad
使用每個變量的歷史梯度值累加作爲更新的分母,起到平衡不同變量梯度數值差異過大的問題
1 2 | cache += dx** 2 x += -learning_rate*dx/(np.sqrt(cache)+1e- 7 ) |
RMSProp
在AdaGrad基礎上加入了decay factor,防止歷史梯度求和過大
1 2 | cache = decay_rate*cache + ( 1 -decay_rate)*dx** 2 x += -learning_rate*dx/(np.sqrt(cache)+1e- 7 ) |
ADAM
初始版本:類似於加入動量的RMSProp
1 2 3 | m = beta1*m + ( 1 -beta1)*dx v = beta2*v + ( 1 -beta2)*(dx** 2 ) x += -learning_rate*m / (np.sqrt(v)+1e- 7 ) |
真實的更新算法如下:
1 2 3 4 5 | m = beta1*m + ( 1 -beta1)*dx v = beta2*v + ( 1 -beta2)*(dx** 2 ) mb = m/( 1 -beta1**t) # t is step number vb = v/( 1 -beta2**t) x += -learning_rate*mb / (np.sqrt(vb)+1e- 7 ) |
mb和vb起到最開始的時候warm up作用,t很大之後(1-beta1**t) =1
Second Order optimization methods
second-order taylor expansion:
J(θ)≈J(θ0)+(θ?theta0)T+12(θ?θ0)TH(θ?θ0)
θ?=θ0?H?1▽θJ(θ0)
Quasi_newton methods (BFGS) with approximate inverse Hessian matrix L-BFGS (limited memory BFGS)
Does not form/store the full inverse Hessian.
Usually works very well in full batch, deterministic mode
實際經驗
ADAM通常會取得比較好的結果,同時收斂非常快相比SGD L-BFGS適用於全batch做優化的情況 有時候可以多種優化方法同時使用,比如使用SGD進行warm up,然後ADAM 對於比較奇怪的需求,deepbit兩個loss的收斂需要進行控制的情況,比較慢的SGD比較適用
tensorflow 不同優化算法對應的參數
SGD
optimizer = tf.train.GradientDescentOptimizer(learning_rate=self.learning_rate)
Momentum
optimizer = tf.train.MomentumOptimizer(lr, 0.9)
AdaGrad
optimizer = tf.train.AdagradientOptimizer(learning_rate=self.learning_rate)
RMSProp
optimizer = tf.train.RMSPropOptimizer(0.001, 0.9)
ADAM
optimizer = tf.train.AdamOptimizer(learning_rate=self.learning_rate, epsilon=1e-08)
部分局部參數需要查找tensorflow官方文檔
直接進行優化
train_op = optimizer.minimize(loss)
獲得提取進行截斷等處理
gradients, v = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, self.max_gradient_norm)
train_op = optimizer.apply_gradients(zip(gradients, v), global_step=self.global_step)
轉載出處:http://www.2cto.com/kf/201612/572613.html