欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PyTorch簡(jiǎn)單手寫(xiě)數(shù)字識(shí)別的實(shí)現(xiàn)過(guò)程

 更新時(shí)間:2021年11月21日 09:27:43   作者:回家種蜜柚  
Pytorch是熱門(mén)的深度學(xué)習(xí)框架之一,通過(guò)經(jīng)典的MNIST數(shù)據(jù)集進(jìn)行快速的pytorch入門(mén),這篇文章主要給大家介紹了關(guān)于PyTorch簡(jiǎn)單手寫(xiě)數(shù)字識(shí)別的相關(guān)資料,需要的朋友可以參考下

具體流程:

① 導(dǎo)入相應(yīng)的包,下載訓(xùn)練集和測(cè)試集對(duì)應(yīng)需要的圖像數(shù)據(jù)。
②進(jìn)行圖像數(shù)據(jù)的變換,使圖像數(shù)據(jù)轉(zhuǎn)化成pytorch可識(shí)別并計(jì)算的張量數(shù)據(jù)類(lèi)型
③數(shù)據(jù)預(yù)覽測(cè)試和數(shù)據(jù)裝載
④模型搭建和參數(shù)優(yōu)化
⑤總代碼
⑥測(cè)試

一、包導(dǎo)入及所需數(shù)據(jù)的下載

torchvision包的主要功能是實(shí)現(xiàn)數(shù)據(jù)的處理、導(dǎo)入、預(yù)覽等,所以如果需要對(duì)計(jì)算機(jī)視覺(jué)的相關(guān)問(wèn)題進(jìn)行處理,就可以借用在torchvision包中提供的大量的類(lèi)來(lái)完成相應(yīng)的工作。

代碼的開(kāi)始部分有這兩個(gè):

import torch
from torchvision import datasets, transforms  # torchvision包的主要功能是實(shí)現(xiàn)數(shù)據(jù)的處理、導(dǎo)入和預(yù)覽等

torchvision.datasets:實(shí)現(xiàn)對(duì)數(shù)據(jù)集的訓(xùn)練集和測(cè)試集的下載,只需使用torchvision再加上需要下載的數(shù)據(jù)集的名稱(chēng)就可以了,比如本例的MNIST

下載數(shù)據(jù)集的代碼如下:

data_train = datasets.MNIST(
    transform=transform,
    root="./data/",
    train=True,
    download=True
)
data_test = datasets.MNIST(
    root="./data/",
    transform=transform,
    train=True,
    download=False
)

①root用于指定數(shù)據(jù)集在下載之后的存放路徑,這里存放在根目錄下的data文件夾

②transform用于指定導(dǎo)入數(shù)據(jù)集是需要對(duì)數(shù)據(jù)進(jìn)行哪種變換操作

train用于指定數(shù)據(jù)集下載完成后需要載入哪部分?jǐn)?shù)據(jù)(如果設(shè)置為T(mén)rue,則說(shuō)明載入的是該數(shù)據(jù)集的訓(xùn)練集部分;如果設(shè)置為False,則說(shuō)明載入的是該數(shù)據(jù)集的測(cè)試集部分)

關(guān)于數(shù)據(jù)集引入的改動(dòng)

此處我對(duì)此進(jìn)行了稍微地小改動(dòng),因?yàn)檎麄€(gè)導(dǎo)入下載的數(shù)據(jù)集大約有6萬(wàn)張圖片,這是一個(gè)極大的數(shù)據(jù)量,一臺(tái)配置正常的電腦程序運(yùn)行的時(shí)間需求將會(huì)是巨大的,我當(dāng)時(shí)大約跑了一上午(一臺(tái)正常配置的學(xué)生電腦),所以此處我將6萬(wàn)張數(shù)據(jù)集的訓(xùn)練集和測(cè)試集都只截取了前1000張用作訓(xùn)練和測(cè)試,雖然說(shuō)精度會(huì)降低,使得偏差較大,但是也足夠用了,在時(shí)間上會(huì)有極大的節(jié)省,代碼如下:

from torch.utils.data import random_split

data_train, _ = random_split(
    dataset=data_train,
    lengths=[1000, 59000],
    generator=torch.Generator().manual_seed(0)
)
data_test, _ = random_split(
    dataset=data_test,
    lengths=[1000, 59000],
    generator=torch.Generator().manual_seed(0)
)

我調(diào)用torch.utils.data import random_split函數(shù)對(duì)數(shù)據(jù)集進(jìn)行了切割,使得數(shù)據(jù)量減少,提升了運(yùn)行速率。

二、進(jìn)行數(shù)據(jù)處理變換操作

在torch.transforms中提供了豐富的類(lèi)對(duì)載入的數(shù)據(jù)進(jìn)行變換。我們知道,在計(jì)算機(jī)視覺(jué)中處理的數(shù)據(jù)集有很大一部分是圖片類(lèi)型的,而在PyTorch中實(shí)際進(jìn)行計(jì)算的是Tensor數(shù)據(jù)類(lèi)型的變量,所以我們首先需要解決的是數(shù)據(jù)類(lèi)型轉(zhuǎn)換的問(wèn)題
對(duì)數(shù)據(jù)進(jìn)行載入及有相應(yīng)變化的代碼如下:

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

我們可以將以上代碼中的torchvision.transforms.Compose類(lèi)看成一種容器,它能夠同時(shí)對(duì)多種數(shù)據(jù)變換進(jìn)行組合。傳入的參數(shù)是一個(gè)列表,列表中的元素就開(kāi)始對(duì)載入的數(shù)據(jù)進(jìn)行各種變換操作。例如本例:

①轉(zhuǎn)化數(shù)據(jù)類(lèi)型為T(mén)ensor(張量)
②對(duì)均值(mean)和標(biāo)準(zhǔn)差(std)均為0.5的原始數(shù)據(jù)進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化變化

三、數(shù)據(jù)預(yù)覽測(cè)試和數(shù)據(jù)裝載

數(shù)據(jù)下載完成并載入之后,我們還需對(duì)數(shù)據(jù)進(jìn)行裝載。

我們可以將數(shù)據(jù)的載入理解為對(duì)圖片的處理,在處理完成后,我們就需要將這些圖片打包好送給我們的模型進(jìn)行訓(xùn)練了,而裝載就是這個(gè)打包的過(guò)程

代碼片如下:

data_loader_train = torch.utils.data.DataLoader(dataset=data_train,
                                                batch_size=4,
                                                shuffle=True)

data_loader_test = torch.utils.data.DataLoader(dataset=data_test,
                                               batch_size=4,
                                               shuffle=True)

對(duì)數(shù)據(jù)的裝載使用的是torch.utils.data.DataLoader類(lèi),類(lèi)中的參數(shù):

①batch_size參數(shù)設(shè)置了每個(gè)包中的圖片數(shù)據(jù)個(gè)數(shù),代碼中的值是4(此處如果電腦配置不是很高或者想讓程序跑的快一點(diǎn)的話可以稍微調(diào)低,原本為64,此處我將其調(diào)為4
②dataset參數(shù)用于指定我們載入的數(shù)據(jù)集的名稱(chēng)。 ③將shuffle參數(shù)設(shè)置為T(mén)rue,在裝載的過(guò)程中會(huì)將數(shù)據(jù)隨機(jī)打亂順序并進(jìn)行打包。

在裝載完成后,我們可以選取其中一個(gè)批次的數(shù)據(jù)進(jìn)行預(yù)覽。進(jìn)行數(shù)據(jù)預(yù)覽的代碼如下:

images, labels = next(iter(data_loader_train))

img = torchvision.utils.make_grid(images)
img = img.numpy().transpose(1, 2, 0)

std = [0.5]
mean = [0.5]
img = img * std + mean

print([labels[i] for i in range(4)])
plt.imshow(img)
plt.show()

在以上代碼中使用了iternext來(lái)獲取一個(gè)批次的圖片數(shù)據(jù)(images)和其對(duì)應(yīng)的圖片標(biāo)簽(abels)

然后使用torchvision.utils中的make_grid類(lèi)方法將一個(gè)批次的圖片構(gòu)造成網(wǎng)格模式。

需要傳遞給torchvision.utils.make_grid的參數(shù)就是一個(gè)批次的裝載數(shù)據(jù),每個(gè)批次的裝載數(shù)據(jù)都是4維的,維度的構(gòu)成從前往后分別為batch_size、channel、height、weight,分別對(duì)應(yīng)一個(gè)批次中的數(shù)據(jù)個(gè)數(shù)、每張圖片的色彩通道數(shù)、每張圖片的高度和寬度。

在通過(guò)torchvision.utils.make_grid之后,圖片的維度就變成了(channel,height,weight),這個(gè)批次的圖片全部被整合到了一起,所以在這個(gè)維度中對(duì)應(yīng)的值也和之前不一樣了,但是色彩通道數(shù)保持不變。

若我們想使用Matplotlib將數(shù)據(jù)顯示成正常的圖片形式,則使用的數(shù)據(jù)首先必須是數(shù)組,其次這個(gè)數(shù)組的維度必須是(height、weight、channel),即色彩通道數(shù)在最后面。

所以我們要通過(guò)numpytranspose完成原始數(shù)據(jù)類(lèi)型的轉(zhuǎn)換和數(shù)據(jù)維度的交換,這樣才能夠使用Matplotlib繪制出正確的圖像。

在完成數(shù)據(jù)預(yù)覽的代碼中,我們先打印輸出了這個(gè)批次中的數(shù)據(jù)的全部標(biāo)簽,然后才對(duì)這個(gè)批次中的所有圖片數(shù)據(jù)進(jìn)行顯示。結(jié)果如下:

在這里插入圖片描述

效果圖如下,可以看到,打印輸出的首先是4張圖片對(duì)應(yīng)的標(biāo)簽,然后是4張圖片的預(yù)覽效果

在這里插入圖片描述

plt.show()的話如果是使用PyCham編譯的話一定要加上去,不然會(huì)出現(xiàn)顯示不出圖像的情況


plt.show()

四、模型搭建和參數(shù)優(yōu)化

在順利完成數(shù)據(jù)裝載之后,我們就可以開(kāi)始編寫(xiě)卷積神經(jīng)網(wǎng)絡(luò)的搭建和參數(shù)優(yōu)化的代碼了。

卷積層使用torch.nn.Conv2d類(lèi)方法來(lái)搭建;
激活層使用torch.nn.ReLU()類(lèi)方法來(lái)搭建;
池化層使用torch.nn.MaxPool2d類(lèi)方法來(lái)搭建;
全連接層使用torch.nn.Linear類(lèi)方法來(lái)搭建

實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)模型搭建的代碼如下

class Model(torch.nn.Module):

    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
            torch.nn.ReLU(),
            torch.nn.MaxPool2d(stride=2, kernel_size=2)
        )

        self.dense = torch.nn.Sequential(
            torch.nn.Linear(14 * 14 * 128, 1024),
            torch.nn.ReLU(),
            torch.nn.Dropout(p=0.5),
            torch.nn.Linear(1024, 10)
        )

    def forward(self, x):
        x = self.conv1(x)  # 卷積處理
        x = x.view(-1, 14*14*128)  # 對(duì)參數(shù)實(shí)行扁平化處理
        x = self.dense(x)
        return x

我們選擇搭建一個(gè)在結(jié)構(gòu)層次上有所簡(jiǎn)化的卷積神經(jīng)網(wǎng)絡(luò)模型,在結(jié)構(gòu)上使用了兩個(gè)卷積層:一個(gè)最大池化層和兩個(gè)全連接層

torch.nn.Conv2d():用于搭建卷積神經(jīng)網(wǎng)絡(luò)的卷積層,主要的輸入?yún)?shù)有輸入通道數(shù)、輸出通道數(shù)、卷積核大小、卷積核移動(dòng)步長(zhǎng)和Padding值。其中,
輸入通道數(shù)的數(shù)據(jù)類(lèi)型是整型,用于確定輸入數(shù)據(jù)的層數(shù);
輸出通道數(shù)的數(shù)據(jù)類(lèi)型也是整型,用于確定輸出數(shù)據(jù)的層數(shù);
卷積核大小的數(shù)據(jù)類(lèi)型是整型,用于確定卷積核的大??;
卷積核移動(dòng)步長(zhǎng)的數(shù)據(jù)類(lèi)型是整型,用于確定卷積核每次滑動(dòng)的步長(zhǎng);
Paddingde的數(shù)據(jù)類(lèi)型是整型,值為0時(shí)代表不進(jìn)行邊界像素的填充,如果值大于0,那么增加數(shù)字所對(duì)應(yīng)的邊界像素層數(shù)。

torch.nn.MaxPool2d():用于實(shí)現(xiàn)卷積神經(jīng)網(wǎng)絡(luò)中的最大池化層,主要的輸入?yún)?shù)時(shí)池化窗口的大小、池化窗口移動(dòng)步長(zhǎng)和Paddingde值。
同樣:
池化窗口大小的數(shù)據(jù)類(lèi)型是整型,用于確定池化窗口的大小。
池化窗口步長(zhǎng)的數(shù)據(jù)類(lèi)型也是整型,用于確定池化窗口每次移動(dòng)的步長(zhǎng)。
Paddingde值和在torch.nn.Conv2d中定義的Paddingde值的用法和意義時(shí)一樣的。

torch.nn.Dropout():torch.nn.Dropout類(lèi)用于防止卷積神經(jīng)網(wǎng)絡(luò)在訓(xùn)練的過(guò)程中發(fā)生過(guò)擬合,其工作原理簡(jiǎn)單來(lái)說(shuō)就是在模型訓(xùn)練的過(guò)程中,以一定的隨機(jī)概率將卷積神經(jīng)網(wǎng)絡(luò)模型的部分參數(shù)歸零,以達(dá)到減少相鄰兩層神經(jīng)連接的目的。

代碼前向傳播forward函數(shù)中的內(nèi)容:

首先,經(jīng)過(guò)self.conv1進(jìn)行卷積處理;然后進(jìn)行x.view(-1 ,14 * 14 *128),對(duì)參數(shù)實(shí)現(xiàn)扁平化因?yàn)橹缶o挨著就是全連接層,所以如果不進(jìn)行扁平化處理,則全連接層的實(shí)際輸出的參數(shù)維度和其定義輸入的維度將不匹配,程序會(huì)報(bào)錯(cuò);最后,通過(guò)self.dense定義的全連接進(jìn)行最后的分類(lèi)。

在編輯完搭建卷積神經(jīng)網(wǎng)絡(luò)模型的代碼之后,我們就可以開(kāi)始對(duì)模型進(jìn)行訓(xùn)練和對(duì)參數(shù)進(jìn)行優(yōu)化了。首先,定義在訓(xùn)練之前使用哪種損失函數(shù)和優(yōu)化函數(shù):

model = Model()
cost = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())
# 損失函數(shù): 交叉熵
# 優(yōu)化函數(shù): Adam自適應(yīng)優(yōu)化算法,需要優(yōu)化的參數(shù)實(shí)在Model中生成的全部參數(shù),
#因?yàn)闆](méi)有定義學(xué)習(xí)速率的值,所以使用默認(rèn)值

最后,卷積神經(jīng)網(wǎng)絡(luò)模型進(jìn)行模型訓(xùn)練和參數(shù)優(yōu)化的代碼如下:

epochs_n = 5
for epoch in range(epochs_n):
    running_loss = 0.0
    running_correct = 0
    print("Epoch{}/{}".format(epoch, epochs_n))
    print("-" * 10)
    for data in data_loader_train:
        X_train, y_train = data
        X_train, y_train = Variable(X_train), Variable(y_train)
        outputs = model(X_train)
        _,pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)

        loss.backward()
        optimizer.step()
        running_loss += loss.data
        running_correct += torch.sum(pred == y_train.data)
    testing_correct = 0
    for data in data_loader_test:
        X_test, y_test = data
        X_test, y_test = Variable(X_test), Variable(y_test)
        outputs = model(X_test)
        _, pred = torch.max(outputs.data, 1)
        testing_correct += torch.sum(pred == y_test.data)
        print("Loss is:{:.4f},Train Accuracy is:{:.4f}%, Test Accuracy is:{:.4f}".format(running_loss / len(data_train),100 * running_correct / len(data_train),100 * testing_correct / len(data_test)))

關(guān)于模型搭建的改動(dòng)

在此處我對(duì)上面模型進(jìn)行了優(yōu)化改動(dòng),大大優(yōu)化了運(yùn)行的時(shí)間,但是對(duì)應(yīng)也減少了一些訓(xùn)練精度。

原理就是,卷積層的運(yùn)算量不會(huì)太大,但全連接層的運(yùn)算量比較大,所以降低全連接的參數(shù)量,以及降低圖像特征圖的尺寸

class Model(torch.nn.Module):

    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 64, kernel_size=3, stride=2, padding=1),
            torch.nn.ReLU(),
            torch.nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),
            torch.nn.ReLU(),
            # torch.nn.MaxPool2d(stride=2, kernel_size=2)
        )

        self.dense = torch.nn.Sequential(
            # torch.nn.Linear(14 * 14 * 128, 1024),
            torch.nn.Linear(7 * 7 * 128, 512),
            torch.nn.ReLU(),
            # torch.nn.Dropout(p=0.5),
            torch.nn.Dropout(p=0.8),
            torch.nn.Linear(512, 10)
        )

    def forward(self, x):
        x = self.conv1(x)  # 卷積處理
        # x = x.view(-1, 14*14*128)  # 對(duì)參數(shù)實(shí)行扁平化處理
        x = x.view(-1, 7*7*128)  # 對(duì)參數(shù)實(shí)行扁平化處理
        x = self.dense(x)
        return x

為了驗(yàn)證我們訓(xùn)練的模型是不是真的已如結(jié)果顯示的一樣準(zhǔn)確,則最好的方法就是隨機(jī)選取一部分測(cè)試集中的圖片,用訓(xùn)練好的模型進(jìn)行預(yù)測(cè),看看和真實(shí)值有多大偏差,并對(duì)結(jié)果進(jìn)行可視化,測(cè)試的代碼如下:

X_test, y_test = next(iter(data_loader_test))
inputs = Variable(X_test)
pred = model(inputs)
_, pred = torch.max(pred,1)

print("Predict Label is:", [i for i in pred.data])
print("Real Label is:", [i for i in y_test])

img = torchvision.utils.make_grid(X_test)
img = img.numpy().transpose(1,2,0)

std = [0.5, 0.5, 0.5]
mean = [0.5, 0.5, 0.5]

img = img*std+mean
plt.imshow(img)
plt.show()

記得末尾一定加上plt.show()

用于測(cè)試的數(shù)據(jù)標(biāo)簽結(jié)果輸出如下:

在這里插入圖片描述

在這里插入圖片描述

在輸出結(jié)果中

第1個(gè)結(jié)果是我們訓(xùn)練好的模型的預(yù)測(cè)值,第2個(gè)結(jié)果是這4個(gè)測(cè)試數(shù)據(jù)的真實(shí)值。

對(duì)測(cè)試數(shù)據(jù)進(jìn)行可視化,如下圖所示:

在這里插入圖片描述

可以看到,在上圖可視化的這部分測(cè)試集圖片,模型的預(yù)測(cè)結(jié)果和真實(shí)結(jié)果是完全一致的。當(dāng)然如果想選取更多的測(cè)試集進(jìn)行可視化,則只需將batch_size設(shè)置的更大,但考慮對(duì)應(yīng)程序的運(yùn)行速度將會(huì)略微降低

總代碼:

import torch
import numpy
import torchvision
import matplotlib.pyplot as plt

from torchvision import datasets, transforms  # torchvision包的主要功能是實(shí)現(xiàn)數(shù)據(jù)的處理、導(dǎo)入和預(yù)覽等
from torch.autograd import Variable

transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=[0.5], std=[0.5])])
data_train = datasets.MNIST(
    transform=transform,
    root="./data/",
    train=True,
    download=True
)
data_test = datasets.MNIST(
    root="./data/",
    transform=transform,
    train=True,
    download=False
)

from torch.utils.data import random_split

data_train, _ = random_split(
    dataset=data_train,
    lengths=[1000, 59000],
    generator=torch.Generator().manual_seed(0)
)
data_test, _ = random_split(
    dataset=data_test,
    lengths=[1000, 59000],
    generator=torch.Generator().manual_seed(0)
)

data_loader_train = torch.utils.data.DataLoader(dataset=data_train,
                                                batch_size=4,
                                                shuffle=True)

data_loader_test = torch.utils.data.DataLoader(dataset=data_test,
                                               batch_size=4,
                                               shuffle=True)


# images, labels = next(iter(data_loader_train))
#
# img = torchvision.utils.make_grid(images)
# img = img.numpy().transpose(1, 2, 0)
#
# std = [0.5]
# mean = [0.5]
# img = img * std + mean
#
# print([labels[i] for i in range(64)])
# plt.imshow(img)
# plt.show()


# class Model(torch.nn.Module):
#
#     def __init__(self):
#         super(Model, self).__init__()
#         self.conv1 = torch.nn.Sequential(
#             torch.nn.Conv2d(1, 64, kernel_size=3, stride=1, padding=1),
#             torch.nn.ReLU(),
#             torch.nn.Conv2d(64, 128, kernel_size=3, stride=1, padding=1),
#             torch.nn.ReLU(),
#             torch.nn.MaxPool2d(stride=2, kernel_size=2)
#         )
#
#         self.dense = torch.nn.Sequential(
#             torch.nn.Linear(14 * 14 * 128, 1024),
#             torch.nn.ReLU(),
#             torch.nn.Dropout(p=0.5),
#             torch.nn.Linear(1024, 10)
#         )
#
#     def forward(self, x):
#         x = self.conv1(x)  # 卷積處理
#         x = x.view(-1, 14*14*128)  # 對(duì)參數(shù)實(shí)行扁平化處理
#         x = self.dense(x)
#         return x

class Model(torch.nn.Module):

    def __init__(self):
        super(Model, self).__init__()
        self.conv1 = torch.nn.Sequential(
            torch.nn.Conv2d(1, 64, kernel_size=3, stride=2, padding=1),
            torch.nn.ReLU(),
            torch.nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),
            torch.nn.ReLU(),
            # torch.nn.MaxPool2d(stride=2, kernel_size=2)
        )

        self.dense = torch.nn.Sequential(
            # torch.nn.Linear(14 * 14 * 128, 1024),
            torch.nn.Linear(7 * 7 * 128, 512),
            torch.nn.ReLU(),
            # torch.nn.Dropout(p=0.5),
            torch.nn.Dropout(p=0.8),
            torch.nn.Linear(512, 10)
        )

    def forward(self, x):
        x = self.conv1(x)  # 卷積處理
        # x = x.view(-1, 14*14*128)  # 對(duì)參數(shù)實(shí)行扁平化處理
        x = x.view(-1, 7 * 7 * 128)  # 對(duì)參數(shù)實(shí)行扁平化處理
        x = self.dense(x)
        return x


model = Model()
cost = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())

epochs_n = 5
for epoch in range(epochs_n):
    running_loss = 0.0
    running_correct = 0
    print("Epoch{}/{}".format(epoch, epochs_n))
    print("-" * 10)

    for data in data_loader_train:
        X_train, y_train = data
        X_train, y_train = Variable(X_train), Variable(y_train)
        outputs = model(X_train)
        _, pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)

        loss.backward()
        optimizer.step()
        running_loss += loss.data
        running_correct += torch.sum(pred == y_train.data)
    testing_correct = 0
    for data in data_loader_test:
        X_test, y_test = data
        X_test, y_test = Variable(X_test), Variable(y_test)
        outputs = model(X_test)
        _, pred = torch.max(outputs.data, 1)
        testing_correct += torch.sum(pred == y_test.data)
        print("Loss is:{:.4f},Train Accuracy is:{:.4f}%, Test Accuracy is:{:.4f}".format(running_loss / len(data_train),
                                                                                         100 * running_correct / len(
                                                                                             data_train),
                                                                                         100 * testing_correct / len(
                                                                                             data_test)))

X_test, y_test = next(iter(data_loader_test))
inputs = Variable(X_test)
pred = model(inputs)
_, pred = torch.max(pred, 1)

print("Predict Label is:", [i for i in pred.data])
print("Real Label is:", [i for i in y_test])

img = torchvision.utils.make_grid(X_test)
img = img.numpy().transpose(1, 2, 0)

std = [0.5, 0.5, 0.5]
mean = [0.5, 0.5, 0.5]

img = img * std + mean
plt.imshow(img)
plt.show()

測(cè)試

最后,關(guān)于這類(lèi)代碼的運(yùn)行時(shí)間的需求都是巨大的,所以短時(shí)間內(nèi)出不來(lái)很正常,盡量別中途中斷程序,若你想檢測(cè)程序是否運(yùn)行:

epochs_n = 5
for epoch in range(epochs_n):
    running_loss = 0.0
    running_correct = 0
    print("Epoch{}/{}".format(epoch, epochs_n))
    print("-" * 10)
    
    iter = 0
    for data in data_loader_train:
    
        iter+=1
        
        print(iter)
        X_train, y_train = data
        X_train, y_train = Variable(X_train), Variable(y_train)
        outputs = model(X_train)
        _, pred = torch.max(outputs.data, 1)
        optimizer.zero_grad()
        loss = cost(outputs, y_train)

        loss.backward()
        optimizer.step()
        running_loss += loss.data
        running_correct += torch.sum(pred == y_train.data)
    testing_correct = 0
    for data in data_loader_test:
        X_test, y_test = data
        X_test, y_test = Variable(X_test), Variable(y_test)
        outputs = model(X_test)
        _, pred = torch.max(outputs.data, 1)
        testing_correct += torch.sum(pred == y_test.data)
        print("Loss is:{:.4f},Train Accuracy is:{:.4f}%, Test Accuracy is:{:.4f}".format(running_loss / len(data_train),
                                                                                         100 * running_correct / len(
                                                                                             data_train),
                                                                                         100 * testing_correct / len(
                                                                                             data_test)))

你可以在此處加上一個(gè)int型的測(cè)試變量iter,通過(guò)觀察iter是否累加迭代來(lái)判斷程序是否繼續(xù)在運(yùn)行

在這里插入圖片描述

在這里插入圖片描述

總結(jié)

到此這篇關(guān)于PyTorch簡(jiǎn)單手寫(xiě)數(shù)字識(shí)別的文章就介紹到這了,更多相關(guān)PyTorch手寫(xiě)數(shù)字識(shí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論