【CV】Pytorch一小时入门教程-代码详解
目錄
- 一、關鍵部分代碼分解
- 1.定義網絡
- 2.損失函數(代價函數)
- 3.更新權值
- 二、訓練完整的分類器
- 1.數據處理
- 2. 訓練模型(代碼詳解)
- CPU訓練
- GPU訓練
- CPU版本與GPU版本代碼區別
以下神經網絡構建均以上圖為例
一、關鍵部分代碼分解
1.定義網絡
import torch
import torch.nn as nn
import torch.nn.functional as F
# 注釋均為注釋下一行class Net(nn.Module):def __init__(self):super(Net, self).__init__()# 第一個卷積,輸入1通道,用6個5×5的卷積核self.conv1 = nn.Conv2d(1, 6, 5)# 第二個卷積,輸入6個通道(因為上一層卷積中用了6個卷積核),用16個5×5的卷積核self.conv2 = nn.Conv2d(6, 16, 5)# 第一個全連接層,輸入16個5×5的圖像(5×5是因為最開始輸入的是32×32的圖像,然后經過2個卷積2個池化變成了5×5),用全連接將其變為120個節點(一維化)self.fc1 = nn.Linear(16 * 5 * 5, 120)# 將120個節點變為84個self.fc2 = nn.Linear(120, 84)# 將84個節點變為10個self.fc3 = nn.Linear(84, 10)def forward(self, x):# conv1的結果先用ReLU激活,再以2×2的池化核做max pool池化x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# conv2的結果先用ReLU激活,再以2×2的池化核做max pool池化,(池化核為正方形的時候,寫2等于寫2×2)x = F.max_pool2d(F.relu(self.conv2(x)), 2)# 將高維向量轉為一維x = x.view(-1, self.num_flat_features(x))# 用ReLU激活fc1的結果x = F.relu(self.fc1(x))# 用ReLU激活fc2的結果x = F.relu(self.fc2(x))# 計算出fc3的結果x = self.fc3(x)return x# 返回總特征數量def num_flat_features(self, x):size = x.size()[1:] # all dimensions except the batch dimension# 計算總特征數量num_features = 1for s in size:num_features *= sreturn num_featuresnet = Net()
print(net)"""
Net((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))(fc1): Linear(in_features=400, out_features=120, bias=True)(fc2): Linear(in_features=120, out_features=84, bias=True)(fc3): Linear(in_features=84, out_features=10, bias=True)
)
"""params = list(net.parameters())
# 共有5層網絡,每層網絡包含一個weight(權重)和bias(偏差),所以一共有10個。并且在每一層中,weight保存在前面,bias保存在后面
print(len(params))
print(params[0].size()) # conv1's .weight
print(params[1].size()) # conv1's .bias
"""
10
torch.Size([6, 1, 5, 5])
torch.Size([6])
"""
# randn中4個參數分別表示batch_size=1, 1通道(即灰度圖像),圖片尺寸為32x32
input = torch.randn(1, 1, 32, 32)
out = net(input)
print(out)"""
tensor([[ 0.0114, 0.0476, -0.0647, 0.0381, 0.0088, -0.1024, -0.0354, 0.0220,-0.0471, 0.0586]], grad_fn=<AddmmBackward>)
"""#清空緩存
net.zero_grad()
out.backward(torch.randn(1, 10))
Pytorch(六)(模型參數的遍歷)——net.parameters() & net.named_parameters() & net.state_dict()
2.損失函數(代價函數)
"""
input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d-> view -> linear -> relu -> linear -> relu -> linear-> MSELoss-> loss
"""
output = net(input)
target = torch.randn(10) # a dummy target, for example
target = target.view(1, -1) # make it the same shape as output
criterion = nn.MSELoss()loss = criterion(output, target)
print(loss)print(loss.grad_fn) # MSELoss
print(loss.grad_fn.next_functions[0][0]) # Linear
print(loss.grad_fn.next_functions[0][0].next_functions[0][0]) # ReLU"""
<MseLossBackward object at 0x7efbcad51a58>
<AddmmBackward object at 0x7efbcad51b38>
<AccumulateGrad object at 0x7efbcad51b38>
"""# 反向傳播計算梯度(就是偏導數)
net.zero_grad() # zeroes the gradient buffers of all parametersprint('conv1.bias.grad before backward')
print(net.conv1.bias.grad)loss.backward()print('conv1.bias.grad after backward')
print(net.conv1.bias.grad)"""
conv1.bias.grad before backward
tensor([0., 0., 0., 0., 0., 0.])
conv1.bias.grad after backward
tensor([ 0.0087, -0.0073, 0.0013, 0.0006, -0.0107, -0.0042])
"""
3.更新權值
這里用隨機梯度下降(SGD),梯度下降中的偏導數值(即梯度)gradientgradientgradient已經在上一節中計算出,更新權值的公式為:weight=weight?learningrate?gradientweight=weight-learning rate*gradientweight=weight?learningrate?gradient,寫成代碼如下
# 梯度下降更新權值的代碼
learning_rate = 0.01
for f in net.parameters():f.data.sub_(f.grad.data * learning_rate)
在神經網絡中用下面的代碼
import torch.optim as optim# create your optimizer
optimizer = optim.SGD(net.parameters(), lr=0.01)# in your training loop:
optimizer.zero_grad() # zero the gradient buffers
output = net(input)
loss = criterion(output, target)
loss.backward()
optimizer.step() # Does the update
二、訓練完整的分類器
1.數據處理
當我們需要處理圖像、文本、音頻或者視頻的時候,可以使用標準的python庫來將這些數據轉化為numpy array,然后可以其再轉化為Tensor。下面列出一些相應的python庫:
- 圖片:Pillow、OpenCV
- 音頻:scipy、librosa
- 文本:原始的Python、Cython、NLTK、SpaCy
對于視覺領域,有torchvision,他可以將很多知名數據的數據集涵蓋在內。并且,通過torchvision.datasets和torch.utils.data.DataLoader進行數據的轉化。
在這里使用 CIFAR10 數據集,它有以下各類: ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。在這個數據集中的圖像尺寸都是32×32的。
2. 訓練模型(代碼詳解)
訓練步驟:
1.裝載數據,并將其標準化;
2.定義CNN;
3.定義損失函數;
4.訓練神經網絡;
5.測試網絡;
CPU訓練
import torch
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import torch.utils.data
import torch.nn as nn
import torch.nn.functional as F# 數據處理
transform = transforms.Compose([transforms.ToTensor(), # 轉換為tensor格式# 對圖像進行標準化,即讓數據集的圖像的均值變為0,標準差變為1,把圖片3個通道中的數據整理到[-1,1]的區間中# 輸入的參數第一個括號內是3個通道的均值,第二個是3個通道的標準差,這些數據需要自己算好再放進這個函數里,不然每次運行normalize函數都要遍歷一遍數據集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)
# 如果沒有import torch.utils.data,這里會出現Warning:Cannot find reference ‘data‘ in ‘__init__.py‘
# torch.utils.data.DataLoader用于將已有的數據讀取接口的輸入按照batch size封裝成Tensor
# shuffle參數表示是否在每個epoch后打亂數據;num_workers表示用多少個子進程加載數據,0表示數據將在主進程中加載,默認為0,這里不知道為啥設置多線程會報錯
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True)
# 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)
# 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')# 顯示圖片函數
def imshow(img):img = img / 2 + 0.5 # 逆歸一化,公式似乎是img/(均值*batchsize)+方差npimg = img.numpy()# plt.imshow()中應有的參數為(imagesize1,imagesize2,channels),在RGB圖像中,channels=3,imagesize1為行數,imagesize2為列數,即分別為圖片的高和寬# npimg中的參數順序為(channels,imagesize1,imagesize2)# np.transpose(0,2,1)表示將數據的第二維和第三維交換# 則np.transpose(npimg, (1, 2, 0))就能將npimg變成(imagesize1,imagesize2,channels)的參數順序,然后輸入plt.imshow()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()# get some random training images得到隨機的batchsize張圖片(隨機是因為之前定義trainloader的時候設置開啟了隨機)
# dataloader本質上是一個可迭代對象,可以使用iter()進行訪問,采用iter(dataloader)返回的是一個迭代器,然后可以使用next()或者enumerate訪問
dataiter = iter(trainloader)
# 訪問iter(dataloader)時,imgs在前,labels在后,分別表示:圖像轉換0~1之間的值,labels為標簽值(在這里labels就是圖像所屬的分類的標號)。并且imgs和labels是按批次進行輸入的。
# 因為之前設置了batch_size=4,所以這里的images中會有4張圖片
images, labels = dataiter.next()# show images
# torchvision.utils.make_grid()將多張圖片組合成一張圖片,padding為多張圖片之間的間隙
imshow(torchvision.utils.make_grid(images, padding=2))
# 按順序輸出四張圖片的標簽(所屬分類的名字)
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))# 定義網絡
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, (5, 5))self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, (5, 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()for epoch in range(2): # 多次循環訪問整個數據集(這里用了兩個epoch,即循環訪問2遍整個數據集)running_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputs 得到輸入的batchsize張圖片,放在inputs中,labels存儲該圖片所屬分類的名字inputs, labels = data# 計算交叉熵https://zhuanlan.zhihu.com/p/98785902criterion = nn.CrossEntropyLoss()# optim.SGD表示使用隨機梯度下降算法# lr是學習率;momentum是動量(在梯度下降算法中添加動量法)https://blog.csdn.net/weixin_40793406/article/details/84666803optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)# 歸零參數梯度optimizer.zero_grad()# forward + backward + optimize# 向神經網絡輸入數據,然后得到輸出outputsoutputs = net(inputs)# 輸入神經網絡輸出的預測和實際的數據的labels,計算交叉熵(偏差)loss = criterion(outputs, labels)# 將誤差反向傳播loss.backward()# 更新所有參數(權重)optimizer.step()# 累加經過這一個batchsize張圖片學習后的誤差# 《pytorch學習:loss為什么要加item()》https://blog.csdn.net/github_38148039/article/details/107144632running_loss += loss.item()if i % 2000 == 1999: # 每2000個mini-batches(即2000個batchsize次)打印一次,然后歸零running_lossprint('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')# 創建測試集的迭代器
dataiter = iter(testloader)
# 讀取測試集中的前四張圖片
images, labels = dataiter.next()# 顯示前面讀取出來的四張圖片和其所屬的分類的名字(label)
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))# 傳入神經網絡得到預測結果
outputs = net(images)# 輸入的第一個參數是softmax輸出的一個tensor,這里就是outputs所存儲的內容;第二個參數是max函數索引的維度,0是取每列的最大值,1是每行的最大值
# 返回的第一個參數是預測出的實際概率,由于我們不需要得知實際的概率,所以在返回的第一個參數填入_不讀取,第二個返回是概率的最大值的索引,存在predicted中
# 《torch.max()使用詳解》https://www.jianshu.com/p/3ed11362b54f
_, predicted = torch.max(outputs, 1)# 打印四張圖片預測的分類
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]for j in range(4)))# 計數器初始化置零
correct = 0
total = 0
# 計算總準確率
# 被該語句包裹起來的代碼將不會被跟蹤梯度,如果測試集進行的運算被跟蹤進度可能會導致顯存爆炸
with torch.no_grad():for data in testloader:# 讀取數據(batchsize個數據,這里為4張圖片)images, labels = data# 得到神經網絡的輸出outputs = net(images)# 返回每行概率最大值的索引_, predicted = torch.max(outputs.data, 1)# labels.size(0)指batchsize的值,這里batchsize=4total += labels.size(0)# predicted == labels對predicted和labels中的每一項判斷是否相等# (predicted == labels).sum()返回一個tensor,tensor中是判斷為真的數量,比如有一項是相同的,則返回tensor(1)# 如果有一項是相同的,(predicted == labels).sum().item()返回1# correct在這里即為4張圖片中預測正確的數量(這里計算的是總概率)correct += (predicted == labels).sum().item()# 輸出神經網絡在測試集上的準確率
print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))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:# 讀取數據(batchsize個數據,這里為4張圖片)images, labels = data# 得到神經網絡的輸出outputs = net(images)# 返回每行概率最大值的索引_, predicted = torch.max(outputs, 1)# squeeze()用于去除維數為1的維度,比如1行3列矩陣就會去掉行這個維度,變成第一維含有3個元素c = (predicted == labels).squeeze()for i in range(4):# label存儲當前圖像所屬分類的索引號label = labels[i]class_correct[label] += c[i].item()class_total[label] += 1
# 輸出神經網絡在測試集上的每個分類準確率
for i in range(10):print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))
GPU訓練
import torch
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import torch.utils.data
import torch.nn as nn
import torch.nn.functional as F# 數據處理
transform = transforms.Compose([transforms.ToTensor(), # 轉換為tensor格式# 對圖像進行標準化,即讓數據集的圖像的均值變為0,標準差變為1,把圖片3個通道中的數據整理到[-1,1]的區間中# 輸入的參數第一個括號內是3個通道的均值,第二個是3個通道的標準差,這些數據需要自己算好再放進這個函數里,不然每次運行normalize函數都要遍歷一遍數據集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)
# 如果沒有import torch.utils.data,這里會出現Warning:Cannot find reference ‘data‘ in ‘__init__.py‘
# torch.utils.data.DataLoader用于將已有的數據讀取接口的輸入按照batch size封裝成Tensor
# shuffle參數表示是否在每個epoch后打亂數據;num_workers表示用多少個子進程加載數據,0表示數據將在主進程中加載,默認為0,這里不知道為啥設置多線程會報錯
trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True)
# 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)
# 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')# 顯示圖片函數
def imshow(img):img = img / 2 + 0.5 # 逆歸一化,公式似乎是img/(均值*batchsize)+方差# numpy不能讀取CUDA tensor 需要將它轉化為 CPU tensornpimg = img.cpu().numpy()# plt.imshow()中應有的參數為(imagesize1,imagesize2,channels),在RGB圖像中,channels=3,imagesize1為行數,imagesize2為列數,即分別為圖片的高和寬# npimg中的參數順序為(channels,imagesize1,imagesize2)# np.transpose(0,2,1)表示將數據的第二維和第三維交換# 則np.transpose(npimg, (1, 2, 0))就能將npimg變成(imagesize1,imagesize2,channels)的參數順序,然后輸入plt.imshow()plt.imshow(np.transpose(npimg, (1, 2, 0)))plt.show()# get some random training images得到隨機的batchsize張圖片(隨機是因為之前定義trainloader的時候設置開啟了隨機)
# dataloader本質上是一個可迭代對象,可以使用iter()進行訪問,采用iter(dataloader)返回的是一個迭代器,然后可以使用next()或者enumerate訪問
dataiter = iter(trainloader)
# 訪問iter(dataloader)時,imgs在前,labels在后,分別表示:圖像轉換0~1之間的值,labels為標簽值(在這里labels就是圖像所屬的分類的標號)。并且imgs和labels是按批次進行輸入的。
# 因為之前設置了batch_size=4,所以這里的images中會有4張圖片
images, labels = dataiter.next()# show images
# torchvision.utils.make_grid()將多張圖片組合成一張圖片,padding為多張圖片之間的間隙
imshow(torchvision.utils.make_grid(images, padding=2))
# 按順序輸出四張圖片的標簽(所屬分類的名字)
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))# 定義網絡
class Net(nn.Module):def __init__(self):super(Net, self).__init__()self.conv1 = nn.Conv2d(3, 6, (5, 5))self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(6, 16, (5, 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()# 如果GPU(CUDA)可用,則用GPU,否則用CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 打印使用的是GPU/CPU
print(device)
# 將網絡放置到GPU
net.to(device)for epoch in range(2): # 多次循環訪問整個數據集(這里用了兩個epoch,即循環訪問2遍整個數據集)running_loss = 0.0for i, data in enumerate(trainloader, 0):# get the inputs 得到輸入的batchsize張圖片,放在inputs中,labels存儲該圖片所屬分類的名字inputs, labels = data# 將數據放置到GPU上inputs, labels = inputs.to(device), labels.to(device)# 計算交叉熵https://zhuanlan.zhihu.com/p/98785902criterion = nn.CrossEntropyLoss()# optim.SGD表示使用隨機梯度下降算法# lr是學習率;momentum是動量(在梯度下降算法中添加動量法)https://blog.csdn.net/weixin_40793406/article/details/84666803optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)# 歸零參數梯度optimizer.zero_grad()# forward + backward + optimize# 向神經網絡輸入數據,然后得到輸出outputsoutputs = net(inputs)# 輸入神經網絡輸出的預測和實際的數據的labels,計算交叉熵(偏差)loss = criterion(outputs, labels)# 將誤差反向傳播loss.backward()# 更新所有參數(權重)optimizer.step()# 累加經過這一個batchsize張圖片學習后的誤差# 《pytorch學習:loss為什么要加item()》https://blog.csdn.net/github_38148039/article/details/107144632running_loss += loss.item()if i % 2000 == 1999: # 每2000個mini-batches(即2000個batchsize次)打印一次,然后歸零running_lossprint('[%d, %5d] loss: %.3f' %(epoch + 1, i + 1, running_loss / 2000))running_loss = 0.0print('Finished Training')# 創建測試集的迭代器
dataiter = iter(testloader)
# 讀取測試集中的前四張圖片
images, labels = dataiter.next()
# 將數據放置到GPU上
images, labels = images.to(device), labels.to(device)# 顯示前面讀取出來的四張圖片和其所屬的分類的名字(label)
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ', ' '.join('%5s' % classes[labels[j]] for j in range(4)))# 傳入神經網絡得到預測結果
outputs = net(images)# 輸入的第一個參數是softmax輸出的一個tensor,這里就是outputs所存儲的內容;第二個參數是max函數索引的維度,0是取每列的最大值,1是每行的最大值
# 返回的第一個參數是預測出的實際概率,由于我們不需要得知實際的概率,所以在返回的第一個參數填入_不讀取,第二個返回是概率的最大值的索引,存在predicted中
# 《torch.max()使用詳解》https://www.jianshu.com/p/3ed11362b54f
_, predicted = torch.max(outputs, 1)# 打印四張圖片預測的分類
print('Predicted: ', ' '.join('%5s' % classes[predicted[j]]for j in range(4)))# 計數器初始化置零
correct = 0
total = 0
# 計算總準確率
# 被該語句包裹起來的代碼將不會被跟蹤梯度,如果測試集進行的運算被跟蹤進度可能會導致顯存爆炸
with torch.no_grad():for data in testloader:# 讀取數據(batchsize個數據,這里為4張圖片)images, labels = data# 將數據放置到GPU上images, labels = images.to(device), labels.to(device)# 得到神經網絡的輸出outputs = net(images)# 返回每行概率最大值的索引_, predicted = torch.max(outputs.data, 1)# labels.size(0)指batchsize的值,這里batchsize=4total += labels.size(0)# predicted == labels對predicted和labels中的每一項判斷是否相等# (predicted == labels).sum()返回一個tensor,tensor中是判斷為真的數量,比如有一項是相同的,則返回tensor(1)# 如果有一項是相同的,(predicted == labels).sum().item()返回1# correct在這里即為4張圖片中預測正確的數量(這里計算的是總概率)correct += (predicted == labels).sum().item()# 輸出神經網絡在測試集上的準確率
print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))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:# 讀取數據(batchsize個數據,這里為4張圖片)images, labels = data# 將數據放置到GPU上images, labels = images.to(device), labels.to(device)# 得到神經網絡的輸出outputs = net(images)# 返回每行概率最大值的索引_, predicted = torch.max(outputs, 1)# squeeze()用于去除維數為1的維度,比如1行3列矩陣就會去掉行這個維度,變成第一維含有3個元素c = (predicted == labels).squeeze()for i in range(4):# label存儲當前圖像所屬分類的索引號label = labels[i]class_correct[label] += c[i].item()class_total[label] += 1
# 輸出神經網絡在測試集上的每個分類準確率
for i in range(10):print('Accuracy of %5s : %2d %%' % (classes[i], 100 * class_correct[i] / class_total[i]))
CPU版本與GPU版本代碼區別
GPU版本相較于CPU版本的主要區別有:
- 第40行
npimg = img.cpu().numpy()
- 第86~91行
# 如果GPU(CUDA)可用,則用GPU,否則用CPU
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
# 打印使用的是GPU/CPU
print(device)
# 將網絡放置到GPU
net.to(device)
- 第101行
inputs, labels = inputs.to(device), labels.to(device)
- 第135行
images, labels = images.to(device), labels.to(device)
- 第163行
images, labels = images.to(device), labels.to(device)
- 第189行
images, labels = images.to(device), labels.to(device)
參考自以下文檔
pytorch一小時教程
pytorch基礎入門教程/一小時學會pytorch_CSDN
如若文中有誤,歡迎批評指正
總結
以上是生活随笔為你收集整理的【CV】Pytorch一小时入门教程-代码详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个性签名古风诗意
- 下一篇: 【CV】Pytorch一小时教程添加损失