線性迴歸的簡潔實現
阿新 • • 發佈:2021-07-26
前言:
簡潔實現:使用深度學習開源框架達到目的
一、生成資料集
#線性迴歸的簡潔實現就是使用pytorch內建的一些模組來實現 import numpy as np import torch from torch.utils import data #從torch.utils中匯入關於data處理的模組 from d2l import torch as d2l
true_w = torch.tensor([2, -3.4])#構造w true_b = 4.2#構造b features, labels = d2l.synthetic_data(true_w, true_b, 1000)#synthetic_data生成資料集函式
在這裡,我們通過true_w和true_b生成有1000個數據的資料集(也就是說,)
二、讀取資料集
1、呼叫框架中現有的API來讀取資料
2、將features
和labels
作為API的引數傳遞,並在例項化資料迭代器物件時指定batch_size
# is_train=True:表示希望資料迭代器物件在每個迭代週期內打亂資料 # data_arrays:表示可以傳入多個矩陣,即是將features和labels作為引數,data_arrays相當於一個API def load_array(data_arrays, batch_size, is_train=True): #@save """構造一個PyTorch資料迭代器。""" #TensorDateset:把輸入的兩類資料進行一一對應; #DataLoader:重新排序 dataset = data.TensorDataset(*data_arrays)#*可以對list解開入參,因為features和labels作為API引數傳遞 return data.DataLoader(dataset, batch_size, shuffle=is_train)#每次隨機挑選batch_size個樣本,shuffle意思是要不要打亂順序
# 讀取10個樣本 batch_size = 10 data_iter = load_array((features, labels), batch_size)
# 不能直接從data_iter中獲得資料 next(iter(data_iter))#將data_iter用iter()函式轉為迭代器,再使用next()函式從迭代器中獲取資料 #輸出結果 [tensor([[-0.5143, -1.0371], [ 0.0254, -0.1204], [ 0.1787, 0.2586], [-0.6284, 0.7571], [-0.3744, 0.5989], [ 0.1679, -1.5357], [-0.6135, -1.2744], [ 0.3798, -0.8941], [-1.6691, -0.6110], [ 0.0555, -0.3930]]), tensor([[6.7026], [4.6815], [3.6661], [0.3918], [1.4045], [9.7481], [7.2834], [7.9958], [2.9436], [5.6409]])]
三、定義模型
1、使用框架的預定義好的層,即我們只需關注使用哪些層來構造模型,而不必關注層的實現細節
2、實現步驟:
首先定義一個模型變數net
,它是一個Sequential
類的例項
Sequential
類為串聯在一起的多個層定義了一個容器。當給定輸入資料,Sequential
例項將資料傳入到第一層,然後將第一層的輸出作為第二層的輸入,依此類推
3、Pytorch中,全連線層在Linear類中定義。Linear中,第一個變數為輸入特徵形狀,第二個變數為輸出特徵形狀
# `nn` 是神經網路的縮寫 from torch import nn # Linear中,第一個指定輸入特徵數,第二個指定輸出數 net = nn.Sequential(nn.Linear(2, 1))#輸入維度是2,輸出維度是1; #nn.Linear(2,1)可以理解為線性迴歸就是簡單的單層神經網路,將其放在一個Sequential中
四、初始化模型引數
1、在使用net前,需要初始化模型引數,如在此需要初始化權重與偏置
2、在這裡,我們指定每個權重引數應該從均值為0、標準差為0.01的正態分佈中隨機取樣,偏置引數將初始化為零
# net[0]:表示使用網路中的第一個圖層 # 權重引數從均值為0,標準差為0.01的正態分佈中隨機取樣 print(net[0].weight.data) net[0].weight.data.normal_(0, 0.01)#normal_(0, 0.01)的意思是使用正態分佈替換data的值,均值為0、標準差為0.01 print(net[0].weight.data) #偏置引數初始化為0 print(net[0].bias.data) net[0].bias.data.fill_(0)#bias偏差 print(net[0].bias.data) #輸出函式 tensor([[ 0.0080, -0.0021]]) tensor([[-0.0073, 0.0137]]) tensor([0.]) tensor([0.])
五、定義損失函式
1、計算均方誤差使用的是MSELoss類,也稱為平方L2範數
2、預設情況下,他返回所有樣本損失的平均值
# 平方L2範數,返回所有樣本損失的平均值 loss = nn.MSELoss()
六、定義優化演算法——梯度下降優化演算法
# net.parameters()常用於做模組引數 # SGD隨機梯度下降求解 trainer = torch.optim.SGD(net.parameters(), lr=0.03)#net.parameters()包括w和b
七、訓練
1、在每個迭代週期裡,我們將完整遍歷一次資料集
2、在每個迭代週期裡,會不停地從中獲取一個小批量的輸入和相應的標籤,對於每一個小批量,操作如下:
- 通過呼叫
net(X)
生成預測並計算損失l
(正向傳播)。 - 通過進行反向傳播來計算梯度。
- 通過呼叫優化器來更新模型引數。
num_epochs = 3#迭代三個週期 for epoch in range(num_epochs): for X, y in data_iter: l = loss(net(X), y)#loss是損失函式 trainer.zero_grad()#trainer優化器,先把梯度清零 l.backward()#等價於l.sum().backward()——求和之後算梯度 trainer.step()#呼叫優化演算法進行模型更新 l = loss(net(features), labels) print(f'epoch {epoch + 1}, loss {l:f}') #輸出結果 epoch 1, loss 0.000215 epoch 2, loss 0.000107 epoch 3, loss 0.000108
3、比較生成資料集的真實引數和通過有限資料訓練獲得的模型引數
w = net[0].weight.data print('w的估計誤差:', true_w - w.reshape(true_w.shape)) b = net[0].bias.data print('b的估計誤差:', true_b - b) #輸出結果 w的估計誤差: tensor([ 5.0187e-05, -1.9765e-04]) b的估計誤差: tensor([0.0008])