Pytorch学习笔记(四)—— 训练一个分类器

训练一个分类器

之前的文章中已经介绍了Pytorch的基本内容,这次将会进入实战,尝试训练一个分类器并进行测试。

开始之前

Python提供了处理各种数据的package,如处理图片时可以使用Pillow、OpenCV等;处理音频时可以使用scipy、librosa等;处理文本时可以使用基于Python或Cython的原始加载或者选择NLTK、Spacy等。
但Pytorch针对视觉处理,专门创建了一个名为torchvision的package,其中包含用于常见数据集(如Imagenet,CIFAR10,MNIST等)的数据加载器,以及用于图像(即torchvision.datasets和torch.utils.data.DataLoader)的数据转换器,这为我们带来了极大的便利。
我们将使用CIFAR10数据集, 它具有以下类别:“飞机”,“汽车”,“鸟”,“猫”,“鹿”,“狗”,“青蛙”,“马”,“船”,“卡车”。 CIFAR-10中的图像尺寸为3x32x32,即尺寸为32x32像素的3通道彩色图像。
CIFAR-10

训练分类器的步骤

我们将按以下步骤完成分类器的训练:
1.使用Torchvision加载和标准化CIFAR10训练和测试数据集
2.定义卷积神经网络
3.定义损失函数
4.根据训练数据训练网络
5.在测试数据上测试网络

数据集下载

import torch
import torchvision
import torchvision.transforms as transforms

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')

可以运行上述代码在官方地址下载,但速度较慢,大约需要几个小时。这里给一个百度云,下载后在项目目录新建一个data目录解压进去。

链接:CIFAR10数据集下载地址
提取码:o6uc

导入相关包以及加载数据集

import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn
import time
import copy
import torch.optim as optim

MINI_BATCH = 8  # 处理数据量较大的数据集时,将数据集分成mini-batch,每次加载一个mini-batch的图片
DEVICE = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')  # 如果GPU可用,使用GPU

# 使用torchvision加载数据集并归一化
# Normalize(mean, std): mean:每个色彩通道的平均值,std:每个色彩通道的方差
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=False, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=MINI_BATCH, shuffle=True, num_workers=4)
# 加载测试集
testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=False, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=4)

注意:如果后续训练在Windows下运行时出现BrokenPipeError错误,将上述代码中DataLoader函数的num_workers参数设置为0。

定义卷积神经网络

这里将新建一个net.py文件来定义网络模型。

# net.py
import torch
import torch.nn as nn
import torch.nn.functional as F


class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)  # 卷积层,输入3通道,输出6通道,过滤器尺寸5*5
        self.conv2 = nn.Conv2d(6, 16, 5)  # 卷积层,输入6通道,输出16通道,过滤器尺寸5*5

        self.pool = nn.MaxPool2d(2, 2)  # 池化层,使用最大池化,尺寸2*2,步长为2

        # 全连接层:16*5*5 -> 120 -> 84 -> 10
        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 = F.relu(self.conv1(x))  # 使用relu激活函数
        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

该网络包含两个卷积层,每个卷积层后接一个池化层,之后是三个全连接层。最终输出的张量维度为(1*10),表示图片属于十个类别的概率。

定义训练函数,得到最优参数

回到之前的文件,继续定义模型训练函数。注意此时应导入net文件中的Net:

from net import Net

然后定义训练函数train:

def train(model, criterion, optimizer, epochs):
    since = time.time()

    best_acc = 0.0  # 记录模型测试时的最高准确率
    best_model_wts = copy.deepcopy(model.state_dict())  # 记录模型测试出的最佳参数

    for epoch in range(epochs):
        print('-' * 30)
        print('Epoch {}/{}'.format(epoch + 1, epochs))

        # 训练模型
        r
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值