深度学习PyTorch框架构建神经网络、分类器

本文介绍了PyTorch的基本元素和运算操作,包括Tensor、Numpy转换及CUDA使用。详细阐述了autograd的原理和Tensor的属性。通过构建神经网络和分类器,演示了损失函数、反向传播和参数更新的过程。最后,展示了在GPU上训练模型的方法,并对CIFAR10数据集进行了分类实验。
摘要由CSDN通过智能技术生成

框架:Pytorch
语言:Python
IDE:jupyter notebook


前言

  Pytorch:pytorch是一个基于Numpy的科学计算包,向用户提供两大功能:

  • 作为Numpy的替代者,向用户提供使用GPU强大功能的能力。
  • 作为一款深度学习框架,向用户提供最大的灵活性和速度。

pytorch


零、安装Pytorch

Pytorch安装参考


一、Pytorch的基本元素操作

  • Tensors张量:张量的概念类似于Numpy中的ndarray数据结构,最大的区别在于Tensor可以利用GPU的加速功能。
  • 我们使用Pytorch的时候,常规步骤是先将torch引用进来:
from __future__ import print_function
import torch
  • 创建矩阵的操作

注意:当声明一个未初始化的矩阵时,它本身不包含任何确切数据的值,当创建一个未初始化的矩阵时,分配给矩阵的内存中有什么数值就赋值给了这个矩阵,本质上是毫无意义的数据。

pt

pt

pt
pt

第一个张量初始化类型是double,第二个类型是float两个张量尺寸相同都是5行3列

x.new_ones(m,n,dtype=touch.double() #新生成:m行n列类型为double的张量

pt
注意:torch函数本质上返回的是一个tuple(元组),因此它支持一切元组操作
pt


二、Pytorch基本运算操作

算术操作

pt

索引操作(接上面的代码)

pt

pt
一定保证数据个数不变:否则出错
pt
item():
pt
pt

Torch Tensor 和Numpy array之间的相互转换

Torch Tensor和Numpy array共享底层的内存空间,因此改变其中一个的值,另一个也会随之改变
pt
Numpy array转换成Torch Tensor: 所有在CPU上的Tensors,出了Char Tensor都可以转换为Numpy array并可以反向转换。
pt

关于CUDA Tensor:Tensor可以用.to()方法来将其移动到任意设备

pt


三、torch.Tensor类中的相关应用

Pytorch中的autograd

  在整个Pytorch框架中,所有的神经网络本质上都是一个autograd package(自动求导工具包)。autograd package 提供了一个对Tensors(张量)上所有的操作进行自动微分的功能。

torch.Tensor

  torch.Tensor是整个package中的核心类,如果将属性requires_grad设置为True,它将追踪在这个类上定义的所有操作。(例:定义一个矩阵,一直追踪该矩阵的操作)当代码要进行反向传播时的时候。直接调用.backward()就可以自动计算所有梯度。在这个Tensor上的所有梯度将被累加进属性.grad中。
  如果想终止一个Tensor在计算图中的回溯,只要执行.detach()就可以将该Tensor从计算图中撇下,在未来的回溯计算中也不会再有该Tensor。
  除了.detach(),如果想终止对计算图的回溯,也就是不再进行方向传播求导过程,也可以采用代码块的方式with torch.no_grad()。这种方式非常适用于对模型进行预测的时候。因为预测阶段不再需要对梯度进行计算。

torch.Function

  Function类是和Tensor类同等重要的一个核心类,它和Tensor共同构建了一个完整的类,每一个Tensor拥有一个.grad_fn属性,代表引用了哪个具体的Function创建了Tensor.
  如果某个张量Tensor是用户自定义的,则具对应的grad_fn is None.

关于Tensor的操作

pt
所有包含下划线 _ 的操作为inplace操作(原地操作)
应该说rand是从0-1的均匀分布中随机抽样,randn是从正态分布中抽样
pt

关于梯度Gradients

在Pytorch中,反向传播是依靠.backward()实现的
pt
pt
说明:

  • 建议大量使用代码块的限制requires_grad,不建议大量使用.detach(),方便项目中做调试
  • x.grad_fn用来输出运算的属性(此时进行了什么运算)
  • a.requires_grad_(True)直接改变requires_grad属性
  • x.grad输出梯度
  • 可以通过.detach()获得一个新的Tensor,拥有相同的内容但不需要自动求导(见上例x和y)

四、PyTorch初步应用(构建神经网络、构建分类器)

使用Pytorch构建一个神经网络

使用Pytorch来构建神经网络,主要的工具都在torch.nn包中 (nn:Neural Network)
nn依赖autograd来定义模型,并对其自动求导

构建神经网络典型流程:

  • 定义一个拥有可学习参数的神经网络 (Cass Net)
  • 遍历训练数据集
  • 处理输入数据使其流经神经网络 (把数据灌入神经网络中)
  • 计算损失值 (计算前选择损失函数)
  • 将网络参数的梯度进行反向传播 loss.backward()
  • 以一定的规则更新网络的权重 (SGD、Adam…)

代码实例:一共5层,两个卷积层,3个全连接层 初始化函数、前项forward函数必写

pt

kernel_size :卷积核; stride:步长; in_features:输入维度; out_features:输出维度

模型中所有的可训练参数,可以通过net.parameters()来获得
pt

pt

在这里插入图片描述
注意:torch.nn构建的神经网络只支持mini-batches的输入,不支持单一样本输入(只接受一批次一批次输入,不能一条一条往里输入)
比如:nn.Conv2d需要一个 4DTensors形状为(nSamples,nChannels,Height,Width)(样本个数,几个通道,高,宽)。如果你的输入只有单一样本形式(后三维(高,宽,输入通道3),则需要执行input.unsqueeze(0),第零个维度增加一个维度即(3,32,32)改为(1,3,32,32),主动将3DTensor扩充成4DTensor。

损失函数

  损失函数的输入是一个输入的对:(output,target)(神经网络输出,真实标签),然后计算出一个数值来评估output(预测)和target(目标标签)之间的差距大小。
  在torch.nn中有若干个不同的损失函数可供使用,比如nn.MSELoss就是通过计算均方差损失来评估输入和目标值之间的差距。

pt

pt
总结:

  • torch.nn.MSELoss()计算均方误差
  • 当通过loss.backward()进行反向传播计算时,整张计算图将loss进行自动求导,所有属性require_grad=True的Tensors都将参与梯度求导运算,并将梯度累加到Tensors中的grad属性中

反向传播

在Pytorch中执行反向传播非常简便,全部操作就是loss.backward()
在执行反向传播之前,要先将梯度清零代码:net.zero_grad(),否则梯度会在不同的批次数据之间被累加

pt

更新网络参数

更新参数最简单的算法是SGD(随机梯度下降)
具体的算法公式是为:weight = weight - learning_rate(学习率) * gradient

#更新参数最简单的算法是SGD(随机梯度下降)
#具体的算法公式是为:weight = weight - learning_rate(学习率) * gradient 
learning_rate = 0.01
for f in net.parameters():     #遍历所有参数    sub_表示就地做减法运算
    f.date.sub_(f.grad.data * learning_rate) # weight = f.grad.data 

pt

#参数的更新方法重要:
#创建优化器对象   所有参数net.parameters() lr给一个学习率
optimizer = optim.SGD(net.parameters(), lr = 0.01)
#通过优化器来执行具体的参数更新
optimizer.step()      

使用Pytorch构建一个分类器

分类器任务和数据介绍

分类器任务: 构造一个将不同图像进行分类的神经网络分类器,对输入的图片进行辨别并完成分类(单一分类,每一个数据一个标签)

数据集: CIFA10数据集

CIFAR10数据集介绍:数据集中每张图片的尺寸是 3 * 32 * 32 彩色图,3代表彩色三通道
CIFAR10数据集共有 10种 不同的分类,分别是"airplane",“automobile”,“bird”,“cat”,“deer”,“dog”,“frog”,“horse”,“ship”,“truck”。
pt

分类器步骤(五步骤):

  1. 使用torchvision下载CIFAR10数据集
  2. 定义卷积神经网路 (class Net)
  3. 定义损失函数 nn.CrossEntropyLoss()
  4. 在训练集上训练模型
  5. 在测试集上测试模型

使用torchvision下载CIFAR10数据集

导入torchvision包来辅助下载数据集
pt
如果下的慢可以直接点结果中的链接使用其他下载方式下载,之后放到指定位置,重新运行代码(因为代码中需要编码)shuffle=True 意思就是数据顺序是打乱的
pt
展示数据
pt

定义卷积神经网络

仿照前边的类构造此处的类,唯一的区别是是此处采用3通道3-channel
2个卷积 1个池化 3个全连接
pt

定义损失函数

采用交叉熵损失函数和随机梯度下降优化器

#定义损失函数
#采用交叉熵损失函数和随机梯度下降优化器
import torch.optim as optim                                  #官方推荐使用的优化器包

#定义损失函数
criterion = nn.CrossEntropyLoss()                             #交叉熵损失函数

#定义优化器 选择随机梯度下降优化器  三个参数 所有可训练的参数net.parameters() lr学习率(越小越好),momentum=0.9动量不要太小(不一定需要)
optimizer = optim.SGD(net.parameters(),lr=0.001,momentum=0.9) 

在训练集上训练模型

采用基于梯度下降的优化算法,都需要很多个轮次的迭代训练 ,从结果上显示loss损失在下降
pt
注意:保存的是状态字典 net.state_dict()

训练时CPU会飞速转!!!
pt
训练的模型会生成在规定的路径下
pt

在测试集上测试模型

打印测试集 %5s标签超不过5个字母
pt
加载模型并对测试图片进行预测 根据结果显示,模型有错误,还不完美
pt
重要:net.load_state_dict(torch.load(PATH))
先把原先的模型文件(torch.save(net.state_dict(),PATH))load进来,再从文件里把dict字典load进来

看一下在全部测试集上的表现,准确率55%
pt
分析结果: 对于拥有10个类别的数据集,随机猜测的准确率是10%,模型达到了55%,说明模型学到了真实的东西!如果10%或9%等等,说明没学到什么!

分别测试不同类别的模型准确率。不同类别差别差别巨大
pt

在GPU上训练模型

验证GPU
gpu
当训练模型的时候,只需要将模型转移到GPU上,同时将输入的图片和标签页转移到GPU上即可

#当训练模型的时候,只需要将模型转移到GPU上,同时将输入的图片和标签页转移到GPU上即可
#将模型转移到GPU上
net.to(device)
#将输入的图片张量和标签张量转移到GPU上
inputs,labels = data[0].to(device),data[1].to(device)

总结

以上就是简单的深度学习PyTorch框架构建神经网络、分类器

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值