PyTorch搭建一維線性回歸模型(二)
PyTorch基礎(chǔ)入門二:PyTorch搭建一維線性回歸模型
1)一維線性回歸模型的理論基礎(chǔ)
給定數(shù)據(jù)集
,線性回歸希望能夠優(yōu)化出一個(gè)好的函數(shù)
,使得
能夠和
盡可能接近。
如何才能學(xué)習(xí)到參數(shù)
和
呢?很簡單,只需要確定如何衡量
與
之間的差別,我們一般通過損失函數(shù)(Loss Funciton)來衡量:
。取平方是因?yàn)榫嚯x有正有負(fù),我們于是將它們變?yōu)槿钦?。這就是著名的均方誤差。我們要做的事情就是希望能夠找到
和
,使得:


均方差誤差非常直觀,也有著很好的幾何意義,對應(yīng)了常用的歐式距離?,F(xiàn)在要求解這個(gè)連續(xù)函數(shù)的最小值,我們很自然想到的方法就是求它的偏導(dǎo)數(shù),讓它的偏導(dǎo)數(shù)等于0來估計(jì)它的參數(shù),即:


求解以上兩式,我們就可以得到最優(yōu)解。
2)代碼實(shí)現(xiàn)
首先,我們需要“制造”出一些數(shù)據(jù)集:
import torch import matplotlib.pyplot as plt x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) y = 3*x + 10 + torch.rand(x.size()) # 上面這行代碼是制造出接近y=3x+10的數(shù)據(jù)集,后面加上torch.rand()函數(shù)制造噪音 # 畫圖 plt.scatter(x.data.numpy(), y.data.numpy()) plt.show()
我們想要擬合的一維回歸模型是
。上面制造的數(shù)據(jù)集也是比較接近這個(gè)模型的,但是為了達(dá)到學(xué)習(xí)效果,人為地加上了torch.rand()值增加一些干擾。
上面人為制造出來的數(shù)據(jù)集的分布如下:

有了數(shù)據(jù),我們就要開始定義我們的模型,這里定義的是一個(gè)輸入層和輸出層都只有一維的模型,并且使用了“先判斷后使用”的基本結(jié)構(gòu)來合理使用GPU加速。
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1) # 輸入和輸出的維度都是1
def forward(self, x):
out = self.linear(x)
return out
if torch.cuda.is_available():
model = LinearRegression().cuda()
else:
model = LinearRegression()
然后我們定義出損失函數(shù)和優(yōu)化函數(shù),這里使用均方誤差作為損失函數(shù),使用梯度下降進(jìn)行優(yōu)化:
criterion = nn.MSELoss() optimizer = torch.optim.SGD(model.parameters(), lr=1e-2)
接下來,開始進(jìn)行模型的訓(xùn)練。
num_epochs = 1000
for epoch in range(num_epochs):
if torch.cuda.is_available():
inputs = Variable(x).cuda()
target = Variable(y).cuda()
else:
inputs = Variable(x)
target = Variable(y)
# 向前傳播
out = model(inputs)
loss = criterion(out, target)
# 向后傳播
optimizer.zero_grad() # 注意每次迭代都需要清零
loss.backward()
optimizer.step()
if (epoch+1) %20 == 0:
print('Epoch[{}/{}], loss:{:.6f}'.format(epoch+1, num_epochs, loss.data[0]))
首先定義了迭代的次數(shù),這里為1000次,先向前傳播計(jì)算出損失函數(shù),然后向后傳播計(jì)算梯度,這里需要注意的是,每次計(jì)算梯度前都要記得將梯度歸零,不然梯度會(huì)累加到一起造成結(jié)果不收斂。為了便于看到結(jié)果,每隔一段時(shí)間輸出當(dāng)前的迭代輪數(shù)和損失函數(shù)。
接下來,我們通過model.eval()函數(shù)將模型變?yōu)闇y試模式,然后將數(shù)據(jù)放入模型中進(jìn)行預(yù)測。最后,通過畫圖工具matplotlib看一下我們擬合的結(jié)果,代碼如下:
model.eval() if torch.cuda.is_available(): predict = model(Variable(x).cuda()) predict = predict.data.cpu().numpy() else: predict = model(Variable(x)) predict = predict.data.numpy() plt.plot(x.numpy(), y.numpy(), 'ro', label='Original Data') plt.plot(x.numpy(), predict, label='Fitting Line') plt.show()
其擬合結(jié)果如下圖:

附上完整代碼:
# !/usr/bin/python
# coding: utf8
# @Time : 2018-07-28 18:40
# @Author : Liam
# @Email : luyu.real@qq.com
# @Software: PyCharm
# .::::.
# .::::::::.
# :::::::::::
# ..:::::::::::'
# '::::::::::::'
# .::::::::::
# '::::::::::::::..
# ..::::::::::::.
# ``::::::::::::::::
# ::::``:::::::::' .:::.
# ::::' ':::::' .::::::::.
# .::::' :::: .:::::::'::::.
# .:::' ::::: .:::::::::' ':::::.
# .::' :::::.:::::::::' ':::::.
# .::' ::::::::::::::' ``::::.
# ...::: ::::::::::::' ``::.
# ```` ':. ':::::::::' ::::..
# '.:::::' ':'````..
# 美女保佑 永無BUG
import torch
from torch.autograd import Variable
import numpy as np
import random
import matplotlib.pyplot as plt
from torch import nn
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)
y = 3*x + 10 + torch.rand(x.size())
# 上面這行代碼是制造出接近y=3x+10的數(shù)據(jù)集,后面加上torch.rand()函數(shù)制造噪音
# 畫圖
# plt.scatter(x.data.numpy(), y.data.numpy())
# plt.show()
class LinearRegression(nn.Module):
def __init__(self):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(1, 1) # 輸入和輸出的維度都是1
def forward(self, x):
out = self.linear(x)
return out
if torch.cuda.is_available():
model = LinearRegression().cuda()
else:
model = LinearRegression()
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=1e-2)
num_epochs = 1000
for epoch in range(num_epochs):
if torch.cuda.is_available():
inputs = Variable(x).cuda()
target = Variable(y).cuda()
else:
inputs = Variable(x)
target = Variable(y)
# 向前傳播
out = model(inputs)
loss = criterion(out, target)
# 向后傳播
optimizer.zero_grad() # 注意每次迭代都需要清零
loss.backward()
optimizer.step()
if (epoch+1) %20 == 0:
print('Epoch[{}/{}], loss:{:.6f}'.format(epoch+1, num_epochs, loss.data[0]))
model.eval()
if torch.cuda.is_available():
predict = model(Variable(x).cuda())
predict = predict.data.cpu().numpy()
else:
predict = model(Variable(x))
predict = predict.data.numpy()
plt.plot(x.numpy(), y.numpy(), 'ro', label='Original Data')
plt.plot(x.numpy(), predict, label='Fitting Line')
plt.show()
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python3 利用face_recognition實(shí)現(xiàn)人臉識(shí)別的方法
這篇文章主要介紹了Python3 利用face_recognition實(shí)現(xiàn)人臉識(shí)別的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
python輸入整條數(shù)據(jù)分割存入數(shù)組的方法
今天小編就為大家分享一篇python輸入整條數(shù)據(jù)分割存入數(shù)組的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11
Flaks基礎(chǔ)之在URL中添加變量的實(shí)現(xiàn)詳解
這篇文章主要介紹了在python開發(fā)中,F(xiàn)laks框架之上在URL鏈接中添加變量的實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-09-09
基于OpenCV和Gradio實(shí)現(xiàn)簡單的人臉識(shí)別詳解
這篇文章主要為大家詳細(xì)介紹了如何基于OpenCV和Gradio實(shí)現(xiàn)簡單的人臉識(shí)別功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04
使用Python操作Excel中的各項(xiàng)頁面設(shè)置功能
在使用Excel進(jìn)行數(shù)據(jù)分析或報(bào)告制作時(shí),頁面設(shè)置是確保最終輸出效果專業(yè)、美觀的關(guān)鍵步驟,合理的頁面設(shè)置不僅能夠優(yōu)化打印效果,還能提升數(shù)據(jù)的可讀性,本文將詳細(xì)介紹如何使用Python操作Excel中的各項(xiàng)頁面設(shè)置功能,需要的朋友可以參考下2024-08-08
pyside6-uic生成py代碼中文為unicode(亂碼)的問題解決方案
這篇文章主要介紹了如何解決pyside6-uic生成py代碼中文為unicode(亂碼)的問題,文中通過代碼和圖文介紹的非常詳細(xì),對大家解決問題有一定的幫助,需要的朋友可以參考下2024-02-02

