PyTorch之CIFAR10
- 前言
- 背景
- 讀取資料,正規化處理
- 資料可視化
- 定義卷積神經網絡
- 設定損失函數和收斂準則
- 訓練資料
- 測試資料
- 儲存模型
- 調用本地模型預測
- 參考文獻
前言
其實一直想學深度學習,都2021年了,還不學點深度學習恐将被社會淘汰,新年伊始,難得有這麼好的一段時間,那就開始吧。本期内容以PyTorch官網60分鐘入門教程裡面的CIFAR10項目為藍本,動手實驗了一番加了一些自己的了解,很多都是依葫蘆畫瓢,從從本文你将要學到深度學習的整個流程
- 如何利用torchvision讀取datasets資料集并正規化處理
- 如何定義一個簡單的卷積神經網絡
- 如何定義損失函數
- 如何用定義好的網絡來訓練資料
- 如何在測試集上測試
- 如何把訓練好的模型儲存到本地
- 如何重新加載本地模型對新資料進行預測
背景
CIFAR10是kaggle計算機視覺競賽的一個圖像分類項目。該資料集共有60000張32*32彩色圖像,一共分為"plane", “car”, “bird”,“cat”, “deer”, “dog”, “frog”,“horse”,“ship”, “truck” 10類,每類6000張圖。有50000張用于訓練,構成了5個訓練批,每一批10000張圖;10000張用于測試,單獨構成一批。
讀取資料,正規化處理
一些經典的資料集,如Imagenet, CIFAR10, MNIST都可以通過torchvision來擷取,并且torchvision還提供了transforms類可以用來正規化處理資料。
import torch
import torchvision
import torchvision.transforms as transforms
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=0)
testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=True, num_workers=0)
classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')
資料可視化
主要是看一看CIFAR10裡面到底是一些什麼圖檔,利用matplotlib子產品進行可視化,此時需要将原來正規化的資料再還原回去,原正規化資料主要是用來模組化用。
import matplotlib.pyplot as plt
import numpy as np
def imshow(img): #繪圖,看一下CIFAR10裡面是什麼東西
img = img/2+0.5
npimg =img.numpy()
plt.imshow(np.transpose(npimg, (1,2,0)))
plt.show()
dataiter = iter(trainloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print(' '.join('%5s' % classes[labels[j]] for j in range(4)))
預覽結果
Files already downloaded and verified
Files already downloaded and verified
horse plane deer cat
定義卷積神經網絡
神經網絡是深度學習最核心的東西,直接關系到最後結果的好壞,本次依葫蘆畫瓢利用nn類搭建一個4層的卷積網絡。
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module): #繼承的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 x
net = Net() #網絡執行個體化
設定損失函數和收斂準則
需要告訴網絡什麼時候訓練結束,以什麼标準結束,這就是損失函數和收斂準則要做的事情了。
import torch.optim as optim
optimizer = optim.SGD(net.parameters(), lr = 0.001, momentum = 0.9)
criterion = nn.CrossEntropyLoss()
訓練資料
當一切準備工作就緒,就該利用設計好的網絡來對資料進行訓練了
for epoch in range(2):
running_loss =0.0
for i, data in enumerate(trainloader, 0):
inputs, labels = data
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss+=loss.item()
if i% 2000 ==1999:
print("[%d, %5d] loss: %.3f" %(epoch +1, i+1, running_loss/2000))
running_loss = 0.0
print("Finished Training")
測試資料
訓練的模型好不好,隻有經過測試集測試才知道,需要看模型在測試集上面的表現,可以看總體的準确率如何,還可以進一步看每一類的準确率如何。
correct = 0
total =0
with torch.no_grad():
for data in testloader:
images, labels = data
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))
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 = data
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] += 1
for i in range(10):
print('Accuracy of %5s : %2d %%' % (
classes[i], 100 * class_correct[i] / class_total[i]))
輸出預覽
[1, 2000] loss: 2.198
[1, 4000] loss: 1.867
[1, 6000] loss: 1.669
[1, 8000] loss: 1.616
[1, 10000] loss: 1.522
[1, 12000] loss: 1.468
[2, 2000] loss: 1.403
[2, 4000] loss: 1.372
[2, 6000] loss: 1.352
[2, 8000] loss: 1.319
[2, 10000] loss: 1.294
[2, 12000] loss: 1.279
Finished Training
Accuracy of the network on the 10000 test images: 54 %
Accuracy of plane : 54 %
Accuracy of car : 52 %
Accuracy of bird : 45 %
Accuracy of cat : 28 %
Accuracy of deer : 46 %
Accuracy of dog : 56 %
Accuracy of frog : 76 %
Accuracy of horse : 52 %
Accuracy of ship : 82 %
Accuracy of truck : 49 %
儲存模型
當建立的模型通過測試集的考驗後效果還不如就可以儲存到本地,友善以後調用進行新資料的預測
PATH = './cifar_net.pth'
torch.save(net.state_dict(), PATH)
dataiter = iter(testloader)
images, labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print("GroundTruth: ", ' '.join('%5s' % classes[labels[j]] for j in range(4)))
net = Net()
net.load_state_dict(torch.load(PATH)) #加載本地模型
outputs = net(images)
print("預測結果為:", outputs)
GroundTruth: ship horse truck frog
預測結果為: tensor([[ 2.0409, -0.8202, 0.0126, -0.6842, -0.2968, -1.4297, -1.3475, -1.5291,
4.3588, 0.0891],
[ 1.7326, -1.1041, 0.4564, 0.4059, 0.9898, 0.2735, -2.0580, 1.5040,
-1.3614, -0.7261],
[ 0.4500, -1.0179, -0.0407, 0.9089, -1.9806, -0.1816, -2.4195, 0.8440,
-0.6270, 3.5349],
[-3.5797, -2.8045, 1.2739, 2.7250, -0.4925, 2.6202, 3.9928, -0.9895,
-3.2739, -0.8431]], grad_fn=<AddmmBackward>)