梯度下降算法的Python實(shí)現(xiàn)

在上一篇邏輯回歸中,我們利用批量梯度下降算法BGD求解使損失函數(shù)J(θ)取得最小值的θ裆赵,同時(shí)也提到了SGD和MBGD弛矛,本篇我們實(shí)現(xiàn)下這三個(gè)算法,并進(jìn)行簡(jiǎn)單比較得问。關(guān)于梯度下降算法的原理可以參考https://www.cnblogs.com/pinard/p/5970503.html囤攀。

1. 批量梯度下降法(Batch Gradient Descent)

批量梯度下降算法是梯度下降算法的最常用形式,即在更新參數(shù)時(shí)利用所有的樣本來(lái)進(jìn)行更新宫纬,參數(shù)的更新過(guò)程可寫成:

BGD.gif

由于有m個(gè)樣本焚挠,所以求梯度的時(shí)候就用了所有m個(gè)樣本的梯度數(shù)據(jù)。

BGD的Python實(shí)現(xiàn)

def BGD_LR(data_x, data_y, alpha=0.1, maxepochs=10000, epsilon=1e-4):
    xMat = np.mat(data_x)
    yMat = np.mat(data_y)
    m,n = xMat.shape
    weights = np.ones((n,1)) #初始化模型參數(shù)
    epochs_count = 0
    loss_list = []
    epochs_list = []
    while epochs_count < maxepochs:
        loss = cost(xMat,weights,yMat) #上一次損失值
        hypothesis = sigmoid(np.dot(xMat,weights)) #預(yù)測(cè)值
        error = hypothesis -yMat #預(yù)測(cè)值與實(shí)際值誤差
        grad = (1.0/m)*np.dot(xMat.T,error) #損失函數(shù)的梯度
        last_weights = weights #上一輪迭代的參數(shù)
        weights = weights - alpha*grad #參數(shù)更新
        loss_new = cost(xMat,weights,yMat)#當(dāng)前損失值
        print(loss_new)
        if abs(loss_new-loss)<epsilon:#終止條件
            break
        loss_list.append(loss_new)
        epochs_list.append(epochs_count)
        epochs_count += 1
    print('迭代到第{}次漓骚,結(jié)束迭代蝌衔!'.format(epochs_count))
    plt.plot(epochs_list,loss_list)
    plt.xlabel('epochs')
    plt.ylabel('loss')
    plt.show()
    return weights

2. 隨機(jī)梯度下降法(Stochastic Gradient Descent)

批量梯度下降算法每次更新參數(shù)都需要遍歷整個(gè)數(shù)據(jù)集(通過(guò)遍歷整個(gè)數(shù)據(jù)集來(lái)計(jì)算損失函數(shù)的梯度),那么在樣本數(shù)據(jù)量巨大的時(shí)候蝌蹂,計(jì)算復(fù)雜度會(huì)很高噩斟。因此出現(xiàn)了隨機(jī)梯度下降算法:即每次迭代都隨機(jī)選取一個(gè)樣本計(jì)算損失函數(shù)的梯度來(lái)更新參數(shù)。參數(shù)更新公式可變?yōu)椋?/p>

SGD.gif

與批量梯度下降算法相比孤个,SGD的區(qū)別在于求梯度時(shí)沒有用所有的m個(gè)樣本數(shù)據(jù)剃允,而是隨機(jī)選取了一個(gè)樣本i來(lái)求梯度。在樣本量很大的時(shí)候,SGD由于僅采用了一個(gè)樣本來(lái)迭代斥废,因此訓(xùn)練速度很快覆享,但很可能導(dǎo)致解不是最優(yōu)的,準(zhǔn)確度下降营袜。

SGD的Python實(shí)現(xiàn)

def SGD_LR(data_x, data_y, alpha=0.1, maxepochs=10000,epsilon=1e-4):
    xMat = np.mat(data_x)
    yMat = np.mat(data_y)
    m, n = xMat.shape
    weights = np.ones((n, 1))  # 模型參數(shù)
    epochs_count = 0
    loss_list = []
    epochs_list = []
    while epochs_count < maxepochs:
        rand_i = np.random.randint(m)  # 隨機(jī)取一個(gè)樣本
        loss = cost(xMat,weights,yMat) #前一次迭代的損失值
        hypothesis = sigmoid(np.dot(xMat[rand_i,:],weights)) #預(yù)測(cè)值
        error = hypothesis -yMat[rand_i,:] #預(yù)測(cè)值與實(shí)際值誤差
        grad = np.dot(xMat[rand_i,:].T,error) #損失函數(shù)的梯度
        weights = weights - alpha*grad #參數(shù)更新
        loss_new = cost(xMat,weights,yMat)#當(dāng)前迭代的損失值
        print(loss_new)
        if abs(loss_new-loss)<epsilon:
            break
        loss_list.append(loss_new)
        epochs_list.append(epochs_count)
        epochs_count += 1
    print('迭代到第{}次,結(jié)束迭代丑罪!'.format(epochs_count))
    plt.plot(epochs_list,loss_list)
    plt.xlabel('epochs')
    plt.ylabel('loss')
    plt.show()
    return weights

3. 小批量梯度下降法(Mini-batch Gradient Descent)

小批量梯度下降法是批量梯度下降算法與隨機(jī)梯度下降算法的折中荚板,因?yàn)橛靡粋€(gè)樣本代表全部可能不太準(zhǔn),那么選取其中一部分來(lái)代表全部的樣本會(huì)比只用一個(gè)好很多吩屹。即對(duì)于m個(gè)樣本跪另,每次迭代選取其中x個(gè)樣本進(jìn)行更新參數(shù),其中x稱為小批量大小(1<x<m)煤搜。對(duì)應(yīng)的參數(shù)更新公式為:

MBGD.gif

MBGD的Python實(shí)現(xiàn)

def MBGD_LR(data_x, data_y, alpha=0.1,batch_size=3, maxepochs=10000,epsilon=1e-4):
    xMat = np.mat(data_x)
    yMat = np.mat(data_y)
    m, n = xMat.shape
    weights = np.ones((n, 1))  # 模型參數(shù)
    epochs_count = 0
    loss_list = []
    epochs_list = []
    while epochs_count < maxepochs:
        randIndex = np.random.choice(range(len(xMat)), batch_size, replace=False)
        loss = cost(xMat,weights,yMat) #前一次迭代的損失值
        hypothesis = sigmoid(np.dot(xMat[randIndex],weights)) #預(yù)測(cè)值
        error = hypothesis -yMat[randIndex] #預(yù)測(cè)值與實(shí)際值誤差
        grad = np.dot(xMat[randIndex].T,error) #損失函數(shù)的梯度
        weights = weights - alpha*grad #參數(shù)更新
        loss_new = cost(xMat,weights,yMat)#當(dāng)前迭代的損失值
        print(loss_new)
        if abs(loss_new-loss)<epsilon:#終止條件
            break
        loss_list.append(loss_new)
        epochs_list.append(epochs_count)
        epochs_count += 1
    print('迭代到第{}次免绿,結(jié)束迭代!'.format(epochs_count))
    plt.plot(epochs_list,loss_list)
    plt.xlabel('epochs')
    plt.ylabel('loss')
    plt.show()
    return weights

運(yùn)行結(jié)果

比較.png
BGD-Loss收斂情況.png
SGD-Loss收斂情況.png
MBGD-Loss收斂情況.png

在小數(shù)據(jù)集上分別跑了這三種方法擦盾,可以看出SGD受噪聲的影響嘲驾,其損失函數(shù)的收斂伴隨的震動(dòng)比較大;而MBGD通過(guò)設(shè)置3個(gè)小批量明顯減弱了收斂的震動(dòng)現(xiàn)象迹卢,且更接近BGD訓(xùn)練得到的最小損失函數(shù)值辽故。

總結(jié)

BGD:每次迭代使用所有樣本來(lái)計(jì)算損失函數(shù)的梯度
SGD:每次迭代隨機(jī)選取1個(gè)樣本來(lái)計(jì)算損失函數(shù)的梯度
MBGD:每次迭代隨機(jī)選取x個(gè)樣本來(lái)計(jì)算損失函數(shù)的梯度

以上只是自己的學(xué)習(xí)反饋,如有錯(cuò)誤腐碱,歡迎指正誊垢。
本文代碼地址:https://github.com/DaHuangTyro/Daily_Machine_Learning

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市症见,隨后出現(xiàn)的幾起案子喂走,更是在濱河造成了極大的恐慌,老刑警劉巖谋作,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芋肠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡遵蚜,警方通過(guò)查閱死者的電腦和手機(jī)业栅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谬晕,“玉大人碘裕,你說(shuō)我怎么就攤上這事≡芮” “怎么了帮孔?”我有些...
    開封第一講書人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我文兢,道長(zhǎng)晤斩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任姆坚,我火速辦了婚禮澳泵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘兼呵。我一直安慰自己兔辅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開白布击喂。 她就那樣靜靜地躺著维苔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪懂昂。 梳的紋絲不亂的頭發(fā)上介时,一...
    開封第一講書人閱讀 49,906評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音凌彬,去河邊找鬼沸柔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛铲敛,可吹牛的內(nèi)容都是我干的勉失。 我是一名探鬼主播,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼原探,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼乱凿!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起咽弦,我...
    開封第一講書人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤徒蟆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后型型,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體段审,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年闹蒜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寺枉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绷落,死狀恐怖姥闪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情砌烁,我是刑警寧澤筐喳,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布催式,位于F島的核電站,受9級(jí)特大地震影響避归,放射性物質(zhì)發(fā)生泄漏荣月。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一梳毙、第九天 我趴在偏房一處隱蔽的房頂上張望哺窄。 院中可真熱鬧,春花似錦账锹、人聲如沸萌业。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至啤握,卻和暖如春鸟缕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背排抬。 一陣腳步聲響...
    開封第一講書人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工懂从, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹲蒲。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓番甩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親届搁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缘薛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容