Lesson 12.3 线性回归建模实验
Lesson 12.3 線性回歸建模實驗
一、深度學習建模流程
??數據準備就緒,接下來就是建模實驗環節,在實際深度學習建模過程中,無論是手動實現還是調庫實現,我們都需要遵循深度學習建模一般流程。在此前的學習過程中,我們曾兩次提及深度學習建模流程,結合此前學習內容,我們先進行簡單回顧。
根據此流程,我們進行線性回歸建模
二、線性回歸的手動實現
??首先,考慮如何手動實現建模過程。
# 隨機模塊 import random# 繪圖模塊 import matplotlib as mpl import matplotlib.pyplot as plt# numpy import numpy as np# pytorch import torch from torch import nn,optim import torch.nn.functional as F from torch.utils.data import Dataset,TensorDataset,DataLoader from torch.utils.tensorboard import SummaryWriter# 自定義模塊 from torchLearning import *1.生成數據集
??利用此前的數據集生成函數,創建一個真實關系為y=2x1?x2+1y = 2x_1-x_2+1y=2x1??x2?+1,且擾動項不是很大的回歸類數據集。
tensorGenReg? #Signature: tensorGenReg(num_examples=1000, w=[2, -1, 1], bias=True, delta=0.01, deg=1) #Docstring: #回歸類數據集創建函數。 # #:param num_examples: 創建數據集的數據量 #:param w: 特征系數矩陣 #:param bias:是否需要截距 #:param delta:擾動項取值 #:param deg:方程次數 #:return: 生成的特征張和標簽張量 #File: f:\code file\pytorch實戰\torchlearning.py #Type: function torch.manual_seed(420) features, labels = tensorGenReg()2.建模流程
- Stage 1.模型選擇
圍繞建模目標,我們可以構建一個只包含一層的神經網絡進行建模。
- Stage 2.確定目標函數
和此前一樣,我們使用MSE作為損失函數,也就是目標函數
def squared_loss(y_hat, y):num_ = y.numel()sse = torch.sum((y_hat.reshape(-1, 1) - y.reshape(-1, 1)) ** 2)return sse / num_- Stage 3.定義優化算法
此處我們采用小批量梯度下降進行求解,每一次迭代過程都是(參數-學習率*梯度)。
def sgd(params, lr):params.data -= lr * params.grad params.grad.zero_() 關于可微張量的in-place operation(對原對像修改操作)的相關討論(1).正常情況下,可微張量的in-place operation會導致系統無法區分葉節點和其他節點的問題
w = torch.tensor(2., requires_grad = True) w #tensor(2., requires_grad=True) w.is_leaf #True開啟可微之后,w的所有計算都會被納入計算圖中
w1 = w * 2 w1 #tensor(4., grad_fn=<MulBackward0>)但如果在計算過程中,我們使用in-place operation,讓新生成的值替換w原始值,則會報錯
w = torch.tensor(2., requires_grad = True) w -= w * 2 #RuntimeError: a leaf Variable that requires grad is being used in an in-place operation.從報錯信息中可知,PyTorch中不允許葉節點使用in-place operation,根本原因是會造成葉節點和其他節點類型混亂。不過,雖然可微張量不允許in-place operation,但卻可以通過其他方法進行對w進行修改。
w = torch.tensor(2., requires_grad = True) w = w * 2不過此時,w就不再是葉節點了
w #tensor(4., grad_fn=<MulBackward0>) w.is_leaf #False自然,我們也無法通過反向傳播求其導數
w = torch.tensor(2., requires_grad = True) w = w * 2 w.backward() # w已經成為輸出節點 w.grad #D:\Users\ASUS\anaconda3\lib\site-packages\ipykernel_launcher.py:1: UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the gradient for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead. See github.com/pytorch/pytorch/pull/30531 for more informations. # """Entry point for launching an IPython kernel.而在一張計算圖中,缺少了對葉節點反向傳播求導數的相關運算,計算圖也就失去了核心價值。因此在實際操作過程中,應該盡量避免導致葉節點丟失的相關操作。
(2).葉節點數值修改方法
??當然,如果出現了一定要修改葉節點的取值的情況,典型的如梯度下降過程中利用梯度值修改參數值時,可以使用此前介紹的暫停追蹤的方法,如使用with torch.no_grad()語句或者torch.detach()方法,使得修改葉節點數值時暫停追蹤,然后再生成新的葉節點帶入計算,如:
當然,此處我們介紹另一種方法,.data來返回可微張量的取值,從在避免在修改的過程中被追蹤
w = torch.tensor(2., requires_grad = True) w #tensor(2., requires_grad=True) w.data # 查看張量的數值 #tensor(2.) w # 但不改變張量本身可微性 #tensor(2., requires_grad=True) w.data -= w * 2 # 對其數值進行修改 w #tensor(-2., requires_grad=True) w.is_leaf # 張量仍然是葉節點 #True這里需要注意,在Lesson 6中我們曾使用手寫梯度下降算法計算線性方程自變量權重,但該過程在修改變量時并未使用反向傳播計算梯度,我們是通過矩陣運算算得的梯度,因此并未出現葉節點位置丟失的問題。當然,更加嚴謹的做法是令weight不可導。
- Stage.4 訓練模型
當然,我們也可以使用tensorboard記錄上述迭代過程中loss的變化過程
writer = SummaryWriter(log_dir='reg_loss')# 初始化核心參數 batch_size = 10 # 每一個小批的數量 lr = 0.03 # 學習率 num_epochs = 3 # 訓練過程遍歷幾次數據 w = torch.zeros(3, 1, requires_grad = True) # 隨機設置初始權重# 參與訓練的模型方程 net = linreg # 使用回歸方程 loss = squared_loss # 均方誤差的一半作為損失函數# 模型訓練過程 for epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w), y)l.backward()sgd(w, lr)train_l = loss(net(features, w), labels)writer.add_scalar('mul', train_l, epoch)然后在命令行輸入:
F: cd "F:\Code File\PyTorch實戰\" tensorboard --logdir="reg_loss"打開瀏覽器,輸入localhost:6006,查看繪制圖像
三、線性回歸的快速實現
??當然,我們可以按照此前課程介紹的,通過調用PyTorch中的函數和類,直接完成建模。當然,該過程也是嚴格按照此前介紹的深度學習建模流程完成的模型構建,相關變量的符號也沿用了Lesson 11中的書寫標準。
??不過,值得一提的是,由于深度學習的特殊性,深度學習的建模流程對于初學者來說并不簡單,很多時候我們既無法對實際的數據進行表格式的查看,也無法精確的控制模型內部的每一步運行,外加需要創建大量的類(無論是讀取數據還是建模),以及大規模的參數輸入,都對初學者的學習造成了不小的麻煩。因此,通過接下來的調庫建模練習,也希望學員能夠進一步熟練掌握PyTorch框架的常用建模函數和類,從而為后續的學習打下良好的代碼基礎。
- 定義核心參數
- 數據準備
- Stage 1.定義模型
- Stage 2.定義損失函數
- Stage 3.定義優化方法
- Stage 4.模型訓練
當然,由于上述模型只有一層,因此也可以通過nn.Linear(2, 1)函數直接建模。
接下來,即可執行模型訓練
# 設置隨機數種子 torch.manual_seed(420) fit(net = LR_model, criterion = criterion, optimizer = optimizer, batchdata = batchData, epochs = num_epochs)查看模型訓練結果
LR_model #LR( # (linear): Linear(in_features=2, out_features=1, bias=True) #) # 查看模型參數 list(LR_model.parameters()) #[Parameter containing: # tensor([[ 1.9992, -1.0003]], requires_grad=True), # Parameter containing: # tensor([0.9994], requires_grad=True)] # 計算MSE criterion(LR_model(features), labels) #tensor(0.0001, grad_fn=<MseLossBackward>)由于數據本身就是按照y=2x1?x2+1y=2x_1-x_2+1y=2x1??x2?+1基本規律加上擾動項構建的,因此通過訓練完成的參數可以看出模型效果較好。當然,真實場景下我們無法從上帝視角獲得真實的數據分布規律,然后通過比對模型來判斷模型好壞,此時我們就需要明確模型評估指標,相關內容我們將在下一節課詳細介紹。
當然,我們也可以通過add_graph方法,在writer中添加上述模型的記錄圖
writer.add_graph(LR_model, (features,))在graph一欄中能看到如下結果
簡單線性回歸局限性
此處我們進一步進行簡單實驗,當自變量和因變量滿足最高次方為2次方的多項式函數關系時,或者擾動項增加時,簡單線性回歸誤差將迅速增大。
# 設置隨機數種子 torch.manual_seed(420) # 創建數據集 features, labels = tensorGenReg(deg=2) features = features[:, :-1] # 剔除最后全是1的列 data = TensorDataset(features, labels) batchData = DataLoader(data, batch_size = batch_size, shuffle = True)# 模型實例化 LR_model = LR()# 定義優化算法 optimizer = optim.SGD(LR_model.parameters(), lr = 0.03)# 模型訓練 fit(net = LR_model, criterion = criterion, optimizer = optimizer, batchdata = batchData, epochs = num_epochs)# MSE結果查看 criterion(LR_model(features), labels) #tensor(10.1555, grad_fn=<MseLossBackward>) # 設置隨機數種子 torch.manual_seed(420) # 創建數據集 features, labels = tensorGenReg(delta=2) features = features[:, :-1] # 剔除最后全是1的列 data = TensorDataset(features, labels) batchData = DataLoader(data, batch_size = batch_size, shuffle = True)# 模型實例化 LR_model = LR()# 定義優化算法 optimizer = optim.SGD(LR_model.parameters(), lr = 0.03)# 模型訓練 fit(net = LR_model, criterion = criterion, optimizer = optimizer, batchdata = batchData, epochs = num_epochs)# MSE結果查看 criterion(LR_model(features), labels) #tensor(4.0763, grad_fn=<MseLossBackward>)總結
以上是生活随笔為你收集整理的Lesson 12.3 线性回归建模实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lesson 12.1 深度学习建模实验
- 下一篇: Lesson 12.4 逻辑回归建模实验