pytorch实战案例-手写数字分类-卷积模型——深度AI科普团队
文章目录
- 数据准备
- 导入需要的模块
- 使用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科普团队相关推荐
- pytorch实战案例-手写数字分类-全链接模型——深度AI科普团队
文章目录 @[TOC] 数据准备 导入需要的模块 将数据转换为tensor 导入训练集和测试集 数据加载器 数据展示 创建模型 定义损失函数 定义优化函数 定义训练和测试函数 开始训练 源码已经上传: ...
- 如何为MNIST手写数字分类开发CNN
导言 MNIST手写数字分类问题是计算机视觉和深度学习中使用的标准数据集. 虽然数据集得到了有效的解决,但它可以作为学习和实践如何开发,评估和使用卷积深度学习神经网络从头开始进行图像分类的基础.这包括 ...
- PyTorch基础与简单应用:构建卷积神经网络实现MNIST手写数字分类
文章目录 (一) 问题描述 (二) 设计简要描述 (三) 程序清单 (四) 结果分析 (五) 调试报告 (六) 实验小结 (七) 参考资料 (一) 问题描述 构建卷积神经网络实现MNIST手写数字分类 ...
- 独家 | 如何从头开始为MNIST手写数字分类建立卷积神经网络(附代码)
翻译:张睿毅 校对:吴金笛 本文约9300字,建议阅读20分钟. 本文章逐步介绍了卷积神经网络的建模过程,最终实现了MNIST手写数字分类. MNIST手写数字分类问题是计算机视觉和深度学习中使用的标 ...
- 基于PyTorch框架的多层全连接神经网络实现MNIST手写数字分类
多层全连接神经网络实现MNIST手写数字分类 1 简单的三层全连接神经网络 2 添加激活函数 3 添加批标准化 4 训练网络 5 结论 参考资料 先用PyTorch实现最简单的三层全连接神经网络,然后 ...
- 深度学习代码实战——基于RNN的手写数字分类
文章目录 1.前言 2.导入模块.定义超参数 3.准备训练数据测试数据 4.构建模型并打印模型结构 5.损失函数和优化器 6.训练 7.测试 1.前言 循环神经网络让神经网络有了记忆, 对于序列型的数 ...
- Keras入门实战(1):MNIST手写数字分类
目录 1)首先我们加载Keras中的数据集 2)网络架构 3)选择编译(compile参数) 4)准备图像数据 5) 训练模型 6)测试数据 前面的博客中已经介绍了如何在Ubuntu下安装Keras深 ...
- 用PyTorch实现MNIST手写数字识别(非常详细)
Keras版本: Keras入门级MNIST手写数字识别超级详细教程 2022/4/17 更新修复下代码.完善优化下文章结构,文末提供一个完整版代码. 可以在这里下载源码文件(免积分): 用 ...
- 基于tensorflow+RNN的MNIST数据集手写数字分类
2018年9月25日笔记 tensorflow是谷歌google的深度学习框架,tensor中文叫做张量,flow叫做流. RNN是recurrent neural network的简称,中文叫做循环 ...
最新文章
- 计算机的c盘是硬盘吗,c盘是硬盘吗
- asm 比 ucontext 快
- xp与Vista双系统 相关问题
- OpenGL基于PBR的irradiance辐照度的实例
- 2015年的Java –重大事件
- Ubuntu18.04 安装搜狗输入法后无法启动的问题
- [剑指offer][JAVA][面试第40题][最小的k个数][快选][堆][BST]
- Linux系统编程-管道入门
- 癌症世界难题_癌强大的真相被发现了,这4个难题不攻克,癌症难以治愈
- ZK Framework(一、HelloWorld)
- C++安全方向opensssl(三)3.1 什么是单项散列函数
- 图解算法之排序算法(4)——堆排序
- 关于数据库设计是否需要加入(建立)外键
- 初级程序员如何写项目周报和月报
- 2021年40个最佳免费WordPress主题
- Apabi Reader 4.0.1正式发布!
- 在哪可以找c语言编程的答案,c语言程序设计课后习题答案.doc
- 离线打包报错缺少io.dcloud.PandoraEntry
- Allegro中anti-etch的作用
- 资源文件冲突error RC2151 : cannot reuse string constants, 61446(0xF006)
热门文章
- python语言控制结构是指_python程序的三种控制结构
- 【script】python使用pymssql模块访问SQL Server(Mssql)
- 【Linux】kali 2019.4 安装中文输入法
- 【Linux】Linux系统备份与还原
- yshon对讲机如何调频率_窄带宽、窄脉宽、高重复频率,主动调Q光纤激光器是如何实现的?...
- python坐标系转换库_转载:python库Pyproj进行坐标转换
- melogin.cn主页登录_melogin.cn登录官网
- 关于autotrace和explain plan是否可以反映真实的执行计划
- 百度前端学院参考答案:第二十五天到第二十七天 倒数开始 滴答滴 滴答滴(2)...
- HDU 3001 三进制状压DP