日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

使用Pytorch搭建模型的步驟

瀏覽:15日期:2022-07-05 13:42:32

本來是只用Tenorflow的,但是因為TF有些Numpy特性并不支持,比如對數組使用列表進行切片,所以只能轉戰Pytorch了(pytorch是支持的)。還好Pytorch比較容易上手,幾乎完美復制了Numpy的特性(但還有一些特性不支持),怪不得熱度上升得這么快。

1 模型定義

和TF很像,Pytorch也通過繼承父類來搭建自定義模型,同樣也是實現兩個方法。在TF中是__init__()和call(),在Pytorch中則是__init__()和forward()。功能類似,都分別是初始化模型內部結構和進行推理。其它功能比如計算loss和訓練函數,你也可以繼承在里面,當然這是可選的。下面搭建一個判別MNIST手寫字的Demo,首先給出模型代碼:

import numpy as npimport matplotlib.pyplot as plt import torch from torch import nn,optim from torchsummary import summary from keras.datasets import mnistfrom keras.utils import to_categoricaldevice = torch.device(’cuda’) #——————1—————— class ModelTest(nn.Module): def __init__(self,device): super().__init__() self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#——————2—————— self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) self.to(device) #——————3—————— self.opt = optim.SGD(self.parameters(),lr=0.01)#——————4—————— def forward(self,inputs): #——————5—————— x = self.layer1(inputs) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) return x def get_loss(self,true_labels,predicts): loss = -true_labels * torch.log(predicts) #——————6—————— loss = torch.mean(loss) return loss def train(self,imgs,labels): predicts = model(imgs) loss = self.get_loss(labels,predicts) self.opt.zero_grad()#——————7—————— loss.backward()#——————8—————— self.opt.step()#——————9——————model = ModelTest(device)summary(model,(1,28,28),3,device=’cuda’) #——————10——————

#1:獲取設備,以方便后面的模型與變量進行內存遷移,設備名只有兩種:’cuda’和’cpu’。通常是在你有GPU的情況下需要這樣顯式進行設備的設置,從而在需要時,你可以將變量從主存遷移到顯存中。如果沒有GPU,不獲取也沒事,pytorch會默認將參數都保存在主存中。

#2:模型中層的定義,可以使用Sequential將想要統一管理的層集中表示為一層。

#3:在初始化中將模型參數遷移到GPU顯存中,加速運算,當然你也可以在需要時在外部執行model.to(device)進行遷移。

#4:定義模型的優化器,和TF不同,pytorch需要在定義時就將需要梯度下降的參數傳入,也就是其中的self.parameters(),表示當前模型的所有參數。實際上你不用擔心定義優化器和模型參數的順序問題,因為self.parameters()的輸出并不是模型參數的實例,而是整個模型參數對象的指針,所以即使你在定義優化器之后又定義了一個層,它依然能優化到。當然優化器你也可以在外部定義,傳入model.parameters()即可。這里定義了一個隨機梯度下降。

#5:模型的前向傳播,和TF的call()類似,定義好model()所執行的就是這個函數。

#6:我將獲取loss的函數集成在了模型中,這里計算的是真實標簽和預測標簽之間的交叉熵。

#7/8/9:在TF中,參數梯度是保存在梯度帶中的,而在pytorch中,參數梯度是各自集成在對應的參數中的,可以使用tensor.grad來查看。每次對loss執行backward(),pytorch都會將參與loss計算的所有可訓練參數關于loss的梯度疊加進去(直接相加)。所以如果我們沒有疊加梯度的意愿的話,那就要在backward()之前先把之前的梯度刪除。又因為我們前面已經把待訓練的參數都傳入了優化器,所以,對優化器使用zero_grad(),就能把所有待訓練參數中已存在的梯度都清零。那么梯度疊加什么時候用到呢?比如批量梯度下降,當內存不夠直接計算整個批量的梯度時,我們只能將批量分成一部分一部分來計算,每算一個部分得到loss就backward()一次,從而得到整個批量的梯度。梯度計算好后,再執行優化器的step(),優化器根據可訓練參數的梯度對其執行一步優化。

#10:使用torchsummary函數顯示模型結構。奇怪為什么不把這個繼承在torch里面,要重新安裝一個torchsummary庫。

2 訓練及可視化

接下來使用模型進行訓練,因為pytorch自帶的MNIST數據集并不好用,所以我使用的是Keras自帶的,定義了一個獲取數據的生成器。下面是完整的訓練及繪圖代碼(50次迭代記錄一次準確率):

import numpy as npimport matplotlib.pyplot as plt import torch from torch import nn,optim from torchsummary import summary from keras.datasets import mnistfrom keras.utils import to_categoricaldevice = torch.device(’cuda’) #——————1—————— class ModelTest(nn.Module): def __init__(self,device): super().__init__() self.layer1 = nn.Sequential(nn.Flatten(),nn.Linear(28*28,512),nn.ReLU())#——————2—————— self.layer2 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) self.layer3 = nn.Sequential(nn.Linear(512,512),nn.ReLU()) self.layer4 = nn.Sequential(nn.Linear(512,10),nn.Softmax()) self.to(device) #——————3—————— self.opt = optim.SGD(self.parameters(),lr=0.01)#——————4—————— def forward(self,inputs): #——————5—————— x = self.layer1(inputs) x = self.layer2(x) x = self.layer3(x) x = self.layer4(x) return x def get_loss(self,true_labels,predicts): loss = -true_labels * torch.log(predicts) #——————6—————— loss = torch.mean(loss) return loss def train(self,imgs,labels): predicts = model(imgs) loss = self.get_loss(labels,predicts) self.opt.zero_grad()#——————7—————— loss.backward()#——————8—————— self.opt.step()#——————9——————def get_data(device,is_train = True, batch = 1024, num = 10000): train_data,test_data = mnist.load_data() if is_train: imgs,labels = train_data else: imgs,labels = test_data imgs = (imgs/255*2-1)[:,np.newaxis,...] labels = to_categorical(labels,10) imgs = torch.tensor(imgs,dtype=torch.float32).to(device) labels = torch.tensor(labels,dtype=torch.float32).to(device) i = 0 while(True): i += batch if i > num: i = batch yield imgs[i-batch:i],labels[i-batch:i] train_dg = get_data(device, True,batch=4096,num=60000) test_dg = get_data(device, False,batch=5000,num=10000) model = ModelTest(device) summary(model,(1,28,28),11,device=’cuda’) ACCs = []import timestart = time.time()for j in range(20000): #訓練 imgs,labels = next(train_dg) model.train(imgs,labels) #驗證 img,label = next(test_dg) predicts = model(img) acc = 1 - torch.count_nonzero(torch.argmax(predicts,axis=1) - torch.argmax(label,axis=1))/label.shape[0] if j % 50 == 0: t = time.time() - start start = time.time() ACCs.append(acc.cpu().numpy()) print(j,t,’ACC: ’,acc)#繪圖x = np.linspace(0,len(ACCs),len(ACCs))plt.plot(x,ACCs)

準確率變化圖如下:

使用Pytorch搭建模型的步驟

3 其它使用技巧

3.1 tensor與array

需要注意的是,pytorch的tensor基于numpy的array,它們是共享內存的。也就是說,如果你把tensor直接插入一個列表,當你修改這個tensor時,列表中的這個tensor也會被修改;更容易被忽略的是,即使你用tensor.detach.numpy(),先將tensor轉換為array類型,再插入列表,當你修改原本的tensor時,列表中的這個array也依然會被修改。所以如果我們只是想保存tensor的值而不是整個對象,就要使用np.array(tensor)將tensor的值復制出來。

3.2 自定義層

在TF中,自定義模型通常繼承keras的Model,而自定義層則是繼承layers.Layer,繼承不同的父類通常會造成初學者的困擾。而在pytorch中,自定義層與自定義模型一樣,都是繼承nn.Module。Pytorch將層與模型都看成了模塊,這很容易理解。的確,層與模型之間本來也沒有什么明確的界限。并且定義方式與上面定義模型的方式一樣,也是實現兩個函數即可。代碼示例如下:

import torch from torch import nn class ParaDeconv(nn.Module):#——————1—————— def __init__(self,in_n,out_n): super().__init__() self.w = nn.Parameter(torch.normal(0,0.01,size = [in_n,out_n]),requires_grad=True) self.b = nn.Parameter(torch.normal(0,0.01,size = [out_n]),requires_grad=True) def forward(self,inputs): x = torch.matmul(inputs,self.w) x = x + self.b return x layer = ParaDeconv(2,3)y = layer(torch.ones(100,2))#——————2——————loss = torch.sum(y)#——————3——————loss.backward()#——————4——————for i in layer.parameters():#——————5—————— print(i.grad)#——————6——————

#1:自定義一個全連接層。層中可訓練參數的定義是使用nn.Parameter,如果直接使用torch.tensor是無法在#5中遍歷到的。

#2/3/4:輸入并計算loss,然后反向傳播計算參數梯度。

#5/6:輸出完成反向傳播后層參數的梯度。

以上定義的層可以和pytorch自帶的層一樣直接插入模型中使用。

3.3 保存/加載

3.3.1 保存/加載模型

有兩種方式,一種是保存模型的參數:

torch.save(model.state_dict(), PATH) #保存 model.load_state_dict(torch.load(PATH),strict=True) #加載

這種加載方式需要先定義模型,然后再加載參數。如果你定義的模型參數名與保存的參數對不上,就會出錯。但如果把strict修改成False,不嚴格匹配,它就會只匹配對應上的鍵值,不會因多出或缺少的參數而報錯。

另一種是直接保存模型:

torch.save(model, PATH) #保存model = torch.load(PATH) #加載

這種方式看似方便,實際上更容易出錯。因為python不能保存整個模型的類,所以它只能保存定義類的代碼文件位置,以在加載時獲取類的結構。如果你改變了定義類的代碼位置,就有可能因為找不到類而出錯。

3.3.2 保存訓練點當你要保存某個訓練階段的狀態,比如包含優化器參數、模型參數、訓練迭代次數等,可以進行如下操作:

#保存訓練點torch.save({ ’epoch’: epoch, ’model_state_dict’: model.state_dict(), ’optimizer_state_dict’: optimizer.state_dict(), ’loss’: loss }, PATH)#加載訓練點model = TheModelClass(*args, **kwargs)optimizer = TheOptimizerClass(*args, **kwargs)checkpoint = torch.load(PATH)model.load_state_dict(checkpoint[’model_state_dict’])optimizer.load_state_dict(checkpoint[’optimizer_state_dict’])epoch = checkpoint[’epoch’]loss = checkpoint[’loss’]

和保存模型一樣,也是使用torch.save()。它很靈活,可以保存字典,因此讀取的時候也按照字典索引讀取即可。當然要注意,并不是任何類型都能保存的,這里保存的四個類型分別是:

1. int

2. collections.OrderedDict

3. collections.OrderedDict

4. list

3.4 修改模型參數

Pytorch沒有提供額外的方式讓我們修改模型參數,我們可以使用上面加載模型參數的方式來修改參數。對于某個參數,我們只要把鍵值和對應要修改的值放在字典中傳入load_state_dict即可。如果沒傳入所有的參數,記得把strict設為False。示例如下:

model.load_state_dict({’weight’:torch.tensor([0.])},strict=False) #修改模型參數

參數名,也就是鍵值,和對應的參數shape可以通過model.state_dict()查看。

以上就是使用Pytorch搭建模型的步驟的詳細內容,更多關于Pytorch搭建模型的資料請關注好吧啦網其它相關文章!

標簽: Pytorch
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
秋霞影视一区二区三区| 国产美女久久| 午夜精品久久久久久久久久蜜桃| 精品五月天堂| 涩涩av在线| 久久久精品日韩| 午夜精品亚洲| 三级久久三级久久久| 国产精品啊啊啊| 在线观看精品| 狠狠干成人综合网| 欧美一区二区三区久久| 久久精品亚洲| 久久久久午夜电影| 一区在线视频观看| 久久国产视频网| 深夜福利视频一区二区| 午夜久久免费观看| 日韩av在线播放中文字幕| 久久精品一区二区国产| 欧美性感美女一区二区| 日韩精彩视频在线观看| www.九色在线| 中文不卡在线| 91亚洲成人| 伊人精品久久| 亚洲精品成人图区| 日韩影院在线观看| 精品国产乱码久久久久久1区2匹| 欧洲一区二区三区精品| 天堂成人免费av电影一区| 精品资源在线| 麻豆久久精品| 国产传媒在线| 亚洲深深色噜噜狠狠爱网站| 久久精品国产99国产| 国产视频一区三区| 美女久久久精品| 久久成人一区| 日本一区二区免费高清| 综合精品一区| 久久精品影视| 捆绑调教美女网站视频一区 | 亚洲国内欧美| 国产精品网站在线看| 国产午夜精品一区二区三区欧美| 久久精品资源| 日韩精品高清不卡| 国产99久久| 精品国产成人| 18国产精品| 日韩精品一二三四| 亚洲www啪成人一区二区| 国产欧美啪啪| 一级成人国产| 不卡在线一区| 日韩精品2区| 久久精品超碰| 亚洲一区二区日韩| 激情综合在线| 久久久男人天堂| 国产精一区二区| 亚洲精品大全| 亚洲黄色在线| 欧美一级精品| 中文字幕一区久| 欧美在线看片| 蜜臀av性久久久久蜜臀aⅴ流畅| 久久天堂成人| 日韩不卡免费高清视频| 久久久久久亚洲精品美女| 日韩一区二区三区精品视频第3页| 亚洲国产影院| 高清不卡亚洲| av中文字幕在线观看第一页| 免费精品一区| 欧美黄色一区| 久久中文字幕一区二区| 国产精品magnet| 国产精品一卡| 欧美激情视频一区二区三区在线播放| 日韩av中文在线观看| 日韩和欧美一区二区| 视频一区中文字幕精品| 亚洲视频二区| 亚洲三级网址| 天海翼精品一区二区三区| 亚洲一区国产| 欧美日韩免费观看一区=区三区| 亚洲高清不卡| 免费视频国产一区| 91精品一区国产高清在线gif| 精品国产第一福利网站| 91亚洲国产成人久久精品| 在线看片福利| 久久精品主播| 中文在线一区| 蜜桃一区二区三区在线观看| 久久高清免费观看| 亚洲综合中文| 国产日韩亚洲| 精品国产乱码| 久久中文视频| 亚洲自啪免费| 日韩av不卡在线观看| 国产福利亚洲| 91麻豆国产自产在线观看亚洲| 蜜臀久久精品| 亚洲二区视频| 日韩在线a电影| 久久国际精品| 国产粉嫩在线观看| 亚洲精品网址| 欧美日本三区| 国产日韩电影| 亚洲激情黄色| 日本少妇精品亚洲第一区| 国产精品一区二区三区四区在线观看 | 日韩三级视频| 91成人在线精品视频| 国产精品一区亚洲| 久久久久久夜| 欧美专区在线| 国产乱码精品一区二区三区亚洲人| 国产精品手机在线播放| 久久亚洲黄色| 欧美sss在线视频| 视频一区欧美精品| 欧美成人一二区| 精品一区欧美| 国产欧美88| 欧美精选一区二区三区| 日韩二区在线观看| 97精品中文字幕| 国产专区一区| 欧美伊人影院| 欧美69视频| 欧美亚洲专区| 亚洲天堂久久| 日韩和欧美一区二区三区| 激情久久99| 久久青草久久| 日韩av电影一区| 国产成人精品一区二区免费看京 | 国产精品原创| 日韩一区二区三区免费视频 | 欧美亚洲一区二区三区| 91精品蜜臀一区二区三区在线| 日韩精品国产欧美| 久久精品青草| 国产精品一级| 午夜国产精品视频免费体验区| 97成人超碰| 久久精品国产www456c0m| 欧美欧美黄在线二区| 国产国产精品| 国产aa精品| 日本成人在线网站| 亚洲大全视频| 国产精品yjizz视频网| 日韩三级精品| 午夜国产一区二区| 精品三区视频| 日韩va亚洲va欧美va久久| 亚洲午夜一级| 亚洲黄色免费看| 国产精品a级| 中文字幕av亚洲精品一部二部| 欧美日韩视频免费观看| 亚洲久草在线| 美女少妇全过程你懂的久久| 国产调教精品| 性一交一乱一区二区洋洋av| 久久婷婷激情| 久久字幕精品一区| 欧美在线日韩| 在线观看一区| 欧美影院三区| 国产精品13p| 欧美极品中文字幕| 日韩av一二三| 亚洲综合国产| 欧美日韩四区| 蜜臀久久99精品久久一区二区| av资源亚洲| 国产成人久久精品一区二区三区| 国产欧美三级| 日本不卡一区二区| 午夜久久av| 一二三区精品| 蜜臀精品久久久久久蜜臀| 欧美午夜不卡| 亚洲国产一区二区在线观看| 人人香蕉久久| 欧美激情另类| 日本一区二区高清不卡| 欧美激情视频一区二区三区免费 | 国产高清亚洲| 麻豆一区二区99久久久久| 97se亚洲|