pytorch文檔筆記4-訓練分類器

 

"""c++

    分類器:網絡

    @在神經網絡一節中,輸入數據都是隨機數據,這裏換爲真實的數據進行一個簡單的訓練;通常數據分爲圖像、文本、音視頻等。dom

    對於圖像,Pillow,OpenCV等軟件包頗有用函數

    對於音頻,請使用scipy和librosa等軟件包工具

    對於文本,基於Python或Cython的原始加載,或者NLTK和SpaCy頗有用測試

 

    @通常在c++中咱們會使用opencv進行圖像加載,至於加載的函數如loadimage或者imread都是由opencv提供的,在pytorch中也封裝了相似的優化

    包,在torchvision中。這個包基本上有最多見的數據加載器;其中最多見的數據加載器包括:spa

        torchvision.datasets和torch.utils.data.DataLoader;orm

    

    @訓練圖像分類器常見步驟以下:視頻

    使用如下命令加載和標準化CIFAR10訓練和測試數據集 torchvision

    定義卷積神經網絡

    定義損失函數

    根據訓練數據訓練網絡

    在測試數據上測試網絡

"""

 

import torch

#包含了目前流行的數據集,模型結構和經常使用的圖片轉換工具

import torchvision

"""

transforms有如下幾個主要功能:

    Compose 組合多個功能步驟爲一個步驟;

    CenterCrop 進行中心切割

    RandomCrop 進行隨機切割

    RandomHorizontalFlip 隨機水平翻轉

    RandomSizedCrop 隨機剪切及重設大小

    Pad 填充

    Normalize 正規化

    ToTensor 轉換爲pytorch支持的Tensor

    ToPILImage 轉換爲PIL圖像

    Lambda 使用lambd轉換器

"""

import torchvision.transforms as transforms # 主要用於圖像一些基本變換以及一些簡單格式封裝

 

"""

把一個取值範圍是[0,255]的PIL.Image或者shape爲(H,W,C)的numpy.ndarray,轉換成形狀爲[C,H,W],取值範圍是[0,1.0]的torch.FloadTensor;

給定均值:(R,G,B) 方差:(R,G,B),將會把Tensor正則化。即:Normalized_image=(image-mean)/std;

方差反應數據的偏離程度,標準差主要是利於咱們肉眼查看。

"""

transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])

 

# train爲True表示訓練集,爲False表示測試集;download表示是否從互聯網進行下載,transforms表示預處理方式,

# 主要目的是將這些如PIL形式數據轉成pytorch支持的;

trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=False,transform=transform)

 

#shuffle表示是否須要打亂數據。

trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=0)

testset = torchvision.datasets.CIFAR10(root='./data',train=False,download=False,transform=transform)

testloader = torch.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=0)

 

classes=('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')

import matplotlib.pyplot as plt 

import numpy as np

def imshow(img):

    img = img/2+0.5

    npimg = img.numpy()

    plt.imshow(np.transpose(npimg,(1,2,0)))#進行軸對換

    plt.show()

 

dataiter = iter(trainloader)#執行到此步驟失敗,須要將以前的num_workers改成0

images,labels = dataiter.next()#這裏注意指向的是第一個元素並不是下一個元素

imshow(torchvision.utils.make_grid(images))#網格顯示

print(' '.join('%5s'%classes[labels[j]] for j in range(4)))

 

#定義卷積神經網絡

import torch.nn as nn

import torch.nn.functional as F


 

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 x


 

net = Net()

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

print(device)

net.to(device)

#定義損失函數和優化器

import torch.optim as optim

criterion = nn.CrossEntropyLoss()

optimizer = optim.SGD(net.parameters(),lr=0.001, momentum=0.9)

 

#訓練網絡

for epoch in range(2):

    running_loss = 0.0

    for i ,data in enumerate(trainloader,0):# 0表明下標起始位置

        #inputs,labels = data #使用CPU

        inputs, labels = data[0].to(device), data[1].to(device)#  使用GPU

        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('trainning finished')

 

#測試網絡

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)))

 

outputs = net(images)

_,predicted = torch.max(outputs,1)#1表明返回最大元素在這一行的列索引

 

#整個數據集表現

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('正確率:%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('%5s正確率:%2d %% '%(classes[i],100*class_correct[i]/class_total[i]))

相關文章
相關標籤/搜索