理論部分
對(duì)于最基本的線性回歸問(wèn)題兼贡,公式如下:
θ是權(quán)重參數(shù)废累,也就是我們需要去梯度下降求解的具體值,
(我們拿一堆的數(shù)據(jù)來(lái)擬合出最佳的θ[誤])
用數(shù)據(jù)擬合h(x)脱盲,通過(guò)最佳的θ邑滨,得到最佳擬合曲線hθ(x),然后在預(yù)測(cè)的時(shí)候就只要直接用這個(gè)公式就好了钱反。梯度下降時(shí)掖看,你如何評(píng)估你最新的參數(shù)是向著正確的方向進(jìn)行修正的呢?我們引入損失函數(shù)面哥,直觀上理解就是我更新一組參數(shù)后哎壳,你效果必須是越來(lái)越好的,誤差也是越來(lái)越少的尚卫。
注意:是最小二乘誤差的和喲耳峦,也就是m個(gè)樣本每個(gè)都要計(jì)算一次樣本(在當(dāng)前的θ參數(shù)下);前面的1/2是為了求偏導(dǎo)時(shí)消除系數(shù)的焕毫。
ps. 為什么用最小二乘作為誤差函數(shù)呢蹲坷? 答案在這!知乎上解釋的很透徹了邑飒。
簡(jiǎn)單來(lái)說(shuō)就是前提假設(shè)是高斯分布循签,因此化簡(jiǎn)(見(jiàn)上述鏈接)后就是最小二乘,而高斯分布是大自然里很自然的一個(gè)屬性疙咸,遵天道县匠。
這是直觀化的梯度下降圖示:
梯度下降更新權(quán)重參數(shù)的過(guò)程中我們需要對(duì)損失函數(shù)求偏導(dǎo)數(shù):
求完偏導(dǎo)數(shù)以后就可以進(jìn)行參數(shù)更新了:
上面公式中的alpha就是下面圖中的步長(zhǎng)lamda:
總結(jié):理論上是先求得誤差函數(shù),然后誤差函數(shù)對(duì)參數(shù)θ求偏導(dǎo)撒轮,求得后再更新參數(shù)就好了
實(shí)踐部分
深度學(xué)習(xí)的核心理念:輸入乞旦,然后設(shè)定期望的輸出,找到二者的相關(guān)性题山。
最小二乘:
我們先猜測(cè)函數(shù)的位置兰粉,然后平方其誤差,重新做出猜測(cè)顶瞳,以減少平方誤差的和玖姑。這是線性回歸的種子愕秫。
#最小二乘法least squares
################################################################################
#在當(dāng)前給定的參數(shù)a,b下計(jì)算所有誤差值的平方和并取均值
# ################################################################################
def compute_error_for_line_given_points(b,a,datas):
totalError = 0
for i in range(0,len(datas)):
x = datas[i][0]
y = datas[i][1]
totalError += (y-(a*x+b))**2
return totalError/float(len(datas))
print compute_error_for_line_given_points(1,2,[[3,6],[6,9],[12,18]])
總結(jié):這里講了如何求誤差函數(shù),當(dāng)然這里求的是最簡(jiǎn)單的一元變量焰络。在一個(gè)給定參數(shù)情況下計(jì)算整體的平均誤差值戴甩。
梯度下降:
比如下面這個(gè)函數(shù),我們知道在極小值左邊導(dǎo)數(shù)是小于0的闪彼,右邊是大于0 的甜孤,同時(shí)越靠近極值點(diǎn)導(dǎo)數(shù)絕對(duì)值越小(可理解為梯度很形吠蟆)缴川。
- 那么我們可以這樣思考:首先我隨機(jī)選擇一個(gè)x點(diǎn),然后計(jì)算其導(dǎo)致郊尝,假如小于0我就往右挪動(dòng)一點(diǎn)二跋,大于0我就往左移動(dòng)一點(diǎn),最終總會(huì)挪動(dòng)到極值點(diǎn)處的流昏;
- 這其中需要思考的是:移動(dòng)步長(zhǎng)多少為好呢扎即?太大了不收斂,太小了時(shí)間花銷大况凉;既然無(wú)法確定谚鄙,那么我們就定一個(gè)超參數(shù)嘛,讓這個(gè)值(就是上面參數(shù)更新公式中的alpha刁绒,也就是下面代碼中的學(xué)習(xí)率)手動(dòng)來(lái)調(diào)闷营,多調(diào)幾次就知道了嘛(目前階段這樣做無(wú)可厚非嘛)~
current_x += -learning_rate*slope_at_given_x_value(previous_x)
################################################################################
#http://mp.weixin.qq.com/s/8as8ai5W0RlLOhHT6sswjA
#梯度下降
################################################################################
current_x = 0.5 #啟動(dòng)點(diǎn)
learning_rate = 0.01#學(xué)習(xí)率
num_iterations = 10 #迭代次數(shù)
#這個(gè)是斜率
def slope_at_given_x_value(x):
return 5*x**4 - 6*x**2
#整體表達(dá)的是一個(gè)移動(dòng)的概念,往“城市”中心移動(dòng)(基于斜率)知市。
#也就是我選定一個(gè)初始點(diǎn)傻盟,然后看這一點(diǎn)的斜率值,在極小值點(diǎn)左邊是斜率小于零嫂丙,右邊是斜率大于零娘赴,
#因此我們隨機(jī)選擇一個(gè)點(diǎn)后,把當(dāng)前點(diǎn)加上一個(gè)趨勢(shì)跟啤,在極值點(diǎn)左邊就加诽表,右邊就減去,這樣不斷迭代就好了隅肥。
for i in range(num_iterations):
previous_x = current_x
current_x += -learning_rate*slope_at_given_x_value(previous_x)
print(previous_x)
print "the local minimum occurs at %f" % current_x
這里可以把x看作是梯度下降里面的參數(shù)竿奏,假設(shè)只有一個(gè)參數(shù)時(shí)的情況,屬一元變量腥放。
總結(jié):可以將上述的
slope_at_given_x_value(x)
函數(shù)看作誤差函數(shù)泛啸,然后這里講了如何求導(dǎo)誤差函數(shù)的極小值,當(dāng)然也是在一元變量的情況下做的捉片。
線性回歸:
通過(guò)組合最小二乘法和梯度下降法平痰,就可以得到線性回歸汞舱。
################################################################################
#最小二乘法 + 梯度下降 == 線性回歸
################################################################################
#price of wheat/Kg and the average price of bread
wheat_and_bread = [[0.5,5],[0.6,5.5],[0.8,6],[1.1,6.8],[1.4,7]]
def step_gradient(b_current,a_current,datas,learningRate):
b_gradient = 0
a_gradient = 0
N = float(len(datas))
#這里是把所有的數(shù)據(jù)集的誤差值求出來(lái)伍纫,然后
for i in range(0,len(datas)):
x = datas[i][0]
y = datas[i][1]
b_gradient += -(2/N) * (y - ((a_current*x + b_current)))
a_gradient += -(2/N) * x * (y - ((a_current*x + b_current)))
new_b = b_current - (learningRate * b_gradient)
new_a = a_current - (learningRate * a_gradient)
return [new_b,new_a]
def gradient_descent_runner(datas,starting_b,starting_a,learning_rate,num_iterations):
b = starting_b
a = starting_a
for i in range(num_iterations):
b,a = step_gradient(b,a,datas,learning_rate)
return [b,a]
print gradient_descent_runner(wheat_and_bread,1,1,0.01,100)
因?yàn)槭且辉兞康木€性擬合宗雇,所以擬合函數(shù)是y=ax+b,需要求的參數(shù)是a,b莹规;
自變量(特征)={x};只有x一個(gè)赔蒲。
參數(shù)θ={a,b};兩個(gè)參數(shù)需求解。
因此我的梯度下降是這樣做的:首先把a(bǔ),b參數(shù)初始化為0良漱,然后由于已知擬合函數(shù)形式了舞虱,因此直接代入偏導(dǎo)函數(shù)求參數(shù):
對(duì)應(yīng)代碼為:
b_gradient += -(2/N) * (y - ((a_current*x + b_current)))
上面的2是因?yàn)槲覀兌x誤差函數(shù)的時(shí)候是沒(méi)有加1/2的,因此這里求偏導(dǎo)后有個(gè)2(2次方)母市,同時(shí)求得是整體的平均誤差矾兜,因此每個(gè)誤差前面乘以個(gè)1/N。
a_gradient += -(2/N) * x * (y - ((a_current*x + b_current)))
分析同上患久,但是這里多乘了個(gè)
x
椅寺,為啥?因?yàn)樘荻裙奖緛?lái)就是這樣的敖А返帕!那個(gè)b_gradient因?yàn)槭浅?shù)項(xiàng),即x的0次方(特征1)所以直接是1了篙挽,省略荆萤;而這個(gè)是x的1次方(特征2),因此直接按公式將這個(gè)特征乘以就好了铣卡。
總結(jié):對(duì)比之前的那個(gè)一元變量的導(dǎo)數(shù)(斜率)可知链韭,這里的偏導(dǎo)思路跟那是一樣的啊,目標(biāo)就是更新參數(shù)煮落,而參數(shù)的更新就是偏導(dǎo)嘛(導(dǎo)數(shù)咯)敞峭,偏導(dǎo)就是上面一元函數(shù)里面的斜率嘛,這么對(duì)照著直接理解的話就可以知道過(guò)程是一樣的州邢,都是圍繞某一個(gè)參數(shù)變量求導(dǎo)數(shù)(當(dāng)然數(shù)據(jù)量多的時(shí)候求導(dǎo)數(shù)的平均值)儡陨,然后不斷修改之就好啦~
三種梯度下降方法
【資料引用來(lái)源】
一般線性回歸函數(shù)的假設(shè)函數(shù)為(x是一些特診變量):
批量梯度下降法(BGD)
我們的目的是要誤差函數(shù)盡可能的小,即求解weights使誤差函數(shù)盡可能小量淌。
首先骗村,我們隨機(jī)初始化weigths,然后不斷反復(fù)的更新weights使得誤差函數(shù)減小呀枢,直到滿足要求時(shí)停止胚股。
這里更新算法我們選擇梯度下降算法,利用初始化的weights并且反復(fù)更新weights:
則對(duì)所有數(shù)據(jù)點(diǎn)刻坊,上述損失函數(shù)的偏導(dǎo)(累和)為:
再最小化損失函數(shù)的過(guò)程中,需要不斷反復(fù)的更新weights使得誤差函數(shù)減小党晋,更新過(guò)程如下:
那么好了谭胚,每次參數(shù)更新的偽代碼如下:
由上圖更新公式我們就可以看到,我們每一次的參數(shù)更新都用到了所有的訓(xùn)練數(shù)據(jù)(比如有m個(gè)未玻,就用到了m個(gè))灾而,如果訓(xùn)練數(shù)據(jù)非常多的話,是非常耗時(shí)的扳剿。
下面給出批梯度下降的收斂圖:
隨機(jī)梯度下降法(SGD)
由于批梯度下降每跟新一個(gè)參數(shù)的時(shí)候旁趟,要用到所有的樣本數(shù),所以訓(xùn)練速度會(huì)隨著樣本數(shù)量的增加而變得非常緩慢庇绽。隨機(jī)梯度下降正是為了解決這個(gè)辦法而提出的锡搜。它是利用每個(gè)樣本的損失函數(shù)對(duì)θ求偏導(dǎo)得到對(duì)應(yīng)的梯度,來(lái)更新θ:
更新過(guò)程如下:
隨機(jī)梯度下降是通過(guò)每個(gè)樣本來(lái)迭代更新一次敛劝,對(duì)比上面的批量梯度下降余爆,迭代一次需要用到所有訓(xùn)練樣本(往往如今真實(shí)問(wèn)題訓(xùn)練數(shù)據(jù)都是非常巨大),一次迭代不可能最優(yōu)夸盟,如果迭代10次的話就需要遍歷訓(xùn)練樣本10次蛾方。
但是,SGD伴隨的一個(gè)問(wèn)題是噪音較BGD要多上陕,使得SGD并不是每次迭代都向著整體最優(yōu)化方向桩砰。
隨機(jī)梯度下降收斂圖如下:
我們可以從圖中看出SGD迭代的次數(shù)較多,在解空間的搜索過(guò)程看起來(lái)很盲目释簿。但是大體上是往著最優(yōu)值方向移動(dòng)亚隅。
小批量梯度下降法(MBGD)
我們從上面兩種梯度下降法可以看出,其各自均有優(yōu)缺點(diǎn)庶溶,那么能不能在兩種方法的性能之間取得一個(gè)折衷呢煮纵?既算法的訓(xùn)練過(guò)程比較快,而且也要保證最終參數(shù)訓(xùn)練的準(zhǔn)確率偏螺,而這正是小批量梯度下降法(Mini-batch Gradient Descent行疏,簡(jiǎn)稱MBGD)的初衷。
我們假設(shè)每次更新參數(shù)的時(shí)候用到的樣本數(shù)為10個(gè)(不同的任務(wù)完全不同套像,這里舉一個(gè)例子而已)
更新偽代碼如下:
三種梯度下降方法的總結(jié)
批梯度下降每次更新使用了所有的訓(xùn)練數(shù)據(jù)酿联,最小化損失函數(shù),如果只有一個(gè)極小值,那么批梯度下降是考慮了訓(xùn)練集所有數(shù)據(jù)贞让,是朝著最小值迭代運(yùn)動(dòng)的周崭,但是缺點(diǎn)是如果樣本值很大的話,更新速度會(huì)很慢喳张。
隨機(jī)梯度下降在每次更新的時(shí)候续镇,只考慮了一個(gè)樣本點(diǎn),這樣會(huì)大大加快訓(xùn)練數(shù)據(jù)蹲姐,也恰好是批梯度下降的缺點(diǎn)磨取,但是有可能由于訓(xùn)練數(shù)據(jù)的噪聲點(diǎn)較多人柿,那么每一次利用噪聲點(diǎn)進(jìn)行更新的過(guò)程中柴墩,就不一定是朝著極小值方向更新,但是由于更新多輪凫岖,整體方向還是大致朝著極小值方向更新江咳,又提高了速度。
小批量梯度下降法是為了解決批梯度下降法的訓(xùn)練速度慢哥放,以及隨機(jī)梯度下降法的準(zhǔn)確性綜合而來(lái)歼指,但是這里注意,不同問(wèn)題的batch是不一樣的甥雕,根據(jù)實(shí)驗(yàn)結(jié)果來(lái)迭代調(diào)整踩身。