Pytorch入门之CIFAR10图片分类

Pytorch初探之CIFAR10图片分类

Pytorch官方文档真的是宝藏,不仅有所有函数功能的讲解,还有丰富的入门案例学习。在看了论文代码以后,感觉自己还是要来补一下基本的入门知识,就写一下其中CIFAR图片分类的知识点。
其实这个数据集和MNIST很像,不过这个数据集的图片是彩色的,也就是说传入的数据集是有RGB三个通道的,同时这个数据内容会比手写数字更加丰富一些,最后也是把图片分为十个类。

这个数据集有十个类 {‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’},每个图片32*32像素的彩色图,具体举例如下:
在这里插入图片描述
在这个数据集上训练一个分类器的过程包含了神经网络的主要步骤:
1. 加载训练和测试数据集
2. 定义卷积神经网络
3. 定义损失函数
4. 训练神经网络
5. 在测试数据上测试训练好的网络

我们看官方文档,如果你需要开始这个分类器的训练,你得先导入一些包:

import torch
from torchvision import datasets,transforms
import torchvision
from torch.autograd import  Variable
import numpy as np
import matplotlib.pyplot as plt
import torch.optim as optim
import argparse
from torch.utils.data.sampler import SubsetRandomSampler
import torch.nn.functional as F

所以你得先安装他们,如果你用的是conda来管理包,那么在命令行使用下面这些命令:

conda install pytorch
conda install matplotlib
conda install argparse

上面用到的那些基本都在这几个包里面。

下面给出神经网络定义的代码:

class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = torch.nn.Conv2d(3, 6, 5)  #卷积
        self.pool = torch.nn.MaxPool2d(2, 2) #最大池化
        self.conv2 = torch.nn.Conv2d(6, 16, 5)
        self.fc1 = torch.nn.Linear(16 * 5 * 5, 240) #线性层
        self.fc2 = torch.nn.Linear(240, 120)
        self.fc3 = torch.nn.Linear(120, 84)
        self.fc4 = torch.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 = F.relu(self.fc3(x))
        x = self.fc4(x)
        return x

有了Pytorch之后你再也不用自己定义每一层内部的函数功能,只要想好每层的输入输出参数是什么,并把参数填好对应上就行,然后把数据处理好传进来,整个网络就能跑起来并且开始训练。

所以接下来是怎么去让这个网络work起来的主函数:

def main():
    

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

    testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                           download=True, transform=transform)
    testloader = torch.utils.data.DataLoader(testset, batch_size=4,
                                             shuffle=False, num_workers=2)

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

    def imshow(img):
        img = img / 2 + 0.5  # unnormalize
        npimg = img.numpy()
        plt.imshow(np.transpose(npimg, (1, 2, 0)))
        plt.show()

    # get some random training images
    dataiter = iter(trainloader)
    images, labels = dataiter.next()

    train_on_gpu=torch.cuda.is_available()
    if not train_on_gpu:
        print('CUDA in not availiable. Training on CPU ...')
    else:
        print('CUDA in availiable. Training on GPU ...')

    net = Net()
    criterion = torch.nn.CrossEntropyLoss()
    #optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
    optimizer = optim.Adam(net.parameters(), lr=0.001, betas=(0.9,0.999),eps=1e-08,weight_decay=0,amsgrad=False)

    for epoch in range(10):  # loop over the dataset multiple times
        running_loss = 0.0
        for i, data in enumerate(trainloader, 0):
            # get the inputs; data is a list of [inputs, labels]
            inputs, labels = data
            
            # zero the parameter gradients
            optimizer.zero_grad()

            # forward + backward + optimize
            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()

            # print statistics
            running_loss += loss.item()
            if i % 2000 == 1999:  # print every 2000 mini-batches
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 2000))
                running_loss = 0.0

    print('Finished Training')
    PATH = './cifar_net.pth'
    torch.save(net.state_dict(), PATH)
#整体测试准确率
    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]))
    print('done!')

if __name__ == '__main__':
    main()

通过这个神经网络训练以后测试的结果是:
在这里插入图片描述
效果比十个类直接盲猜的结果(10%)还是好了不少,但是63%的效果还是不够好,这个数据集上很多人已经做到接近爆表了,所以接下来考虑学习一下如何提高这个网络分类效果的方法。

到这里整个网络的定义和训练都写完了(虽然是从官方文档里抄来的,但是跑起来看到一些效果还是可以),但是对于代码中的一些函数(Conv2d,不同的参数优化函数的对比),以及数据的传入(通道的概念),函数的传参等过程还是有一些细节不甚了解,下次就这些问题补一个博客。(希望这个坑能尽快填上!)

代码下载链接://download.csdn.net/download/faithfulzl/12009241

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值