圖文詳解梯度下降算法的原理及Python實(shí)現(xiàn)
1.引例
給定如圖所示的某個(gè)函數(shù),如何通過計(jì)算機(jī)算法編程求f(x)min?
2.數(shù)值解法
傳統(tǒng)方法是數(shù)值解法,如圖所示
按照以下步驟迭代循環(huán)直至最優(yōu):
① 任意給定一個(gè)初值x0;
② 隨機(jī)生成增量方向,結(jié)合步長(zhǎng)生成Δx;
③ 計(jì)算比較f(x0)與f(x0+Δx)的大小,若f(x0+Δx)<f(x0)則更新位置,否則重新生成Δx;
④ 重復(fù)②③直至收斂到最優(yōu)f(x)min。
數(shù)值解法最大的優(yōu)點(diǎn)是編程簡(jiǎn)明,但缺陷也很明顯:
① 初值的設(shè)定對(duì)結(jié)果收斂快慢影響很大;
② 增量方向隨機(jī)生成,效率較低;
③ 容易陷入局部最優(yōu)解;
④ 無法處理“高原”類型函數(shù)。
所謂陷入局部最優(yōu)解是指當(dāng)?shù)M(jìn)入到某個(gè)極小值或其鄰域時(shí),由于步長(zhǎng)選擇不恰當(dāng),無論正方向還是負(fù)方向,學(xué)習(xí)效果都不如當(dāng)前,導(dǎo)致無法向全局最優(yōu)迭代。就本問題而言如圖所示,當(dāng)?shù)萑離=xj時(shí),由于學(xué)習(xí)步長(zhǎng)step的限制,無法使f(xj±Step)<f(xj),因此迭代就被鎖死在了圖中的紅色區(qū)段??梢钥闯鰔=xj并非期望的全局最優(yōu)。
若出現(xiàn)下圖所示的“高原”函數(shù),也可能使迭代得不到更新。
3.梯度下降算法
梯度下降算法可視為數(shù)值解法的一種改進(jìn),闡述如下:
記第k輪迭代后,自變量更新為x=xk,令目標(biāo)函數(shù)f(x)在x=xk泰勒展開:
f(x)=f(xk?)+f′(xk?)(x−xk?)+o(x)
考察f(x)min ,則期望f(xk+1)<f(xk),從而:
f(xk+1?)−f(xk?)=f′(xk?)(xk+1?−xk?)<0
若f′(xk)>0則xk+1<xk ,即迭代方向?yàn)樨?fù);反之為正。不妨設(shè)xk+1−xk=−f′(xk),從而保證f(xk+1)−f(xk)<0。必須指出,泰勒公式成立的條件是x→x0,故|f′(xk)|不能太大,否則xk+1與xk距離太遠(yuǎn)產(chǎn)生余項(xiàng)誤差。因此引入學(xué)習(xí)率γ∈(0,1)來減小偏移度,即xk+1-xk=−γf′(xk?)
在工程上,學(xué)習(xí)率γ \gammaγ要結(jié)合實(shí)際應(yīng)用合理選擇,γ \gammaγ過大會(huì)使迭代在極小值兩側(cè)振蕩,算法無法收斂;γ \gammaγ過小會(huì)使學(xué)習(xí)效率下降,算法收斂慢。
對(duì)于向量 ,將上述迭代公式推廣為
xk+1?=xk?−γ∇xk??
其中
為多元函數(shù)的梯度,故此迭代算法也稱為梯度下降算法
梯度下降算法通過函數(shù)梯度確定了每一次迭代的方向和步長(zhǎng),提高了算法效率。但從原理上可以知道,此算法并不能解決數(shù)值解法中初值設(shè)定、局部最優(yōu)陷落和部分函數(shù)鎖死的問題。
4.代碼實(shí)戰(zhàn):Logistic回歸
import pandas as pd import numpy as np import os import matplotlib.pyplot as plt import matplotlib as mpl from Logit import Logit ''' * @breif: 從CSV中加載指定數(shù)據(jù) * @param[in]: file -> 文件名 * @param[in]: colName -> 要加載的列名 * @param[in]: mode -> 加載模式, set: 列名與該列數(shù)據(jù)組成的字典, df: df類型 * @retval: mode模式下的返回值 ''' def loadCsvData(file, colName, mode='df'): assert mode in ('set', 'df') df = pd.read_csv(file, encoding='utf-8-sig', usecols=colName) if mode == 'df': return df if mode == 'set': res = {} for col in colName: res[col] = df[col].values return res if __name__ == '__main__': # ============================ # 讀取CSV數(shù)據(jù) # ============================ csvPath = os.path.abspath(os.path.join(__file__, "../../data/dataset3.0alpha.csv")) dataX = loadCsvData(csvPath, ["含糖率", "密度"], 'df') dataY = loadCsvData(csvPath, ["好瓜"], 'df') label = np.array([ 1 if i == "是" else 0 for i in list(map(lambda s: s.strip(), list(dataY['好瓜']))) ]) # ============================ # 繪制樣本點(diǎn) # ============================ line_x = np.array([np.min(dataX['密度']), np.max(dataX['密度'])]) mpl.rcParams['font.sans-serif'] = [u'SimHei'] plt.title('對(duì)數(shù)幾率回歸模擬\nLogistic Regression Simulation') plt.xlabel('density') plt.ylabel('sugarRate') plt.scatter(dataX['密度'][label==0], dataX['含糖率'][label==0], marker='^', color='k', s=100, label='壞瓜') plt.scatter(dataX['密度'][label==1], dataX['含糖率'][label==1], marker='^', color='r', s=100, label='好瓜') # ============================ # 實(shí)例化對(duì)數(shù)幾率回歸模型 # ============================ logit = Logit(dataX, label) # 采用梯度下降法 logit.logitRegression(logit.gradientDescent) line_y = -logit.w[0, 0] / logit.w[1, 0] * line_x - logit.w[2, 0] / logit.w[1, 0] plt.plot(line_x, line_y, 'b-', label="梯度下降法") # 繪圖 plt.legend(loc='upper left') plt.show()
到此這篇關(guān)于圖文詳解梯度下降算法的原理及Python實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Python梯度下降算法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python讀取Ansible?playbooks返回信息示例解析
這篇文章主要為大家介紹了Python讀取Ansible?playbooks返回信息示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12python實(shí)現(xiàn)WebSocket服務(wù)端過程解析
這篇文章主要介紹了python實(shí)現(xiàn)WebSocket服務(wù)端過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10Flask Paginate實(shí)現(xiàn)表格分頁的使用示例
flask_paginate是Flask框架的一個(gè)分頁擴(kuò)展,用于處理分頁相關(guān)的功能,本文就來介紹一下Flask Paginate實(shí)現(xiàn)表格分頁的使用示例,感興趣的可以了解一下2023-11-11Python實(shí)現(xiàn)公歷(陽歷)轉(zhuǎn)農(nóng)歷(陰歷)的方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)公歷(陽歷)轉(zhuǎn)農(nóng)歷(陰歷)的方法,涉及農(nóng)歷算法原理及Python日期運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下2017-08-08python類型強(qiáng)制轉(zhuǎn)換long to int的代碼
python的int型最大值和系統(tǒng)有關(guān),32位和64位系統(tǒng)結(jié)果是不同的,分別為2的31次方減1和2的63次方減1,可以通過sys.maxint查看此值2013-02-02簡(jiǎn)單的Python動(dòng)態(tài)可視化神器,編程小白也能上手
這篇文章就來介紹簡(jiǎn)單的Python動(dòng)態(tài)可視化神器,最近發(fā)現(xiàn)了一個(gè)寶藏動(dòng)態(tài)可視化庫,非常簡(jiǎn)單,即使是小白也能輕松上手。這個(gè)庫就是motionchart,它能夠用 pandas 的 dataframe 數(shù)據(jù)直接創(chuàng)建交互式的動(dòng)態(tài)圖表,下面來簡(jiǎn)單看一下如何使用。2021-10-10python實(shí)現(xiàn)拉普拉斯特征圖降維示例
今天小編就為大家分享一篇python實(shí)現(xiàn)拉普拉斯特征圖降維示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-112020最新pycharm漢化安裝(python工程獅親測(cè)有效)
這篇文章主要介紹了2020最新pycharm漢化安裝(python工程獅親測(cè)有效),文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04