我的書:
淘寶購買連結
當當購買連結
京東購買連結
##tensorflow優化器
種類如下,其中Optimizer是基類
tf.train.Optimizer
tf.train.GradientDescentOptimizer
tf.train.AdadeltaOptimizer
tf.train.AdagradOptimizer
tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizer
tf.train.AdamOptimizer
tf.train.FtrlOptimizer
tf.train.ProximalGradientDescentOptimizer
tf.train.ProximalAdagradOptimizer
tf.train.RMSPropOptimizer
##tf.train.GradientDescentOptimizer
###梯度下降法
設:
h θ ( x ) = θ 1 x h_\theta(x)=\theta_1x hθ(x)=θ1x,其參數是 θ 1 \theta_1 θ1,則其損失函數是:
J ( θ 1 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J(\theta_1)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 J(θ1)=2m1∑i=1m(hθ(x(i))−y(i))2
則 θ 1 \theta_1 θ1通過如下求得:
m i n i m i z e θ 1 J ( θ 1 ) minimize_{\theta_1}J(\theta_1) minimizeθ1J(θ1)
###梯度下降原理
設樣本集合是{(1,1), (2,2), (3,3)}.下圖是 θ 1 \theta_1 θ1和 J ( θ 1 ) J(\theta_1) J(θ1)變化情況。
θ j = θ j − α ∂ ∂ θ j J ( θ 0 , θ 1 ) \theta_{j}=\theta_j-\alpha \frac{\partial}{\partial \theta_j}J(\theta_0,\theta_1) θj=θj−α∂θj∂J(θ0,θ1)
對參數中向量 θ \theta θ中的每個分量 θ j \theta_j θj,疊代減去速率因子 η ∗ d J ( θ ) d θ j \eta*\frac{dJ(\theta)}{d\theta_j} η∗dθjdJ(θ)
###梯度下降法
####批量梯度下降法
$\theta_j=\theta_j-\eta \cdot \bigtriangledown_{\theta}J(\theta) $
如上例:
h ( θ ) = ∑ j = 0 n θ j x j h(\theta)=\sum_{j=0}^n\theta_jx_j h(θ)=∑j=0nθjxj
J ( θ ) = 1 2 m ∑ i = 1 m ( y i − h θ ( x i ) ) 2 J(\theta)=\frac{1}{2m}\sum_{i=1}^m(y^i-h_\theta(x^i))^2 J(θ)=2m1∑i=1m(yi−hθ(xi))2
2.求解方法
∂ J ( θ ) ∂ θ j = − 1 m ∑ i = 1 m ( y i − h θ ( x i ) ) x j i \frac{\partial{J(\theta)}}{\partial \theta_j}=-\frac{1}{m}\sum_{i=1}^m(y^i-h_\theta(x^i))x_j^i ∂θj∂J(θ)=−m1∑i=1m(yi−hθ(xi))xji
θ j = θ j + 1 m ∑ i = 1 m ( y i − h θ ( x i ) ) x j i \theta_j=\theta_j+\frac{1}{m}\sum_{i=1}^{m}(y^i-h_\theta(x^i))x_j^i θj=θj+m1∑i=1m(yi−hθ(xi))xji
全局最優,但是m很大時,計算量較大。
for i in range(nb_epochs):
params_grad = evaluate_gradient(loss_function, data, params)
params = params - learning_rate * params_grad
####随機梯度下降法
對每一個樣本 x i x^i xi根據label y i y^i yi進行更新
θ j = θ j − η ⋅ ▽ θ J ( θ ; x ( i ) ; y ( i ) ) \theta_j=\theta_j-\eta\cdot \bigtriangledown_{\theta}J(\theta;x^{(i)};y^{(i)}) θj=θj−η⋅▽θJ(θ;x(i);y(i))
如上例:
J ( θ ) = 1 2 m ∑ i = 1 m ( y i − h θ ( x i ) ) 2 J(\theta)=\frac{1}{2m}\sum_{i=1}^m(y^i-h_\theta(x^i))^2 J(θ)=2m1∑i=1m(yi−hθ(xi))2
梯度更新:
θ j = θ j + ( y i − h θ ( x i ) ) x j i , 對 每 一 個 j 求 解 \theta_j=\theta_j+(y^i-h_\theta(x^i))x_j^i,對每一個j求解 θj=θj+(yi−hθ(xi))xji,對每一個j求解
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
####mini-batch 梯度下降法
θ j = θ j − η ⋅ ▽ θ J ( θ ; x ( i ; i + n ) ; y ( i ; i + n ) ) \theta_j=\theta_j-\eta\cdot \bigtriangledown_{\theta}J(\theta;x^{(i;i+n)};y^{(i;i+n)}) θj=θj−η⋅▽θJ(θ;x(i;i+n);y(i;i+n))
如n取50的情況:
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
###問題
1.合适的學習率, α \alpha α比較難獲得
α \alpha α過大導緻震蕩無法得到最優解,過小導緻學習過程漫長。
2.對所有參數學習率隻有一個,如果資料是稀疏的,并且特征具有不同的頻率時,更傾向于對不同頻率特征使用不同的學習率,對很少發生的特征采用較大的學習率。
3.目标函數門限需要提前定義,一旦計算中小于門限就停止,資料排程訓練的選擇對其有影響,通常使用shuffle打斷以減小這種影響。
4.高維非凸誤差函數最小求解技術難度大。
##tf.train.AdadeltaOptimizer
該算法不需要手動調優學習速率 α \alpha α,抗噪聲能力強,可以選擇不同的模型結構。
Adadelta是對Adagrad的擴充。Adadelta隻累加強定大小的項,并且也不直接存儲這些項,僅僅是計算對應的平均值。
上一節的參數更新模型是:
θ t + 1 = θ t − α d J ( θ ) d θ t \theta_{t+1}=\theta_t-\alpha\frac{dJ(\theta)}{d\theta_t} θt+1=θt−αdθtdJ(θ)
為友善,把 d J ( θ ) d θ t \frac{dJ(\theta)}{d\theta_t} dθtdJ(θ)記作 g t g_t gt,把平滑後的梯度記作 E [ g ] t E[g]_t E[g]t,則其平方表示如下:
E [ g 2 ] t = ρ E [ g 2 ] t − 1 + ( 1 − ρ ) g t 2 E[g^2]_t=\rho E[g^2]_{t-1}+(1-\rho)g_t^2 E[g2]t=ρE[g2]t−1+(1−ρ)gt2
其中 ρ \rho ρ是平滑/衰減因子。其均方根得到的該值如下:
R M S [ g ] t = E [ g 2 ] t + ϵ RMS[g]_t=\sqrt{E[g^2]_t+\epsilon} RMS[g]t=E[g2]t+ϵ
其中 ϵ \epsilon ϵ是為了防止後續計算分母為零而引入的參數常量。
Δ θ = − R M S [ Δ θ ] t − 1 R M S [ g ] t g t \Delta \theta=-\frac{RMS[\Delta \theta]_{t-1}}{RMS[g]_t}g_t Δθ=−RMS[g]tRMS[Δθ]t−1gt
θ t + 1 = θ t + Δ θ t \theta_{t+1}=\theta_t+\Delta \theta_t θt+1=θt+Δθt
###ADADELTA t時刻跟新過程如下:
前提衰減因子 ρ \rho ρ,常數 ϵ \epsilon ϵ,初始的 θ \theta θ值。
1 計算變量 E [ g 2 ] 0 = 0 E[g^2]_0=0 E[g2]0=0, E [ Δ θ 2 ] 0 = 0 E[\Delta\theta^2]_0=0 E[Δθ2]0=0
2: for t=1:T do %%Loop over #of updates
3: 計算梯度: g t g_t gt
4: 滑動平均梯度: E [ g 2 ] t = ρ E [ g 2 ] t − 1 + ( 1 − ρ ) g t 2 E[g^2]_t=\rho E[g^2]_{t-1}+(1-\rho)g_t^2 E[g2]t=ρE[g2]t−1+(1−ρ)gt2
-
計算參數跟新$\Delta \theta = - \frac{RMS[\Delta \theta^2]_t}{RMS[g]_t}g_t$
-
計算更新$E[\Delta x^2]_t=\rho E[\Delta \theta^2]_{t-1}+(1-\rho)\theta^2$
-
更新參數$\theta_{t+1}=\theta_t+\Delta \theta_t$
8.end for
##tf.train.AdagradOptimizer
Adagrad會累加之前所有的梯度平方。
Δ θ t = − η ∑ τ t g τ 2 + ϵ ⨀ g t \Delta \theta_t=-\frac{\eta}{\sqrt{\sum_\tau^tg_{\tau}^2+ \epsilon}} \bigodot g_t Δθt=−∑τtgτ2+ϵ
η⨀gt
θ t + 1 = θ t − η ∑ τ t g τ 2 + ϵ ⨀ g t \theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\sum_\tau^tg_{\tau}^2+\epsilon}} \bigodot g_t θt+1=θt−∑τtgτ2+ϵ
η⨀gt
通常上述的求和針對一個窗長 w w w求解,以減小運算量。
##tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizer
動量法的原理是,如果梯度長時間保持一個方向(為正或者長時間為負),則增大參數更新幅度,反之,如果頻繁發生符号翻轉,則說明這是要減小參數更新幅度。可以把這一過程了解成從山頂放下一個球,會滑的越來越快。
θ t = ρ θ t − 1 − η d J ( θ ) d θ t \theta_t=\rho\theta_{t-1}-\eta\frac{dJ(\theta)}{d\theta_t} θt=ρθt−1−ηdθtdJ(θ)
##tf.train.AdamOptimizer
Adam(Adaptive Moment Estimation)加上了bias校正和momentum,在優化末期,梯度更稀疏時,它比RMSprop稍微好點。
m t = β 1 m t − 1 + ( 1 − β 1 ) g t m_t=\beta_1m_{t-1}+(1-\beta_1)g_t mt=β1mt−1+(1−β1)gt
v t = β 2 v t − 1 + ( 1 − β 2 ) g t 2 v_t=\beta_2v_{t-1}+(1-\beta_2)g_t^2 vt=β2vt−1+(1−β2)gt2
其中 m t m_t mt是梯度均值, v t v_t vt是梯度偏方差。這兩個值初始化時為0的張量。在訓練開始時, m t m_t mt和 v t v_t vt趨向于零。可以使用如下估計方法抵消:
m ^ t = m t 1 − β 1 t \hat m_t=\frac{m_t}{1-\beta_1^t} m^t=1−β1tmt
v ^ t = v t 1 − β 2 t \hat v_t=\frac{v_t}{1-\beta_2^t} v^t=1−β2tvt
θ t + 1 = θ t − η v ^ t + ϵ m ^ t \theta_{t+1}=\theta_t-\frac {\eta}{\sqrt{\hat v_t + \epsilon}}\hat m_t θt+1=θt−v^t+ϵ
ηm^t
##tf.train.FtrlOptimizer
##tf.train.ProximalGradientDescentOptimizer
##tf.train.ProximalAdagradOptimizer
##tf.train.RMSPropOptimizer
E [ g 2 ] t = 0.9 E [ g 2 ] t − 1 + 0.1 g t 2 E[g^2]_t=0.9E[g^2]_{t-1}+0.1g_t^2 E[g2]t=0.9E[g2]t−1+0.1gt2
θ ) t + 1 = θ t − η E [ g 2 ] t + ϵ ⨀ g t \theta){t+1}=\theta_t-\frac{\eta}{\sqrt{E[g^2]_t+\epsilon}}\bigodot g_t θ)t+1=θt−E[g2]t+ϵ
η⨀gt
學習速率梯度均方根均值指數衰減。
##如何選用optimizer
對于稀疏資料,使用學習率可自适應的優化方法,不用手動調節,而且最好采用預設值
SGD通常訓練時間更長,容易陷入鞍點,但是在好的初始化和學習率排程方案的情況下,結果更可靠
如果在意更快的收斂,并且需要訓練較深較複雜的網絡時,推薦使用學習率自适應的優化方法。
Adadelta,RMSprop,Adam是比較相近的算法,在相似的情況下表現差不多。
##其它梯度優化方法
1.資料重拍(shuffle函數)和資料多次重複訓練
2.批量歸一化,防止逐級訓練中的梯度消失和溢出
3.提前終止,防止過拟合,監控驗證資料集在訓練中的損失,合适時提前終止。
4.增加高斯分布的梯度噪聲,
g t , i = g t , i + N ( 0 , δ 2 ) g_{t,i}=g_{t,i}+N(0,\delta^2) gt,i=gt,i+N(0,δ2)
δ t 2 = η ( 1 + t ) γ \delta_t^2=\frac{\eta}{(1+t)^{\gamma}} δt2=(1+t)γη
這使得網絡對初始化不敏感。
##tensorflow中使用方法
建立優化器
# Create an optimizer with the desired parameters.
opt = GradientDescentOptimizer(learning_rate=0.1)
# Add Ops to the graph to minimize a cost by updating a list of variables.
# "cost" is a Tensor, and the list of variables contains tf.Variable
# objects.
opt_op = opt.minimize(cost, var_list=<list of variables>)
在訓練步驟中
# Execute opt_op to do one step of training:
opt_op.run()
minimize()函數處理了梯度計算和參數更新兩個操作,如果想獲得梯度并單獨處理,則compute_gradients()函數用于擷取梯度,apply_gradients()用于更新參數。
# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)
# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)
# grads_and_vars is a list of tuples (gradient, variable). Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]
# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)