pytorch_訓練CIFAR數據集


cifar數據集訓練與測試

CIFAR數據集下載
https://download.csdn.net/download/wangxiaobei2017/12474160

# !/usr/bin/env python
# -*- coding: utf-8 -*-
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
import cv2
from PIL import Image
import numpy as np

class LeNet(nn.Module):
    # 一般在__init__中定義網絡需要的操作算子,比如卷積、全連接算子等等
    def __init__(self):
        super(LeNet, self).__init__()
        # Conv2d的第一個參數是輸入的channel數量,第二個是輸出的channel數量,第三個是kernel size
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.conv2 = nn.Conv2d(6, 16, 5)
        # 由於上一層有16個channel輸出,每個feature map大小為5*5,所以全連接層的輸入是16*5*5
        self.fc1 = nn.Linear(16*5*5, 120)
        self.fc2 = nn.Linear(120, 84)
        # 最終有10類,所以最后一個全連接層輸出數量是10
        self.fc3 = nn.Linear(84, 10)
        self.pool = nn.MaxPool2d(2, 2)
    # forward這個函數定義了前向傳播的運算,只需要像寫普通的python算數運算那樣就可以了
    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.pool(x)
        x = F.relu(self.conv2(x))
        x = self.pool(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
# 在構建數據集的時候指定transform,就會應用我們定義好的transform
# root是存儲數據的文件夾,download=True指定如果數據不存在先下載數據
class ImageClassify(object):
    def __init__(self):
        self.cifar_train = 0
        self.cifar_test = 0
        self.trainloader =0
        self.testloader  =0
        self.criterion = 0
        self.optimizer = 0
        self.net = LeNet()
    def GetImgData(self):
        # cifar-10官方提供的數據集是用numpy array存儲的
        # 下面這個transform會把numpy array變成torch tensor,然后把rgb值歸一到[0, 1]這個區間
        print('獲取數據集....')
        transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
        self.cifar_train = torchvision.datasets.CIFAR10(root='E:\\2019PythonProject\\Pytorch_step1\\data', train=True,download=False, transform=transform)
        self.cifar_test  = torchvision.datasets.CIFAR10(root='E:\\2019PythonProject\\Pytorch_step1\\data', train=False,transform=transform)
        print(self.cifar_train)
        print(self.cifar_test)
    def LoadData(self):
        # 加載數據集
        print("加載數據集...")
        batch_size = 32
        self.trainloader = torch.utils.data.DataLoader(self.cifar_train, batch_size=batch_size, shuffle=True)
        self.testloader = torch.utils.data.DataLoader(self.cifar_test, batch_size=batch_size, shuffle=True)
    def LossFun(self):
        print("lossing...")
        # CrossEntropyLoss就是我們需要的損失函數
        self.criterion = nn.CrossEntropyLoss()
        self.optimizer = optim.SGD(self.net.parameters(), lr=0.001, momentum=0.9)
    def TrainingData(self):
        self.LoadData()
        self.LossFun()
        print("Start Training...")
        for epoch in range(30):
            # 我們用一個變量來記錄每100個batch的平均loss
            loss100 = 0.0
            # 我們的dataloader派上了用場
            for i, data in enumerate(self.trainloader):
                inputs, labels = data
                # inputs, labels = inputs.to(device), labels.to(device)  # 注意需要復制到GPU
                self.optimizer.zero_grad()
                # print(len(inputs))
                outputs = self.net.forward(inputs)
                # print(len(outputs))
                loss = self.criterion(outputs, labels)
                loss.backward()
                self.optimizer.step()
                loss100 += loss.item()
                if i % 2 == 0:
                    print('[Epoch %d, Batch %5d] loss: %.3f' %
                          (epoch + 1, i + 1, loss100 / 2))
                    loss100 = 0.0
        # 保存網絡模型 保存整個模型
        torch.save(self.net, 'model_shanbu_128.pkl')
        print("Done Training!")
    def TestingData(self):
        model_net = torch.load('model_shanbu_128.pkl')
        self.LoadData()
        # 構造測試的dataloader
        dataiter = iter(self.testloader)
        # 預測正確的數量和總數量
        correct = 0
        total = 0
        # 使用torch.no_grad的話在前向傳播中不記錄梯度,節省內存
        # cv2.namedWindow('predictPic', cv2.WINDOW_NORMAL)
        to_pil_image  = transforms.ToPILImage()
        with torch.no_grad():
            for images, labels in dataiter:
                # images, labels = data
                # print(images)
                print(len(images.data))
                # images, labels = images.to(device), labels.to(device)
                # 預測
                # outputs = self.net(images)
                outputs = model_net(images)

                # 我們的網絡輸出的實際上是個概率分布,去最大概率的哪一項作為預測分類
                _, predicted = torch.max(outputs.data, 1)
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
                # print(images.data[0])
                # print(len(images.data[0]))
                # input_flag = input()
                # if input_flag == 'p':
                #     break
                # elif input_flag == 'c':
                #     continue
                # cv2.imshow('predictPic', images)
                # cv2.waitKey(0)
                # cv2.destroyAllWindows()
        print('Accuracy of the self.network on the 10000 test images: %d %%' % (
                100 * correct / total))
def main():
    ImgCla = ImageClassify()
    ImgCla.GetImgData()
    ImgCla.TrainingData()
    ImgCla.TestingData()
    pass

if __name__ == '__main__':
    main()                                                  

下載數據后更改配置,將下載路徑改成自己的路徑

訓練 並 預測


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM