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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Pytorch神经网络基础理论篇】 07 线性回归 + 基础优化算法

發(fā)布時間:2024/7/5 编程问答 66 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Pytorch神经网络基础理论篇】 07 线性回归 + 基础优化算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

一、線性代數(shù)

回歸是指一類為一個或多個自變量與因變量之間關(guān)系建模的方法。在自然科學(xué)和社會科學(xué)領(lǐng)域,回歸經(jīng)常用來表示輸入和輸出之間的關(guān)系。 在機(jī)器學(xué)習(xí)領(lǐng)域中的大多數(shù)任務(wù)通常都與預(yù)測(prediction)有關(guān)。

當(dāng)我們想預(yù)測一個數(shù)值時,就會涉及到回歸問題。常見的例子包括:預(yù)測價格(房屋、股票等)、預(yù)測住院時間(針對住院病人)、預(yù)測需求(零售銷量)等。

但不是所有的預(yù)測都是回歸問題。在后面的章節(jié)中,我們將介紹分類問題。分類問題的目標(biāo)是預(yù)測數(shù)據(jù)屬于一組類別中的哪一個。

1.1?線性回歸的基本元素

線性回歸基于幾個簡單的假設(shè):首先,假設(shè)自變量x和因變量y之間的關(guān)系是線性的,即y可以表示為x中元素的加權(quán)和,這里通常允許包含觀測值的一些噪聲;其次,我們假設(shè)任何噪聲都比較正常,如噪聲遵循正態(tài)分布。

為了解釋線性回歸,我們舉一個實際的例子:我們希望根據(jù)房屋的面積(平方英尺)和房齡(年)來估算房屋價格(美元)。

為了開發(fā)一個能預(yù)測房價的模型,我們需要收集一個真實的數(shù)據(jù)集。這個數(shù)據(jù)集包括了房屋的銷售價格、面積和房齡。

在機(jī)器學(xué)習(xí)的術(shù)語中,該數(shù)據(jù)集稱為訓(xùn)練數(shù)據(jù)集(training data set)或訓(xùn)練集(training set),每行數(shù)據(jù)(在這個例子中是與一次房屋交易相對應(yīng)的數(shù)據(jù))稱為樣本(sample),也可以稱為數(shù)據(jù)點(data point)或數(shù)據(jù)樣本(data instance)。

我們要試圖預(yù)測的目標(biāo)(在這個例子中是房屋價格)稱為標(biāo)簽(label)或目標(biāo)(target)。

預(yù)測所依據(jù)的自變量(面積和房齡)稱為特征(feature)或協(xié)變量(covariate)。

通常,我們使用n來表示數(shù)據(jù)集中的樣本數(shù)。

1.2?線性模型

線性假設(shè)是指目標(biāo)(房屋價格)可以表示為特征(面積和房齡)的加權(quán)和,如下面的式子:

Warea和Wage稱為權(quán)重(weight),b稱為偏置(bias)、偏移量(offset)、截距(intercept)。

權(quán)重決定了每個特征對我們預(yù)測值的影響。

偏置是指當(dāng)所有特征都取值為0時,預(yù)測值應(yīng)該為多少,如果沒有偏置項,我們模型的表達(dá)能力將受到限制。

嚴(yán)格來說,上式是輸入特征的一個仿射變換(affine transformation)。仿射變換的特點是通過加權(quán)和對特征進(jìn)行線性變換,并通過偏置項來進(jìn)行平移。

給定一個數(shù)據(jù)集,我們的目標(biāo)是尋找模型的權(quán)重w和偏置b,使得根據(jù)模型做出的預(yù)測大體符合數(shù)據(jù)里的真實價格。輸出的預(yù)測值由輸入特征通過線性模型的仿射變換決定,仿射變換由所選權(quán)重和偏置確定。

在我們開始尋找最好的模型參數(shù)w和b之前,我們還需要兩個東西:
(1)一種模型質(zhì)量的度量方式;
(2)一種能夠更新模型以提高模型預(yù)測質(zhì)量的方法。

1.3損失函數(shù)

損失函數(shù)能夠量化目標(biāo)的實際值與預(yù)測值之間的差距。通常我們會選擇非負(fù)數(shù)作為損失,且數(shù)值越小表示損失越小,完美預(yù)測時的損失為0。回歸問題中最常用的損失函數(shù)是平方誤差函數(shù)。

為了進(jìn)一步說明,來看下面的例子。我們?yōu)橐痪S情況下的回歸問題繪制圖像,如圖所示。

?

?在平方誤差函數(shù)中,猶豫估計值和觀測值之間的差值將使的整個模型的誤差變大,因此通過損失均值可以降低誤差的顯示范圍,如下:

在訓(xùn)練模型時,我們希望尋找一組參數(shù)(w,b),這組參數(shù)能最小化在所有訓(xùn)練樣本上的總損失。

1.3解析解

????????線性回歸剛好是一個很簡單的優(yōu)化問題。與我們將在本書中所講到的其他大部分模型不同,線性回歸的解可以用一個公式簡單地表達(dá)出來,這類解叫作解析解(analytical solution)。

????????線性回歸這樣的簡單問題存在解析解,但并不是所有的問題都存在解析解。解析解可以進(jìn)行很好的數(shù)學(xué)分析,但解析解的限制很嚴(yán)格,導(dǎo)致它無法應(yīng)用在深度學(xué)習(xí)里。

1.4 小批量隨機(jī)梯度下降

梯度下降(gradient descent)幾乎可以優(yōu)化所有深度學(xué)習(xí)模型,它通過不斷地在損失函數(shù)遞減的方向上更新參數(shù)來降低誤差。

1.4.1小批量隨機(jī)梯度下降

梯度下降最簡單的用法是計算損失函數(shù)(數(shù)據(jù)集中所有樣本的損失均值)關(guān)于模型參數(shù)的導(dǎo)數(shù)(在這里也可以稱為梯度)。但實際中的執(zhí)行可能會非常慢:因為在每一次更新參數(shù)之前,我們必須遍歷整個數(shù)據(jù)集。

因此,我們通常會在每次需要計算更新的時候隨機(jī)抽取一小批樣本,這種變體叫做小批量隨機(jī)梯度下降。

在每次迭代中,我們首先隨機(jī)抽樣一個小批量B,它是由固定數(shù)量的訓(xùn)練樣本組成的。然后,我們計算小批量的平均損失關(guān)于模型參數(shù)的導(dǎo)數(shù)(也可以稱為梯度)。最后,我們將梯度乘以一個預(yù)先確定的正數(shù)η,并從當(dāng)前參數(shù)的值中減掉。

我們用下面的數(shù)學(xué)公式來表示這一更新過程(?表示偏導(dǎo)數(shù)):

總結(jié)一下,算法的步驟如下:

(1)初始化模型參數(shù)的值,如隨機(jī)初始化;

(2)從數(shù)據(jù)集中隨機(jī)抽取小批量樣本且在負(fù)梯度的方向上更新參數(shù),并不斷迭代這一步驟。

對于平方損失和仿射變換,我們可以明確地寫成如下形式:

公式 (3.1.10)中的wx都是向量。在這里,更優(yōu)雅的向量表示法比系數(shù)表示法(w1,w2,…,wd)更具可讀性。 |B|表示每個小批量中的樣本數(shù),這也稱為批量大小(batch size)。η表示學(xué)習(xí)率(learning rate)。

批量大小和學(xué)習(xí)率的值通常是手動預(yù)先指定,而不是通過模型訓(xùn)練得到的。

超參數(shù)指:可以調(diào)整但不在訓(xùn)練過程中更新的參數(shù),?超參數(shù)通常是根據(jù)在獨立的驗證數(shù)據(jù)集上評估得到的訓(xùn)練迭代結(jié)果來調(diào)整的

調(diào)參:選擇超參數(shù)的過程。

在訓(xùn)練了預(yù)先確定的若干迭代次數(shù)后(或者直到滿足某些其他停止條件后),我們記錄下模型參數(shù)的估計值,表示為w^,b^。但是,即使我們的函數(shù)確實是線性的且無噪聲,這些估計值也不會使損失函數(shù)真正地達(dá)到最小值。因為算法會使得損失向最小值緩慢收斂,但卻不能在有限的步數(shù)內(nèi)非常精確地達(dá)到最小值。

線性回歸恰好是一個在整個域中只有一個最小值的學(xué)習(xí)問題。但是對于像深度神經(jīng)網(wǎng)絡(luò)這樣復(fù)雜的模型來說,損失平面上通常包含多個最小值。幸運的是,出于某種原因,深度學(xué)習(xí)實踐者很少會去花費大力氣尋找這樣一組參數(shù),使得在訓(xùn)練集上的損失達(dá)到最小。

事實上,更難做到的是找到一組參數(shù),這組參數(shù)能夠在我們從未見過的數(shù)據(jù)上實現(xiàn)較低的損失,這一挑戰(zhàn)被稱為泛化。

1.4.1用學(xué)習(xí)到的模型進(jìn)行預(yù)測

現(xiàn)在我們可以通過給定的房屋面積x1和房齡x2來估計一個未包含在訓(xùn)練數(shù)據(jù)中的新房屋價格。給定特征估計目標(biāo)的過程通常稱為預(yù)測(prediction)或推斷(inference)。

1.5?正態(tài)分布與平方損失

1.5.1?正態(tài)分布(normal distribution)

正態(tài)分布,也稱為高斯分布和線性回歸之間的關(guān)系很密切。?

下面我們定義一個Python函數(shù)來計算正態(tài)分布。

def normal(x, mu, sigma):p = 1 / math.sqrt(2 * math.pi * sigma**2)return p * np.exp(-0.5 / sigma**2 * (x - mu)**2)

我們現(xiàn)在可視化正態(tài)分布。

# 再次使用numpy進(jìn)行可視化 x = np.arange(-7, 7, 0.01)# 均值和標(biāo)準(zhǔn)差對 params = [(0, 1), (0, 2), (3, 1)] d2l.plot(x, [normal(x, mu, sigma) for mu, sigma in params], xlabel='x',ylabel='p(x)', figsize=(4.5, 2.5),legend=[f'mean {mu}, std {sigma}' for mu, sigma in params])

由上圖可知,在高斯分布上改變均值會產(chǎn)生沿x軸的偏移,增加方差將會分散分布、降低其峰值。

1.5.2?均方誤差損失函數(shù)(簡稱均方損失)

其可以用于線性回歸的一個原因是:我們假設(shè)了觀測中包含噪聲,其中噪聲服從正態(tài)分布。

噪聲正態(tài)分布如下式:

1.5.3 最大似然估計量

根據(jù)最大似然估計法選擇的估計量稱為最大似然估計量。

雖然使許多指數(shù)函數(shù)的乘積最大化看起來很困難,但是我們可以在不改變目標(biāo)的前提下,通過最大化似然對數(shù)來簡化,優(yōu)化通常是說最小化而不是最大化。

?因此,在高斯噪聲的假設(shè)下,最小化均方誤差等價于對線性模型的最大似然估計。

?1.6??從線性回歸到深度網(wǎng)絡(luò)

1.6.1?神經(jīng)網(wǎng)絡(luò)圖

我們將線性回歸模型描述為一個神經(jīng)網(wǎng)絡(luò),該圖只顯示連接模式,即只顯示每個輸入如何連接到輸出,隱去了權(quán)重和偏置的值。

?由于模型重點在發(fā)生計算的地方,所以通常我們在計算層數(shù)時不考慮輸入層。也就是說, 圖3.1.2中神經(jīng)網(wǎng)絡(luò)的層數(shù)為1。

對于線性回歸,每個輸入都與每個輸出(在本例中只有一個輸出)相連,我們將這種變換( 圖3.1.2中的輸出層)稱為全連接層(fully-connected layer),或稱為稠密層(dense layer)。

1.6.2?神經(jīng)網(wǎng)絡(luò)與生物學(xué)

圖3.1.3,這是一張由樹突(dendrites,輸入終端)、細(xì)胞核(nucleu,CPU)組成的生物神經(jīng)元圖片。軸突(axon,輸出線)和軸突端子(axon terminal,輸出端子)通過突觸(synapse)與其他神經(jīng)元連接。

?二、基礎(chǔ)優(yōu)化方法

?

?

?

?三、從零開始實現(xiàn)線性回歸

?在這一節(jié)中,我們將只使用張量和自動求導(dǎo)。

PS:d2l包可以直接在conda的prompt里面輸入命令 pip install -U d2l 來安裝

%matplotlib inline import random import torch from d2l import torch as d2l

3.1 生成數(shù)據(jù)集

在該部分生成一個包含1000個樣本的數(shù)據(jù)集,每個樣本包含從標(biāo)準(zhǔn)正態(tài)分布中采樣的2個特征。

def synthetic_data(w, b, num_examples): #@save"""生成 y = Xw + b + 噪聲。"""X = torch.normal(0, 1, (num_examples, len(w)))y = torch.matmul(X, w) + by += torch.normal(0, 0.01, y.shape)return X, y.reshape((-1, 1))true_w = torch.tensor([2, -3.4]) true_b = 4.2 features, labels = synthetic_data(true_w, true_b, 1000)

注意,features中的每一行都包含一個二維數(shù)據(jù)樣本,labels中的每一行都包含一維標(biāo)簽值(一個標(biāo)量),下面將其輸出。

print('features:', features[0],'\nlabel:', labels[0]) features: tensor([-1.5273, 0.5069]) label: tensor([-0.5713])

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

d2l.set_figsize() d2l.plt.scatter(features[:, (1)].detach().numpy(), labels.detach().numpy(), 1);

?3.2?讀取數(shù)據(jù)集

我們定義一個data_iter函數(shù), 該函數(shù)接收批量大小、特征矩陣和標(biāo)簽向量作為輸入,生成大小為batch_size的小批量,每個小批量包含一組特征和標(biāo)簽。

def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 這些樣本是隨機(jī)讀取的,沒有特定的順序random.shuffle(indices)for i in range(0, num_examples, batch_size):batch_indices = torch.tensor(indices[i: min(i + batch_size, num_examples)])yield features[batch_indices], labels[batch_indices]

通常,我們使用合理大小的小批量來利用GPU硬件的優(yōu)勢,因為GPU在并行處理方面表現(xiàn)出色。每個樣本都可以并行地進(jìn)行模型計算,且每個樣本損失函數(shù)的梯度也可以被并行地計算,GPU可以在處理幾百個樣本時,所花費的時間不比處理一個樣本時多太多。

讓我們直觀感受一下。讀取第一個小批量數(shù)據(jù)樣本并打印。每個批量的特征維度說明了批量大小和輸入特征數(shù),?同樣的,批量的標(biāo)簽形狀與batch_size相等。

batch_size = 10for X, y in data_iter(batch_size, features, labels):print(X, '\n', y)break tensor([[-0.5309, 0.2644],[ 0.5849, -0.4633],[ 0.0618, -1.1239],[ 0.2240, 0.0085],[ 0.7633, 0.9449],[ 0.8836, 0.8245],[-2.5749, -0.5567],[-0.0975, 0.8569],[ 0.8215, -0.3621],[ 0.7872, 0.2790]])tensor([[2.2405],[6.9425],[8.1252],[4.6162],[2.5107],[3.1595],[0.9252],[1.0848],[7.0856],[4.8352]])

上面實現(xiàn)的迭代對于教學(xué)來說很好,但它的執(zhí)行效率很低,可能會在實際問題上陷入麻煩。 例如,它要求我們將所有數(shù)據(jù)加載到內(nèi)存中,并執(zhí)行大量的隨機(jī)內(nèi)存訪問。

在深度學(xué)習(xí)框架中實現(xiàn)的內(nèi)置迭代器效率要高得多,它可以處理存儲在文件中的數(shù)據(jù)和通過數(shù)據(jù)流提供的數(shù)據(jù)。

?3.3 初始化模型參數(shù)

在下面代碼中,通過從均值為0、標(biāo)準(zhǔn)差為0.01的正態(tài)分布中采樣隨機(jī)數(shù)來初始化權(quán)重,并將偏置初始化為0。

w = torch.normal(0, 0.01, size=(2,1), requires_grad=True) b = torch.zeros(1, requires_grad=True)

在初始化參數(shù)之后,我們的任務(wù)是更新這些參數(shù),直到這些參數(shù)足夠擬合我們的數(shù)據(jù)。

每次更新都需要計算損失函數(shù)關(guān)于模型參數(shù)的梯度,我們根據(jù)梯度的變化,可以向減小損失的方向更新每個參數(shù)。

?3.4 定義模型

接下來,我們必須定義模型,將模型的輸入和參數(shù)同模型的輸出關(guān)聯(lián)起來。 回想一下,要計算線性模型的輸出,我們只需計算輸入特征 X 和模型權(quán)重 w 的矩陣向量乘法后加上偏置 b 。

def linreg(X, w, b): #@save"""線性回歸模型。"""return torch.matmul(X, w) + b

?3.5?定義損失函數(shù)

因為更新模型需要計算損失函數(shù)的梯度,所以我們應(yīng)該先定義損失函數(shù)。 這里我們使用平方損失函數(shù)。 在實現(xiàn)中,我們需要將真實值y的形狀轉(zhuǎn)換為和預(yù)測值y_hat的形狀相同。

def squared_loss(y_hat, y): #@save"""均方損失。"""return (y_hat - y.reshape(y_hat.shape)) ** 2 / 2

?3.6?定義優(yōu)化函數(shù)

在每一步中,使用從數(shù)據(jù)集中隨機(jī)抽取的一個小批量,然后根據(jù)參數(shù)計算損失的梯度。接下來,朝著減少損失的方向更新我們的參數(shù)。

我們將在這里介紹小批量隨機(jī)梯度下降的工作示例,下面的函數(shù)實現(xiàn)小批量隨機(jī)梯度下降更新。該函數(shù)接受模型參數(shù)集合、學(xué)習(xí)速率和批量大小作為輸入。每一步更新的大小由學(xué)習(xí)速率lr決定。 因為我們計算的損失是一個批量樣本的總和,所以我們用批量大小(batch_size)來歸一化步長,這樣步長大小就不會取決于我們對批量大小的選擇。

def sgd(params, lr, batch_size): #@save"""小批量隨機(jī)梯度下降。"""with torch.no_grad():for param in params:param -= lr * param.grad / batch_sizeparam.grad.zero_()

?3.7?訓(xùn)練

現(xiàn)在我們已經(jīng)準(zhǔn)備好了模型訓(xùn)練所有需要的要素,可以實現(xiàn)主要的訓(xùn)練過程部分了。

在每次迭代中,我們讀取一小批量訓(xùn)練樣本,并通過我們的模型來獲得一組預(yù)測。 計算完損失后,我們開始反向傳播,存儲每個參數(shù)的梯度。

最后,我們調(diào)用優(yōu)化算法sgd來更新模型參數(shù)。

概括一下,我們將執(zhí)行以下循環(huán):

在每個迭代周期中,我們使用data_iter函數(shù)遍歷整個數(shù)據(jù)集,并將訓(xùn)練數(shù)據(jù)集的所有樣本都使用一次(假設(shè)樣本數(shù)能夠被批量大小整除)。這里的迭代周期個數(shù)num_epochs和學(xué)習(xí)率lr都是超參數(shù),分別設(shè)為3和0.03。

設(shè)置超參數(shù)很棘手,需要通過反復(fù)試驗進(jìn)行調(diào)整。

lr = 0.03 num_epochs = 3 net = linreg loss = squared_lossfor epoch in range(num_epochs):for X, y in data_iter(batch_size, features, labels):l = loss(net(X, w, b), y) # `X`和`y`的小批量損失# 因為`l`形狀是(`batch_size`, 1),而不是一個標(biāo)量。`l`中的所有元素被加到一起,# 并以此計算關(guān)于[`w`, `b`]的梯度l.sum().backward()sgd([w, b], lr, batch_size) # 使用參數(shù)的梯度更新參數(shù)with torch.no_grad():train_l = loss(net(features, w, b), labels)print(f'epoch {epoch + 1}, loss {float(train_l.mean()):f}') epoch 1, loss 0.043538 epoch 2, loss 0.000165 epoch 3, loss 0.000050

因為我們使用的是自己合成的數(shù)據(jù)集,所以我們知道真正的參數(shù)是什么。 因此,我們可以通過比較真實參數(shù)和通過訓(xùn)練學(xué)到的參數(shù)來評估訓(xùn)練的成功程度。事實上,真實參數(shù)和通過訓(xùn)練學(xué)到的參數(shù)確實非常接近。

print(f'w的估計誤差: {true_w - w.reshape(true_w.shape)}') print(f'b的估計誤差: {true_b - b}') w的估計誤差: tensor([0.0010, 0.0004], grad_fn=<SubBackward0>) b的估計誤差: tensor([2.0504e-05], grad_fn=<RsubBackward1>)

注意,我們不應(yīng)該想當(dāng)然地認(rèn)為我們能夠完美地恢復(fù)參數(shù)。

在機(jī)器學(xué)習(xí)中,我們通常不太關(guān)心恢復(fù)真正的參數(shù),而更關(guān)心那些能高度準(zhǔn)確預(yù)測的參數(shù)。

幸運的是,即使是在復(fù)雜的優(yōu)化問題上,隨機(jī)梯度下降通常也能找到非常好的解。其中一個原因是,在深度網(wǎng)絡(luò)中存在許多參數(shù)組合能夠?qū)崿F(xiàn)高度精確的預(yù)測。

四、線性回歸的簡潔實現(xiàn)

通過這些框架可以自動化實現(xiàn)基于梯度的學(xué)習(xí)算法中重復(fù)性的工作。

在 上一節(jié)節(jié)中,我們只依賴了:(1)通過張量來進(jìn)行數(shù)據(jù)存儲和線性代數(shù);(2)通過自動微分來計算梯度。實際上,由于數(shù)據(jù)迭代器、損失函數(shù)、優(yōu)化器和神經(jīng)網(wǎng)絡(luò)層很常用,現(xiàn)代深度學(xué)習(xí)庫也為我們實現(xiàn)了這些組件。

我們將介紹如何通過使用深度學(xué)習(xí)框架來簡潔地實現(xiàn)上節(jié)中的線性回歸模型。

4.1 生成數(shù)據(jù)集

from mxnet import autograd, gluon, np, npx from d2l import mxnet as d2lnpx.set_np()true_w = np.array([2, -3.4]) true_b = 4.2 features, labels = d2l.synthetic_data(true_w, true_b, 1000)

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

我們可以調(diào)用框架中現(xiàn)有的API來讀取數(shù)據(jù)。我們將features和labels作為API的參數(shù)傳遞,并在實例化數(shù)據(jù)迭代器對象時指定batch_size。

此外,布爾值is_train表示是否希望數(shù)據(jù)迭代器對象在每個迭代周期內(nèi)打亂數(shù)據(jù)。

def load_array(data_arrays, batch_size, is_train=True): #@save"""構(gòu)造一個PyTorch數(shù)據(jù)迭代器。"""dataset = data.TensorDataset(*data_arrays)return data.DataLoader(dataset, batch_size, shuffle=is_train)batch_size = 10 data_iter = load_array((features, labels), batch_size)

使用data_iter的方式與我們在 3.2節(jié)中使用data_iter函數(shù)的方式相同。為了驗證是否正常工作,讓我們讀取并打印第一個小批量樣本。這里我們使用iter構(gòu)造Python迭代器,并使用next從迭代器中獲取第一項。

next(iter(data_iter)) [tensor([[-0.6054, -0.8844],[-0.7336, 1.4959],[ 0.0251, -0.5782],[-0.3874, -2.7577],[-0.2987, -1.6454],[-1.6794, 0.9353],[-1.1240, 0.0860],[ 0.7230, -0.3869],[ 0.2812, -1.3614],[ 1.4122, 0.7235]]),tensor([[ 5.9993],[-2.3407],[ 6.2172],[12.8106],[ 9.2043],[-2.3530],[ 1.6639],[ 6.9765],[ 9.3874],[ 4.5664]])]

4.3?定義模型

當(dāng)我們在 3.2節(jié)中實現(xiàn)線性回歸時,我們明確定義了模型參數(shù)變量,并編寫了計算的代碼,這樣通過基本的線性代數(shù)運算得到輸出。

我們首先定義一個模型變量net,它是一個Sequential類的實例。Sequential類為串聯(lián)在一起的多個層定義了一個容器。當(dāng)給定輸入數(shù)據(jù),Sequential實例將數(shù)據(jù)傳入到第一層,然后將第一層的輸出作為第二層的輸入,依此類推。

在下面的例子中,我們的模型只包含一個層,因此實際上不需要Sequential。但是由于以后幾乎所有的模型都是多層的,在這里使用Sequential會讓你熟悉標(biāo)準(zhǔn)的流水線。

回顧圖3.1.2中的單層網(wǎng)絡(luò)架構(gòu),這一單層被稱為全連接層(fully-connected layer),因為它的每一個輸入都通過矩陣-向量乘法連接到它的每個輸出。

# `nn` 是神經(jīng)網(wǎng)絡(luò)的縮寫 from torch import nnnet = nn.Sequential(nn.Linear(2, 1))

4.5?初始化模型參數(shù)

?深度學(xué)習(xí)框架通常有預(yù)定義的方法來初始化參數(shù)。 我們指定每個權(quán)重參數(shù)應(yīng)該從均值為0、標(biāo)準(zhǔn)差為0.01的正態(tài)分布中隨機(jī)采樣,偏置參數(shù)將初始化為零。

正如我們在構(gòu)造nn.Linear時指定輸入和輸出尺寸一樣。現(xiàn)在我們直接訪問參數(shù)以設(shè)定初始值。

我們通過net[0]選擇網(wǎng)絡(luò)中的第一個圖層,然后使用weight.data和bias.data方法訪問參數(shù),然后使用替換方法normal_和fill_來重寫參數(shù)值。

net[0].weight.data.normal_(0, 0.01) net[0].bias.data.fill_(0) tensor([0.])

4.6?定義損失函數(shù)

計算均方誤差使用的是MSELoss類,也稱為平方 L2 范數(shù)。默認(rèn)情況下,它返回所有樣本損失的平均值。

loss = nn.MSELoss()

4.7?定義優(yōu)化算法

小批量隨機(jī)梯度下降算法是一種優(yōu)化神經(jīng)網(wǎng)絡(luò)的標(biāo)準(zhǔn)工具,PyTorch在optim模塊中實現(xiàn)了該算法的許多變種。

當(dāng)我們實例化SGD實例時,我們要指定優(yōu)化的參數(shù)(可通過net.parameters()從我們的模型中獲得)以及優(yōu)化算法所需的超參數(shù)字典。

小批量隨機(jī)梯度下降只需要設(shè)置lr值,這里設(shè)置為0.03。

trainer = torch.optim.SGD(net.parameters(), lr=0.03)

4.8?訓(xùn)練

通過深度學(xué)習(xí)框架的高級API來實現(xiàn)我們的模型只需要相對較少的代碼。 我們不必單獨分配參數(shù)、不必定義我們的損失函數(shù),也不必手動實現(xiàn)小批量隨機(jī)梯度下降。

回顧一下:在每個迭代周期里,我們將完整遍歷一次數(shù)據(jù)集(train_data),不停地從中獲取一個小批量的輸入和相應(yīng)的標(biāo)簽。

對于每一個小批量,我們會進(jìn)行以下步驟:①通過調(diào)用net(X)生成預(yù)測并計算損失(正向傳播)。

②通過進(jìn)行反向傳播來計算梯度。③通過調(diào)用優(yōu)化器來更新模型參數(shù)。

為了更好的衡量訓(xùn)練效果,我們計算每個迭代周期后的損失,并打印它來監(jiān)控訓(xùn)練過程。

num_epochs = 3 for epoch in range(num_epochs):for X, y in data_iter:l = loss(net(X) ,y)trainer.zero_grad()l.backward()trainer.step()l = loss(net(features), labels)print(f'epoch {epoch + 1}, loss {l:f}') epoch 1, loss 0.000254 epoch 2, loss 0.000098 epoch 3, loss 0.000098

下面我們比較生成數(shù)據(jù)集的真實參數(shù)和通過有限數(shù)據(jù)訓(xùn)練獲得的模型參數(shù)。 要訪問參數(shù),我們首先從net訪問所需的層,然后讀取該層的權(quán)重和偏置。 正如在從零開始實現(xiàn)中一樣,我們估計得到的參數(shù)與生成數(shù)據(jù)的真實參數(shù)非常接近。

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([0.0007, 0.0007])

b的估計誤差: tensor([-0.0007])

五、小結(jié)

1、我們可以使用PyTorch的高級API更簡潔地實現(xiàn)模型。

2、在PyTorch中,data模塊提供了數(shù)據(jù)處理工具,nn模塊定義了大量的神經(jīng)網(wǎng)絡(luò)層和常見損失函數(shù)。

3、我們可以通過_結(jié)尾的方法將參數(shù)替換,從而初始化參數(shù)。

QA:

1.推薦使用colab

2.損失為什么要平均?相當(dāng)于平均了學(xué)習(xí)率

3.batchsize小點好

4.學(xué)習(xí)率和批量大小不會影響最終的結(jié)果

5.隨機(jī)梯度的批量大小是根據(jù)多個樣點來取值

6.datach()的作用:不參與求梯度

7.不做學(xué)習(xí)率衰減,問題不大

8.

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的【Pytorch神经网络基础理论篇】 07 线性回归 + 基础优化算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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