天天看點

PyTorch之CIFAR10

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張用于測試,單獨構成一批。

PyTorch之CIFAR10

讀取資料,正規化處理

一些經典的資料集,如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)))
           

預覽結果

PyTorch之CIFAR10
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>)
           

繼續閱讀