python+numpy+matplotalib實(shí)現(xiàn)梯度下降法
這個(gè)階段一直在做和梯度一類算法相關(guān)的東西,索性在這兒做個(gè)匯總:
一、算法論述
梯度下降法(gradient descent)別名最速下降法(曾經(jīng)我以為這是兩個(gè)不同的算法-.-),是用來求解無約束最優(yōu)化問題的一種常用算法。下面以求解線性回歸為題來敘述:
設(shè):一般的線性回歸方程(擬合函數(shù))為:(其中的值為1)
則這一組向量參數(shù)選擇的好與壞就需要一個(gè)機(jī)制來評(píng)估,據(jù)此我們提出了其損失函數(shù)為(選擇均方誤差):
我們現(xiàn)在的目的就是使得損失函數(shù)取得最小值,即目標(biāo)函數(shù)為:
如果的值取到了0,意味著我們構(gòu)造出了極好的擬合函數(shù),也即選擇出了最好的
值,但這基本是達(dá)不到的,我們只能使得其無限的接近于0,當(dāng)滿足一定精度時(shí)停止迭代。
那么問題來了如何調(diào)整使得
取得的值越來越小呢?方法很多,此處以梯度下降法為例:
分為兩步:(1)初始化的值。
(2)改變的值,使得
按梯度下降的方向減少。
值的更新使用如下的方式來完成:
其中為步長(zhǎng)因子,這里我們?nèi)《ㄖ担⒁馊绻?img alt="" src="http://img.jbzj.com/file_images/article/201808/2018083108455312.gif" />取得過小會(huì)導(dǎo)致收斂速度過慢,
過大則損失函數(shù)可能不會(huì)收斂,甚至逐漸變大,可以在下述的代碼中修改
的值來進(jìn)行驗(yàn)證。后面我會(huì)再寫一篇關(guān)于隨機(jī)梯度下降法的文章,其實(shí)與梯度下降法最大的不同就在于一個(gè)求和符號(hào)。
二、代碼實(shí)現(xiàn)
import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import axes3d from matplotlib import style #構(gòu)造數(shù)據(jù) def get_data(sample_num=10000): """ 擬合函數(shù)為 y = 5*x1 + 7*x2 :return: """ x1 = np.linspace(0, 9, sample_num) x2 = np.linspace(4, 13, sample_num) x = np.concatenate(([x1], [x2]), axis=0).T y = np.dot(x, np.array([5, 7]).T) return x, y #梯度下降法 def GD(samples, y, step_size=0.01, max_iter_count=1000): """ :param samples: 樣本 :param y: 結(jié)果value :param step_size: 每一接迭代的步長(zhǎng) :param max_iter_count: 最大的迭代次數(shù) :param batch_size: 隨機(jī)選取的相對(duì)于總樣本的大小 :return: """ #確定樣本數(shù)量以及變量的個(gè)數(shù)初始化theta值 m, var = samples.shape theta = np.zeros(2) y = y.flatten() #進(jìn)入循環(huán)內(nèi) print(samples) loss = 1 iter_count = 0 iter_list=[] loss_list=[] theta1=[] theta2=[] #當(dāng)損失精度大于0.01且迭代此時(shí)小于最大迭代次數(shù)時(shí),進(jìn)行 while loss > 0.001 and iter_count < max_iter_count: loss = 0 #梯度計(jì)算 theta1.append(theta[0]) theta2.append(theta[1]) for i in range(m): h = np.dot(theta,samples[i].T) #更新theta的值,需要的參量有:步長(zhǎng),梯度 for j in range(len(theta)): theta[j] = theta[j] - step_size*(1/m)*(h - y[i])*samples[i,j] #計(jì)算總體的損失精度,等于各個(gè)樣本損失精度之和 for i in range(m): h = np.dot(theta.T, samples[i]) #每組樣本點(diǎn)損失的精度 every_loss = (1/(var*m))*np.power((h - y[i]), 2) loss = loss + every_loss print("iter_count: ", iter_count, "the loss:", loss) iter_list.append(iter_count) loss_list.append(loss) iter_count += 1 plt.plot(iter_list,loss_list) plt.xlabel("iter") plt.ylabel("loss") plt.show() return theta1,theta2,theta,loss_list def painter3D(theta1,theta2,loss): style.use('ggplot') fig = plt.figure() ax1 = fig.add_subplot(111, projection='3d') x,y,z = theta1,theta2,loss ax1.plot_wireframe(x,y,z, rstride=5, cstride=5) ax1.set_xlabel("theta1") ax1.set_ylabel("theta2") ax1.set_zlabel("loss") plt.show() def predict(x, theta): y = np.dot(theta, x.T) return y if __name__ == '__main__': samples, y = get_data() theta1,theta2,theta,loss_list = GD(samples, y) print(theta) # 會(huì)很接近[5, 7] painter3D(theta1,theta2,loss_list) predict_y = predict(theta, [7,8]) print(predict_y)
三、繪制的圖像如下:
迭代次數(shù)與損失精度間的關(guān)系圖如下:步長(zhǎng)為0.01
變量、
與損失函數(shù)loss之間的關(guān)系:(從初始化之后會(huì)一步步收斂到loss滿足精度,之后
、
會(huì)變的穩(wěn)定下來)
下面我們來看一副當(dāng)步長(zhǎng)因子變大后的圖像:步長(zhǎng)因子為0.5(很明顯其收斂速度變緩了)
當(dāng)步長(zhǎng)因子設(shè)置為1.8左右時(shí),其損失值已經(jīng)開始震蕩
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用Python處理Excel文件并將數(shù)據(jù)存儲(chǔ)到PostgreSQL的方法
在日常工作中,我們經(jīng)常會(huì)遇到需要處理大量文件并將數(shù)據(jù)存儲(chǔ)至數(shù)據(jù)庫或整合到一個(gè)文件的需求,本文將向大家展示如何使用Python處理Excel文件并將數(shù)據(jù)存儲(chǔ)到PostgreSQL數(shù)據(jù)庫中,需要的朋友可以參考下2024-01-01python實(shí)現(xiàn)貪吃蛇雙人大戰(zhàn)
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)貪吃蛇雙人大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04Python3進(jìn)行表格數(shù)據(jù)處理的示例詳解
數(shù)據(jù)處理是一個(gè)當(dāng)下非常熱門的研究方向,通過對(duì)于大型實(shí)際場(chǎng)景中的數(shù)據(jù)進(jìn)行建模,可以用于預(yù)測(cè)下一階段可能出現(xiàn)的情況。本文就來聊聊Python3進(jìn)行表格數(shù)據(jù)處理的相關(guān)操作,需要的可以參考一下2023-03-03python3的UnicodeDecodeError解決方法
這篇文章主要介紹了python3的UnicodeDecodeError解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12pandas創(chuàng)建DataFrame的7種方法小結(jié)
這篇文章主要介紹了pandas創(chuàng)建DataFrame的7種方法小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06如何利用python給微信公眾號(hào)發(fā)消息實(shí)例代碼
使用過微信公眾號(hào)的小伙伴應(yīng)該知道微信公眾號(hào)有時(shí)候會(huì)給你推一些文章,當(dāng)你選擇它的某個(gè)功能時(shí),它還會(huì)返回一些信息,下面這篇文章主要給大家介紹了關(guān)于如何利用python給微信公眾號(hào)發(fā)消息的相關(guān)資料,需要的朋友可以參考下2022-03-03Python中dtype、type()和astype()的區(qū)別詳解
這篇文章主要介紹了Python中dtype、type()和astype()的區(qū)別詳解,type()是python內(nèi)置的函數(shù),type()返回?cái)?shù)據(jù)結(jié)構(gòu)類型(list、dict、numpy.ndarray 等),需要的朋友可以參考下2023-08-08allure結(jié)合python生成測(cè)試報(bào)告教程
這篇文章主要介紹了allure結(jié)合python生成測(cè)試報(bào)告教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06