文章目录

  • 数据准备
    • 导入需要的模块
  • 使用GPU训练
    • 将数据转换为tensor
    • 导入训练集和测试集
  • 数据加载器
  • 数据展示
  • 创建模型
    • 将模型复制到GPU
    • 损失函数
  • 定义训练和测试函数
    • 开始训练

源码已经上传:手写数字识别参考代码和数据集


数据准备

导入需要的模块

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
import torchvision
from torchvision import datasets, transforms
%matplotlib inline

torch.nn为我们提供了更多的类和模块来实现和训练神经网络。具体函数可参考:http://www.srcmini.com/31857.html

torch.optim是一个实现了多种优化算法的包,大多数通用的方法都已支持,提供了丰富的接口调用,未来更多精炼的优化算法也将整合进来。

torchvision内置了常用数据集和最常见的模型。

vision.datasets : 几个常用视觉数据集,可以下载和加载,这里主要的高级用法就是可以看源码如何自己写自己的Dataset的子类
vision.models : 流行的模型,例如 AlexNet, VGG, ResNet 和 Densenet 以及 与训练好的参数。
vision.transforms : 常用的图像操作,例如:随机切割,旋转,数据类型转换,图像到tensor ,numpy 数组到tensor , tensor 到 图像等。
vision.utils : 用于把形似 (3 x H x W) 的张量保存到硬盘中,给一个mini-batch的图像可以产生一个图像格网。

使用GPU训练

在GPU上训练只需两步:

  • 将模型转移到GPU
  • 将每一个批次的训练数据转移到GPU

这里查看gpu是否可以用

torch.__version__,torch.cuda.is_available()

这里是如果有多块GPU,只选用第一块

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
devicedevice(type='cuda', index=0)

将数据转换为tensor

这是一个数据处理函数,transforms.Compose可以组合几个变换连续一起操作,这里只是将数据转换为tensor

transformation = transforms.Compose([transforms.ToTensor(),
])

导入训练集和测试集

datasets.MNIST(
root,
train=True,
transform=None,
target_transform=None,
download=False,
)
root 取数据的地址
train 设置是读取train数据集 还是test lecun的数据集有4个
transform就是对图像数据进行处理 传入dataloader的transform类型
target_transform(可调用,可选)–接受目标并对其进行转换的函数/转换。
download 设置 强调是否一定要download

这里用了上面定义的数据处理函数,对读取的minist数据进行totensor操作。

train_ds = datasets.MNIST('data/',train=True,transform=transformation,download=True
)
test_ds = datasets.MNIST('data/',train=False,transform=transformation,download=True
)

数据加载器

torch.utils.data.DataLoader数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集。

在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据。直至把所有的数据都抛出。就是做一个数据的初始化。

如下第一个函数就是将训练集生成迭代数据,每次迭代的数据为64个,shuffle为洗牌操作,即打乱顺序。

train_dl = torch.utils.data.DataLoader(train_ds, batch_size=64, shuffle=True)
test_dl = torch.utils.data.DataLoader(test_ds, batch_size=256)

train_dl本质上是一个可迭代对象,可以使用iter()进行访问,采用iter(dataloader)返回的是一个迭代器,然后可以使用next()访问。
也可以使用enumerate(dataloader)的形式访问。

imgs, labels = next(iter(train_dl))
imgs.shape ,labels.shape(torch.Size([64, 1, 28, 28]), torch.Size([64]))

数据展示

img = imgs[0]
img.shape # torch.Size([1, 28, 28])
# 将tensor转换为numpy
img = img.numpy()
# 从数组的形状中删除单维条目,即把shape中为1的维度去掉
img = np.squeeze(img)
img.shape(28, 28)
plt.imshow(img)

创建模型

nn.Conv2d(self, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True))
参数:
  in_channel: 输入数据的通道数,例RGB图片通道数为3;
  out_channel: 输出数据的通道数,这个根据模型调整;
  kennel_size: 卷积核大小,可以是int,或tuple;kennel_size=2,意味着卷积大小2, kennel_size=(2,3),意味着卷积在第一维度大小为2,在第二维度大小为3;
  stride:步长,默认为1,与kennel_size类似,stride=2,意味在所有维度步长为2, stride=(2,3),意味着在第一维度步长为2,意味着在第二维度步长为3;
  padding: 零填充

class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)
kernel_size(int or tuple) - max pooling的窗口大小,
stride(int or tuple, optional) - max pooling的窗口移动的步长。默认值是kernel_size
padding(int or tuple, optional) - 输入的每一条边补充0的层数
dilation(int or tuple, optional) – 一个控制窗口中元素步幅的参数
return_indices - 如果等于True,会返回输出最大值的序号,对于上采样操作会有帮助
ceil_mode - 如果等于True,计算输出信号大小的时候,会使用向上取整,代替默认的向下取整的操作

class Model(nn.Module):def __init__(self):# 继承model的所有父类super().__init__()# 输入通道为单通道的(灰度图),输出通道为6通道,卷积核大小为5*5,# 也就相当于用6个5*5的卷积核对这个图像进行卷积操作self.conv1 = nn.Conv2d(1, 6, 5)# 这里是用了最大池化,kernel为2,步长为2self.pool = nn.MaxPool2d((2, 2))# 6为上一层的输出通道数,然后用16个5*5的卷积核进行卷积self.conv2 = nn.Conv2d(6, 16, 5) # 添加全连接层,进行分类,也就是将卷积后的数据展开,为16个4*4的图像, # 下层的输入为上层的输出,所以16*4*4self.liner_1 = nn.Linear(16*4*4, 256)self.liner_2 = nn.Linear(256, 10)def forward(self, input):# 卷积 由28*28 ->24*24x = F.relu(self.conv1(input))# 最大池化 24*24 -> 12*12x = self.pool(x)# 卷积 由12*12 ->8*8x = F.relu(self.conv2(x))# 最大池化-> 4*4 x = self.pool(x)# view()函数作用是将一个多行的Tensor,拼接成一行。x = x.view(-1, 16*4*4)# 加到全连接后relu激活x = F.relu(self.liner_1(x))# 输出层x = self.liner_2(x)return x

将模型复制到GPU

model = Model()
model.to(device)

损失函数

loss_fn = torch.nn.CrossEntropyLoss()  # 损失函数

定义训练和测试函数

def fit(epoch, model, trainloader, testloader):correct = 0total = 0running_loss = 0for x, y in trainloader:# 将训练数据放入显存x, y = x.to(device), y.to(device)# x是数值特征,y是lebel,y_pred是x的预测值y_pred = model(x)# 得到损失值loss = loss_fn(y_pred, y)# 将梯度置为0optim.zero_grad()# 反向传播loss.backward()# 优化optim.step()# torch.no_grad() 是一个上下文管理器,被该语句包起来的部分将不会追踪梯度。with torch.no_grad():# 这里是找预测值最大的那个数的位置,如果在第五个位置上,该预测值就是5y_pred = torch.argmax(y_pred, dim=1)# 一个元素张量可以用item得到元素值# 所有正确的加起来correct += (y_pred == y).sum().item()total += y.size(0)# 损失值加起来running_loss += loss.item()epoch_loss = running_loss / len(trainloader.dataset)epoch_acc = correct / totaltest_correct = 0test_total = 0test_running_loss = 0 # 测试集的操作with torch.no_grad():for x, y in testloader:x, y = x.to(device), y.to(device)y_pred = model(x)loss = loss_fn(y_pred, y)y_pred = torch.argmax(y_pred, dim=1)test_correct += (y_pred == y).sum().item()test_total += y.size(0)test_running_loss += loss.item()epoch_test_loss = test_running_loss / len(testloader.dataset)epoch_test_acc = test_correct / test_totalprint('epoch: ', epoch, 'loss: ', round(epoch_loss, 3),'accuracy:', round(epoch_acc, 3),'test_loss: ', round(epoch_test_loss, 3),'test_accuracy:', round(epoch_test_acc, 3))return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc

开始训练

for epoch in range(epochs):epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch,model,                                                          train_dl,                                                         test_dl)

pytorch实战案例-手写数字分类-卷积模型——深度AI科普团队相关推荐

  1. pytorch实战案例-手写数字分类-全链接模型——深度AI科普团队

    文章目录 @[TOC] 数据准备 导入需要的模块 将数据转换为tensor 导入训练集和测试集 数据加载器 数据展示 创建模型 定义损失函数 定义优化函数 定义训练和测试函数 开始训练 源码已经上传: ...

  2. 如何为MNIST手写数字分类开发CNN

    导言 MNIST手写数字分类问题是计算机视觉和深度学习中使用的标准数据集. 虽然数据集得到了有效的解决,但它可以作为学习和实践如何开发,评估和使用卷积深度学习神经网络从头开始进行图像分类的基础.这包括 ...

  3. PyTorch基础与简单应用:构建卷积神经网络实现MNIST手写数字分类

    文章目录 (一) 问题描述 (二) 设计简要描述 (三) 程序清单 (四) 结果分析 (五) 调试报告 (六) 实验小结 (七) 参考资料 (一) 问题描述 构建卷积神经网络实现MNIST手写数字分类 ...

  4. 独家 | 如何从头开始为MNIST手写数字分类建立卷积神经网络(附代码)

    翻译:张睿毅 校对:吴金笛 本文约9300字,建议阅读20分钟. 本文章逐步介绍了卷积神经网络的建模过程,最终实现了MNIST手写数字分类. MNIST手写数字分类问题是计算机视觉和深度学习中使用的标 ...

  5. 基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类

    多层全连接神经网络实现MNIST手写数字分类 1 简单的三层全连接神经网络 2 添加激活函数 3 添加批标准化 4 训练网络 5 结论 参考资料 先用PyTorch实现最简单的三层全连接神经网络,然后 ...

  6. 深度学习代码实战——基于RNN的手写数字分类

    文章目录 1.前言 2.导入模块.定义超参数 3.准备训练数据测试数据 4.构建模型并打印模型结构 5.损失函数和优化器 6.训练 7.测试 1.前言 循环神经网络让神经网络有了记忆, 对于序列型的数 ...

  7. Keras入门实战(1):MNIST手写数字分类

    目录 1)首先我们加载Keras中的数据集 2)网络架构 3)选择编译(compile参数) 4)准备图像数据 5) 训练模型 6)测试数据 前面的博客中已经介绍了如何在Ubuntu下安装Keras深 ...

  8. 用PyTorch实现MNIST手写数字识别(非常详细)

    ​​​​​Keras版本: Keras入门级MNIST手写数字识别超级详细教程 2022/4/17 更新修复下代码.完善优化下文章结构,文末提供一个完整版代码. 可以在这里下载源码文件(免积分): 用 ...

  9. 基于tensorflow+RNN的MNIST数据集手写数字分类

    2018年9月25日笔记 tensorflow是谷歌google的深度学习框架,tensor中文叫做张量,flow叫做流. RNN是recurrent neural network的简称,中文叫做循环 ...

最新文章

  1. 计算机的c盘是硬盘吗,c盘是硬盘吗
  2. asm 比 ucontext 快
  3. xp与Vista双系统 相关问题
  4. OpenGL基于PBR的irradiance辐照度的实例
  5. 2015年的Java –重大事件
  6. Ubuntu18.04 安装搜狗输入法后无法启动的问题
  7. [剑指offer][JAVA][面试第40题][最小的k个数][快选][堆][BST]
  8. Linux系统编程-管道入门
  9. 癌症世界难题_癌强大的真相被发现了,这4个难题不攻克,癌症难以治愈
  10. ZK Framework(一、HelloWorld)
  11. C++安全方向opensssl(三)3.1 什么是单项散列函数
  12. 图解算法之排序算法(4)——堆排序
  13. 关于数据库设计是否需要加入(建立)外键
  14. 初级程序员如何写项目周报和月报
  15. 2021年40个最佳免费WordPress主题
  16. Apabi Reader 4.0.1正式发布!
  17. 在哪可以找c语言编程的答案,c语言程序设计课后习题答案.doc
  18. 离线打包报错缺少io.dcloud.PandoraEntry
  19. Allegro中anti-etch的作用
  20. 资源文件冲突error RC2151 : cannot reuse string constants, 61446(0xF006)

热门文章

  1. python语言控制结构是指_python程序的三种控制结构
  2. 【script】python使用pymssql模块访问SQL Server(Mssql)
  3. 【Linux】kali 2019.4 安装中文输入法
  4. 【Linux】Linux系统备份与还原
  5. yshon对讲机如何调频率_窄带宽、窄脉宽、高重复频率,主动调Q光纤激光器是如何实现的?...
  6. python坐标系转换库_转载:python库Pyproj进行坐标转换
  7. melogin.cn主页登录_melogin.cn登录官网
  8. 关于autotrace和explain plan是否可以反映真实的执行计划
  9. 百度前端学院参考答案:第二十五天到第二十七天 倒数开始 滴答滴 滴答滴(2)...
  10. HDU 3001 三进制状压DP