轉載請注明出處,樓燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/
這幾種方法呢都是在求最優解中經常出現的方法,主要是應用迭代的思想來逼近。在梯度下降算法中,都是圍繞以下這個式子展開:
其中在上面的式子中\(h_\theta(x)\)代表,輸入為x的時候的其當時\(\theta\)參數下的輸出值,與y相減則是一個相對誤差,之后再平方乘以1/2,並且其中
這里我列舉了一個簡單的例子,當然實際的x可以有n多個維度。我們知道曲面上方向導數的最大值的方向就代表了梯度的方向,因此我們在做梯度下降的時候,應該是沿着梯度的反方向進行權重的更新,可以有效的找到全局的最優解。這個\(\theta\)的更新過程可以描述為
我一開始看這個式子也沒怎么看明白,后來想了一下,運來就是根據每一個x的分量以及當時的偏差值進行\(\theta\)的更新,其中\(\alpha\)為步長,一開始沒搞清楚步長和學習速率的關系。這里提一下其實這兩個是一個概念,叫法不一樣,最優化問題中叫步長,但一般在神經網絡中也叫學習速率,比較好理解。
對比梯度下降和隨機梯度下降和批量梯度下降
之前看的知識比較零散,沒有一個系統的解釋說明,看了一些網上的博主的分析,總結了一下自己的理解。
-
梯度下降:梯度下降就是我上面的推導,要留意,在梯度下降中,對於\(\theta\)的更新,所有的樣本都有貢獻,也就是參與調整\(\theta\).其計算得到的是一個標准梯度。因而理論上來說一次更新的幅度是比較大的。如果樣本不多的情況下,當然是這樣收斂的速度會更快啦~
-
隨機梯度下降:可以看到多了隨機兩個字,隨機也就是說我用樣本中的一個例子來近似我所有的樣本,來調整\(\theta\),因而隨機梯度下降是會帶來一定的問題,因為計算得到的並不是准確的一個梯度,容易陷入到局部最優解中
-
批量梯度下降:其實批量的梯度下降就是一種折中的方法,他用了一些小樣本來近似全部的,其本質就是我1個指不定不太准,那我用個30個50個樣本那比隨機的要准不少了吧,而且批量的話還是非常可以反映樣本的一個分布情況的。
例子這里我參照其他博主的例子做了一些修改,首先是梯度下降
#-*- coding: utf-8 -*-
import random
#This is a sample to simulate a function y = theta1*x1 + theta2*x2
input_x = [[1,4], [2,5], [5,1], [4,2]]
y = [19,26,19,20]
theta = [1,1]
loss = 10
step_size = 0.001
eps =0.0001
max_iters = 10000
error =0
iter_count = 0
while( loss > eps and iter_count < max_iters):
loss = 0
#這里更新權重的時候所有的樣本點都用上了
for i in range (3):
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
theta[0] = theta[0] - step_size * (pred_y - y[i]) * input_x[i][0]
theta[1] = theta[1] - step_size * (pred_y - y[i]) * input_x[i][1]
for i in range (3):
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
error = 0.5*(pred_y - y[i])**2
loss = loss + error
iter_count += 1
print 'iters_count', iter_count
print 'theta: ',theta
print 'final loss: ', loss
print 'iters: ', iter_count
iters_count 219
iters_count 220
iters_count 221
iters_count 222
iters_count 223
iters_count 224
iters_count 225
theta: [3.0027765778748003, 3.997918297015663]
final loss: 9.68238055213e-05
iters: 225
[Finished in 0.2s]
隨機梯度下降
每次選取一個隨機值,隨機一個點更新\(\theta\)
#-*- coding: utf-8 -*-
import random
#This is a sample to simulate a function y = theta1*x1 + theta2*x2
input_x = [[1,4], [2,5], [5,1], [4,2]]
y = [19,26,19,20]
theta = [1,1]
loss = 10
step_size = 0.001
eps =0.0001
max_iters = 10000
error =0
iter_count = 0
while( loss > eps and iter_count < max_iters):
loss = 0
#每一次選取隨機的一個點進行權重的更新
i = random.randint(0,3)
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
theta[0] = theta[0] - step_size * (pred_y - y[i]) * input_x[i][0]
theta[1] = theta[1] - step_size * (pred_y - y[i]) * input_x[i][1]
for i in range (3):
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
error = 0.5*(pred_y - y[i])**2
loss = loss + error
iter_count += 1
print 'iters_count', iter_count
print 'theta: ',theta
print 'final loss: ', loss
print 'iters: ', iter_count
其結果的輸出是
iters_count 1226
iters_count 1227
iters_count 1228
iters_count 1229
iters_count 1230
iters_count 1231
iters_count 1232
theta: [3.002441488688225, 3.9975844154600226]
final loss: 9.989420302e-05
iters: 1232
[Finished in 0.3s]
批量隨機梯度下降
這里用了2個樣本點
#-*- coding: utf-8 -*-
import random
#This is a sample to simulate a function y = theta1*x1 + theta2*x2
input_x = [[1,4], [2,5], [5,1], [4,2]]
y = [19,26,19,20]
theta = [1,1]
loss = 10
step_size = 0.001
eps =0.0001
max_iters = 10000
error =0
iter_count = 0
while( loss > eps and iter_count < max_iters):
loss = 0
i = random.randint(0,3) #注意這里,我這里批量每次選取的是2個樣本點做更新,另一個點是隨機點+1的相鄰點
j = (i+1)%4
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
theta[0] = theta[0] - step_size * (pred_y - y[i]) * input_x[i][0]
theta[1] = theta[1] - step_size * (pred_y - y[i]) * input_x[i][1]
pred_y = theta[0]*input_x[j][0]+theta[1]*input_x[j][1]
theta[0] = theta[0] - step_size * (pred_y - y[j]) * input_x[j][0]
theta[1] = theta[1] - step_size * (pred_y - y[j]) * input_x[j][1]
for i in range (3):
pred_y = theta[0]*input_x[i][0]+theta[1]*input_x[i][1]
error = 0.5*(pred_y - y[i])**2
loss = loss + error
iter_count += 1
print 'iters_count', iter_count
print 'theta: ',theta
print 'final loss: ', loss
print 'iters: ', iter_count
其最后的輸出結果是
.....
iters_count 543
iters_count 544
iters_count 545
iters_count 546
iters_count 547
iters_count 548
iters_count 549
theta: [3.0023012574840764, 3.997553282857357]
final loss: 9.81717138358e-05
iters: 549
對比一下結果,每個例子我都跑了幾次,基本上都維持在哪個迭代次數,可以看到梯度下降迭代的次數最少,因為我這里樣本點少,所以這樣快。數據多了的話,你想動則幾萬的樣本計算一次的時間就夠嗆。隨機梯度的話因為每次都用一個樣本,所以收斂的速度就會慢一些。批量的話這里用了2個樣本點,因而速度基本上隨機是1200度次迭代,批量大概是550。
其實這些概念一開始沒搞明白,在Caffe中,跑網絡,里面讓你選的這個batch其實就是這么回事。你設一個比較恰當的batch值是可以幫助網絡加速收斂的。
