專門做中文音譯歌曲的網(wǎng)站新網(wǎng)域名注冊(cè)官網(wǎng)
假設(shè)我們的基礎(chǔ)模型就是y = wx + b
,其中w和b均為參數(shù),我們使用y = 3x+0.8
來(lái)構(gòu)造數(shù)據(jù)x、y,所以最后通過(guò)模型應(yīng)該能夠得出w和b應(yīng)該分別接近3和0.8。
步驟如下:
- 準(zhǔn)備數(shù)據(jù)
- 計(jì)算預(yù)測(cè)值
- 計(jì)算損失,把參數(shù)的梯度置為0,進(jìn)行反向傳播
- 更新參數(shù)
方式一
該方式?jīng)]有用pytorch
的模型api
,手動(dòng)實(shí)現(xiàn)
import torch,numpy
import matplotlib.pyplot as plt# 1、準(zhǔn)備數(shù)據(jù)
learning_rate = 0.01
#y=3x + 0.8
x = torch.rand([500,1])
y_true= x*3 + 0.8# 2、通過(guò)模型計(jì)算y_predict
w = torch.rand([1,1],requires_grad=True)
b = torch.tensor(0,requires_grad=True,dtype=torch.float32)# 3、通過(guò)循環(huán),反向傳播,更新參數(shù)
for i in range(500):# 4、計(jì)算lossy_predict = torch.matmul(x,w) + bloss = (y_true-y_predict).pow(2).mean()# 每次循環(huán)判斷是否存在梯度,防止累加if w.grad is not None:w.grad.data.zero_()if b.grad is not None:b.grad.data.zero_()# 反向傳播loss.backward()w.data = w.data - learning_rate*w.gradb.data = b.data - learning_rate*b.grad# 每50次輸出一下結(jié)果if i%50==0:print("w,b,loss",w.item(),b.item(),loss.item())#可視化顯示
plt.figure(figsize=(20,8))
plt.scatter(x.numpy().reshape(-1),y_true.numpy().reshape(-1))
y_predict = torch.matmul(x,w) + b
plt.plot(x.numpy().reshape(-1),y_predict.detach().numpy().reshape(-1),c="r")
plt.show()
循環(huán)500
次的效果
循環(huán)2000
次的結(jié)果
方式二
方式一的方式雖然已經(jīng)購(gòu)簡(jiǎn)便了,但是還是有些許繁瑣,所以我們可以采用pytorch
的api
來(lái)實(shí)現(xiàn)。
nn.Module
是torch.nn
提供的一個(gè)類,是pytorch
中我們自定義網(wǎng)絡(luò)的一個(gè)基類,在這個(gè)類中定義了很多有用的方法,讓我們?cè)诶^承這個(gè)類定義網(wǎng)絡(luò)的時(shí)候非常簡(jiǎn)單。
當(dāng)我們自定義網(wǎng)絡(luò)的時(shí)候,有兩個(gè)方法需要特別注意:
1.__init__
需要調(diào)用super
方法,繼承父類的屬性和方法
2. forward
方法必須實(shí)現(xiàn),用來(lái)定義我們的網(wǎng)絡(luò)的向前計(jì)算的過(guò)程用前面的y = wx+b
的模型舉例如下:
#定義模型
from torch import nn
class Lr(nn.Module): #繼承nn.Moduledef __init__(self):super(Lr, self).__init__()self.linear = nn.Linear(1,1)def forward(self,x):out = self.linear(x)return out
全部代碼如下:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import torch
from torch import nn
from torch import optim
import numpy as np
from matplotlib import pyplot as plt#1、定義數(shù)據(jù)
x = torch.rand([50,1])
y = x*3 + 0.8#定義模型
class Lr(nn.Module): #繼承nn.Moduledef __init__(self):super(Lr, self).__init__()self.linear = nn.Linear(1,1)def forward(self,x):out = self.linear(x)return out
#2、實(shí)例化模型、loss函數(shù)以及優(yōu)化器
model = Lr()
criterion = nn.MSELoss() #損失函數(shù)
optimizer = optim.SGD(model.parameters(),lr=1e-3) #優(yōu)化器#3、訓(xùn)練模型
for i in range(3000):out = model(x)# 獲取預(yù)測(cè)值loss = criterion(y,out) #計(jì)算損失optimizer.zero_grad() #梯度歸零loss.backward() #計(jì)算梯度optimizer.step() #更新梯度if(i+1) % 20 ==0:print('Epoch[{}/{}],loss:{:.6f}'.format(i,500,loss.data))#4、模型評(píng)估
model.eval() #設(shè)置模型為評(píng)估模式,即預(yù)測(cè)模式
predict = model(x)
predict = predict.data.numpy()
plt.scatter(x.data.numpy(),y.data.numpy(),c="r")
plt.plot(x.data.numpy(),predict)
plt.show()
注意:
model.eval()
表示設(shè)置模型為評(píng)估模式,即預(yù)測(cè)模式
model.train(mode=True)
表示設(shè)置模型為訓(xùn)練模式
在當(dāng)前的線性回歸中,上述并無(wú)區(qū)別
但是在其他的一些模型中,訓(xùn)練的參數(shù)和預(yù)測(cè)的參數(shù)會(huì)不相同,到時(shí)候就需要具體告訴程序我們是在進(jìn)行訓(xùn)練還是預(yù)測(cè),比如模型中存在Dropout,BatchNorm的時(shí)候
循環(huán)2000
次的結(jié)果:
循環(huán)30000
次的結(jié)果: