日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

深度学习pytorch--线性回归(二)

發(fā)布時間:2023/12/3 pytorch 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习pytorch--线性回归(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

線性回歸無框架實現(xiàn)

    • 線性回歸的從零開始實現(xiàn)
    • 生成數(shù)據(jù)集(簡單的人工構(gòu)造)
    • 讀取數(shù)據(jù)
    • 初始化模型參數(shù)
    • 定義模型
    • 定義損失函數(shù)
    • 定義優(yōu)化算法
    • 訓練模型
    • 小結(jié)
    • 完整代碼(可直接運行)

線性回歸的從零開始實現(xiàn)

為了深入理解深度學習是如何工作的,本節(jié)不使用強大的深度學習框架,而是介紹如何只利用Tensor和autograd來實現(xiàn)一個線性回歸的訓練。

首先,導入本節(jié)中實驗所需的包或模塊如下:

import torch from matplotlib import pyplot as plt import numpy as np import random

生成數(shù)據(jù)集(簡單的人工構(gòu)造)

設(shè)訓練數(shù)據(jù)集樣本數(shù)為1000,輸入個數(shù)(特征數(shù))為2。給定隨機生成的批量樣本特征 X∈R1000×2\boldsymbol{X} \in \mathbb{R}^{1000 \times 2}XR1000×2,我們使用線性回歸模型真實權(quán)重 w=[2,?3.4]?\boldsymbol{w} = [2, -3.4]^\topw=[2,?3.4]? 和偏差 b=4.2b = 4.2b=4.2,以及一個隨機噪聲項 ?\epsilon? 來生成標簽
y=Xw+b+?\boldsymbol{y} = \boldsymbol{X}\boldsymbol{w} + b + \epsilon y=Xw+b+?

其中噪聲項 ?\epsilon? 服從均值為0、標準差為0.01的正態(tài)分布。噪聲代表了數(shù)據(jù)集中無意義的干擾。下面,讓我們生成數(shù)據(jù)集。

#生成數(shù)據(jù)集以及計算grand-truth,下面的計算可以根據(jù)公式來看 num_inputs=2 #要訓練的權(quán)重個數(shù)(面積和房齡兩個特征(影響放假的因素)的權(quán)重) num_examples=1000 #樣本數(shù)量 true_w=[2,-4] true_b=4.2 features=torch.randn(num_examples,num_inputs,dtype=torch.float32) #代表X矩陣 labels=torch.mm(features,torch.Tensor(true_w).view(-1,1)) #mm為矩陣相乘,此處為1000*2的矩陣乘以2*1的矩陣,mul為點乘 labels+=torch.tensor(np.random.normal(0, 0.01, size=labels.size()),dtype=torch.float32) #加均值為0,方差為1的隨機噪聲項

注意,features的每一行是一個長度為2的向量,形狀為torch.Size([1000,2]),代表X矩陣,而labels形狀為torch.Size([1000,1]),每一行是一個長度為1的向量(標量),代表每個樣本(房子)的真實價格。

print(features[0], labels[0])

輸出:

tensor([0.8557, 0.4793]) tensor([4.2887])

通過生成第二個特征features[:, 1]和標簽 labels 的散點圖,可以更直觀地觀察兩者間的線性關(guān)系。

plt.scatter(features[:, 1].numpy(), labels.numpy(), 1) plt.show()

讀取數(shù)據(jù)

在訓練模型的時候,我們需要遍歷數(shù)據(jù)集并不斷讀取小批量數(shù)據(jù)樣本。這里我們定義一個函數(shù):它每次返回batch_size(批量大小)個隨機樣本的特征和標簽。

def data_iter(batch_size, features, labels):num_examples = len(features) #1000indices = list(range(num_examples))random.shuffle(indices) # 樣本的讀取順序是隨機的for i in range(0, num_examples, batch_size):j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) # 最后一次可能不足一個batchyield features.index_select(0, j), labels.index_select(0, j)

讓我們讀取第一個小批量數(shù)據(jù)樣本并打印。每個批量的特征形狀為(10, 2),分別對應(yīng)批量大小和輸入個數(shù);標簽形狀為批量大小。

batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, y)break

輸出:

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]])

初始化模型參數(shù)

我們將權(quán)重初始化成均值為0、標準差為0.01的正態(tài)隨機數(shù),偏差則初始化成0。

w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32) b = torch.zeros(1, dtype=torch.float32)

之后的模型訓練中,需要對這些參數(shù)求梯度來迭代參數(shù)的值,因此我們要讓它們的requires_grad=True。

w.requires_grad_(requires_grad=True) b.requires_grad_(requires_grad=True) #或者在創(chuàng)建tensor時加requires_grad=True

定義模型

下面是線性回歸的矢量計算表達式的實現(xiàn)。我們使用mm函數(shù)做矩陣乘法。

def linreg(X, w, b): # 本函數(shù)已保存在d2lzh_pytorch包中方便以后使用return torch.mm(X, w) + b

定義損失函數(shù)

我們使用上一節(jié)描述的平方損失來定義線性回歸的損失函數(shù)。在實現(xiàn)中,我們需要把真實值y變形成預(yù)測值y_hat的形狀。以下函數(shù)返回的結(jié)果也將和y_hat的形狀相同。

def squared_loss(y_hat, y): # 本函數(shù)已保存在d2lzh_pytorch包中方便以后使用# 注意這里返回的是向量, 另外, pytorch里的MSELoss并沒有除以 2return (y_hat - y.view(y_hat.size())) ** 2 / 2

定義優(yōu)化算法

以下的sgd函數(shù)實現(xiàn)了上一節(jié)中介紹的小批量隨機梯度下降算法。它通過不斷迭代模型參數(shù)來優(yōu)化損失函數(shù)。這里自動求梯度模塊計算得來的梯度是一個批量樣本的梯度和。我們將它除以批量大小來得到平均值。

def sgd(params, lr, batch_size): # 本函數(shù)已保存在d2lzh_pytorch包中方便以后使用for param in params:param.data -= lr * param.grad / batch_size # 注意這里更改param時用的param.data

訓練模型

在訓練中,我們將多次迭代模型參數(shù)。在每次迭代中,我們根據(jù)當前讀取的小批量數(shù)據(jù)樣本(特征X和標簽y),通過調(diào)用反向函數(shù)backward計算小批量隨機梯度,并調(diào)用優(yōu)化算法sgd迭代模型參數(shù)。由于我們之前設(shè)批量大小batch_size為10,每個小批量的損失l的形狀為(10, 1)。回憶一下自動求梯度一節(jié)。由于變量l并不是一個標量,所以我們可以調(diào)用.sum()將其求和得到一個標量,再運行l(wèi).backward()得到該變量有關(guān)模型參數(shù)的梯度。注意在每次更新完參數(shù)后不要忘了將參數(shù)的梯度清零。

在一個迭代周期(epoch)中,我們將完整遍歷一遍data_iter函數(shù),并對訓練數(shù)據(jù)集中所有樣本都使用一次(假設(shè)樣本數(shù)能夠被批量大小整除)。這里的迭代周期個數(shù)num_epochs和學習率lr都是超參數(shù),分別設(shè)3和0.03。在實踐中,大多超參數(shù)都需要通過反復(fù)試錯來不斷調(diào)節(jié)。雖然迭代周期數(shù)設(shè)得越大模型可能越有效,但是訓練時間可能過長。而有關(guān)學習率對模型的影響,我們會在后面“優(yōu)化算法”一章中詳細介紹。

lr = 0.01 num_epochs = 5 net = linreg loss = squared_lossfor epoch in range(num_epochs): # 訓練模型一共需要num_epochs個迭代周期# 在每一個迭代周期中,會使用訓練數(shù)據(jù)集中所有樣本一次(假設(shè)樣本數(shù)能夠被批量大小整除)。X# 和y分別是小批量樣本的特征和標簽for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y).sum() # l是有關(guān)小批量X和y的損失l.backward() # 小批量的損失對模型參數(shù)求梯度sgd([w, b], lr, batch_size) # 使用小批量隨機梯度下降迭代模型參數(shù)# 不要忘了梯度清零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 1.3475228548049927 epoch 2,loss 0.18588872253894806 epoch 3,loss 0.02577354572713375 epoch 4,loss 0.0036298963241279125 epoch 5,loss 0.0005514014046639204

訓練完成后,我們可以比較學到的參數(shù)和用來生成訓練集的真實參數(shù)。它們應(yīng)該很接近。

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)

小結(jié)

  • 可以看出,僅使用Tensor和autograd模塊就可以很容易地實現(xiàn)一個模型。接下來,本書會在此基礎(chǔ)上描述更多深度學習模型,并介紹怎樣使用更簡潔的代碼(見下一節(jié))來實現(xiàn)它們。

完整代碼(可直接運行)

import torch import numpy as np import random#生成數(shù)據(jù)集以及計算grand-truth,下面的計算可以根據(jù)公式來看 num_inputs=2 #要訓練的權(quán)重個數(shù)(面積和房齡兩個特征(影響放假的因素)的權(quán)重) num_examples=1000 #樣本數(shù)量 true_w=[2,-4] true_b=4.2 features=torch.randn(num_examples,num_inputs,dtype=torch.float32) #代表X矩陣 labels=torch.mm(features,torch.Tensor(true_w).view(-1,1)) #mm為矩陣相乘,此處為1000*2的矩陣乘以2*1的矩陣,mul為點乘 labels+=torch.tensor(np.random.normal(0, 0.01, size=labels.size()),dtype=torch.float32) #加均值為0,方差為1的隨機噪聲項#數(shù)據(jù)預(yù)處理 def data_iter(batch_size, features, labels):num_examples = len(features) #1000indices = list(range(num_examples))random.shuffle(indices) # 樣本的讀取順序是隨機的for i in range(0, num_examples, batch_size):j = torch.LongTensor(indices[i: min(i + batch_size, num_examples)]) #LongTensor默認64位整型 后面為切片操作,使用min是因為最后一次可能不足一個batchyield features.index_select(0, j), labels.index_select(0, j)#初始化模型參數(shù),由于要訓練計算梯度,所以加requires_grad=True w = torch.tensor(np.random.normal(0, 0.01, (num_inputs, 1)), dtype=torch.float32,requires_grad=True) #形狀為torch.Size([2,1]) b = torch.zeros(1, dtype=torch.float32,requires_grad=True)#定義模型 def linreg(X,w,b):return torch.mm(X,w)+b #定義損失函數(shù) def squared_loss(y_hat,y):return (y_hat-y)**2/2 #定義優(yōu)化算法 def sgd(params,Ir,batch_size):for param in params:param.data-=Ir*param.grad/batch_size #除以batch_size之后計算批量loss的時候就不用求平均了,只需要sum() #訓練模型 num_epochs=5 Ir=0.01 batch_size = 10 net=linreg #模型 loss=squared_loss #損失函數(shù)for epoch in range(num_epochs):for X,y in data_iter(batch_size,features,labels): #每批十個l=loss(net(X,w,b),y).sum() #10個loss在一個張量里,所以用sum對張量中的元素進行求和#至于為什么不求平均,在參數(shù)更新處有所體現(xiàn)(除以了batch_size)l.backward()#反向傳播sgd([w,b],Ir,batch_size)#梯度清零w.grad.data.zero_()b.grad.data.zero_()train_l=loss(net(features,w,b),labels)print("epoch {},loss {}".format(epoch+1,train_l.mean().item())) #mean()對loss求平均 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的深度学习pytorch--线性回归(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。