(pytorch-深度学习系列)pytorch实现线性回归
pytorch實現線性回歸
1. 實現線性回歸前的準備
線性回歸輸出是一個連續值,因此適用于回歸問題。回歸問題在實際中很常見,如預測房屋價格、氣溫、銷售額等連續值的問題。
與回歸問題不同,分類問題中模型的最終輸出是一個離散值。我們所說的圖像分類、垃圾郵件識別、疾病檢測等輸出為離散值的問題都屬于分類問題的范疇。softmax回歸則適用于分類問題。
定義兩個1000維的向量
import torch from time import timea = torch.ones(1000) b = torch.ones(1000)向量相加的一種方法是,將這兩個向量按元素逐一做標量加法。如下:
start = time() c = torch.zeros(1000) for i in range(1000):c[i] = a[i] + b[i] print(time() - start)輸出:
0.02039504051208496向量相加的另一種方法是,將這兩個向量直接做矢量加法。
start = time() d = a + b print(time() - start) # 0.0008330345153808594結果很明顯,后者比前者更省時。因此,我們應該盡可能采用矢量計算,以提升計算效率。
定義一個房價預測問題,實例化應用場景:
我們通常收集一系列的真實數據,例如多棟房屋的真實售出價格和它們對應的面積和房齡。我們希望在這個數據上面尋找模型參數來使模型的預測價格與真實價格的誤差最小。在機器學習術語里,該數據集被稱為訓練數據集(training data set)或訓練集(training set),一棟房屋被稱為一個樣本(sample),其真實售出價格叫作標簽(label),用來預測標簽的兩個因素叫作特征(feature)。特征用來表征樣本的特點。
在模型訓練中,我們需要衡量價格預測值與真實值之間的誤差。通常我們會選取一個非負數作為誤差,且數值越小表示誤差越小。一個常用的選擇是平方函數。它在評估索引為 i 的樣本誤差的表達式為:
誤差越小表示預測價格與真實價格越相近,且當二者相等時誤差為0
我們用訓練數據集中所有樣本誤差的平均來衡量模型預測的質量:
2. 線性回歸的pytorch實現
導入所需的包或模塊,其中的matplotlib包可用于作圖,且設置成嵌入顯示。
%matplotlib inline import torch from IPython import display from matplotlib import pyplot as plt # matplotlib包可用于作圖,且設置成嵌入顯示 import numpy as np import random生成一個數據集:
num_inputs = 2 #特征數量 num_examples = 1000 # 數據數量,即樣本數量 true_w = [2, -3.4] # 線性回歸模型真實權重 true_b = 4.2 # 偏差 features = torch.randn(num_examples, num_inputs,dtype=torch.float32) labels = true_w[0] * features[:, 0] + true_w[1] * features[:, 1] + true_b # y=k*x+b labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()),dtype=torch.float32) # 噪聲項,服從均值為0、標準差為0.01的正態分布。噪聲代表了數據集中無意義的干擾features的每一行是一個長度為2的向量,而labels的每一行是一個長度為1的向量(標量)
通過生成第二個特征features[:, 1]和標簽 labels 的散點圖,可以更直觀地觀察兩者間的線性關系。
def use_svg_display():# 用矢量圖顯示display.set_matplotlib_formats('svg') # 設置圖類型為svg圖def set_figsize(figsize=(3.5, 2.5)):use_svg_display()# 設置圖的尺寸plt.rcParams['figure.figsize'] = figsizeset_figsize() plt.scatter(features[:, 1].numpy(), labels.numpy(), 1) # 注意這里將tensor轉化為numpy
在訓練模型的時候,我們需要遍歷數據集并不斷讀取小批量數據樣本。這里我們定義一個函數:它每次返回batch_size(批量大小)個隨機樣本的特征和標簽。
讀取第一個小批量數據樣本并打印。每個批量的特征形狀為(10, 2),分別對應批量大小和輸入個數;標簽形狀為批量大小。
batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, y)break # 讀取一個batch輸出:
tensor([[-1.4239, -1.3788],[ 0.0275, 1.3550],[ 0.7616, -1.1384],[ 0.2967, -0.1162],[ 0.0822, 2.0826],[-0.6343, -0.7222],[ 0.4282, 0.0235],[ 1.4056, 0.3506],[-0.6496, -0.5202],[-0.3969, -0.9951]]) tensor([ 6.0394, -0.3365, 9.5882, 5.1810, -2.7355, 5.3873, 4.9827, 5.7962,4.6727, 6.7921])我們將模型參數權重初始化成均值為0、標準差為0.01的正態隨機數,偏差則初始化成0。
w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32) b = torch.zeros(1, dtype=torch.float32)之后的模型訓練中,需要對這些參數求梯度來迭代參數的值,因此我們要讓它們的requires_grad=True:
w.requires_grad_(requires_grad=True) b.requires_grad_(requires_grad=True)定義模型:
def linreg(X, w, b): # 矢量表達式return torch.mm(X, w) + bdef squared_loss(y_hat, y): # 損失函數# 注意這里返回的是向量, 另外, pytorch里的MSELoss并沒有除以 2return (y_hat - y.view(y_hat.size())) ** 2 / 2def sgd(params, lr, batch_size): # 優化算法:小批量隨機梯度下降算法for param in params:param.data -= lr * param.grad / batch_size # 注意這里更改param時用的是param.data在求數值解的優化算法中,小批量隨機梯度下降(mini-batch stochastic gradient descent)在深度學習中被廣泛使用。它的算法很簡單:先選取一組模型參數的初始值,如隨機選取;接下來對參數進行多次迭代,使每次迭代都可能降低損失函數的值。在每次迭代中,先隨機均勻采樣一個由固定數目訓練數據樣本所組成的小批量(mini-batch),然后求小批量中數據樣本的平均損失有關模型參數的導數(梯度),最后用此結果與預先設定的一個正數的乘積作為模型參數在本次迭代的減小量。
訓練模型:
lr = 0.03 # 學習率 num_epochs = 3 net = linreg loss = squared_lossfor epoch in range(num_epochs): # 訓練模型一共需要num_epochs個迭代周期# 在每一個迭代周期中,會使用訓練數據集中所有樣本一次(假設樣本數能夠被批量大小整除)。X# 和y分別是小批量樣本的特征和標簽for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y).sum() # l是有關小批量X和y的損失l.backward() # 小批量的損失對模型參數求梯度sgd([w, b], lr, batch_size) # 使用小批量隨機梯度下降迭代模型參數# 不要忘了梯度清零w.grad.data.zero_()b.grad.data.zero_()train_l = loss(net(features, w, b), labels)print('epoch %d, loss %f' % (epoch + 1, train_l.mean().item())) epoch 1, loss 0.021578 epoch 2, loss 0.000096 epoch 3, loss 0.000050輸出學到的參數和用來生成訓練集的真實參數:
print(true_w, '\n', w) print(true_b, '\n', b) [2, -3.4] tensor([[ 1.9998],[-3.3998]], requires_grad=True) 4.2 tensor([4.2001], requires_grad=True)總結
以上是生活随笔為你收集整理的(pytorch-深度学习系列)pytorch实现线性回归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 拉普拉斯方程之美:万物的数学之匙
- 下一篇: 我们为什么要学数学?这里给你一个答案。