【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析

简介: Autograd模块:在神经网络的反向传播中,基于正向计算的结果进行微分计算,从而实现对于网络权重的更新与迭代,提供了张量的自动求微分功能,可以通过代码来实现对反向过程的控制,使得权重参数朝着目标结果进行更新与发展。

同学你好!本文章于2021年末编写,获得广泛的好评!


故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现,


Pytorch深度学习·理论篇(2023版)目录地址为:


CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录


本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!

https://v9999.blog.csdn.net/article/details/127587345


欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~


458e7a0083c741ca90c3b12eaf8e49ab.png


1 Variable类型与自动微分模块概述


1.1 Variable类型


Variable是由Autograd模块对张量进行进一步封装实现的,具有自动求导的功能


1.2 Autograd模块(自动求导模块)


Autograd模块:在神经网络的反向传播中,基于正向计算的结果进行微分计算,从而实现对于网络权重的更新与迭代,提供了张量的自动求微分功能,可以通过代码来实现对反向过程的控制,使得权重参数朝着目标结果进行更新与发展。


2 Variable类型与自动微分模块实战


2.1 Variable类型对象与张量对象之间的转化


2.1.1 代码实现


import torch
from torch.autograd import Variable
a = torch.FloatTensor([4]) #创建张量
print(Variable(a)) # 将张量转化为Variable对象
# 输出 tensor([4.])
print(Variable(a,requires_grad=True)) # requires_grad允许自动求导
# 输出 tensor([4.], requires_grad=True)
print(a.data) #将Variable对象转化为张量
# 输出 tensor([4.])


2.1.2 注意


import torch
from torch.autograd import Variable
### 使用requires_grad时,要求张量的值必须为浮点型
x = torch.tensor([1],requires_grad=True) #报错 
x = torch.tensor([1.],requires_grad=True) #正确写法


2.2 torch.no_grad()


2.2.1 概述


torch.no_grad():使Variable类型变量的requires_grad失效


torch.enable_grad():使Variable类型变量的requires_grad有效


2.2.2 使用torch.no_grad()配合with语句限制requires_grad的作用域


import torch
from torch.autograd import Variable
x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象
with torch.no_grad():
    y = x * 2
print(y.requires_grad) # 输出 False


2.2.3 使用装饰器@实现


import torch
from torch.autograd import Variable
### 在神经网络中将网络模型进行封装,使用装饰器方便实现开发的便捷性
x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象
@torch.no_grad()
def doubler(x):
    return x * 2
z = doubler(x)
print(z.requires_grad) # 输出 False


2.3 函数enable_grad()与no_grad()的嵌套使用


2.3.1 enable_grad()配合with语句限制requires_grad的作用域


import torch
x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象
with torch.no_grad():
    with torch.enable_grad():
        y = x * 2
        print(y.requires_grad) # True
    print(y.requires_grad) # True
print(y.requires_grad) # True


2.3.2 使用enable_grad装饰器


import torch
x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象
@torch.enable_grad()
def doubler(x): #封装到函数中
    return x * 2
with torch.no_grad(): #使得计算梯度失效
    z = doubler(x)
print(z.requires_grad) #True


2.3.3 作用在没有requires_grad的Variable类型变量上将会失效,不能使其重新获得计算梯度的属性


import torch
x = torch.ones(2,2) # 定义一个不需要梯度计算的Variable类型对象
with torch.enable_grad():
    y = x * 2
print(y.requires_grad) # False


2.3 set_grad_enabled()实现统一管理梯度计算


import torch
x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象
torch.set_grad_enabled(False) # 统一关闭梯度计算
y = x * 2
print(y.requires_grad) # False
torch.set_grad_enabled(True) # 统一开启梯度计算
y = x * 2
print(y.requires_grad) # True


2.4 Variable类型对象的grad_fn属性


2.4.1 grad_fn属性概述


Variable类型对象在经过前向传播后,将会增加一个grad_fn属性,该属性随着backward()方法进行自动的梯度计算。没有经过计算的Variable类型对象是没有这个属性的,在requires_grad=False的情况下,无论如何计算他都不会有grad_fn属性。


2.4.2 grad_fn属性代码实现


import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad=True)
print(x)
# 输出 tensor([[1., 1.],[1., 1.]], requires_grad=True)
print(x.grad_fn)
# 输出 None
m = x + 2 # 经过正向计算,获得grad_fn属性
print(m.grad_fn)
# 输出 <AddBackward0 object at 0x0000024E1AA14D00>
print(m.grad_fn(x)) #对x变量进行求梯度计算
# 输出 (tensor([[1., 1.],[1., 1.]], requires_grad=True), None)
x2 = torch.ones(2,2) # 创建一个不需要梯度计算的张量
m = x2 + 2
print(m.grad_fn)
# 输出 None


2.5 Variable类型对象的is_leaf函数


2.5.1 is_leaf()概述


1、定义Variable类型对象时,若将requires_grad设为True,则将该Variable类型对象称为种子节点,其 is_leaf的属性为True。


2、若Variable类型对象不是通过自定义生成的,而是通过其他张量计算所得时,则不是叶子节点,则该该Variable类型对象称为叶子节点,其 is_leaf的属性为False。


3、Pytorch会记录每个张量的由来,由此来在内存中行程树状结构实现反向链式计算,叶子节点主要在求导过程为递归循环提供信号指示,当反向链式计算遇到叶子节点则终止递归循环。


2.5.2 is_leaf()代码


import torch
from torch.autograd import Variable
x = Variable(torch.ones(2,2),requires_grad=True)
print(x.is_leaf) # True
m = x + 2
print(m.is_leaf) # False


2.6 backward()实现自动求导


2.6.1 backward()概述


backward():必须在当前变量内容是标量的情况下使用,否则会报错。


2.6.3 自动求导的作用


从复杂的神经网络中,自动将每一层中的每个参数的梯度计算出来,实现训练过程中的反向传播。


2.6.2 代码


import torch
from torch.autograd import Variable
### y = (x + 2)/4
x = Variable(torch.ones(2,2),requires_grad=True)
m = x + 2
f = m.mean() #得到一个标量
f.backward() # 自动求导
print(f) #输出 tensor(3., grad_fn=<MeanBackward0>)
print(x.grad) # 输出 tensor([[0.2500, 0.2500],[0.2500, 0.2500]])


2.7 detach()将Variable类型对象分离成种子节点


2.7.1 将需要求梯度的Variable类型对象转化为Numpy对象


import torch
from torch.autograd import Variable
### 如果被分离的Variable对象的volatile属性为True,那么被分离出的volatile属性也为True
### 被返回的Variable对象和被分离的Variable对象指向同一个张量,并且永远不会需要梯度
x = Variable(torch.ones(2,2),requires_grad=True)
# x.numpy() # 报错Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.
x1 = x.detach().numpy()
print(x1)# 输出 [[1.,1.],[1.,1.]]


2.7.2 实现对网络中的部分参数求梯度


10f6f06e5b60495984f95c0f8b274bf6.png


2.8 volatile属性


早期代码中可以通过设置Variable类型对象的volatile属性为True的方法来实现停止梯度更新。

目录
打赏
0
0
0
0
691
分享
相关文章
RT-DETR改进策略【Neck】| ASF-YOLO 注意力尺度序列融合模块改进颈部网络,提高小目标检测精度
RT-DETR改进策略【Neck】| ASF-YOLO 注意力尺度序列融合模块改进颈部网络,提高小目标检测精度
183 3
RT-DETR改进策略【Neck】| ASF-YOLO 注意力尺度序列融合模块改进颈部网络,提高小目标检测精度
基于Pytorch 在昇腾上实现GCN图神经网络
本文详细讲解了如何在昇腾平台上使用PyTorch实现图神经网络(GCN)对Cora数据集进行分类训练。内容涵盖GCN背景、模型特点、网络架构剖析及实战分析。GCN通过聚合邻居节点信息实现“卷积”操作,适用于非欧氏结构数据。文章以两层GCN模型为例,结合Cora数据集(2708篇科学出版物,1433个特征,7种类别),展示了从数据加载到模型训练的完整流程。实验在NPU上运行,设置200个epoch,最终测试准确率达0.8040,内存占用约167M。
基于Pytorch 在昇腾上实现GCN图神经网络
Perforated Backpropagation:神经网络优化的创新技术及PyTorch使用指南
深度学习近年来在多个领域取得了显著进展,但其核心组件——人工神经元和反向传播算法自提出以来鲜有根本性突破。穿孔反向传播(Perforated Backpropagation)技术通过引入“树突”机制,模仿生物神经元的计算能力,实现了对传统神经元的增强。该技术利用基于协方差的损失函数训练树突节点,使其能够识别神经元分类中的异常模式,从而提升整体网络性能。实验表明,该方法不仅可提高模型精度(如BERT模型准确率提升3%-17%),还能实现高效模型压缩(参数减少44%而无性能损失)。这一革新为深度学习的基础构建模块带来了新的可能性,尤其适用于边缘设备和大规模模型优化场景。
81 16
Perforated Backpropagation:神经网络优化的创新技术及PyTorch使用指南
基于Pytorch Gemotric在昇腾上实现GAT图神经网络
本实验基于昇腾平台,使用PyTorch实现图神经网络GAT(Graph Attention Networks)在Pubmed数据集上的分类任务。内容涵盖GAT网络的创新点分析、图注意力机制原理、多头注意力机制详解以及模型代码实战。实验通过两层GAT网络对Pubmed数据集进行训练,验证模型性能,并展示NPU上的内存使用情况。最终,模型在测试集上达到约36.60%的准确率。
基于Pytorch Gemotric在昇腾上实现GraphSage图神经网络
本实验基于PyTorch Geometric,在昇腾平台上实现GraphSAGE图神经网络,使用CiteSeer数据集进行分类训练。内容涵盖GraphSAGE的创新点、算法原理、网络架构及实战分析。GraphSAGE通过采样和聚合节点邻居特征,支持归纳式学习,适用于未见节点的表征生成。实验包括模型搭建、训练与验证,并在NPU上运行,最终测试准确率达0.665。
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
神经常微分方程(Neural ODEs)是深度学习领域的创新模型,将神经网络的离散变换扩展为连续时间动力系统。本文基于Torchdyn库介绍Neural ODE的实现与训练方法,涵盖数据集构建、模型构建、基于PyTorch Lightning的训练及实验结果可视化等内容。Torchdyn支持多种数值求解算法和高级特性,适用于生成模型、时间序列分析等领域。
289 77
PyTorch生态系统中的连续深度学习:使用Torchdyn实现连续时间神经网络
RT-DETR改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 StarNet,超级精简高效的轻量化模块
RT-DETR改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 StarNet,超级精简高效的轻量化模块
479 63
RT-DETR改进策略【模型轻量化】| 替换骨干网络 CVPR-2024 StarNet,超级精简高效的轻量化模块
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 MobileViTv1高效的信息编码与融合模块,获取局部和全局信息
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 MobileViTv1高效的信息编码与融合模块,获取局部和全局信息
286 62
RT-DETR改进策略【模型轻量化】| 替换骨干网络为 MobileViTv1高效的信息编码与融合模块,获取局部和全局信息
Deepseek 3FS解读与源码分析(2):网络通信模块分析
2025年2月28日,DeepSeek 正式开源其颠覆性文件系统Fire-Flyer 3FS(以下简称3FS),重新定义了分布式存储的性能边界。本文基于DeepSeek发表的技术报告与开源代码,深度解析 3FS 网络通信模块的核心设计及其对AI基础设施的革新意义。
Deepseek 3FS解读与源码分析(2):网络通信模块分析
RT-DETR改进策略【Neck】| ECCV-2024 RCM 矩形自校准模块 优化颈部网络
RT-DETR改进策略【Neck】| ECCV-2024 RCM 矩形自校准模块 优化颈部网络
180 10
RT-DETR改进策略【Neck】| ECCV-2024 RCM 矩形自校准模块 优化颈部网络

推荐镜像

更多
目录
AI助理
登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问

你好,我是AI助理

可以解答问题、推荐解决方案等