深度學習優化器總結

 

Adam優化器

 

計算t時間步的梯度:

 

首先,計算梯度的指數移動平均數,m_{0} 初始化爲0。

\beta _{1}係數爲指數衰減率,控制權重分配(動量與當前梯度),通常取接近於1的值。默認爲0.9

 

其次,計算梯度平方的指數移動平均數,v_{0}初始化爲0。

\beta _{2} 係數爲指數衰減率,控制之前的梯度平方的影響情況。默認爲0.999

 

第三,由於m_{0}初始化爲0,會導致m_{t}偏向於0,尤其在訓練初期階段。

所以,此處需要對梯度均值m_{t}進行偏差糾正,降低偏差對訓練初期的影響。

 

第四,與m_{0} 類似,因爲v_{0}初始化爲0導致訓練初始階段v_{t}偏向0,對其進行糾正。

 

第五,更新參數,初始的學習率\alpha乘以梯度均值與梯度方差的平方根之比。

其中默認學習率α=0.001

\epsilon=10^{-8},避免除數變爲0。

由表達式可以看出,對更新的步長計算,能夠從梯度均值及梯度平方兩個角度進行自適應地調節,而不是直接由當前梯度決定。

 

python 實現

import sys
import autograd.numpy as np
from autograd import grad

EPOCHS = 1000

class Adam:
	def __init__(self, loss, weights, lr=0.001, beta1=0.9, beta2=0.999, epislon=1e-8):
		self.loss = loss
		self.theta = weights
		self.lr = lr
		self.beta1 = beta1
		self.beta2 = beta2
		self.epislon = epislon
		self.get_gradient = grad(loss)
		self.m = 0
		self.v = 0
		self.t = 0

	def minimize_raw(self):
		self.t += 1
		g = self.get_gradient(self.theta)
		self.m = self.beta1 * self.m + (1 - self.beta1) * g
		self.v = self.beta2 * self.v + (1 - self.beta2) * (g * g)
		self.m_cat = self.m / (1 - self.beta1 ** self.t)
		self.v_cat = self.v / (1 - self.beta2 ** self.t)
		self.theta -= self.lr * self.m_cat / (self.v_cat ** 0.5 + self.epislon)

	def minimize(self):
		self.t += 1
		g = self.get_gradient(self.theta)
		lr = self.lr * (1 - self.beta2 ** self.t) ** 0.5 / (1 - self.beta1 ** self.t)
		self.m = self.beta1 * self.m + (1 - self.beta1) * g
		self.v = self.beta2 * self.v + (1 - self.beta2) * (g * g)
		self.theta -= lr * self.m / (self.v ** 0.5 + self.epislon)


	def minimize_show(self, epochs=5000):
		for _ in range(epochs):
			self.t += 1
			g = self.get_gradient(self.theta)
			lr = self.lr * (1 - self.beta2 ** self.t) ** 0.5 / (1 - self.beta1 ** self.t)
			self.m = self.beta1 * self.m + (1 - self.beta1) * g
			self.v = self.beta2 * self.v + (1 - self.beta2) * (g * g)
			self.theta -= lr * self.m / (self.v ** 0.5 + self.epislon)
			print("step{: 4d} g:{} lr:{} m:{} v:{} theta:{}".format(self.t, g, lr, self.m, self.v, self.theta))

		final_loss = self.loss(self.theta)
		# print("final loss:{} weights:{}".format(final_loss, self.theta))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章