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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

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

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

?

一、線性代數(shù)

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

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

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

1.1?線性回歸的基本元素

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

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

為了開(kāi)發(fā)一個(gè)能預(yù)測(cè)房?jī)r(jià)的模型,我們需要收集一個(gè)真實(shí)的數(shù)據(jù)集。這個(gè)數(shù)據(jù)集包括了房屋的銷(xiāo)售價(jià)格、面積和房齡。

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

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

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

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

1.2?線性模型

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

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

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

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

嚴(yán)格來(lái)說(shuō),上式是輸入特征的一個(gè)仿射變換(affine transformation)。仿射變換的特點(diǎn)是通過(guò)加權(quán)和對(duì)特征進(jìn)行線性變換,并通過(guò)偏置項(xiàng)來(lái)進(jìn)行平移。

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

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

1.3損失函數(shù)

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

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

?

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

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

1.3解析解

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

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

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

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

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

梯度下降最簡(jiǎn)單的用法是計(jì)算損失函數(shù)(數(shù)據(jù)集中所有樣本的損失均值)關(guān)于模型參數(shù)的導(dǎo)數(shù)(在這里也可以稱(chēng)為梯度)。但實(shí)際中的執(zhí)行可能會(huì)非常慢:因?yàn)樵诿恳淮胃聟?shù)之前,我們必須遍歷整個(gè)數(shù)據(jù)集。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

下面我們定義一個(gè)Python函數(shù)來(lái)計(jì)算正態(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)差對(duì) 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])

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

1.5.2?均方誤差損失函數(shù)(簡(jiǎn)稱(chēng)均方損失)

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

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

1.5.3 最大似然估計(jì)量

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

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

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

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

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

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

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

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

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

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

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

?

?

?

?三、從零開(kāi)始實(shí)現(xiàn)線性回歸

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

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

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

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

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

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中的每一行都包含一個(gè)二維數(shù)據(jù)樣本,labels中的每一行都包含一維標(biāo)簽值(一個(gè)標(biāo)量),下面將其輸出。

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

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

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

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

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

def data_iter(batch_size, features, labels):num_examples = len(features)indices = list(range(num_examples))# 這些樣本是隨機(jī)讀取的,沒(méi)有特定的順序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]

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

讓我們直觀感受一下。讀取第一個(gè)小批量數(shù)據(jù)樣本并打印。每個(gè)批量的特征維度說(shuō)明了批量大小和輸入特征數(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]])

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

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

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

在下面代碼中,通過(guò)從均值為0、標(biāo)準(zhǔn)差為0.01的正態(tài)分布中采樣隨機(jī)數(shù)來(lái)初始化權(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ù)。

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

?3.4 定義模型

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

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

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

因?yàn)楦履P托枰?jì)算損失函數(shù)的梯度,所以我們應(yīng)該先定義損失函數(shù)。 這里我們使用平方損失函數(shù)。 在實(shí)現(xiàn)中,我們需要將真實(shí)值y的形狀轉(zhuǎn)換為和預(yù)測(cè)值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ī)抽取的一個(gè)小批量,然后根據(jù)參數(shù)計(jì)算損失的梯度。接下來(lái),朝著減少損失的方向更新我們的參數(shù)。

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

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)練所有需要的要素,可以實(shí)現(xiàn)主要的訓(xùn)練過(guò)程部分了。

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

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

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

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

設(shè)置超參數(shù)很棘手,需要通過(guò)反復(fù)試驗(yàn)進(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`的小批量損失# 因?yàn)?#96;l`形狀是(`batch_size`, 1),而不是一個(gè)標(biāo)量。`l`中的所有元素被加到一起,# 并以此計(jì)算關(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

因?yàn)槲覀兪褂玫氖亲约汉铣傻臄?shù)據(jù)集,所以我們知道真正的參數(shù)是什么。 因此,我們可以通過(guò)比較真實(shí)參數(shù)和通過(guò)訓(xùn)練學(xué)到的參數(shù)來(lái)評(píng)估訓(xùn)練的成功程度。事實(shí)上,真實(shí)參數(shù)和通過(guò)訓(xùn)練學(xué)到的參數(shù)確實(shí)非常接近。

print(f'w的估計(jì)誤差: {true_w - w.reshape(true_w.shape)}') print(f'b的估計(jì)誤差: {true_b - b}') w的估計(jì)誤差: tensor([0.0010, 0.0004], grad_fn=<SubBackward0>) b的估計(jì)誤差: 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ù)測(cè)的參數(shù)。

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

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

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

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

我們將介紹如何通過(guò)使用深度學(xué)習(xí)框架來(lái)簡(jiǎn)潔地實(shí)現(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來(lái)讀取數(shù)據(jù)。我們將features和labels作為API的參數(shù)傳遞,并在實(shí)例化數(shù)據(jù)迭代器對(duì)象時(shí)指定batch_size。

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

def load_array(data_arrays, batch_size, is_train=True): #@save"""構(gòu)造一個(gè)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的方式與我們?cè)?3.2節(jié)中使用data_iter函數(shù)的方式相同。為了驗(yàn)證是否正常工作,讓我們讀取并打印第一個(gè)小批量樣本。這里我們使用iter構(gòu)造Python迭代器,并使用next從迭代器中獲取第一項(xiàng)。

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)我們?cè)?3.2節(jié)中實(shí)現(xiàn)線性回歸時(shí),我們明確定義了模型參數(shù)變量,并編寫(xiě)了計(jì)算的代碼,這樣通過(guò)基本的線性代數(shù)運(yùn)算得到輸出。

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

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

回顧圖3.1.2中的單層網(wǎng)絡(luò)架構(gòu),這一單層被稱(chēng)為全連接層(fully-connected layer),因?yàn)樗拿恳粋€(gè)輸入都通過(guò)矩陣-向量乘法連接到它的每個(gè)輸出。

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

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

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

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

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

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

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

計(jì)算均方誤差使用的是MSELoss類(lèi),也稱(chēng)為平方 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模塊中實(shí)現(xiàn)了該算法的許多變種。

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

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

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

4.8?訓(xùn)練

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

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

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

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

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

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ù)和通過(guò)有限數(shù)據(jù)訓(xùn)練獲得的模型參數(shù)。 要訪問(wèn)參數(shù),我們首先從net訪問(wèn)所需的層,然后讀取該層的權(quán)重和偏置。 正如在從零開(kāi)始實(shí)現(xiàn)中一樣,我們估計(jì)得到的參數(shù)與生成數(shù)據(jù)的真實(shí)參數(shù)非常接近。

w = net[0].weight.data print('w的估計(jì)誤差:', true_w - w.reshape(true_w.shape)) b = net[0].bias.data print('b的估計(jì)誤差:', true_b - b)

w的估計(jì)誤差: tensor([0.0007, 0.0007])

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

五、小結(jié)

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

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

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

QA:

1.推薦使用colab

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

3.batchsize小點(diǎn)好

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

5.隨機(jī)梯度的批量大小是根據(jù)多個(gè)樣點(diǎn)來(lái)取值

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

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

8.

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

總結(jié)

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

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