深度学习修炼(三)——自动求导机制
文章目錄
- 致謝
- 3 自動(dòng)求導(dǎo)機(jī)制
- 3.1 傳播機(jī)制與計(jì)算圖
- 3.1.1 前向傳播
- 3.1.2 反向傳播
- 3.2 自動(dòng)求導(dǎo)
- 3.3 再來(lái)做一次
- 3.4 線性回歸
- 3.4.1 回歸
- 3.4.2 線性回歸的基本元素
- 3.4.3 線性模型
- 3.4.4 線性回歸的實(shí)現(xiàn)
- 3.4.4.1 獲取數(shù)據(jù)集
- 3.4.4.2 模型搭建
- 3.4.4.3 損失函數(shù)
- 3.4.4.4 訓(xùn)練模型
- 3.5 后記
致謝
Pytorch中常用的四種優(yōu)化器SGD、Momentum、RMSProp、Adam - 簡(jiǎn)書(shū) (jianshu.com)
反向傳播算法(過(guò)程及公式推導(dǎo))_好的嗡嗡嗡的博客-CSDN博客
動(dòng)手學(xué)深度學(xué)習(xí)——矩陣求導(dǎo)之自動(dòng)求導(dǎo)_時(shí)生丶的博客-CSDN博客
(1條消息) Pytorch入門(mén)(四)——計(jì)算圖與自動(dòng)求導(dǎo)_xinye0090的博客-CSDN博客
(1條消息) pytorch 計(jì)算圖以及backward_coderwangson的博客-CSDN博客_pytorch清空計(jì)算圖
3 自動(dòng)求導(dǎo)機(jī)制
要明白自動(dòng)求導(dǎo)機(jī)制,我們就要先知道計(jì)算圖是什么。在后面的學(xué)習(xí)中,我們會(huì)學(xué)習(xí)到多層感知機(jī),而為了計(jì)算多層感知機(jī),我們求需要?jiǎng)佑糜?jì)算圖和利用自動(dòng)求導(dǎo)。
3.1 傳播機(jī)制與計(jì)算圖
pytorch框架和TensorFlow框架在計(jì)算圖中最大的不同是:pytorch是動(dòng)態(tài)的計(jì)算圖,它能邊搭建邊運(yùn)行;而TensorFlow是靜態(tài)的計(jì)算圖,它必須先把圖搭建好后才能開(kāi)始計(jì)算。
3.1.1 前向傳播
我們來(lái)看看什么是前向傳播。前向傳播英文是(forward propagation或forward pass),它指的是:按順序(從輸入層到輸出層)計(jì)算和存儲(chǔ)神經(jīng)網(wǎng)絡(luò)中每層的結(jié)果。
如果你聽(tīng)不懂的話,可以看一下下面前向傳播的計(jì)算圖。
上述的計(jì)算圖反映了一件事,如果把上述過(guò)程看做是神經(jīng)網(wǎng)絡(luò),那么前向傳播實(shí)際上是在計(jì)算每一層的值。
3.1.2 反向傳播
比較重要的是反向傳播。反向傳播(backward propagation或backpropagation)指的是計(jì)算神經(jīng)網(wǎng)絡(luò)參數(shù)梯度的方法。簡(jiǎn)而言之就是,該方法根據(jù)微積分中的鏈?zhǔn)揭?guī)則,按相反的順序從輸出層到輸入層遍歷網(wǎng)絡(luò)。同理,反向傳播計(jì)算圖如下圖所示。
反向傳播實(shí)際上就是根據(jù)求導(dǎo),來(lái)算出某一節(jié)點(diǎn)對(duì)于另外的某一節(jié)點(diǎn)所給的“回饋”。即導(dǎo)數(shù),但是對(duì)于多個(gè)變量求偏導(dǎo),我們叫其結(jié)果為梯度。
3.2 自動(dòng)求導(dǎo)
pytorch為我們提供了自動(dòng)求導(dǎo)機(jī)制,其機(jī)制用torch.autograd來(lái)實(shí)現(xiàn)。為了照顧新手,我們不直接給出API,而采取循循引誘的方式來(lái)講解。
對(duì)于pytorch的自動(dòng)求導(dǎo)來(lái)說(shuō),由于版本的更新迭代,老版本的實(shí)現(xiàn)和新版本的實(shí)現(xiàn)大有差異,在老版本中,自動(dòng)求導(dǎo)必須調(diào)用autograd.Variable來(lái)把變量包裝起來(lái),而新版本則不需要了,只需在需要自動(dòng)求導(dǎo)的張量里添加requires_grad = True即可。
# 方法1 x = torch.randn(3,4,requires_grad = True) xout:
tensor([[-0.1225, 0.5622, 0.3288, -1.2560],
[-0.7067, 0.2453, 1.8471, 0.9765],
[-0.7606, 0.8300, -0.9079, -0.2566]], requires_grad=True)
上述的方法是下面方法的簡(jiǎn)化版。
# 方法2 x = torch.randn(3,4) x.requires_grad = True xout:
tensor([[-0.3050, 1.6089, 0.4765, 0.8169],
[-1.4941, -0.9640, 0.4670, -1.5811],
[ 0.1837, -0.5159, 0.4066, 1.8279]], requires_grad=True)
以上的兩個(gè)方法均可以使用。
我們單單只是構(gòu)建張量可不夠,只要一個(gè)張量要求啥子導(dǎo)。我們?cè)跇?gòu)建一個(gè)張量b。
b = torch.randn(3,4,requires_grad = True)做完上述的步驟后,我們構(gòu)建一個(gè)沒(méi)有權(quán)重的線性模型。
# 構(gòu)建一個(gè)線性模型 t = x + b當(dāng)我們做完上述的步驟后,實(shí)際上一個(gè)比較簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)就搭建起來(lái)了。
如果我們把線性回歸描述成神經(jīng)網(wǎng)絡(luò)。那么我們的輸入層就是所有的特征,而輸出層就是預(yù)測(cè)值。
在如圖所示的神經(jīng)網(wǎng)絡(luò)中,輸入為x1,x2...xdx_1,x_2...x_dx1?,x2?...xd?,因此輸入層中的輸入數(shù)(由于我們常常把輸入的特征放入向量,實(shí)際上向量的長(zhǎng)度就是維度,故我們把輸入數(shù)也叫特征維度)為d。
由于我們通常計(jì)算時(shí)發(fā)生在輸出層里,輸入層只是負(fù)責(zé)傳入數(shù)據(jù),所以一般輸入層不算入層數(shù),這么說(shuō)下來(lái),我們可以得出結(jié)論:這是一個(gè)單層神經(jīng)網(wǎng)絡(luò)。
再啰嗦幾句,上面的輸入層把數(shù)據(jù)輸?shù)捷敵鰧?#xff0c;所以給人感覺(jué)就好像輸出層一下子要處理很多的輸入(笑。。。不知道你能不能get到那種感覺(jué)),所以這大概率為什么這種輸入到輸出的變化被叫做全連接層(fully_connected layer)或稱為稠密層(dense layer)的原因了。
好,回到我們的主題,既然已經(jīng)搭好了一個(gè)線性回歸模型了,我們?cè)趺词蛊浞聪騻鞑?#xff1f;我們知道,反向傳播的前提條件是要知道前向傳播中的輸出值。所以我們繼續(xù)往下:
y = t.sum yout:
tensor(-1.6405, grad_fn=)
在pytorch中,如果需要反向傳播,只需在每個(gè)張量里指定自動(dòng)求導(dǎo),而后在最后一步調(diào)用以上方法即可。如在本例中,調(diào)用y.backward即可進(jìn)行反向傳播。
y.backward()而后,如果我們想看b的梯度,我們可以通過(guò)以下的方式:
b.gradout:
tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]])
這里可能會(huì)有一個(gè)疑問(wèn)哈,y已經(jīng)進(jìn)行反向傳播了,此時(shí)如果通過(guò)變量.grad調(diào)用的是什么梯度?因?yàn)槟闶褂玫氖莥的反向傳播,拿b來(lái)舉例,b.grad實(shí)際上就是求y對(duì)于b的偏導(dǎo)。
還有一個(gè)問(wèn)題是,在上述的操作過(guò)程中,我們并沒(méi)有打開(kāi)t張量的自動(dòng)求導(dǎo)開(kāi)關(guān),那他是否也能自動(dòng)求導(dǎo)得到梯度呢?
我們調(diào)用tensor.requires_grad即可查看該張量是否打開(kāi)了自動(dòng)求導(dǎo)開(kāi)關(guān)。
x.requires_grad,b.requires_grad,t.requires_gradout:
(True, True, True)
以上的結(jié)果側(cè)面印證了一個(gè)問(wèn)題,即使沒(méi)有指定某一張量可自動(dòng)求導(dǎo),但是和打開(kāi)自動(dòng)求導(dǎo)的張量進(jìn)行運(yùn)算時(shí),其運(yùn)算結(jié)果的自動(dòng)求導(dǎo)開(kāi)關(guān)也會(huì)被打開(kāi)。
3.3 再來(lái)做一次
我相信經(jīng)過(guò)上面的一次操作,你已經(jīng)大概知道torch的自動(dòng)求導(dǎo)機(jī)制了。我們趁熱打鐵,試著做一下下面的工作。
如果我們要對(duì)上述的計(jì)算圖計(jì)算的話,我們可以進(jìn)行以下步驟:
# 計(jì)算流程 x = torch.rand(1) b = torch.rand(1,requires_grad = True) w = torch.rand(1,requires_grad = True) y = w * x z = y + b# 我們查看各參數(shù)的自動(dòng)求導(dǎo)打開(kāi)情況 x.requires_grad, b.requires_grad, w.requires_grad, y.requires_gradout:
(False, True, True, True)
實(shí)際上,我們還可以把計(jì)算圖看成計(jì)算樹(shù)來(lái)查看哪些參數(shù)是葉子結(jié)點(diǎn)。
# 我們還可以看一下哪些參數(shù)為計(jì)算圖(樹(shù))的葉子結(jié)點(diǎn) x.is_leaf, b.is_leaf, w.is_leaf, y.is_leaf, z.is_leafout:
(True, True, True, False, False)
當(dāng)上述處理完畢后,我們對(duì)z進(jìn)行反向傳播計(jì)算。
z.backward(retain_graph = True) # 保存計(jì)算圖然后我們分別查看下面參數(shù)的梯度。
w.gradout:
tensor([0.3843])
b.gradout:
tensor([1.])
你可以在jupyter notebook上執(zhí)行完上述的兩個(gè)參數(shù)的梯度后再執(zhí)行一次,第二次時(shí),你發(fā)現(xiàn)它們居然是第一次運(yùn)行結(jié)果的兩倍了。也是因?yàn)槲覀冊(cè)趜的反向傳播時(shí)指定保存計(jì)算計(jì)算圖,使得后面在計(jì)算某參數(shù)的梯度時(shí),他都是根據(jù)上一次計(jì)算圖的結(jié)果繼續(xù)累加。
3.4 線性回歸
繼機(jī)器學(xué)習(xí)一別,我們已經(jīng)許久未見(jiàn)狹義線性模型了。對(duì)此,我們希望在深度學(xué)習(xí)中能再次實(shí)現(xiàn)它。
3.4.1 回歸
回歸,英文名regression。在先修課機(jī)器學(xué)習(xí)中,我們經(jīng)常能夠遇見(jiàn)兩個(gè)名詞:回歸和分類。這兩者的區(qū)別實(shí)際上就是:回歸是根據(jù)以往的經(jīng)驗(yàn)來(lái)預(yù)測(cè)未來(lái)的趨勢(shì)或走向,比如說(shuō)經(jīng)典的房?jī)r(jià)預(yù)測(cè)問(wèn)題;而分類是根據(jù)根據(jù)以往的經(jīng)驗(yàn)來(lái)預(yù)測(cè)下一個(gè)東西是屬于什么,經(jīng)典的就是二分類問(wèn)題;從宏觀上來(lái)看,回歸是相對(duì)于連續(xù)的,而分類是相對(duì)于離散的。
3.4.2 線性回歸的基本元素
線性回歸基于幾個(gè)簡(jiǎn)單的假設(shè):首先,假設(shè)自變量x和因變量y之間的關(guān)系是線性的,即y可以表示為x中元素的加權(quán)和,這里通常允許包含觀測(cè)值的一些噪聲;其次,我們假設(shè)任何噪聲都比較正常,如噪聲遵循正態(tài)分布。
為了解釋線性回歸,我們舉一個(gè)實(shí)際的例子,我們希望根據(jù)房屋的面積和房齡來(lái)估算房屋的價(jià)格。接下來(lái)這里涉及到許多機(jī)器學(xué)習(xí)的術(shù)語(yǔ);為了開(kāi)發(fā)一個(gè)能夠預(yù)測(cè)房?jī)r(jià)的模型,我們需要收集一個(gè)真實(shí)的數(shù)據(jù)集,這個(gè)數(shù)據(jù)集包括了以往房屋的預(yù)售價(jià)格、面積和房齡,當(dāng)然,如果你要收集更多的特征也不是不行,但是我們目前從最簡(jiǎn)單的開(kāi)始講起。
在機(jī)器學(xué)習(xí)的術(shù)語(yǔ)中,我們把這部分收集來(lái)用作訓(xùn)練房?jī)r(jià)模型的數(shù)據(jù)集叫做訓(xùn)練數(shù)據(jù)集(training data set)或訓(xùn)練集(training set)。每行數(shù)據(jù)或者用數(shù)據(jù)庫(kù)的術(shù)語(yǔ)來(lái)說(shuō)叫元組在這里稱為樣本,也可以稱為數(shù)據(jù)樣本(training instance)或者數(shù)據(jù)點(diǎn)(data point)。我們把試圖預(yù)測(cè)的目標(biāo)(在這個(gè)例子中指的是房屋價(jià)格)稱為標(biāo)簽(label)或者目標(biāo)(target)。預(yù)測(cè)所依據(jù)的自變量(在這個(gè)例子中指的是面積和房齡)稱為特征(feature)或者協(xié)變量(covariate)。
通常,我們使用n來(lái)表示數(shù)據(jù)集中的樣本數(shù)。對(duì)索引為i的樣本,其輸入表示為:x(i)=[x1(i),x2(i)]Tx^{(i)} = [x_1^{(i)},x_2^{(i)}]^Tx(i)=[x1(i)?,x2(i)?]T,其對(duì)應(yīng)的標(biāo)簽是y(i)y^{(i)}y(i)。
3.4.3 線性模型
線性假設(shè)是指目標(biāo)可以表示為特征的加權(quán)和,也就是我們高中所熟悉的一次函數(shù)y = kx+b,只是在深度學(xué)習(xí)中,我們換成了y=w1x1+w2x2+....+by = w_1x_1 + w_2x_2 +....+by=w1?x1?+w2?x2?+....+b。其中www叫做權(quán)重(weight),b叫做截距(intercept),b在高中數(shù)學(xué)中叫截距比較多一點(diǎn),但是在深度學(xué)習(xí)中它通常被叫做偏置(bias)。偏置是指當(dāng)前所有特征都取值為0時(shí),預(yù)測(cè)值應(yīng)該為多少。雖然特征取值為0可能在我們說(shuō)的預(yù)測(cè)房?jī)r(jià)的例子中并不存在,但是我們?nèi)匀恍枰?#xff0c;因?yàn)槿绻麤](méi)有偏置那我們的模型會(huì)受到限制。
嚴(yán)格來(lái)說(shuō),如果應(yīng)用到房?jī)r(jià)預(yù)測(cè)的例子上的話,我們可以寫(xiě)出這樣的式子:price=warea?area+wage?age+bprice = w_{area}·area+w_{age}·age+bprice=warea??area+wage??age+b
如果是單純地一個(gè)特征就寫(xiě)一個(gè)x,那個(gè)式子就會(huì)變?yōu)?#xff1a;y=w1x1+w2x2+....wnxn+by = w_1x_1+w_2x_2+....w_nx_n+by=w1?x1?+w2?x2?+....wn?xn?+b,這樣的話實(shí)際上不利于我們計(jì)算,而且不簡(jiǎn)潔。根據(jù)我們線性代數(shù)學(xué)過(guò)的知識(shí),我們知道可以用向量存放特征,即x = {x1,x2,x3…xn},當(dāng)然,這僅僅是一個(gè)樣本,如果是多樣本的話,我們可以用矩陣來(lái)放。X的每一行是一個(gè)樣本,每一列是一種特征
KaTeX parse error: Undefined control sequence: \ at position 115: … \end{bmatrix} \? ?
如同我們前面所說(shuō),下標(biāo)表示第幾個(gè)特征,上標(biāo)表示第幾個(gè)樣本。
同樣地我們也把權(quán)重w放進(jìn)矩陣,那么模型簡(jiǎn)化為:y^=wTx+b\hat{y} = w^Tx + by^?=wTx+b
其中w之所以加轉(zhuǎn)置是因?yàn)榫仃嚦朔ň褪?span id="ozvdkddzhkzd" class="katex--inline">ATBA^TBATB。而w和x兩個(gè)矩陣相乘后,由于b是標(biāo)量,這個(gè)時(shí)候就會(huì)用到python的廣播機(jī)制去相加。
在我們給定訓(xùn)練數(shù)據(jù)X和對(duì)應(yīng)的已知標(biāo)簽y后,線性回歸的目標(biāo)就是找到一組權(quán)重向量w和偏置b,找到后這個(gè)模型就確定下來(lái)了;當(dāng)有新的x進(jìn)來(lái)后,這個(gè)模型預(yù)測(cè)的y能夠和真實(shí)的y盡可能的接近。
雖然我們相信給定x預(yù)測(cè)y的最佳模型會(huì)是線性的,但我們很難找到一個(gè)有n個(gè)樣本的真實(shí)數(shù)據(jù)集,然后算出來(lái)的結(jié)果真的是線性的,這根線一點(diǎn)彎曲都沒(méi)有,這是不可能的。因此,即使我們確信他們的潛在關(guān)系是線性,我們也需要加入一個(gè)噪聲項(xiàng)來(lái)考慮誤差所帶來(lái)的影響。
3.4.4 線性回歸的實(shí)現(xiàn)
3.4.4.1 獲取數(shù)據(jù)集
上面一直在吹理論,實(shí)際上,如果你看過(guò)我的機(jī)器學(xué)習(xí)中關(guān)于線性回歸的闡述,應(yīng)該是或多或少了解的。而本小節(jié)的重點(diǎn),我們將會(huì)放在如何用torch提供的API去實(shí)現(xiàn)一個(gè)線性回歸上。
繼上一小節(jié)最后說(shuō)的,我們很難找到一個(gè)數(shù)據(jù)集用于構(gòu)建線性模型,為此,我們自己捏一個(gè)出來(lái)。
import numpy as np import matplotlib.pyplot as pltx_values = [i for i in range(11)] x_train = np.array(x_values,dtype=np.float32) x_train = x_train.reshape(-1,1) x_trainy_values = [2*i +1 for i in x_values] y_train = np.array(y_values,dtype=np.float32) y_train = y_train.reshape(-1,1) y_train捏造出數(shù)據(jù)集后,我們可視化這些數(shù)據(jù)集看一下長(zhǎng)啥樣。
plt.figure() plt.scatter(x_train,y_train) plt.show()out:
3.4.4.2 模型搭建
當(dāng)我們獲取到數(shù)據(jù)集后,我們要做的第二步是搭建一個(gè)線性模型。
#導(dǎo)入模塊 import torch.nn as nn import torchclass LinearRegressionModel(nn.Module):def __init__(self,input_dim,output_dim):super(LinearRegressionModel,self).__init__()self.linear = nn.Linear(input_dim,output_dim) #全連接層# 前向傳播 def forward(self,x):out = self.linear(x)return out在上述的類中,我們需要去繼承torch.nn.Module包,以方便我們后續(xù)神經(jīng)網(wǎng)絡(luò)層搭建。繼承完畢后,我們?cè)O(shè)定類中初始化方法,我們調(diào)用父類方法初始化,并且指定我們要搭建的線性回歸神經(jīng)網(wǎng)絡(luò)的層,在這里,我們需要的僅僅是一個(gè)有輸入和輸出的全連接層,且其中不需要添加激活函數(shù),我們調(diào)用nn.Linear(input_dim,output_dim)即可搭建,里面?zhèn)魅氲膮?shù)分別是輸入數(shù)據(jù)的維度和輸出數(shù)據(jù)的維度,在線性回歸中,通過(guò)輸入數(shù)據(jù)和輸出數(shù)據(jù)的維度全設(shè)為1即可。
除了初始化,我們還需要在類中添加一個(gè)前向傳播成員函數(shù),前向傳播的計(jì)算實(shí)際上就是上面nn.Linear()輸入數(shù)據(jù)后得出的結(jié)果。
搭建好神經(jīng)網(wǎng)絡(luò)后,我們需要實(shí)例化神經(jīng)網(wǎng)絡(luò)類并且為其傳參。
# 實(shí)例化類 model = LinearRegressionModel(input_dim=1,output_dim=1) modelout:
LinearRegressionModel(
(linear): Linear(in_features=1, out_features=1, bias=True)
)
3.4.4.3 損失函數(shù)
搭建好模型后,我們還需要搭建損失函數(shù),以此訓(xùn)練模型。
epochs = 1000 #訓(xùn)練次數(shù) learning_rate = 0.01 #學(xué)習(xí)率 # 優(yōu)化器 optimizer = torch.optim.SGD(model.parameters(),lr = learning_rate) # 優(yōu)化器使用的誤差函數(shù) criterion = nn.MSELoss()在上面的代碼中,我們調(diào)用torch.optim包下的SGD(隨機(jī)梯度下降法)來(lái)優(yōu)化我們的訓(xùn)練模型,并且我們采用均方誤差(Mean Square Error,MSE)進(jìn)行梯度下降。SGD的有參構(gòu)造器中需要傳入我們神經(jīng)網(wǎng)絡(luò)對(duì)象中所有參數(shù),并且還要傳入一個(gè)學(xué)習(xí)率。
定義好損失函數(shù)后,下一步,我們就該進(jìn)行訓(xùn)練了。
3.4.4.4 訓(xùn)練模型
我們著重訓(xùn)練我們的模型。
for epoch in range(epochs):# 每梯度下降一次,epoch+1epoch += 1# 前面的數(shù)據(jù)是array格式,torch只能處理tensor格式inputs = torch.from_numpy(x_train)labels = torch.from_numpy(y_train)# 梯度要清零每一次迭代optimizer.zero_grad()# 前向傳播outputs = model(inputs)# 計(jì)算損失loss = criterion(outputs,labels)# 反向傳播loss.backward()# 更新權(quán)重參數(shù)optimizer.step()# 打印每五十次梯度下降后對(duì)應(yīng)損失值if epoch % 50 == 0:print(f'epoch {epoch}, loss {loss.item()}')out:
epoch 50, loss 0.23870129883289337
epoch 100, loss 0.13614629209041595
epoch 150, loss 0.07765268534421921
epoch 200, loss 0.04429023712873459
epoch 250, loss 0.02526141330599785
epoch 300, loss 0.014408227056264877
epoch 350, loss 0.008217886090278625
epoch 400, loss 0.00468717934563756
epoch 450, loss 0.0026733996346592903
epoch 500, loss 0.0015248022973537445
epoch 550, loss 0.0008696810691617429
epoch 600, loss 0.0004960428341291845
epoch 650, loss 0.00028292808565311134
epoch 700, loss 0.0001613689964869991
epoch 750, loss 9.204218804370612e-05
epoch 800, loss 5.2495626732707024e-05
epoch 850, loss 2.9940983949927613e-05
epoch 900, loss 1.7078866221709177e-05
epoch 950, loss 9.74200611381093e-06
epoch 1000, loss 5.556627456826391e-06
在第一講中我們不是說(shuō)了tensor很重要嗎,現(xiàn)在可以告訴你為什么重要了,因?yàn)樯窠?jīng)網(wǎng)絡(luò)只接收tensor格式。所以對(duì)于array的數(shù)據(jù),我們必須將其先轉(zhuǎn)換為tensor再進(jìn)行處理。
我們還要先注意在前面我們說(shuō)過(guò)計(jì)算圖可以保存梯度,為了防止誤操作,我們?cè)诿看翁荻认陆禃r(shí),我們都要清零迭代后的梯度數(shù)據(jù)。
接著我們需要計(jì)算前向傳播,而后根據(jù)前向傳播的輸出值,通過(guò)損失函數(shù)反向傳播,反向傳播后優(yōu)化器內(nèi)參數(shù)不會(huì)自動(dòng)更新需要手動(dòng)更新。
訓(xùn)練完模型后,我們可以看看模型的預(yù)測(cè)結(jié)果,這里你照做就行,后面我再和你解釋這是怎么一回事。
predicted = model(torch.from_numpy(x_train).requires_grad_()).data.numpy() predicted訓(xùn)練好的模型如果效果十分好,那我們可以選擇保存該模型,以便下次的使用。保存模型的方法如下:
torch.save(model.state_dict(),'model.pkl')需要知道的是,模型的保存是以字典形式進(jìn)行保存,保存的僅僅是模型的參數(shù),并且保存的名字為’model.pkl’且。
如果我們需要讀入模型,可以如下:
# 讀取模型 model.load_state_dict(torch.load('model.pkl'))最后,在整個(gè)訓(xùn)練過(guò)程中,實(shí)際上我們并沒(méi)有用到GPU來(lái)加速我們的訓(xùn)練過(guò)程,這是因?yàn)槲覀兊哪P褪趾?jiǎn)單,所有的數(shù)據(jù)集也很少。在面對(duì)大數(shù)據(jù)的時(shí)候,我們通常需要GPU來(lái)加速我們模型的訓(xùn)練,其方法是在實(shí)例化神經(jīng)網(wǎng)絡(luò)類后,將該對(duì)象傳出cuda設(shè)備。并且在后面將訓(xùn)練集傳入模型的時(shí)候,也要傳入cuda。
#將神經(jīng)網(wǎng)絡(luò)對(duì)象傳給設(shè)備 device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") model.to(device)#將數(shù)據(jù)傳入cuda inputs = torch.from_numpy(x_train).to(device) Labels = torch.from_numpy(y_train).to(device)3.5 后記
這一講中講的自動(dòng)求導(dǎo)機(jī)制并沒(méi)有什么復(fù)雜,并不需要魔化它,你需要知道的僅僅是:在構(gòu)建數(shù)據(jù)集張量的時(shí)候打開(kāi)自動(dòng)求導(dǎo),并且先計(jì)算前向傳播后根據(jù)前向傳播的值,輸入損失函數(shù)然后反向傳播更新參數(shù)即可。其他的底層的東西如果你真想弄明白,何必呢,你搞底層就不會(huì)來(lái)看我這一篇筆記了不是。而且人家框架就是為了讓你避免重復(fù)造輪子。
至于3.4中線性回歸模型的搭建,這只是一個(gè)簡(jiǎn)單到不能再簡(jiǎn)單的torch的初體驗(yàn),實(shí)際上,里面的很多方法包含有很多的參數(shù),都是我們不宜直接一波灌輸進(jìn)去的,在后面的學(xué)習(xí)中,我們會(huì)逐步地去掌握它們。
總結(jié)
以上是生活随笔為你收集整理的深度学习修炼(三)——自动求导机制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 高新园区到大连计算机学校,大连高新区中心
- 下一篇: 口罩遮挡人脸数据集