第一学:pytorch入门60min
生活随笔
收集整理的這篇文章主要介紹了
第一学:pytorch入门60min
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄
1、Tensor張量
2、自動(dòng)微分
3、神經(jīng)網(wǎng)絡(luò)
4、pytorch圖像分類器
5、數(shù)據(jù)并行處理
1、Tensor張量
#Tensors類似于NumPy的ndarrays,同時(shí)Tensors可以使用GPU進(jìn)行計(jì)算 #張量就是按照任意維排列的一堆數(shù)字的推廣 #其實(shí)標(biāo)量,向量,矩陣它們?nèi)齻€(gè)也是張量,標(biāo)量是零維的張量,向量是一維的張量,矩陣是二維的張量。 import torch x=torch.empty(5,3)#構(gòu)造一個(gè)5x3矩陣,不初始化。 x1=torch.rand(5,3)#構(gòu)造一個(gè)隨機(jī)初始化的矩陣 x2=torch.zeros(5,3,dtype=torch.long)#構(gòu)造一個(gè)矩陣全為 0,而且數(shù)據(jù)類型是 long x3=torch.tensor([5,5,3])#構(gòu)造一個(gè)張量,直接使用數(shù)據(jù)#創(chuàng)建一個(gè)tensor基于已經(jīng)存在的tensor x4=x3.new_ones(5,3,dtype=torch.double) print(x4) x5=torch.randn_like(x4) print(x5)#獲取它的維度,torch.Size是一個(gè)元組,它支持左右的元組操作 print(x5.size())#操作 #加法:方式一 y=torch.rand(5,3) print(x+y) #加法,方式二 print(torch.add(x,y))#加法:提供一個(gè)輸出tensor作為參數(shù) result=torch.empty(5,3) torch.add(x,y,out=result) print(result)#加法:in-place,adds x to y #注意,任何使張量發(fā)生變化的操作都有一個(gè)前綴,如x.copy(y),x.t_(),將會(huì)改變x y.add_(x) print(y)#可以使用標(biāo)準(zhǔn)的Numpy類似的索引操作,按行存儲(chǔ) print(x[:,1])#改變大小:如果想改變一個(gè)tensor的大小或形狀,可以使用torch.view x=torch.randn(4,4) y=x.view(16) z=x.view(-1,8)#-1是從其他維度推斷出來(lái)的 print(x.size(),y.size(),z.size())#如果有一個(gè)元素的tensor,使用.item()來(lái)獲取這個(gè)value x=torch.randn(1) print(x) print(x.item()) print(x,x1,x2)2、自動(dòng)微分
""" 1、torch.Tensor 是包的核心類。如果將其屬性?.requires_grad 設(shè)置為 True,則會(huì)開始跟蹤針對(duì) tensor的所有操作 2、可以調(diào)用 .backward() 來(lái)自動(dòng)計(jì)算所有梯度。該張量的梯度將累積到.grad 屬性中 3、要停止 tensor 歷史記錄的跟蹤,您可以調(diào)用 .detach(),它將其與計(jì)算歷史記錄分離,并防止將來(lái)的計(jì)算被跟蹤 4、要停止跟蹤歷史記錄(和使用內(nèi)存),您還可以將代碼塊使用 with?torch.no_grad(): 包裝起來(lái)。在評(píng)估模型時(shí),這是特別有用 5、還有一個(gè)類對(duì)于 autograd 實(shí)現(xiàn)非常重要那就是 Function。Tensor 和 Function 互相連接并構(gòu)建一個(gè)非循環(huán)圖,它保存整個(gè)完整的計(jì)算過程的歷史信息 6、每個(gè)張量都有一個(gè) .grad_fn 屬性保存著創(chuàng)建了張量的 Function 的引用 7、如果你想計(jì)算導(dǎo)數(shù),你可以調(diào)用 Tensor.backward()。如果 Tensor 是標(biāo)量(即它包含一個(gè)元素?cái)?shù)據(jù)),則不需要指定任何參數(shù)backward() 8、如果它有更多元素,則需要指定一個(gè)gradient?參數(shù)來(lái)指定張量的形狀 """ import torch #創(chuàng)建一個(gè)張量,設(shè)置requires_grad=True來(lái)跟蹤與它相關(guān)的計(jì)算 x=torch.ones(2,2,requires_grad=True) print(x)#針對(duì)向量做一個(gè)操作 y=x+2 print(y) #y作為操作的結(jié)果被創(chuàng)建,所以它有g(shù)rad_fn print(y.grad_fn)#針對(duì)y做更多的操作 z=y*y*3 out=z.mean() print(z,out)#.requires_grad_(...)會(huì)改變張量的requires_grad標(biāo)記。輸入的標(biāo)記默認(rèn)是False,如果沒有提供相應(yīng)的參數(shù) a=torch.randn(2,2) a=((a*3)/(a-1)) print(a.requires_grad) a.requires_grad_(True) print(a.requires_grad) b=(a*a).sum() print(b.grad_fn)#梯度 #現(xiàn)在向后傳播,因?yàn)檩敵霭粋€(gè)標(biāo)量,out.backward()等同于out.backward(torch.tensor(1.)) out.backward() #打印d(out)/dx print(x.grad)#看一個(gè)雅可比向量積的例子 x=torch.randn(3,requires_grad=True) y=x*2 while y.data.norm()<1000:#它對(duì)張量y中的每個(gè)元素進(jìn)行平方,然后對(duì)它們求和,最后取平方根.這些操作計(jì)算所謂的L2規(guī)范.y=y*2 print(y)""" 現(xiàn)在在這種情況下,y 不再是一個(gè)標(biāo)量。torch.autograd 不能夠直接計(jì)算整個(gè)雅可比,但是如果我 們只想要雅可比向量積,只需要簡(jiǎn)單的傳遞向量給 backward 作為參數(shù)。 """ v=torch.tensor([0.1,1.0,0.0001],dtype=torch.float) y.backward(v) print(x.grad)#可以通過將代碼包裹在with torch.no_grad(),來(lái)停止對(duì)從跟蹤歷史中的.requires_grad=True的張量自動(dòng)求導(dǎo) print(x.requires_grad) print((x**2).requires_grad)with torch.no_grad():print((x**2).requires_grad)3、神經(jīng)網(wǎng)絡(luò)
input為1通道32*32,卷積核為5*5,輸出6通道,另一個(gè)卷積為5*5,輸出16通道,兩個(gè)池化(下采樣)為2*2滑動(dòng)窗口,三個(gè)全連接層
卷積,激活,池化,卷積,激活,池化,全連接,激活,全連接,激活,全連接
import torch import torch.nn as nn import torch.nn.functional as F """ 現(xiàn)在對(duì)于自動(dòng)梯度(autograd)有一些了解,神經(jīng)網(wǎng)絡(luò)是基于自動(dòng)梯度 (autograd)來(lái)定義一些模型。 一個(gè)?nn.Module 包括層和一個(gè)方法?forward(input) 它會(huì)返回輸出(output)。 """ """ 一個(gè)典型的神經(jīng)網(wǎng)絡(luò)訓(xùn)練過程包括以下幾點(diǎn): 1.定義一個(gè)包含可訓(xùn)練參數(shù)的神經(jīng)網(wǎng)絡(luò) 2.迭代整個(gè)輸入 3.通過神經(jīng)網(wǎng)絡(luò)處理輸入 4.計(jì)算損失(loss) 5.反向傳播梯度到神經(jīng)網(wǎng)絡(luò)的參數(shù) 6.更新網(wǎng)絡(luò)的參數(shù),典型的用一個(gè)簡(jiǎn)單的更新方法:weight?=?weight?-?learning_rate?*gradient """ class Net(nn.Module):def __init__(self):super(Net,self).__init__()self.conv1=nn.Conv2d(1,6,5)#5*5的卷積核,1為輸入通道,6為輸出通道self.conv2=nn.Conv2d(6,16,5)self.fc1=nn.Linear(16*5*5,120)#全連接層self.fc2=nn.Linear(120,84)self.fc3=nn.Linear(84,10)def forward(self, x):x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))#池化,2*2的滑動(dòng)窗口,下采樣,為了降維x=F.max_pool2d(F.relu(self.conv2(x)),2)x=x.view(-1,self.num_flat_features(x))x=F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.fc3(x)return xdef num_flat_features(self,x):size=x.size()[1:]num_features=1for s in size:num_features*=sreturn num_featuresnet=Net() print(net) #一個(gè)模型可訓(xùn)練的參數(shù)可以通過調(diào)用 net.parameters() 返回 params = list(net.parameters()) print(len(params)) print(params[0].size()) # conv1's .weight#讓我們嘗試隨機(jī)生成一個(gè)?32x32 的輸入。注意:期望的輸入維度是?32x32 。為了使用這個(gè)網(wǎng)絡(luò)在MNIST 數(shù)據(jù)及上,你需要把數(shù)據(jù)集中的圖片維度修改為?32x32 input = torch.randn(1, 1, 32, 32) out = net(input) print(input,input.size()) print(out)#把所有參數(shù)梯度緩存器置零,用隨機(jī)的梯度來(lái)反向傳播 net.zero_grad() out.backward(torch.randn(1,10))#損失函數(shù) """ 一個(gè)損失函數(shù)需要一對(duì)輸入:模型輸出和目標(biāo),然后計(jì)算一個(gè)值來(lái)評(píng)估輸出距離目標(biāo)有多遠(yuǎn)。 有一些不同的損失函數(shù)在 nn 包中。一個(gè)簡(jiǎn)單的損失函數(shù)就是?nn.MSELoss ,這計(jì)算了均方誤差 """ output=net(input) target=torch.randn(10) target=target.view(1,-1)#和輸出保持相同的形狀 criterion=nn.MSELoss() loss=criterion(output,target) print(loss)""" 當(dāng)我們調(diào)用?loss.backward(),整個(gè)圖都會(huì)微分,而且所有的在圖中的requires_grad=True 的張量將會(huì)讓他們的?grad 張量累計(jì)梯度 """ print(loss.grad_fn) print(loss.grad_fn.next_functions[0][0])#Linear print(loss.grad_fn.next_functions[0][0].next_functions[0][0])#Relu#反向傳播 """ 為了實(shí)現(xiàn)反向傳播損失,我們所有需要做的事情僅僅是使用?loss.backward()。你需要清空現(xiàn)存的 梯度,要不然都將會(huì)和現(xiàn)存的梯度累計(jì)到一起。 現(xiàn)在我們調(diào)用?loss.backward() ,然后看一下 conv1 的偏置項(xiàng)在反向傳播之前和之后的變化 """ net.zero_grad()#所有的梯度清零 print('conv1.bias.grad before backward') print(net.conv1.bias.grad)loss.backward() print('conv1.bias.grad after backward') print(net.conv1.bias.grad)""" 現(xiàn)在我們看到了,如何使用損失函數(shù)。 唯一剩下的事情就是更新神經(jīng)網(wǎng)絡(luò)的參數(shù)。 更新神經(jīng)網(wǎng)絡(luò)參數(shù): 最簡(jiǎn)單的更新規(guī)則就是隨機(jī)梯度下降。 weight?=?weight?-?learning_rate?*?gradient """ learning_rate=0.01 for f in net.parameters():f.data.sub_(f.grad.data*learning_rate)""" 盡管如此,如果你是用神經(jīng)網(wǎng)絡(luò),你想使用不同的更新規(guī)則,類似于 SGD, Nesterov-SGD, Adam, RMSProp, 等。為了讓這可行,我們建立了一個(gè)小包:torch.optim 實(shí)現(xiàn)了所有的方法。使用它非常 的簡(jiǎn)單 """ #創(chuàng)建優(yōu)化器 optimizer=torch.optim.SGD(net.parameters(),lr=0.01) #訓(xùn)練區(qū)域 optimizer.zero_grad() output=net(input) loss=criterion(output,target) loss.backward() optimizer.step()#權(quán)值更新4、pytorch圖像分類器
數(shù)據(jù)集
""" 現(xiàn)在你也許會(huì)想應(yīng)該怎么處理數(shù)據(jù)? 通常來(lái)說,當(dāng)你處理圖像,文本,語(yǔ)音或者視頻數(shù)據(jù)時(shí),你可以使用標(biāo)準(zhǔn) python 包將數(shù)據(jù)加載成 numpy 數(shù)組格式,然后將這個(gè)數(shù)組轉(zhuǎn)換成 torch.*Tensor 對(duì)于圖像,可以用 Pillow,OpenCV 對(duì)于語(yǔ)音,可以用 scipy,librosa 對(duì)于文本,可以直接用 Python 或 Cython 基礎(chǔ)數(shù)據(jù)加載模塊,或者用 NL TK 和 SpaCy 特別是對(duì)于視覺,我們已經(jīng)創(chuàng)建了一個(gè)叫做 totchvision 的包,該包含有支持加載類似Imagenet, CIFAR10,MNIST 等公共數(shù)據(jù)集的數(shù)據(jù)加載模塊 torchvision.datasets 和支持加載圖像數(shù)據(jù)數(shù)據(jù)轉(zhuǎn) 換模塊 torch.utils.data.DataLoader。 這提供了極大的便利,并且避免了編寫“樣板代碼”。 對(duì)于本教程,我們將使用CIFAR10數(shù)據(jù)集,它包含十個(gè)類別:‘a(chǎn)irplane’, ‘a(chǎn)utomobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。CIFAR-10 中的圖像尺寸為3*32*32,也就是RGB的3層顏色 通道,每層通道內(nèi)的尺寸為32*32。 """""" 訓(xùn)練一個(gè)圖像分類器 我們將按次序的做如下幾步: 1、使用torchvision加載并且歸一化CIFAR10的訓(xùn)練和測(cè)試數(shù)據(jù)集 2、定義一個(gè)卷積神經(jīng)網(wǎng)絡(luò) 3、定義一個(gè)損失函數(shù) 4、在訓(xùn)練樣本數(shù)據(jù)上訓(xùn)練網(wǎng)絡(luò) 5、在測(cè)試樣本數(shù)據(jù)上測(cè)試網(wǎng)絡(luò) """ import torch import torchvision import torchvision.transforms as transformsimport matplotlib.pyplot as plt import numpy as npimport torch.nn as nn import torch.nn.functional as Fimport torch.optim as optim """ 加載并歸一化 CIFAR10 使用 torchvision ,用它來(lái)加載 CIFAR10 數(shù)據(jù)非常簡(jiǎn)單 torchvision 數(shù)據(jù)集的輸出是范圍在[0,1]之間的 PILImage,我們將他們轉(zhuǎn)換成歸一化范圍為[-1,1]之 間的張量 Tensors。 """ transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))]) trainset=torchvision.datasets.CIFAR10(root='data',train=True,download=True,transform=transform) trainloader=torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2) testset=torchvision.datasets.CIFAR10(root='data',train=False,download=True,transform=transform) testloader=torch.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=2) classes=('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')""" 定義一個(gè)卷積神經(jīng)網(wǎng)絡(luò) 在這之前先 從神經(jīng)網(wǎng)絡(luò)章節(jié) 復(fù)制神經(jīng)網(wǎng)絡(luò),并修改它為3通道的圖片(在此 之前它被定義為1通道) """class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1=nn.Conv2d(3,6,5)self.pool=nn.MaxPool2d(2,2)self.conv2=nn.Conv2d(6,16,5)self.fc1=nn.Linear(16*5*5,120)self.fc2=nn.Linear(120,84)self.fc3=nn.Linear(84,10)def forward(self, x):x=self.pool(F.relu(self.conv1(x)))x=self.pool(F.relu(self.conv2(x)))x=x.view(-1,16*5*5)x=F.relu(self.fc1(x))x=F.relu(self.fc2(x))x=self.fc3(x)return xnet=Net()""" 我們?cè)趺丛贕PU上跑這些神經(jīng)網(wǎng)絡(luò)? 在GPU上訓(xùn)練 就像你怎么把一個(gè)張量轉(zhuǎn)移到GPU上一樣,你要將神經(jīng)網(wǎng)絡(luò)轉(zhuǎn)到GPU上。 如果CUDA 可以用,讓我們首先定義下我們的設(shè)備為第一個(gè)可見的cuda設(shè)備。 """ device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print(device)""" 本節(jié)剩余部分都會(huì)假定設(shè)備就是臺(tái)CUDA設(shè)備。 接著這些方法會(huì)遞歸地遍歷所有模塊,并將它們的參數(shù)和緩沖器轉(zhuǎn)換為CUDA張量。 """ net.to(device)""" 定義一個(gè)損失函數(shù)和優(yōu)化器 讓我們使用分類交叉熵Cross-Entropy 作損失函數(shù),動(dòng)量SGD做優(yōu)化 器。 """criterion=nn.CrossEntropyLoss() optimizer=optim.SGD(net.parameters(),lr=0.001,momentum=0.9)""" 訓(xùn)練網(wǎng)絡(luò) 這里事情開始變得有趣,我們只需要在數(shù)據(jù)迭代器上循環(huán)傳給網(wǎng)絡(luò)和優(yōu)化器 輸入就可 以。 """ #--------------訓(xùn)練開始-------------- if __name__=='__main__':print('Start Training')for epoch in range(2):#對(duì)數(shù)據(jù)集進(jìn)行多次迭代running_loss=0.0#獲取索引列表for i,data in enumerate(trainloader,0):#enumerate is useful for obtaining an indexed list: (0, seq[0]), (1, seq[1]), (2, seq[2])#得到輸入inputs,labels=datainputs,labels=inputs.to(device),labels.to(device)#將輸入數(shù)據(jù)放到gpu上,如果放在cpu則刪掉這條語(yǔ)句#參數(shù)梯度清零optimizer.zero_grad()#前向+反向+梯度outputs=net(inputs)loss=criterion(outputs,labels)loss.backward()optimizer.step()#打印統(tǒng)計(jì)數(shù)據(jù)running_loss+=loss.item()if i%2000==1999:#每2000小批打印一次print('[%d,%5d] loss:%.3f'%(epoch+1,i+1,running_loss/2000))running_loss=0.0print('Finished Training') #----------------訓(xùn)練結(jié)束--------------------# 展示其中的一些訓(xùn)練圖片 def imshow(img):img = img / 2 + 0.5npimg = img.cpu().numpy()#這里把img放到了gpu上,如果使用img.numpy()會(huì)報(bào)錯(cuò),所以要把img.cpu()才不報(bào)錯(cuò)plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()if __name__ == '__main__':# 得到一些隨機(jī)的訓(xùn)練圖片dataiter = iter(trainloader)images, labels = dataiter.next()images,labels=images.to(device),labels.to(device)#將輸入數(shù)據(jù)放到gpu上,如果放在cpu則刪掉這條語(yǔ)句# 展示圖片imshow(torchvision.utils.make_grid(images))# 打印標(biāo)簽print(' '.join('%5s' % classes[labels[j]] for j in range(4)))"""在測(cè)試集上測(cè)試網(wǎng)絡(luò) 我們已經(jīng)通過訓(xùn)練數(shù)據(jù)集對(duì)網(wǎng)絡(luò)進(jìn)行了2次訓(xùn)練,但是我們需要檢查網(wǎng)絡(luò)是否已經(jīng)學(xué)到了東西。我們將用神經(jīng)網(wǎng)絡(luò)的輸出作為預(yù)測(cè)的類標(biāo)來(lái)檢查網(wǎng)絡(luò)的預(yù)測(cè)性能,用樣本的真實(shí)類標(biāo)來(lái)校對(duì)。如果預(yù)測(cè)是正確的,我們將樣本添加到正確預(yù)測(cè)的列表里"""outputs=net(images)print(outputs)"""輸出是預(yù)測(cè)與十個(gè)類的近似程度,與某一個(gè)類的近似程度越高,網(wǎng)絡(luò)就越認(rèn)為圖像是屬于這一類別。所以讓我們打印其中最相似類別類標(biāo)"""_,predicted=torch.max(outputs,1)print('Predicted:',' '.join('%5s' % classes[predicted[j]] for j in range(4)))#結(jié)果看起開非常好,讓我們看看網(wǎng)絡(luò)在整個(gè)數(shù)據(jù)集上的表現(xiàn)correct=0total=0with torch.no_grad():for data in testloader:images,labels=dataimages,labels=images.to(device),labels.to(device)#將輸入數(shù)據(jù)放到gpu上,如果放在cpu則刪掉這條語(yǔ)句outputs=net(images)_,predicted=torch.max(outputs.data,1)total+=labels.size(0)correct+=(predicted==labels).sum().item()print('Accuracy of the network on the 10000 test images:%d %%'%(100*correct/total))#這看起來(lái)比隨機(jī)預(yù)測(cè)要好,隨機(jī)預(yù)測(cè)的準(zhǔn)確率為10%(隨機(jī)預(yù)測(cè)出為10類中的哪一類)。看來(lái)網(wǎng)絡(luò)學(xué)到了東西class_correct=list(0.for i in range(10))class_total=list(0.for i in range(10))with torch.no_grad():for data in testloader:images,labels=dataimages,labels=images.to(device),labels.to(device)#將輸入數(shù)據(jù)放到gpu上,如果放在cpu則刪掉這條語(yǔ)句outputs=net(images)_,predicted=torch.max(outputs,1)c=(predicted==labels).squeeze()for i in range(4):label=labels[i]class_correct[label]+=c[i].item()class_total[label]+=1for i in range(10):print('Accuracy of %5s : %2d %%'%(classes[i],100*class_correct[i]/class_total[i]))5、數(shù)據(jù)并行處理
""" 在這個(gè)教程中,我們將學(xué)習(xí)如何用 DataParallel 來(lái)使用多 GPU。 通過 PyTorch 使用多個(gè) GPU 非常 簡(jiǎn)單。你可以將模型放在一個(gè) GPU: device = torch.device("cuda:0") model.to(device) 然后,你可以復(fù)制所有的張量到 GPU: mytensor = my_tensor.to(device) 請(qǐng)注意,只是調(diào)用 my_tensor.to(device) 返回一個(gè) my_tensor 新的復(fù)制在GPU上,而不是重寫 my_tensor。你需要分配給他一個(gè)新的張量并且在 GPU 上使用這個(gè)張量。 """""" 在多 GPU 中執(zhí)行前饋,后饋操作是非常自然的。盡管如此,PyTorch 默認(rèn)只會(huì)使用一個(gè) GPU。通 過使用 DataParallel 讓你的模型并行運(yùn)行,你可以很容易的在多 GPU 上運(yùn)行你的操作。 model = nn.DataParallel(model) """ import torch import torch.nn as nn from torch.utils.data import Dataset,DataLoader#參數(shù) input_size=5 output_size=2 batch_size=30 data_size=100device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")#生成一個(gè)實(shí)驗(yàn)數(shù)據(jù),只需要實(shí)現(xiàn)getitem class RandomDataset(Dataset):def __init__(self,size,length):self.len=lengthself.data=torch.randn(length,size)#100*5def __getitem__(self, index):return self.data[index]def __len__(self):return self.lenrand_loader=DataLoader(dataset=RandomDataset(input_size,data_size),batch_size=batch_size,shuffle=True)""" 簡(jiǎn)單模型 為了做一個(gè)小 demo,我們的模型只是獲得一個(gè)輸入,執(zhí)行一個(gè)線性操作,然后給一個(gè)輸出。盡管 如此,你可以使用?DataParallel? ?在任何模型(CNN, RNN, Capsule Net 等等.) 我們放置了一個(gè)輸出聲明在模型中來(lái)檢測(cè)輸出和輸入張量的大小。請(qǐng)注意在 batch rank 0 中的輸 出。 """ class Model(nn.Module):def __init__(self,input_size,output_size):super(Model, self).__init__()self.fc=nn.Linear(input_size,output_size)def forward(self, input):output=self.fc(input)print("\tIn Model:input size",input.size(),"output size",output.size())return output """ 創(chuàng)建模型并且數(shù)據(jù)并行處理 這是整個(gè)教程的核心。首先我們需要一個(gè)模型的實(shí)例,然后驗(yàn)證我們是否有多個(gè) GPU。如果我們 有多個(gè) GPU,我們可以用nn.DataParallel來(lái)包裹我們的模型。然后我們使用 model.to(device) 把模型放到多 GPU 中。 """ model=Model(input_size,output_size) if torch.cuda.device_count()>1:print("Let's use",torch.cuda.device_count(),"GPUs")model=nn.DataParallel(model)#放到多個(gè)GPU上 model.to(device)#運(yùn)行模型:現(xiàn)在我們可以看到輸入和輸出張量的大小 for data in rand_loader:input = data.to(device)output = model(input)print("Outside:input size", input.size(), "output_size", output.size())""" 總結(jié): 數(shù)據(jù)并行自動(dòng)拆分了你的數(shù)據(jù)并且將任務(wù)單發(fā)送到多個(gè) GPU 上。當(dāng)每一個(gè)模型都完成自己的任務(wù) 之后,DataParallel 收集并且合并這些結(jié)果,然后再返回給你。 """豬豬&&憨憨
總結(jié)
以上是生活随笔為你收集整理的第一学:pytorch入门60min的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: #ifndef的详细意思
- 下一篇: 18岁创业从哪入手?读透这5点则事半功倍