pytorch实现简单的cifar10和cifar100训练、测试、识别

 代码非原创,具体我暂时不懂,都是通过到处copy的代码最终实现想要的效果

cifar10训练20轮,精确度达到73%,如果想要达到更好的精确度,建议换个模型跑。

cifar10训练

1.对图片归一化处理

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

2.加载数据集

train_dataset = torchvision.datasets.CIFAR10(root=PATH, train=True, transform=transform, download=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_dataset = torchvision.datasets.CIFAR10(root=PATH, train=False, transform=transform, download=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']

 3.搭建网络模型

class CNN(nn.Module):#简单网络
    def __init__(self):
        super(CNN, 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

 4.选择设备

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)

 5.定义网络模型

cnn = CNN().to(device)

6.学习率和动量

crit = torch.nn.CrossEntropyLoss()
opti = torch.optim.SGD(cnn.parameters(), lr=0.002, momentum=0.9)

7.训练模型

 

def train():
     for epoch in range(1):
        running_loss = 0.0
        for i, data in enumerate(train_loader):
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device)
            outputs = cnn(inputs)
            opti.zero_grad()
            loss = crit(outputs, labels)
            loss.backward()
            opti.step()

            running_loss += loss.item()
            if i % 200 == 199:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
        print('Finish training')

8.测试模型和计算代码运行时间

 

def test():
    correct = 0
    total = 0
    for data in test_loader:
        images, labels = data
        outputs = cnn(Variable(images))
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()
    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 test_loader:
            images, labels = data
            images, labels = images.to(device), labels.to(device)
            outputs = cnn(images).to(device)
            _, 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]))

    end_time = time.time()
    print('总耗时:', int(end_time - start_time) / 60, 'minutes')

 9.完整cifar10训练、测试代码

import time
import cv2
import torch
import torchvision
# from PIL import Image
import torch.nn as nn
import torchvision.transforms as transforms
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torch.autograd import Variable

PATH = 'cifar10'
BATCH_SIZE =64

start_time = time.time()

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

train_dataset = torchvision.datasets.CIFAR10(root=PATH, train=True, transform=transform, download=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_dataset = torchvision.datasets.CIFAR10(root=PATH, train=False, transform=transform, download=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']



class CNN(nn.Module):#简单网络
    def __init__(self):
        super(CNN, 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

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)


cnn = CNN().to(device)

crit = torch.nn.CrossEntropyLoss()
opti = torch.optim.SGD(cnn.parameters(), lr=0.002, momentum=0.9)


def train():
     for epoch in range(1):#选择训练轮数
        running_loss = 0.0
        for i, data in enumerate(train_loader):
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device)
            outputs = cnn(inputs)
            opti.zero_grad()
            loss = crit(outputs, labels)
            loss.backward()
            opti.step()

            running_loss += loss.item()
            if i % 200 == 199:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
        print('Finish training')

        # PATH1 = 'cnn.pt'
        # torch.save(cnn, PATH1)
        # print('保存完成')


def test():
    correct = 0
    total = 0
    for data in test_loader:
        images, labels = data
        outputs = cnn(Variable(images))
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()
    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 test_loader:
            images, labels = data
            images, labels = images.to(device), labels.to(device)
            outputs = cnn(images).to(device)
            _, 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]))

    end_time = time.time()
    print('总耗时:', int(end_time - start_time) / 60, 'minutes')






if __name__=='__main__':
    train()
    PATH1 = 'cnn.pt'
    torch.save(cnn, PATH1)
    print('保存完成')
    test()

 cifar10图片识别完整代码

import time
import cv2
import torch
import torchvision
from PIL import Image
import torch.nn as nn
import torchvision.transforms as transforms
import torch.nn.functional as F
from torch.utils.data import DataLoader
import cifar10_3
from cifar10_3 import CNN
# import dataset

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)


cnn = CNN().to(device)


def predicted_one():
    cnn = torch.load('cnn.pt')
    cnn.to(device)

    img_path = r'C:\Users\86152\pythonProject3\data\img_16.png'
    img = Image.open(img_path).convert('RGB')
    img_ = cifar10_3.transform(img).unsqueeze(0)
    # print(img_.shape)
    img = img_.to(device)
    outputs = cnn(img)

    _, indices = torch.max(outputs, 1)
    percentage = torch.nn.functional.softmax(outputs, dim=1)[0] * 100
    perc = percentage[int(indices)].item()
    result = cifar10_3.classes[indices]
    print('predicted:', result)
    pic = cv2.imread(img_path)
    cv2.imshow('pic', pic)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    predicted_one()

 

cifar100

由于cifar100是在cifar10的基础上训练的,所有它训练20次的精确度只有43%。

改动不多,

1.加载数据集

train_dataset = torchvision.datasets.CIFAR100(root=PATH, train=True, transform=transform, download=False)
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_dataset = torchvision.datasets.CIFAR100(root=PATH, train=False, transform=transform, download=False)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
labels=train_dataset.classes
classes=(labels)

没下cifar100数据集的download都要改为Ture 

其中labels=train_dataset.classes classes=(labels)是取数据集内分类信息标签,用于后面识别图片

2.网络模型

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, 5)
        self.conv2 = nn.Conv2d(64, 128, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(128 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 100)
        # self.fc3 = nn.Linear(84, 100)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 128 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        # x = self.fc3(x)
        return x

 因为要分类100,所有将10改为100,又因为84<100,所有直接删了,哈哈

3.cifar100完整训练、测试代码

# from pytorch_lightning import Trainer
import time
import cv2
import torch
import torchvision
# from PIL import Image
import torch.nn as nn
import torchvision.transforms as transforms
import torch.nn.functional as F
from torch.utils.data import DataLoader
from torch.autograd import Variable
import pickle

PATH = 'cifar100'
BATCH_SIZE =100

start_time = time.time()

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

train_dataset = torchvision.datasets.CIFAR100(root=PATH, train=True, transform=transform, download=False)
train_loader = DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
test_dataset = torchvision.datasets.CIFAR100(root=PATH, train=False, transform=transform, download=False)
test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
#classes = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
labels=train_dataset.classes
classes=(labels)
# print(classes)


# # Load the cifar100 meta file
# with open('cif100', '') as f:
#     meta = pickle.load(f)
#
# # # Print the fine label names
# fine_label_names = PATH['fine_label_names']
# print(fine_label_names)

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 64, 5)
        self.conv2 = nn.Conv2d(64, 128, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(128 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 100)
        # self.fc3 = nn.Linear(84, 100)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 128 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        # x = self.fc3(x)
        return x

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)


cnn = CNN().to(device)

crit = torch.nn.CrossEntropyLoss()
opti = torch.optim.SGD(cnn.parameters(), lr=0.002, momentum=0.9)


def train():
     for epoch in range(1):
        running_loss = 0.0
        for i, data in enumerate(train_loader):
            inputs, labels = data
            inputs, labels = inputs.to(device), labels.to(device)
            outputs = cnn(inputs)
            opti.zero_grad()
            loss = crit(outputs, labels)
            loss.backward()
            opti.step()

            running_loss += loss.item()
            if i % 200 == 199:
                print('[%d, %5d] loss: %.3f' % (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0
        print('Finish training')

        # PATH1 = 'cnn.pt'
        # torch.save(cnn, PATH1)
        # print('保存完成')


def test():
    correct = 0
    total = 0
    for data in test_loader:
        images, labels = data
        outputs = cnn(Variable(images))
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()
    print('Accuracy of the network on the 10000 test images: %d %%' % (100 * correct / total))

    class_correct = list(0. for i in range(100))
    class_total = list(0. for i in range(100))
    with torch.no_grad():
        for data in test_loader:
            images, labels = data
            images, labels = images.to(device), labels.to(device)
            outputs = cnn(images).to(device)
            _, 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]))
    #     print(BATCH_SIZE, '/', len(test_loader), 'epoch: %d' %, 'Loss: %.3f | Acc: %.3f%% (%d/%d)'
    #           % (test_loss / (batch_idx + 1), 100. * correct / total, correct, total))

    end_time = time.time()
    print('总耗时:', int(end_time - start_time) / 60, 'minutes')






if __name__=='__main__':
    train()
    PATH1 = 'cnn1.pt'
    torch.save(cnn, PATH1)
    print('保存完成')
    test()

cifar100识别图片

 

import time
import cv2
import torch
import torchvision
from PIL import Image
import torch.nn as nn
import torchvision.transforms as transforms
import torch.nn.functional as F
from torch.utils.data import DataLoader
import cifar100
from cifar100 import CNN
# import dataset

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(device)


cnn = CNN().to(device)


def predicted_one():
    cnn = torch.load('cnn1.pt')
    cnn.to(device)

    img_path = r'C:\Users\86152\pythonProject3\data\img_17.png'
    img = Image.open(img_path).convert('RGB')
    img_ = cifar100.transform(img).unsqueeze(0)
    # print(img_.shape)
    img = img_.to(device)
    outputs = cnn(img)

    _, indices = torch.max(outputs, 1)
    percentage = torch.nn.functional.softmax(outputs, dim=1)[0] * 100
    perc = percentage[int(indices)].item()
    result = cifar100.classes[indices]
    print('predicted:', result)
    pic = cv2.imread(img_path)
    cv2.imshow('pic', pic)
    cv2.waitKey(0)
    cv2.destroyAllWindows()


if __name__ == '__main__':
    predicted_one()

 

虽然这精确度有点低,不过大家可以用来学习; 

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2023年11月13日
下一篇 2023年11月13日

相关推荐