当前位置:首页 >> 编程语言 >> 【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析,acer a100

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

0evadmin 编程语言 1
文件名:【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析,acer a100 【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析

 

同学你好!本文章于2021年末编写,获得广泛的好评! 故在2022年末对本系列进行填充与更新,欢迎大家订阅最新的专栏,获取基于Pytorch1.10版本的理论代码(2023版)实现, Pytorch深度学习·理论篇(2023版)目录地址为:

CSDN独家 | 全网首发 | Pytorch深度学习·理论篇(2023版)目录本专栏将通过系统的深度学习实例,从可解释性的角度对深度学习的原理进行讲解与分析,通过将深度学习知识与Pytorch的高效结合,帮助各位新入门的读者理解深度学习各个模板之间的关系,这些均是在Pytorch上实现的,可以有效的结合当前各位研究生的研究方向,设计人工智能的各个领域,是经过一年时间打磨的精品专栏!https://v9999.blog.csdn.net/article/details/127587345欢迎大家订阅(2023版)理论篇

以下为2021版原文~~~~

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

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

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

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

2 Variable类型与自动微分模块实战 2.1 Variable类型对象与张量对象之间的转化 2.1.1 代码实现 import torchfrom torch.autograd import Variablea = 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 torchfrom 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 torchfrom torch.autograd import Variablex = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象with torch.no_grad():y = x * 2print(y.requires_grad) # 输出 False 2.2.3 使用装饰器@实现 import torchfrom torch.autograd import Variable### 在神经网络中将网络模型进行封装,使用装饰器方便实现开发的便捷性x = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象@torch.no_grad()def doubler(x):return x * 2z = doubler(x)print(z.requires_grad) # 输出 False 2.3 函数enable_grad()与no_grad()的嵌套使用 2.3.1 enable_grad()配合with语句限制requires_grad的作用域 import torchx = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象with torch.no_grad():with torch.enable_grad():y = x * 2print(y.requires_grad) # Trueprint(y.requires_grad) # Trueprint(y.requires_grad) # True 2.3.2 使用enable_grad装饰器 import torchx = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象@torch.enable_grad()def doubler(x): #封装到函数中return x * 2with torch.no_grad(): #使得计算梯度失效z = doubler(x)print(z.requires_grad) #True 2.3.3 作用在没有requires_grad的Variable类型变量上将会失效,不能使其重新获得计算梯度的属性 import torchx = torch.ones(2,2) # 定义一个不需要梯度计算的Variable类型对象with torch.enable_grad():y = x * 2print(y.requires_grad) # False 2.3 set_grad_enabled()实现统一管理梯度计算 import torchx = torch.ones(2,2,requires_grad=True) # 定义一个需要梯度计算的Variable类型对象torch.set_grad_enabled(False) # 统一关闭梯度计算y = x * 2print(y.requires_grad) # Falsetorch.set_grad_enabled(True) # 统一开启梯度计算y = x * 2print(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 torchfrom torch.autograd import Variablex = Variable(torch.ones(2,2),requires_grad=True)print(x)# 输出 tensor([[1., 1.],[1., 1.]], requires_grad=True)print(x.grad_fn)# 输出 Nonem = 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 + 2print(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 torchfrom torch.autograd import Variablex = Variable(torch.ones(2,2),requires_grad=True)print(x.is_leaf) # Truem = x + 2print(m.is_leaf) # False 2.6 backward()实现自动求导 2.6.1 backward()概述

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

2.6.3 自动求导的作用

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

2.6.2 代码 import torchfrom torch.autograd import Variable### y = (x + 2)/4x = Variable(torch.ones(2,2),requires_grad=True)m = x + 2f = 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 torchfrom 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 实现对网络中的部分参数求梯度

 2.8 volatile属性

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

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接