手把手教你玩转深度学习-PyTorch教程1

手把手教你玩转深度学习-PyTorch教程1

文章目录

目录

前言

一、LeNet是什么?

二、CIFAR-10数据集

1.数据集介绍

2.下载方式

 三、使用PyTorch构建并训练LeNet

1.利用PyTorch进行图像分类任务的基本步骤

2.引入所需包

3.加载数据集

4.构造LeNet网络

5.定义损失函数和优化器

6.模型训练

7.模型验证

总结


前言

之前的文章中,我们已经对如何搭建深度学习环境进行了讲述。本文将对如何使用PyTorch环境进行深度学习训练进行介绍,本次以LeNet为出发点,向大家展示如何在PyTorch中搭建LeNet,

并使用LeNet在CIFAR-10数据集上进行图像分类工作。


 

一、LeNet是什么?

LeNet是由深度学习三巨头之一的LeCun提出的一种卷积神经网络(CNN,Convolutional Neural Networks),其结构中包含了目前CNN中的几种经典的结构,如卷积、池化等等,而且LeNet结构十分简单,

非常适合于初学者学习,因此本次选取LeNet为出发点。由于关于LeNet原理介绍的文章很多,在本文中对LeNet就不予赘述了,需要了解LeNet原理的同学,请移步:

LeNet神经网络


 

二、CIFAR-10数据集

1.数据集介绍

CIFAR-10数据集是常用的图像分类数据集,其中包含了60000张彩色图像,分为'airplane','automonbile','bird','cat','deer','dog','frog','horse','ship','truck'共10个种类,每类6000张图,图片大小32*32像素。其示意图如下图:

手把手教你玩转深度学习-PyTorch教程1_第1张图片

2.下载方式

在使用CIFAR-10数据集的过程中,我们可以选择使用PyTorch中的torchvision自动下载,也可以自行下载,数据集共分为了Python版本、MATLAB版本和二进制版本,一般情况下我们使用python版本。

由于下载数据集的网站在国外,因此建议大家自行下载,以提升效率,下面链接为下载地址:

官网下载地址:

http://www.cs.toronto.edu/~kriz/cifar.html

百度网盘下载地址:

链接:https://pan.baidu.com/s/1N3WL5dJd1ANq-eKS0EsOZA 
提取码:ioct 

下载完成后,将数据集进行解压,可以看到如下文件:

手把手教你玩转深度学习-PyTorch教程1_第2张图片 


 三、使用PyTorch构建并训练LeNet

1.利用PyTorch进行图像分类任务的基本步骤

在使用PyTorch进行图像分类任务时,主要在指定的任务中(即数据集下)针对分类模型进行训练的过程,这个过程可以分为1.引入所需包;2.加载数据集;3.构造网络;4.定义损失函数和优化器;5.模型训练;

6.模型验证共6个部分,下面分别对这些部分进行介绍:

2.引入所需包

任何一个深度学习模型在构建、训练、显示等过程中,都需要其他包的支持,因此我们首先将所需要的包都进行引入,需要引入包如下:

import torch as t #引入pytorch
import torchvision as tv #引入torchvision
import torchvision.transforms as transforms#引入torchvision的transforms,用于数据预处理
import torch.nn as nn #引入神经网络工具箱
import torch.nn.functional as F #引入函数接口
from torch import optim #引入优化器
from torch.autograd import Variable #引入Variable 

这里面大家不着急对每个包的作用进行详细了解,先将整个LeNet搭建起来,后面随着搭建的过程,会在过程中及后续的文章中对使用到的各个包进行详细的介绍。

3.加载数据集

深度学习模型的训练依赖于数据,LeNet也不例外,因此我们需要将CIFAR-10数据集进行加载,此时我们使用torchvision工具包进行处理。torchvision为图像操作提供了一些方便工具库,如常用的数据集、模型、转换函数等等。

如果此时已经下载好CIFAR-10数据集,并解压完成,则使用如下代码加载数据集:

#利用torchvision对训练数据集进行设置
trainset = tv.datasets.CIFAR10(root='../dataset/cifar-10-python/',train=True,download=False,transform=transform)

#利用dataloader加载训练数据集,其中shuffle是指在每个epoch开始的时候,对数据进行重新排序;num_workers指使用几个线程参与工作
trainloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)

 如果此时没有下载好CIFAR-10数据集,只需要将上面代码中的download=False改为True,torchvision会自动对CIFAR-10数据集进行下载,则使用如下代码加载数据集:

#利用torchvision对训练数据集进行设置
trainset = tv.datasets.CIFAR10(root='../dataset/cifar-10-python/',train=True,download=True,transform=transform)

#利用dataloader加载训练数据集,其中shuffle是指在每个epoch开始的时候,对数据进行重新排序;num_workers指使用几个线程参与工作
trainloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)

同理,可以用于加载测试数据集,代码如下:


testset = tv.datasets.CIFAR10(root='../dataset/cifar-10-python/',train=False,download=False,transform=transform)

testloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=False,num_workers=2)

4.构造LeNet网络

LeNet的网络结构如第一节中介绍,我们将通过PyTorch的神经网络工具箱nn建立网络。建立过程中,定义一个LetNet类,类中包含了init函数和forward函数,其中init函数定了LeNet的基本结构(即包含多少层以及每层是什么等),

forward函数则定义了网络的计算过程,这里要注意的是我们必须定义forward函数,这是由于在神经网络的训练过程中,反向传播是极其重要的计算过程,而只有定义了forward,PyTorch才能自动的进行反向传播的计算。

具体定义代码如下:

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)
        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 = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

定义完成后,我们可以实例化一个对象,并将其进行打印来查看定义好的网络结构:

net = LeNet()
print(net)

 会得到如下输出:

LeNet(
  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

5.定义损失函数和优化器

pytorch中定义损失函数和优化器十分的方便,神经网络工具箱nn和优化器工具库optim已经将最常用的损失函数和优化器进行了封装,我们只需要调用相应代码即可,如:

#定义使用交叉熵损失函数
criterion = nn.CrossEntropyLoss() 
#定义优化器为随机梯度下降SGD
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

6.模型训练

在上述2-4步都完成的情况下,我们就可以用CIFAR-10数据集对LeNet模型进行训练,代码如下:

import torch as t #引入pytorch
import torchvision as tv #引入torchvision
import torchvision.transforms as transforms#引入torchvision的transforms,用于数据预处理
import torch.nn as nn #引入神经网络工具箱
import torch.nn.functional as F #引入函数接口
from torch import optim #引入优化器
from torch.autograd import Variable #引入Variable 

#利用torchvision对训练数据集进行设置
trainset = tv.datasets.CIFAR10(root='../dataset/cifar-10-python/',train=True,download=False,transform=transform)

#利用dataloader加载训练数据集,其中shuffle是指在每个epoch开始的时候,对数据进行重新排序;num_workers指使用几个线程参与工作
trainloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=2)

testset = tv.datasets.CIFAR10(root='../dataset/cifar-10-python/',train=False,download=False,transform=transform)

testloader = t.utils.data.DataLoader(trainset,batch_size=4,shuffle=False,num_workers=2)

#定义使用交叉熵损失函数
criterion = nn.CrossEntropyLoss() 
#定义优化器为随机梯度下降SGD
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9)

#定义LetNet
class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)
        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 = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x


#训练网络
for epoch in range(2):
    running_loss = 0.0
    for i,data in enumerate(trainloader,0):
        inputs,labels = data
        inputs,labels = Variable(inputs),Variable(labels)
        
        #梯度清零
        optimizer.zero_grad()
        
        outputs = net(inputs)
        loss = criterion(outputs,labels)
        loss.backward()
        
        #更新参数
        optimizer.step()
        
        #打印log
        running_loss += loss.item()
        if i%2000 == 1999: #每2000个batch打印一次状态
            print('[%d,%5d] loss: %.3f' % (epoch+1,i+1,running_loss/2000))
            running_loss = 0.0
print("训练完成")

训练完成后会得到如下结果,可以看到随着训练的进行,损失不断降低:

[1, 2000] loss: 2.193
[1, 4000] loss: 1.867
[1, 6000] loss: 1.673
[1, 8000] loss: 1.583
[1,10000] loss: 1.497
[1,12000] loss: 1.453
[2, 2000] loss: 1.388
[2, 4000] loss: 1.348
[2, 6000] loss: 1.314
[2, 8000] loss: 1.293
[2,10000] loss: 1.281
[2,12000] loss: 1.248
训练完成

7.模型验证

模型的训练工作完成后,我们可以通过测试数据集验证一下模型的训练结果,此时我们加载测试数据集,并将测试数据集中的图片输入模型中,计算相应的分类label。具体代码如下:

correct = 0 #存储预测正确的图片数量
total = 0 #总数
for data in testloader:
    images,labels = data
    outputs = net(Variable(images))
    _,predicted = t.max(outputs.data,1)
    total += labels.size(0)
    correct += (predicted == labels).sum()
print('准确率为:%d %%' %(100 *correct / total))   

总结

以上,我们便完成了利用PyTorch搭建LeNet模型,并在CIFAR-10数据集上完成模型的训练及验证的工作,大家可以通过这个例子,先直观的对PyTorch的使用建立一个印象。在后续的文章中,

我们会对PyTorch中的其他知识进行讲解来帮助大家进一步的理解和运用PyTorch。

你可能感兴趣的:(深度学习,pytorch,深度学习)