第5講 pytorch實作線性回歸 Linear Regression with PyTorch
pytorch學習視訊——B站視訊連結:《PyTorch深度學習實踐》完結合集_哔哩哔哩_bilibili
以下是視訊内容筆記以及小練習源碼,筆記純屬個人了解,如有錯誤勿介或者歡迎路過的大佬指出 。
目錄
1. 構造神經網絡一般步驟
2. 第一步——準備資料集 prepare dataset
3. 第二步——模型設計
4. 第三步——構造損失函數和優化器
4. 第四步——訓練
5. 本節代碼
6. 其它優化器訓練結果
1. 構造神經網絡一般步驟
- 準備資料集
- 設計模型
- 計算預測值y_pred的模型
- 構造損失函數和優化器
- 使用pytorch封裝好的API即可
- 訓練循環
- 前饋——計算損失
- 回報——計算梯度
- g更新——用梯度下降算法更新權重
2. 第一步——準備資料集 prepare dataset
用mini-batch構造資料集,x和y必須是矩陣的形式
将資料集定義成矩陣形式(張量),如下x_data, y_data都是3X1的矩陣,權重w也被當成矩陣進行參與計算。w也是3X1矩陣,與x_data矩陣進行點乘,對應位置元素相乘(不是矩陣相乘)。
3. 第二步——模型設計
-
基本内容
設計模型也就是構造計算圖的過程,需要已知x和y的次元,由此可以确定w和b的次元。計算梯度時隻需要從loss處反向一步一步求出即可,不需要手動求偏導,有了這個從w和x求出loss的模型之後,用反向傳播就可以自動求出這條鍊上的梯度。
最後計算出的loss是一個标量數值???,才可以調用backward():
- 最基本的代碼架構
- 把模型定義成一個類LinearModel,繼承自torch.nn.Module。構造計算圖,所有的神經網絡模型都要繼承Module類。
class LinearModel(torch.nn.Module):
# 構造函數——初始化變量
def __init__(self):
super(LinearModel, self).__init__()
# 構造對象 線性模型
self.linear = torch.nn.Linear(1, 1)
# 對module類中原forward函數的重寫
def forward(self, x):
# linear——可調用對象 linear(x), __call__函數
y_pred = self.linear(x)
return y_pred
# model也是一個可調用對象
model = LinearModel()
-
代碼說明
torch.nn.Linear
self.linear = torch.nn.Linear(1, 1) # Linear類的格式如下圖所示,in_features是輸入資料的維數,y_features是輸出樣本的維數,bias是偏置值,預設是True # 執行個體化對象之後相當于進行y = xw + b的計算
- 關于w的次元問題,如圖所示的兩種形式
- x是nX3矩陣,要求的y是nX2矩陣
4. 第三步——構造損失函數和優化器
- 損失函數:MSE損失函數
- 優化器:SGD,優化器不需要建立計算圖
torch.nn.MSELoss 類如圖所示,size_average表示損失是否求均值;reduce表示求出的損失是否降維,預設為True,在這個例子中就是将loss轉換為标量。 優化器SGD如圖所示,model.parameters()找出model中要訓練的所有權重,在這裡就是linear的權重w,lr是學習率,其它參數可參考官方文檔。# MSELoss類繼承自Module,torch.nn.MSELoss,可調用,pytorch提供的MSE損失函數。 criterion = torch.nn.MSELoss(size_average=False) # 執行個體化一個優化器對象 optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
4. 第四步——訓練
- 訓練步驟:
- 前饋——回報——更新
- 模型;求損失——求梯度——更新權重
for epoch in range(100):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
optimizer.zero_grad()
print(loss)
loss.backward()
optimizer.step()
- SGD訓練結果:
随機梯度下降,現在一般指mini-batch gradient descent,計算一個mini-batch的損失,疊代也是以一個批次為機關來更新權重。
5. 本節代碼
linear_regression.py
import torch
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
class LinearModel(torch.nn.Module):
# 構造函數——初始化變量
def __init__(self):
super(LinearModel, self).__init__()
# 構造對象 線性模型
self.linear = torch.nn.Linear(1, 1)
# 對module類中原forward函數的重寫
def forward(self, x):
# linear——可調用對象 linear(x), __call__函數
y_pred = self.linear(x)
return y_pred
# model也是一個可調用對象
model = LinearModel()
# MSELoss類繼承自Module,torch.nn.MSELoss,可調用,pytorch提供的MSE損失函數。
criterion = torch.nn.MSELoss(size_average=False)
# 執行個體化一個優化器對象,parameters是所有權重參數
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 訓練
for epoch in range(100):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
# loss計算出來是一個
print(epoch, loss.item())
# 将梯度值清0
optimizer.zero_grad()
# 反向傳播求梯度
print(loss)
loss.backward()
# 優化器 更新權重
optimizer.step()
# 列印出最終的權重和偏置值
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
x_test = torch.tensor([4.0])
y_test = model(x_test)
print('y_pred = ', y_test.data)
作業 optimizer_test_job.py
(隻試了前幾個優化器,效果都不是很好)
import torch
from matplotlib import pyplot as plt
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[2.0], [4.0], [6.0]])
class LinearModel(torch.nn.Module):
# 構造函數——初始化變量
def __init__(self):
super(LinearModel, self).__init__()
# 構造對象 線性模型
self.linear = torch.nn.Linear(1, 1)
# 對module類中原forward函數的重寫
def forward(self, x):
# linear——可調用對象 linear(x), __call__函數
y_pred = self.linear(x)
return y_pred
# model也是一個可調用對象
model = LinearModel()
# MSELoss類繼承自Module,torch.nn.MSELoss,可調用,pytorch提供的MSE損失函數。
criterion = torch.nn.MSELoss(size_average=False)
# 執行個體化一個優化器對象,parameters是所有權重參數
optimizer = torch.optim.Adamax(model.parameters(), lr=0.01)
# optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# optimizer = torch.optim.Adagrad(model.parameters(), lr=0.2)
# 訓練
l_list = []
for epoch in range(100):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
# loss計算出來是一個tensor
if epoch % 10 == 0:
print(epoch, loss.item())
l_list.append(loss.item())
# 将梯度值清0
optimizer.zero_grad()
# 反向傳播求梯度
loss.backward()
# 優化器 更新權重
optimizer.step()
# 列印出最終的權重和偏置值
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
x_test = torch.tensor([4.0])
y_test = model(x_test)
print('y_pred = ', y_test.data)
x = range(100)
plt.plot(x, l_list)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
(以上代碼已經在pycharm上經過測試)
6. 其它優化器訓練結果
- Adagrad:
結果如圖所示,如果學習率設定為0.01,那結果基本不收斂,改為0.2後效果好一點,可嘗試增大訓練次數或者增大學習率。
-
Adam
效果不好
torch中的其它優化器如圖所示
深度學習幾種優化器的比較
examples:
Learning PyTorch with Examples — PyTorch Tutorials 1.9.0+cu102 documentation
——pytorch官方中文文檔:
torch - PyTorch中文文檔 (pytorch-cn.readthedocs.io)
——未完待續……