【学习笔记】 pytorch的使用语法和代码实例
數(shù)據(jù)類型
( 1) torch.FloatTensor : 用于生成數(shù)據(jù)類型為浮點(diǎn)型的Tensor ,傳遞給torch.FloatTensor的參數(shù)可以是一個(gè)列表,也可以是一個(gè)維度值。
torch.randn :用于生成數(shù)據(jù)類型為浮點(diǎn)型且維度指定的隨機(jī)Tensor ,和在N umPy中使用numpy . randn 生成隨機(jī)數(shù)的方法類似,隨機(jī)生成的浮點(diǎn)數(shù)的取值滿足均值為0 、方差為1的正態(tài)分布
torch.clamp : 對(duì)輸入?yún)?shù)按照自定義的范圍進(jìn)行裁剪, 最后將參數(shù)裁剪的結(jié)果作為輸出。所以輸入?yún)?shù)一共有三個(gè),分別是需要進(jìn)行裁剪的Tensor 數(shù)據(jù)類型的變量、裁剪的上邊界和裁剪的下邊界, 具體的裁剪過程是: 使用變量中的每個(gè)元素分別和裁剪的上邊界及裁剪的下邊界的值進(jìn)行比較,如果元素的值小于裁剪的下邊界的值, 該元素就被重寫成裁剪的下邊界的值: 同理,如果元素的值大于裁剪的上邊界的值, 該元素就被重寫成裁剪的上邊界的值。
結(jié)果:
torch.div : 將參數(shù)傳遞到to rch.div 后返回輸入?yún)?shù)的求商結(jié)果作為輸出,同樣,參與運(yùn)算的參數(shù)可以全部是Tensor 數(shù)據(jù)類型的變量,也可以是Tensor 數(shù)據(jù)類型的變量和標(biāo)量的組合。
torch.mm : 將參數(shù)傳遞到torch.mm 后返回輸入?yún)?shù)的求積結(jié)果作為輸出,不過這個(gè)求積的方式和之前的torch.mul運(yùn)算方式不太一樣, torch.mm 運(yùn)用矩陣之間的乘法規(guī)則進(jìn)行計(jì)算,所以被傳入的參數(shù)會(huì)被當(dāng)作矩陣進(jìn)行處理, 參數(shù)的維度自然也要滿足矩陣乘法的前提條件,即前一個(gè)矩陣的行數(shù)必須和后一個(gè)矩陣的列數(shù)相等,否則不能進(jìn)行計(jì)算。
torch.mv : 將參數(shù)傳遞到torch.mv后返回輸入?yún)?shù)的求積結(jié)果作為輸出,torch.mv運(yùn)用矩陣與向量之間的乘法規(guī)則進(jìn)行計(jì)算, 被傳入的參數(shù)中的第1個(gè)參數(shù)代表矩陣,第2個(gè)參數(shù)代表向量, 順序不能顛倒。
torch. autograd
torch. autograd 包的主要功能是完成神經(jīng)網(wǎng)絡(luò)后向傳播中的鏈?zhǔn)角髮?dǎo),手動(dòng)實(shí)現(xiàn)鏈?zhǔn)角髮?dǎo)的代碼會(huì)給我們帶來很大的困擾,而torch.autograd 包中豐富的類減少了這些不必要的麻煩
。如果用autograd.Variable 來定義參數(shù),則 Variable 自動(dòng)定義了兩個(gè)變量,data代表原始權(quán)重?cái)?shù)據(jù);而 grad 代表求導(dǎo)后的數(shù)據(jù),也就是梯度。每次迭代過程就用這個(gè) grad 對(duì)權(quán)重?cái)?shù)據(jù)進(jìn)行修正。
實(shí)現(xiàn)自動(dòng)梯度功能的過程大致為:先通過輸入的Tensor 數(shù)據(jù)類型的變量在神經(jīng)網(wǎng)絡(luò)的前向傳播過程中生成一張計(jì)算圖,然后根據(jù)這個(gè)計(jì)算圖和輸出結(jié)果準(zhǔn)確計(jì)算出每個(gè)參數(shù)需要更新的梯度,并通過完成后向傳播完成對(duì)參數(shù)的梯度更新。
這個(gè)包的使用:
input_ data 是輸入數(shù)據(jù)的特征個(gè)數(shù), hidden_layer 是通過隱藏層后輸出的特征數(shù),output_ data 是最后輸出的分類結(jié)果數(shù),如果requires_grad 的值是False ,那么表示該變量在進(jìn)行自動(dòng)梯度計(jì)算的過程中不會(huì)保留梯度值,將輸入的數(shù)據(jù)x 和輸出的數(shù)據(jù)y 的requires_grad 參數(shù)均設(shè)置為False , 這是因?yàn)檫@兩個(gè)變量并不是我們的模型需要優(yōu)化的參數(shù)。w1 w2的requires_grad 參數(shù)均設(shè)置為True 。
關(guān)于Variable :Variable 不光包含了數(shù)據(jù),還包含了其他東西,
x=Variable(torch.Tensor(2,2)) 默認(rèn) Variable 是有導(dǎo)數(shù) grad的,x.data 是數(shù)據(jù),這里 x.data 就是Tensor。x.grad 是計(jì)算過程中動(dòng)態(tài)變化的導(dǎo)數(shù)。
定義訓(xùn)練次數(shù)和學(xué)習(xí)率:
epoch_n = 20 learning_rate = 1e-6權(quán)值更新方法:
weight = weight + learning_rate * gradient learning_rate = 0.01 for f in model.parameters():f.data.sub_(f.grad.data * learning_rate)learning_rate 是學(xué)習(xí)速率,多數(shù)時(shí)候就叫做 lr,是學(xué)習(xí)步長(zhǎng),用步長(zhǎng) *導(dǎo)數(shù)就是每次權(quán)重修正的 delta 值,lr 越大表示學(xué)習(xí)的速度越快,相應(yīng)的精度就會(huì)降低。
如同使用PyTorch 中的自動(dòng)梯度方法一樣,在搭建復(fù)雜的神經(jīng)網(wǎng)絡(luò)模型的時(shí)候, 我們也可以使用PyTorch 中己定義的類和方法,這些類和方法覆蓋了神經(jīng)網(wǎng)絡(luò)中的線性變換、激活函數(shù)、卷積層、全連接層、池化層等常用神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)的實(shí)現(xiàn)。在完成模型的搭建之后, 我們還可以使用PyTorch 提供的類型豐富的優(yōu)化函數(shù)來完成對(duì)模型參數(shù)的優(yōu)化, 除此之外, 還有很多防止模型在模型訓(xùn)練過程中發(fā)生過擬合的類。
torch.nn
PyTorch 中的torch.nn 包提供了很多與實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)中的具體功能相關(guān)的類,這些類涵蓋了深度神經(jīng)網(wǎng)絡(luò)模型在搭建和參數(shù)優(yōu)化過程中的常用內(nèi)容,比如神經(jīng)網(wǎng)絡(luò)中的卷積層、池化層、全連接層這類層次構(gòu)造的方法、防止過擬合的參數(shù)歸一化方法、Dropout 方法,還有激活函數(shù)部分的線性激活函數(shù)、非線性激活函數(shù)相關(guān)的方法, 等等
torch .nn 包中的類能夠幫助我們自動(dòng)生成和初始化對(duì)應(yīng)維度的權(quán)重參數(shù)。模型搭建的代碼如下:
通過torch.nn .Linear( input_data, hidden layer)完成從輸入層到隱藏層的線性變換,然后經(jīng)過激活函數(shù)及torch.nn .Linear(hidden layer, output_ da ta)完成從隱藏層到輸出層的線性變換。torch.nn.Linear 類接收的參數(shù)有三個(gè),分別是輸入特征數(shù)、輸出特征數(shù)和是否使用偏置,設(shè)置是否使用偏置的參數(shù)是一個(gè)布爾值,默認(rèn)為True ,即使用偏置。在實(shí)際使用的過程中,我們只需將輸入的特征數(shù)和輸出的特征數(shù)傳遞給
torch.nn.Linear 類, 就會(huì)自動(dòng)生成對(duì)應(yīng)維度的權(quán)重參數(shù)和偏置
torch.nn.Sequential類是torch. nn 中的一種序列容器,通過
在容器中嵌套各種實(shí)現(xiàn)神經(jīng)網(wǎng)絡(luò)中具體功能相關(guān)的類,來完成對(duì)神經(jīng)網(wǎng)絡(luò)模型的搭建,最主要的是,參數(shù)會(huì)按照我們定義好的序列自動(dòng)傳遞下去。我們可以將嵌套在容器中的各個(gè)部分看作各種不同的模塊,這些模塊可以自由組合。模塊的加入一般有兩種方式, 一種是在以上代碼中使用的直接嵌套,另一種是以orderdict 有序字典的方式進(jìn)行傳入,這兩種方式的唯一區(qū)別是,使用后者搭建的模型的每個(gè)模塊都有我們自定義的名字, 而前者默認(rèn)使用從零開始的數(shù)字序列作為每個(gè)模塊的名字。下面通過示例來直觀地看一下字典方
式搭建的模型。
字典:
torch.nn.Linear類用于定義模型的線性層,即完成前面提到的
不同的層之間的線性變換。torch.nn.Linear 類接收的參數(shù)有三個(gè),分別是輸入特征數(shù)、輸出特征數(shù)和是否使用偏置,設(shè)置是否使用偏置的參數(shù)是一個(gè)布爾值,默認(rèn)為True ,即使用偏置。在實(shí)際使用的過程中,我們只需將輸入的特征數(shù)和輸出的特征數(shù)傳遞給torch.nn.Linear 類, 就會(huì)自動(dòng)生成對(duì)應(yīng)維度的權(quán)重參數(shù)和偏置
torch.nn.ReLU 類屬于非線性激活分類,在定義時(shí)默認(rèn)不需要傳入?yún)?shù)。當(dāng)然,在torch.nn 包中還有許多非線性激活函數(shù)類可供選擇,比如之前講到的PReLU 、LeakyReLU 、Tanh 、S igmoid 、Softmax 等。
torch.nn.MSELoss類使用均方誤差函數(shù)對(duì)損失值進(jìn)行計(jì)算,
在定義類的對(duì)象時(shí)不用傳入任何參數(shù),但在使用實(shí)例時(shí)需要輸入兩個(gè)維度一樣的參數(shù)方可進(jìn)行計(jì)算
torch.nn.L1Loss 類使用平均絕對(duì)誤差函數(shù)對(duì)損失值進(jìn)行計(jì)算,
同樣,在定義類的對(duì)象時(shí)不用傳入任何參數(shù),但在使用實(shí)例時(shí)需要輸入兩個(gè)維度一樣的參數(shù)進(jìn)行計(jì)算。
torch.nn.CrossEntropyLoss 類用于計(jì)算交叉熵,在定義類的對(duì)象時(shí)不用傳入任何參數(shù),在使用實(shí)例時(shí)需要輸入兩個(gè)滿足交叉熵計(jì)算條件的參數(shù)
nn.NLLLoss2d
和上面類似,但是多了幾個(gè)維度,一般用在圖片上。
input, (N, C, H, W)
target, (N, H, W)
比如用全卷積網(wǎng)絡(luò)做分類時(shí),最后圖片的每個(gè)點(diǎn)都會(huì)預(yù)測(cè)一個(gè)類別標(biāo)簽。
Adam 優(yōu)化函數(shù)還有一個(gè)強(qiáng)大的功能,就是可以對(duì)梯度更新使用到的學(xué)習(xí)速率進(jìn)行自適應(yīng)調(diào)節(jié)
PyTorch 之torch.optim
優(yōu)化器Optim
優(yōu)化器用通俗的話來說就是一種算法,是一種計(jì)算導(dǎo)數(shù)的算法。各種優(yōu)化器的目的和發(fā)明它們的初衷其實(shí)就是能讓用戶選擇一種適合自己場(chǎng)景的優(yōu)化器。優(yōu)化器的最主要的衡量指標(biāo)就是優(yōu)化曲線的平穩(wěn)度,最好的優(yōu)化器就是每一輪樣本數(shù)據(jù)的優(yōu)化都讓權(quán)重參數(shù)勻速的接近目標(biāo)值,而不是忽上忽下跳躍的變化。因此損失值的平穩(wěn)下降對(duì)于一個(gè)深度學(xué)習(xí)模型來說是一個(gè)非常重要的衡量指標(biāo)。
在PyTorch 的torch.optim 包中提供了非常多的可實(shí)現(xiàn)參數(shù)自動(dòng)優(yōu)化的類,比如SGD 、AdaGrad 、RMS Prop 、Adam 等,這些類都可以被直接調(diào)用,使用起來也非常方便。可以直接調(diào)用optimzer. zero_grad 來完成對(duì)模型參數(shù)梯度的歸零; optimzer.step , 它的主要功能是使用計(jì)算得到的梯度值對(duì)各個(gè)節(jié)點(diǎn)的參數(shù)進(jìn)行梯度更新。
SGD
SGD 指stochastic gradient descent,即隨機(jī)梯度下降,隨機(jī)的意思是隨機(jī)選取部分?jǐn)?shù)據(jù)集參與計(jì)算,是梯度下降的 batch 版本。SGD 支持動(dòng)量參數(shù),支持學(xué)習(xí)衰減率
optimizer = optim.SGD(model.parameters(), lr = 0.01, momentum=0.9)lr:大于 0 的浮點(diǎn)數(shù),學(xué)習(xí)率。
momentum:大于 0 的浮點(diǎn)數(shù),動(dòng)量參數(shù)。
parameters:Variable 參數(shù),要優(yōu)化的對(duì)象。
對(duì)于訓(xùn)練數(shù)據(jù)集,我們首先將其分成 n 個(gè) batch,每個(gè) batch 包含 m 個(gè)樣本。我們每次更新都利用一個(gè) batch 的數(shù)據(jù),而非整個(gè)訓(xùn)練集,
手寫數(shù)字識(shí)別
使用torchvision. datasets 可以輕易實(shí)現(xiàn)對(duì)這些數(shù)據(jù)集的訓(xùn)練集和測(cè)試集的下載,只需要使用torchvision.datasets 再加上需要下載的數(shù)據(jù)集的名稱就可以了,
1.下載數(shù)據(jù)集:
train 用于指定在數(shù)據(jù)集下載完成后需要載入哪部分?jǐn)?shù)據(jù),如果設(shè)置為True ,則說明載入的是該數(shù)據(jù)集的訓(xùn)練集部分; 如果設(shè)置為False ,則說明載入的是該數(shù)據(jù)集的測(cè)試集部分。
torch.transforms 中有大量的數(shù)據(jù)變換類, 其中有很大一部分可以用于實(shí)現(xiàn)數(shù)據(jù)增強(qiáng)
torchvision. transforms 中常用的數(shù)據(jù)變換操作:
torchvision.transforms.Resize :用于對(duì)載入的圖片數(shù)據(jù)按我們需求的大小進(jìn)行縮放。傳遞給這個(gè)類的參數(shù)可以是一個(gè)整型數(shù)據(jù),也可以是一個(gè)類似于(h , w)的序列, 其中, h 代表高度, w 代表寬度,但是如果使用的是一個(gè)整型數(shù)據(jù),那么表示縮放的寬度和高度都是這個(gè)整型數(shù)據(jù)的值。
torchvision.transforms.Scale : 用于對(duì)載入的圖片數(shù)據(jù)按我們需求的大小進(jìn)行縮放,用法和torchvision . transforms.Resize 類似
torchvision.transforms.CenterCrop :用于對(duì)載入的圖片以圖片中心為參考點(diǎn), 按我們需要的大小進(jìn)行裁剪。傳遞給這個(gè)類的參數(shù)可以是一個(gè)整型數(shù)據(jù),也可以是一個(gè)類似于( h , w )的序列。
torchvision.transforms.RandomHorizontaIFlip : 用于對(duì)載入的圖片按隨機(jī)概率進(jìn)行水平翻轉(zhuǎn)。我們可以通過傳遞給這個(gè)類的參數(shù)自定義隨機(jī)概率,如果沒有定義,則使用默認(rèn)的概率值0.5
torchvision.transforms.Random VerticalFlip : 用于對(duì)載入的圖片按隨機(jī)概率進(jìn)行垂直翻轉(zhuǎn)。我們可以通過傳遞給這個(gè)類的參數(shù)自定義隨機(jī)概率,如果沒有定義,則使用默認(rèn)的概率值0. 5
torchvision.transforms. ToPILlmage : 用于將Tensor 變量的數(shù)據(jù)轉(zhuǎn)換成PIL 圖片
torchvision.transforms. ToTensor : 用于對(duì)載入的圖片數(shù)據(jù)進(jìn)行類型轉(zhuǎn)換, 將之前構(gòu)成PIL 圖片的數(shù)據(jù)轉(zhuǎn)換成Tensor 數(shù)據(jù)類型的變量, 讓PyTorch 能夠?qū)ζ溥M(jìn)行計(jì)算和處理。
torchvision.transforms.Compose 類看作一種容器, 它能夠同時(shí)對(duì)多種數(shù)據(jù)變換進(jìn)行組合。傳入的參數(shù)是一個(gè)列表,列表中的元素就是對(duì)載入的數(shù)據(jù)進(jìn)行的各種變換操作。如:
transform =transforms.Compose([transforms.ToTensor(),
transforms.Normalize(mean=[0.5, 0.5, 0.5] , std=[0.5 , 0.5, 0.5])])
transforms.Normalize這里使用的標(biāo)準(zhǔn)化變換也叫作標(biāo)準(zhǔn)差變換法,這種方法需要使用原始數(shù)據(jù)的均值( Mean )和標(biāo)準(zhǔn)差來進(jìn)行數(shù)據(jù)的標(biāo)準(zhǔn)化,在經(jīng)過標(biāo)準(zhǔn)化變換之后,數(shù)據(jù)全部符合均值為0 、標(biāo)準(zhǔn)差為1的標(biāo)準(zhǔn)正態(tài)分布
2.裝載圖片:
data_loader_train = torch.utils.data.DataLoader(dataset=data_train,batch_size = 64,shuffle = True) data_loader_test= torch.utils.data.DataLoader (dataset=data_test,batch_size = 64 ,shuffle = True)對(duì)數(shù)據(jù)的裝載使用的是torch.utils .data. Data Loader 類, 類中的dataset 參數(shù)用于指定我們載入的數(shù)據(jù)集名稱, batch_s ize 參數(shù)設(shè)置了每個(gè)包中的圖片數(shù)據(jù)個(gè)數(shù),代碼中的值是64,
所以在每個(gè)包中會(huì)包含64 張圖片。將shuffle 參數(shù)設(shè)置為True , 在裝載的過程會(huì)將數(shù)據(jù)隨機(jī)打亂順序并進(jìn)行打包。
全部代碼:
因?yàn)橄螺d過程中實(shí)在太慢,一小時(shí)了才百分之零點(diǎn)幾,所有就沒有繼續(xù)跑了。
模型搭建和參數(shù)優(yōu)化
在順利完成數(shù)據(jù)裝載后, 我們就可以開始編寫卷積神經(jīng)網(wǎng)絡(luò)模型的搭建和參數(shù)優(yōu)化的代碼了。因?yàn)槲覀兿胍罱ㄒ粋€(gè)包含了卷積層、激活函數(shù)、池化層、全連接層的卷積神經(jīng)網(wǎng)絡(luò)來解決這個(gè)問題,所以模型在結(jié)構(gòu)上會(huì)和之前簡(jiǎn)單的神經(jīng)網(wǎng)絡(luò)有所區(qū)別, 當(dāng)然, 各個(gè)部分的功能實(shí)現(xiàn)依然是通過torch.nn 中的類來完成的
如卷積層使用torch.nn.Conv2d 類方法來搭建; 激活層使用torch.nn.ReLU 類方法來搭建; 池化層使用torch.nn .MaxPool2d
實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)模型搭建的代碼如下:
class Model(torch . nn .Module):def init (self):super(Model,self)__init__()self.convl=torch.nn.Sequential(torch.nn.Conv2d (l, 64 ,kernel_size=3 , stride=l , padding=l) ,torch.nn.ReLU (),torch.nn.Conv2d(64,128,kernel_size=3 , stride=l,padding=l),torch.nn.ReLU() ,torch.nn.MaxPool2d(stride=2,kernel size=2))self.dense=torch.nn.Sequential(torch.nn.Linear(14*14*128,10 24);torch.nn.ReLU(),torch.nn.Dropout (p=O.5) ,torch.nn.Linear (1024, 10))def forward(self, x) :x = self.convl(x)x = x.view(-1 , 14*14*128)x = self.dense(x)return xtorch.nn.Conv2d :用于搭建卷積神經(jīng)網(wǎng)絡(luò)的卷積層,Paddingde 的數(shù)據(jù)類型是整型,值為0 時(shí)表示不進(jìn)行邊界像素的填充,如果值大于0 ,那么增加數(shù)字所對(duì)應(yīng)的邊界像素層數(shù)。
torch.nn.MaxPool2d : 用于實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)中的最大池化層,主要的輸入?yún)?shù)是池化窗口大小、池化窗口移動(dòng)步長(zhǎng)和Paddingde 值。
torch.nn.Dropout 類用于防止卷積神經(jīng)網(wǎng)絡(luò)在訓(xùn)練的過程中發(fā)
生過擬合, 其工作原理簡(jiǎn)單來說就是在模型訓(xùn)練的過程中,以一定的隨機(jī)概率將卷積神經(jīng)網(wǎng)絡(luò)模型的部分參數(shù)歸零, 以達(dá)到減少相鄰兩層神經(jīng)連接的目的
nn.Sequential:一個(gè)Sequential容器,是一個(gè)包含其他模塊的模塊,它可以快速搭建神經(jīng)網(wǎng)絡(luò)
Linear:每個(gè)Linear模塊使用線性函數(shù)來計(jì)算,它會(huì)內(nèi)部創(chuàng)建需要的weight和bias
一些代碼的解釋:
獲取一個(gè)批次的數(shù)據(jù)井迸行數(shù)據(jù)預(yù)覽和分析,代碼如下:
X_example , y_example = next(iter(dataloader [“train” ]))
以上代碼通過next 和iter迭代操作獲取一個(gè)批次的裝載數(shù)據(jù)
_, predicted = torch.max(outputs.data, 1):
首先,torch.max()這個(gè)函數(shù)返回的是兩個(gè)值,第一個(gè)值是具體的value(我們用下劃線_表示),第二個(gè)值是value所在的index(也就是predicted)。數(shù)字1其實(shí)可以寫為dim=1,這里簡(jiǎn)寫為1,python也可以自動(dòng)識(shí)別,dim=1表示輸出所在行的最大值,若改寫成dim=0則輸出所在列的最大值。
總結(jié)
以上是生活随笔為你收集整理的【学习笔记】 pytorch的使用语法和代码实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【笔记】numpy使用详解 matplo
- 下一篇: 【链表】链表变化时其中的节点变化情况