卷积神经网络学习——第二部分:卷积神经网络训练的基本流程
一、序言
本文承接第一部分,基于对卷积神经网络网络组成的认识,开始学习如何去使用卷积神经网络进行对应的训练。模型评估作为优化部分,我们将放在第三个部分中再好好讲他的作用以及意义~
训练的基本流程主要是数据集引入、训练及参数设置、验证及反馈这三个步骤,我们现在分三个步骤来认识一下这个训练的基本流程。
PS:我更新真是快啊~
——2020年11月20日于北邮教三539
二、训练流程
1、数据集引入
本文根据对应的实验要求,主要采用的是Pytorch中自带的MNIST数据集。MNIST数据集由于比较基础,历年来都是被各种玩坏的主要对象~
引入数据集的时候主要需要注意的是预处理的一个操作,在这里主要用的是ToTensor和Normalize两个函数进行归一化处理。其实也不一定需要Normalize这个函数,因为训练其实都是可以进行的。
但是这里需要注意一下,因为导入数据集的时候操作是固定的。所以为了保证这个操作固定,就最好是用Compose把他们固定起来,不然在后续操作中可能就会添麻烦。
如果你在做自己的手写图像识别,并且老是正确率比较低,那么一定注意一下这几个点。
第一个是图像的前后的前后处理的时候是不一样的,很容易直接用自己的图像直接拿去识别了,但是因为之前训练集中的都是经过Compose结合后的组合处理后的图像。但是你直接拿去处理的图像是没有经过处理的,输入到模型中的和此前的格式是不一样的。
第二个就是因为你手写的时候,导出的文件无论是png还是jpg,他们基本都是彩色图片。(是的,哪怕你看到的都是黑色,但他们本身还都是彩色图片)这个时候可以使用transforms.Grayscale函数先将你的图像灰度处理,不然在用Normalize的时候还是会带来问题。由于预处理不同,所以你在前后训练的素材和你最后手写的素材不是一个格式,难免会导致你的准确率很低。预处理函数的设置是后面新增自定义素材时的必要保障。
(2020.11.22补充:识别率和笔触的关系较大,可以参考训练集中图像的大小和笔触进行书写;在一定程度上,黑底白字比起白底黑字来说,准确率更高——by绚佬)
关于transforms中包含有多少函数,有什么对应的作用,可以参考:二十二种 transforms 图片数据预处理方法
import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.autograd import Variable
from torchvision import datasets, transforms
# 步骤一:数据载入
# 1.transforms.Compose()将各种预处理操作组合到一起
# 2.transforms.ToTensor()将图片转换成 PyTorch 中处理的对象 Tensor.在转化的过程中 PyTorch 自动将图片标准化了,也就是说Tensor的范用是(0,1)之间
# 3.transforms.Normalize()要传入两个参数:均值、方差,做的处理就是减均值,再除以方差。将图片转化到了(-1,1)之间
# 4.注意因为图片是灰度图,所以只有一个通道,如果是彩色图片,有三个通道,transforms.Normalize([a,b,c],[d,e,f])来表示每个通道对应的均值和方差。
data_tf = transforms.Compose([transforms.ToTensor(),
transforms.Normalize([0.5],[0.5])
])
# PyTorch 的内置函数 torchvision.datasets.MNIST 导入数据集
# 这里存储的还是MNIST数据集的格式,但是不一样的是这个数据集当中的元素是以tensor格式存储的
train_dataset = datasets.MNIST(
root = '/Users/air/Desktop/【2020秋】数据科学基础/第三次作业',
train = True,
transform = data_tf,
download = True
)
test_dataset = datasets.MNIST(
root = '/Users/air/Desktop/【2020秋】数据科学基础/第三次作业',
train = False,
transform = data_tf
)
# 定义超参数
BATCH_SIZE = 128 # 训练的包的大小,通过将训练包分为2的倍数以加快训练过程的方式
LR = 1e-2 # 学习率,学习率太小会减慢训练效果,学习率太高会导致准确率降低
EPOCHS = 5 # 定义循环次数,避免因为次数太多导致时间过长
# torch.utils.data.DataLoader 建立一个数据迭代器,传入数据集和 batch size, 通过 shuffle=True 来表示每次迭代数据的时候是否将数据打乱。
# 测试集无需打乱顺序;训练集打乱顺序,为了增加训练模型的泛化能力
# 但是由于这里的训练集本身就已经满足要求,所以打乱顺序对于泛化能力本身的提升并不是必要的
train_loader = torch.utils.data.DataLoader(train_dataset,
batch_size = BATCH_SIZE,
shuffle = True)
test_loader = torch.utils.data.DataLoader(test_data