Pytorch学习:图像分类入门!使用CIFAR-10数据集,完整地创建深度神经网络进行训练、测试并保存和读取

前言

本模型最终能得到约 83%分类测试精度,占用约1.7g显存大小。
使用的是经典CIFAR-10数据集,里面包含了10个种类的图片:
在这里插入图片描述

1. 导入Pytorch以及相关包

本文使用pytorch=1.5.1+cuda10.1

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 time,os

torch.nntorch.nn.functional中包含了很多高度集成的函数。
torchvision中提供了主流的公开数据集,如MNIST、CIFAR-10、CIFAR-100等。MNIST(手写黑白图像数据集)比较小并且简单,并不能很好地体现现在模型的性能。使用CIFAR-10包含了共十类彩色图像数据集),可以较好地测试模型的能力。CIFAR-100更加困难一些。
torchvision.transforms可以对图像进行数据增强,并使用transforms.ToTensr()将数据转换成训练所需要的tensor。
torch.optim中包含了pytorch中可使用的各种optimizer,如Adam、SGD等等。

2. 下载、加载数据集并进行增强

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

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

train_dataset = torchvision.datasets.CIFAR10(root='./datasets', train=True,
                                        download=False, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=50,
                                          shuffle=True, num_workers=0)

test_dataset = torchvision.datasets.CIFAR10(root='./datasets', train=False,
                                       download=False, transform=transform_test)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=25,
                                         shuffle=False, num_workers=0)

使用Compose()整合地对数据进行增强/预处理。其中:

  • RandomRotation(0.5)(),对图像进行角度旋转,0.5代表在(-0.5, +0.5)范围内进行旋转,可以自行设置
  • RandomGrayscale(),随机对图像转换成灰度图,默认为50%
  • ToTensor(),将图像从numpy的array转化为pytorch训练需要的tensor
  • Normalize(),将tensor集合转换成指定的mean和std,这里都取0.5。其实,0.5是常用标准,要想提升模型能力,对于不同的数据集,应该使用不同具体的的mean和std,具体如何计算不同数据集的mean和std,可能以后会写。

一般,loader函数中的num_wokers设置成2,具体作用可以自行搜索,这里设置成0是因为我的电脑GPU在多线程载入数据时会出现某些错误,当程序报错的时候会无法杀死旧的进程,设置成0就没事了。

数据增强/预处理,能够通过改变数据集的多样性,提升模型的鲁棒性和精度,几乎所有的训练都要对数据进行增强,是模型训练中必不可少的一部分。关于更多预处理的简单介绍请看
使用torchvision.datasets.CIFAR10()下载数据集,需要设置download=Trueroot=为下载位置,下载成功后只要不改变下载位置不会反复下载,所以建议都下载在统一文件夹中,便于管理并节省空间;在训练集中,需要设置train=True,表示对训练集进行训练,测试集则不需要;transform代表使用之前定义好的transform方法。
可以通过以下代码对数据集某个数据进行可视化:

import matplotlib.pyplot as plt
fig = plt.figure()
plt.imshow(train_dataset.data[0]) # 第一个数据
plt.show()

整个训练集为5W个32*32*3的彩色图,其中一个示例:
在这里插入图片描述

3. 模型设计

深度学习网络框架由AlexNet建立,包含了卷积层、激活函数、池化层和全连接层;之后的VGG通过将7*7卷积替换成两个3*3卷积,减少了参数,并且由于可以额外增加一个激活函数,增加了模型的非线性程度,性能得到较大提升;而ResNet通过residual block结构,将深度一词发挥的非常彻底,也极大地提升了模型的性能。
本文基于VGG设计网络结构,由于苦逼1050GPU只有2G大,所以为了提高性能,只能通过增加多个1x1卷积减少模型参数

class Model(nn.Module):
    def __init__(self,num_classes=10): # 
        super(Model,self).__init__()
        layers = [] # 将层数添加到此列表中
        in_dim = 3  # 输入3通道的彩色图片
        out_dim = 64
        for i in range(1, 6): # 共5个block;
            layers += [nn.Conv2d(in_dim, out_dim, kernel_size=3, stride=1, padding=1),
                       nn.BatchNorm2d(out_dim), nn.ReLU(inplace=True),
                       # 使用1x1卷积减少模型参数
                       nn.Conv2d(out_dim, out_dim, kernel_size=1, stride=1, padding=0),
                       
                       nn.BatchNorm2d(out_dim), nn.ReLU(inplace=True),                                                  
                       nn.Conv2d(out_dim, out_dim, kernel_size=3, stride=1, padding=1),
                       nn.BatchNorm2d(out_dim),nn.ReLU(inplace=True),   
                      ]
            # 使用步长为2的卷积代替maxpooling 
            if i==2 or i==3 or i==4:              
                layers += [nn.Conv2d(out_dim, out_dim, 
                					kernel_size=3, stride=2, padding=1)]
            # 也可以使用maxpooling
            # layers+= [nn.Maxpool2d(2,2,padding=1)]
            
            in_dim = out_dim # 交换
            if i != 4:  # 通道翻倍
                out_dim *= 2
        self.features = nn.Sequential(*layers)
        # 布置全连接层进行分类
        self.classifier = nn.Sequential(nn.Linear(8192, 1024),nn.Dropout2d(),
                                       nn.Linear(1024,1024),nn.Dropout2d(),
                                       nn.Linear(1024,num_classes))
    # 前向传播                                                
    def forward(self,x):
        x = self.features(x)
        # 将BxCxWxH的数据类型=>Bx(C*W*H)后进入全连接层
        x = torch.flatten(x, 1)  
        x = self.classifier(x)
        return x

继承nn.Module类后开始初始化__init__(),并前向传播forward()

  • 初始化:使用self.featuresself.classifier保存网络结构,其中self.features保存在layers中,包含了网络中的卷积层、池化层、BN层、激活层等等
  • 前向传播:输入x传进网络中,然后通过展平,将self.features的输出通道与self.classifier的输入通道保持一致,计算并得到输出。现在还没进行反向传播

这里全连接层的参数8192是如何来的呢?在工程上一般不需要直接设定好,直接搭建好模型,跑一遍。会报出BUG,BUG会显示无法进行矩阵相乘。这时只需要将报出的数据填入就好,具体我就不展示了,大家可以自己试一下。
通过:

model = Model()
model

打印出所构建的五层(除去全连接层)网络结构:

Model(
  (features): Sequential(
    (0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
    (1)
  • 3
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
gan cifar10是指使用生成对抗网络(GAN)来对CIFAR-10数据集进行图像生成或图像分类的任务。 CIFAR-10是一个经典的计算机视觉数据集,包含10个不同类别的60000张32x32像素彩色图像。这个数据集常用于评估图像分类算法的性能。而GAN是一种由生成器和判别器组成的深度学习框架,通过对抗学习的方式训练生成器生成以假乱真的图像,并让判别器尽可能准确地区分真实图像和生成图像。 gan cifar10的任务可以分为两个方向: 第一,使用GAN生成CIFAR-10图像。通过训练一个生成器网络,它从随机噪声中生成逼真的CIFAR-10图像。这个生成器网络经过不断的迭代训练,使得生成的图像能够在视觉上与真实的CIFAR-10图像越来越接近。这个任务的目标是让生成器网络生成的图像能够与原始CIFAR-10数据集的图像在视觉上无法区分。 第二,使用GAN对CIFAR-10图像进行分类。在这个任务中,GAN被用作一个特征提取器和分类器,它能够自动学习CIFAR-10图像的特征表示,并基于这些特征对图像进行分类。通过使用GAN,可以让分类器更好地理解CIFAR-10数据集的特点,从而提高分类的准确性。 综上所述,gan cifar10是指使用GAN对CIFAR-10数据集进行图像生成或图像分类的任务。通过训练生成器网络来生成逼真的CIFAR-10图像,或使用GAN作为特征提取器和分类器来对CIFAR-10图像进行分类,可以提高图像生成和图像分类的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值