监督学习——随机梯度下降算法(sgd)和批梯度下降算法(bgd)
線(xiàn)性回歸
?????? 首先要明白什么是回歸。回歸的目的是通過(guò)幾個(gè)已知數(shù)據(jù)來(lái)預(yù)測(cè)另一個(gè)數(shù)值型數(shù)據(jù)的目標(biāo)值。
????? 假設(shè)特征和結(jié)果滿(mǎn)足線(xiàn)性關(guān)系,即滿(mǎn)足一個(gè)計(jì)算公式h(x),這個(gè)公式的自變量就是已知的數(shù)據(jù)x,函數(shù)值h(x)就是要預(yù)測(cè)的目標(biāo)值。這一計(jì)算公式稱(chēng)為回歸方程,得到這個(gè)方程的過(guò)程就稱(chēng)為回歸。
?????? 假設(shè)房子的房屋面積和臥室數(shù)量為自變量x,用x1表示房屋面積,x2表示臥室數(shù)量;房屋的交易價(jià)格為因變量y,我們用h(x)來(lái)表示y。假設(shè)房屋面積、臥室數(shù)量與房屋的交易價(jià)格是線(xiàn)性關(guān)系。
他們滿(mǎn)足公式
上述公式中的θ為參數(shù),也稱(chēng)為權(quán)重,可以理解為x1和x2對(duì)h(x)的影響度。對(duì)這個(gè)公式稍作變化就是
公式中θ和x都可以看成是向量,n是特征數(shù)量。
假如我們依據(jù)這個(gè)公式來(lái)預(yù)測(cè)h(x),公式中的x是我們已知的(樣本中的特征值),然而θ的取值卻不知道,只要我們把θ的取值求解出來(lái),我們就可以依據(jù)這個(gè)公式來(lái)做預(yù)測(cè)了。
最小均方法(Least Mean squares)
?????? 在介紹LMS之前先了解一下什么損失函數(shù)的概念。
?????? 我們要做的是依據(jù)我們的訓(xùn)練集,選取最優(yōu)的θ,在我們的訓(xùn)練集中讓h(x)盡可能接近真實(shí)的值。h(x)和真實(shí)的值之間的差距,我們定義了一個(gè)函數(shù)來(lái)描述這個(gè)差距,這個(gè)函數(shù)稱(chēng)為損失函數(shù),表達(dá)式如下:
?????? 這里的這個(gè)損失函數(shù)就是著名的最小二乘損失函數(shù),這里還涉及一個(gè)概念叫最小二乘法,這里不再展開(kāi)了。我們要選擇最優(yōu)的θ,使得h(x)最近進(jìn)真實(shí)值。這個(gè)問(wèn)題就轉(zhuǎn)化為求解最優(yōu)的θ,使損失函數(shù)J(θ)取最小值。(損失函數(shù)還有其它很多種類(lèi)型)
那么如何解決這個(gè)轉(zhuǎn)化后的問(wèn)題呢?這又牽扯到一個(gè)概念:LMS 和 梯度下降(Radient Descent)。
????? LMS是求取h(x)回歸函數(shù)的理論依據(jù),通過(guò)最小化均方誤差來(lái)求最佳參數(shù)的方法。
梯度下降
?????? 我們要求解使得J(θ)最小的θ值,梯度下降算法大概的思路是:我們首先隨便給θ一個(gè)初始化的值,然后改變?chǔ)戎底孞(θ)的取值變小,不斷重復(fù)改變?chǔ)仁笿(θ)變小的過(guò)程直至J(θ)約等于最小值。
首先我們給θ一個(gè)初始值,然后向著讓J(θ)變化最大的方向更新θ的取值,如此迭代。公式如下:
公式中α稱(chēng)為步長(zhǎng)(learning rate),它控制θ每次向J(θ)變小的方向迭代時(shí)的變化幅度。J(θ)對(duì)θ的偏導(dǎo)表示J(θ)變化最大的方向。由于求的是極小值,因此梯度方向是偏導(dǎo)數(shù)的反方向。
- α取值太小收斂速度太慢,太大則可能會(huì)Overshoot the minimum。
- 越接近最小值時(shí),下降速度越慢
- 收斂: 當(dāng)前后兩次迭代的差值小于某一值時(shí),迭代結(jié)束
求解一下這個(gè)偏導(dǎo),過(guò)程如下:
那么θ的迭代公式就變?yōu)?#xff1a;
上述表達(dá)式只針對(duì)樣本數(shù)量只有一個(gè)的時(shí)候適用,那么當(dāng)有m個(gè)樣本值時(shí)該如何計(jì)算預(yù)測(cè)函數(shù)?批梯度下降算法和隨機(jī)梯度下降算法
批梯度下降算法(BGD)
有上一節(jié)中單個(gè)樣本的參數(shù)計(jì)算公式轉(zhuǎn)化為處理多個(gè)樣本就是如下表達(dá):
這種新的表達(dá)式每一步計(jì)算都需要全部訓(xùn)練集數(shù)據(jù),所以稱(chēng)之為批梯度下降(batch gradient descent)。
注意,梯度下降可能得到局部最優(yōu),但在優(yōu)化問(wèn)題里我們已經(jīng)證明線(xiàn)性回歸只有一個(gè)最優(yōu)點(diǎn),因?yàn)閾p失函數(shù)J(θ)是一個(gè)二次的凸函數(shù),不會(huì)產(chǎn)生局部最優(yōu)的情況。(假設(shè)學(xué)習(xí)步長(zhǎng)α不是特別大)
批梯度下降的算法執(zhí)行過(guò)程如下圖:
大家仔細(xì)看批梯度下降的數(shù)學(xué)表達(dá)式,每次迭代的時(shí)候都要對(duì)所有數(shù)據(jù)集樣本計(jì)算求和,計(jì)算量就會(huì)很大,尤其是訓(xùn)練數(shù)據(jù)集特別大的情況。那有沒(méi)有計(jì)算量較小,而且效果也不錯(cuò)的方法呢?有!這就是:隨機(jī)梯度下降(Stochastic Gradient Descent, SGD)
隨機(jī)梯度下降算法(SGD)
隨機(jī)梯度下降在計(jì)算下降最快的方向時(shí)時(shí)隨機(jī)選一個(gè)數(shù)據(jù)進(jìn)行計(jì)算,而不是掃描全部訓(xùn)練數(shù)據(jù)集,這樣就加快了迭代速度。
隨機(jī)梯度下降并不是沿著J(θ)下降最快的方向收斂,而是震蕩的方式趨向極小點(diǎn)。
隨機(jī)梯度下降表達(dá)式如下:
執(zhí)行過(guò)程如下圖:
批梯度下降和隨機(jī)梯度下降在三維圖上對(duì)比如下:
基于梯度下降算法的python3實(shí)現(xiàn)如下:(注釋部分為BGD的實(shí)現(xiàn))
1 # -*- coding: cp936 -*- 2 import numpy as np 3 from scipy import stats 4 import matplotlib.pyplot as plt 5 6 7 # 構(gòu)造訓(xùn)練數(shù)據(jù) 8 x = np.arange(0., 10., 0.2) 9 m = len(x) # 訓(xùn)練數(shù)據(jù)點(diǎn)數(shù)目 10 x0 = np.full(m, 1.0) 11 input_data = np.vstack([x0, x]).T # 將偏置b作為權(quán)向量的第一個(gè)分量 12 target_data = 2 * x + 5 + np.random.randn(m) 13 14 15 # 兩種終止條件 16 loop_max = 10000 # 最大迭代次數(shù)(防止死循環(huán)) 17 epsilon = 1e-3 18 19 # 初始化權(quán)值 20 np.random.seed(0) 21 w = np.random.randn(2) 22 #w = np.zeros(2) 23 24 alpha = 0.001 # 步長(zhǎng)(注意取值過(guò)大會(huì)導(dǎo)致振蕩,過(guò)小收斂速度變慢) 25 diff = 0. 26 error = np.zeros(2) 27 count = 0 # 循環(huán)次數(shù) 28 finish = 0 # 終止標(biāo)志 29 # -------------------------------------------隨機(jī)梯度下降算法---------------------------------------------------------- 30 31 while count < loop_max: 32 count += 1 33 34 # 遍歷訓(xùn)練數(shù)據(jù)集,不斷更新權(quán)值 35 for i in range(m): 36 diff = np.dot(w, input_data[i]) - target_data[i] # 訓(xùn)練集代入,計(jì)算誤差值 37 38 # 采用隨機(jī)梯度下降算法,更新一次權(quán)值只使用一組訓(xùn)練數(shù)據(jù) 39 w = w - alpha * diff * input_data[i] 40 41 # ------------------------------終止條件判斷----------------------------------------- 42 # 若沒(méi)終止,則繼續(xù)讀取樣本進(jìn)行處理,如果所有樣本都讀取完畢了,則循環(huán)重新從頭開(kāi)始讀取樣本進(jìn)行處理。 43 44 # ----------------------------------終止條件判斷----------------------------------------- 45 # 注意:有多種迭代終止條件,和判斷語(yǔ)句的位置。終止判斷可以放在權(quán)值向量更新一次后,也可以放在更新m次后。 46 if np.linalg.norm(w - error) < epsilon: # 終止條件:前后兩次計(jì)算出的權(quán)向量的絕對(duì)誤差充分小 47 finish = 1 48 break 49 else: 50 error = w 51 print ('loop count = %d' % count, '\tw:[%f, %f]' % (w[0], w[1])) 52 53 54 # -----------------------------------------------梯度下降法----------------------------------------------------------- 55 56 ''' 57 while count < loop_max: 58 count += 1 59 60 # 標(biāo)準(zhǔn)梯度下降是在權(quán)值更新前對(duì)所有樣例匯總誤差,而隨機(jī)梯度下降的權(quán)值是通過(guò)考查某個(gè)訓(xùn)練樣例來(lái)更新的 61 # 在標(biāo)準(zhǔn)梯度下降中,權(quán)值更新的每一步對(duì)多個(gè)樣例求和,需要更多的計(jì)算 62 sum_m = np.zeros(2) 63 for i in range(m): 64 dif = (np.dot(w, input_data[i]) - target_data[i]) * input_data[i] 65 sum_m = sum_m + dif # 當(dāng)alpha取值過(guò)大時(shí),sum_m會(huì)在迭代過(guò)程中會(huì)溢出 66 67 w = w - alpha * sum_m # 注意步長(zhǎng)alpha的取值,過(guò)大會(huì)導(dǎo)致振蕩 68 #w = w - 0.005 * sum_m # alpha取0.005時(shí)產(chǎn)生振蕩,需要將alpha調(diào)小 69 70 # 判斷是否已收斂 71 if np.linalg.norm(w - error) < epsilon: 72 finish = 1 73 break 74 else: 75 error = w 76 print ('loop count = %d' % count, '\tw:[%f, %f]' % (w[0], w[1])) 77 78 ''' 79 80 # check with scipy linear regression 81 slope, intercept, r_value, p_value, slope_std_error = stats.linregress(x, target_data) 82 print ('intercept = %s slope = %s' %(intercept, slope)) 83 84 plt.plot(x, target_data, 'k+') 85 plt.plot(x, w[1] * x + w[0], 'r') 86 plt.show() 87總結(jié):
???? 開(kāi)年第一篇,加油
參考:
http://mp.weixin.qq.com/s/7WlGN8JxfSmpJ8K_EyvgQA
http://m.elecfans.com/article/587673.html
轉(zhuǎn)載于:https://www.cnblogs.com/NeilZhang/p/8454890.html
總結(jié)
以上是生活随笔為你收集整理的监督学习——随机梯度下降算法(sgd)和批梯度下降算法(bgd)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一个简单IOC与DI示例
- 下一篇: ps 命令详解