pytorch:一维线性回归(二)
首先,這是對上一篇文章(pytorch:一維線性回歸(一))的改進。
其次,為什么想要改進上一篇文章嘞?
答案:我使用這個寫好的模型后,想著既然參數已經訓練出來了,那么預測的時候,就只需要直接根據參數和輸入數據就可以計算出預測值,速度應該很快。
然而,按照上一篇文章這樣的寫法,仔細的人會發現,每次預測的時候都又進行了訓練,那么之前我的訓練就等于白費了。
于是,我得找原因在哪里,不難發現,我雖然訓練了模型,但是沒有對參數進行保存。
于是我查詢了pytorch是如何保存模型參數的,一共有兩種方式:保存整個模型和保存模型參數。
根據需求,保存整個模型顯然是不合理的,因為我的核心是想要得到模型的參數,y=wx+b,參數就是w和b,也就是代碼中的weight和bias
因為參數固定,那么模型就確定了,輸入x,就能輸出預測值。
思路有了,于是開始實踐:
1、構建模型。把模型單獨設置為一個類,名字不要亂取,最好見名知意,方便下次直接使用,模型的名字是LinearRegression,那么類的名字就是LinearRegression,整個文件名字是:LinearRegression.py
# -*- coding: utf-8 -*-from torch import nn as nn# 構建線性模型 class LinearRegression(nn.Module):def __init__(self):super(LinearRegression, self).__init__()# 輸入和輸出的維度都是1self.linear = nn.Linear(1, 1)def forward(self, x):out = self.linear(x)return out2、訓練模型。新建一個train.py
# -*- coding: utf-8 -*- import torch import numpy as np from torch import nn, optim from torch.autograd import Variable# 引入模型 from LinearRegression import LinearRegression # 步驟1中構建的模型# 訓練數據 x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168],[9.779], [6.182], [7.59], [2.167], [7.042],[10.791], [5.313], [7.997], [3.1]], dtype=np.float32) y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573],[3.366], [2.596], [2.53], [1.221], [2.827],[3.465], [1.65], [2.904], [1.3]], dtype=np.float32) # 把訓練數據轉換為張量:numpy->torch, x_train = torch.from_numpy(x_train) y_train = torch.from_numpy(y_train) # 判斷是否有可用的GPU if torch.cuda.is_available():model = LinearRegression().cuda() else:model = LinearRegression()# 損失函數:均方誤差(計算損失的方法是什么,衡量誤差的標準是什么) criterion = nn.MSELoss() # 采用隨機梯度下降 optimizer = optim.SGD(model.parameters(), lr=1e-3)num_epochs = 1000 # 訓練總次數 for epoch in range(num_epochs):if torch.cuda.is_available():inputs = Variable(x_train).cuda()target = Variable(y_train).cuda()else:inputs = Variable(x_train)target = Variable(y_train)# 向前傳播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.item())) # 訓練結束后,打印出w和b的值 print('w:', model.state_dict()['linear.weight'].numpy().squeeze()) print('b:', model.state_dict()['linear.bias'].numpy().squeeze()) # 保存模型的參數,也就是w和b的值 torch.save(model.state_dict(), "LinearRegression_train.pt")訓練結束后可以看到參數值,我運行的時候運行結果:
3、預測。使用模型來預測值,這里我批量預測3個值。文件名可以隨意取名了,因為模型參數已經保存在
LinearRegression_train.pt中,測試可以將文件名設置為test.py或者predict.py均可。 # -*- coding: utf-8 -*- import torch import numpy as np from torch.autograd import Variable from LinearRegression import LinearRegression # 等待預測的數據 x_train = np.array([[1.0], [2.0], [3.0]], dtype=np.float32) # 實例化模型 model = LinearRegression() # 加載模型參數 model.load_state_dict(torch.load("LinearRegression_train.pt")) # 根據用CPU還是GPU來計算,將預測結果顯示出來 if torch.cuda.is_available():predict = model(Variable(torch.from_numpy(x_train)).cuda())predict = predict.data.cpu().numpy()print(predict) else:predict = model(Variable(torch.from_numpy(x_train)))predict = predict.data.numpy()print("=======")print(predict)運行結果:
從結果可以看出,電腦是使用的CPU計算的,因為打印出了等號。
其次,還需要手動計算一下,是否符合我們心中所想。
根據步驟2,參數w=0.307263 b=0.41873494
根據公式:y = w*x+b
則y1 =?0.307263*1.0+0.41873494 =0.72599794
y1 =?0.307263*2.0+0.41873494 = 1.03326094
y1 =?0.307263*3.0+0.41873494 = 1.34052394
將y1、y2、y3與程序運行結果對比,大致符合,因為計算機存在小數位數多的時候計算不精確,所以小數點后距離較遠的數據存在差異。
總結:改進后的好處:模型訓練好后,用于預測不需要再進行重新訓練,節約了時間,訓練模型的目的就是為了使用模型進行預測,如果預測時還需要耗時去重新訓練模型,尤其是將模型用于B/S系統展示,前端用戶會等待很長時間,用戶體驗極其不佳。雖然將一個文件拆分為了三個文件,但是思路更加清晰了!
?
總結
以上是生活随笔為你收集整理的pytorch:一维线性回归(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pytorch | Softmax->L
- 下一篇: PyTorch | Tensor、Num