Pytorch-自动微分模块

2024-04-20 07:36
文章标签 模块 自动 pytorch 微分

本文主要是介绍Pytorch-自动微分模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

49739c720cb4452c9336253d032fc756.gif

🥇接下来我们进入到Pytorch的自动微分模块torch.autograd~

自动微分模块是PyTorch中用于实现张量自动求导的模块。PyTorch通过torch.autograd模块提供了自动微分的功能,这对于深度学习和优化问题至关重要,因为它可以自动计算梯度,无需手动编写求导代码。torch.autograd模块的一些关键组成部分:

  1. 函数的反向传播torch.autograd.function 包含了一系列用于定义自定义操作的函数,这些操作可以在反向传播时自动计算梯度。
  2. 计算图的反向传播torch.autograd.functional 提供了一种构建计算图并自动进行反向传播的方式,这类似于其他框架中的符号式自动微分。
  3. 数值梯度检查torch.autograd.gradcheck 用于检查数值梯度与自动微分得到的梯度是否一致,这是确保正确性的一个有用工具。
  4. 错误检测模式torch.autograd.anomaly_mode 在自动求导时检测错误产生路径,有助于调试。
  5. 梯度模式设置torch.autograd.grad_mode 允许用户设置是否需要梯度,例如在模型评估时通常不需要计算梯度。
  6. 求导方法:PyTorch提供backward()torch.autograd.grad()两种求梯度的方法。backward()会将梯度填充到叶子节点的.grad字段,而torch.autograd.grad()直接返回梯度结果。
  7. requires_grad属性:在创建张量时,可以通过设置requires_grad=True来指定该张量是否需要进行梯度计算。这样在执行操作时,PyTorch会自动跟踪这些张量的计算过程,以便后续进行梯度计算。

梯度基本计算

def func1():x = torch.tensor(10, requires_grad=True, dtype=torch.float64)f = x ** 2 +10# 自动微分求导f.backward()   # 反向求导# backward 函数计算的梯度值会存储在张量的 grad 变量中print(x.grad)
def func2():x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)# 变量经过中间计算f1 = x ** 2 + 10# f2 = f1.mean()  # 平均损失,相当于每个值/4f2 = f1.sum()  # 求和损失,相当于每个值*1f2.backward()print(x.grad)
def func3():x1 = torch.tensor(10, requires_grad=True, dtype=torch.float64)x2 = torch.tensor(20, requires_grad=True, dtype=torch.float64)y = x1 ** 2 + x2 ** 2 + x1 * x2y = y.sum()y.backward()print(x1.grad, x2.grad)def func4():x1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)x2 = torch.tensor([30, 40], requires_grad=True, dtype=torch.float64)y = x1 ** 2 + x2 ** 2 + x1 * x2y = y.sum()y.backward()print(x1.grad,x2.grad)

func1func2,它们分别处理标量张量和向量张量的梯度计算。

  • func1中,首先创建了一个标量张量x,并设置requires_grad=True以启用自动微分。然后计算f = x ** 2 + 10,接着使用f.backward()进行反向求导。最后,通过打印x.grad输出梯度值。
  • func2中,首先创建了一个向量张量x,并设置requires_grad=True以启用自动微分。然后计算f1 = x ** 2 + 10,接着使用f1.sum()对向量张量进行求和操作,得到一个标量张量f2。最后,使用f2.backward()进行反向求导。
  • func3func4分别求多个标量和向量的情况,与上面相似。

控制梯度计算

我们可以通过一些方法使 requires_grad=True 的张量在某些时候计算时不进行梯度计算。 

  1. 第一种方式是使用torch.no_grad()上下文管理器,在这个上下文中进行的所有操作都不会计算梯度。
  2. 第二种方式是通过装饰器@torch.no_grad()来装饰一个函数,使得这个函数中的所有操作都不会计算梯度。
  3. 第三种方式是通过torch.set_grad_enabled(False)来全局关闭梯度计算功能,之后的所有操作都不会计算梯度,直到下一次再次调用此方法torch.set_grad_enabled(True)开启梯度计算功能。
x = torch.tensor(10, requires_grad=True, dtype=torch.float64)
print(x.requires_grad)# 第一种方式: 对代码进行装饰
with torch.no_grad():y = x ** 2
print(y.requires_grad)# 第二种方式: 对函数进行装饰
@torch.no_grad()
def my_func(x):return x ** 2
print(my_func(x).requires_grad)# 第三种方式
torch.set_grad_enabled(False)
y = x ** 2
print(y.requires_grad)

默认张量的 grad 属性会累计历史梯度值,如果需要重复计算每次的梯度,就需要手动清除。

x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)for _ in range(3):f1 = x ** 2 + 20f2 = f1.mean()if x.grad is not None:x.grad.data.zero_()   # 本身来改动f2.backward()print(x.grad)

x.grad不是x,因为x是一个tensor张量,而x.grad是x的梯度。在PyTorch中,张量的梯度是通过自动求导机制计算得到的,而不是直接等于张量本身。

梯度下降优化最优解

x = torch.tensor(10, requires_grad=True, dtype=torch.float64)for _ in range(5000):f = x ** 2# 梯度清零if x.grad is not None:x.grad.data.zero_()# 反向传播计算梯度f.backward()# 更新参数x.data = x.data - 0.001 * x.gradprint('%.10f' % x.data)

更新参数相当于通过学习率对当前数值进行迭代。

f.backward()是PyTorch中自动梯度计算的函数,用于计算张量`f`关于其所有可学习参数的梯度。在这个例子中,`f`是一个标量张量,它只有一个可学习参数`x`。当调用f.backward()`时,PyTorch会自动计算`f`关于`x`的梯度,并将结果存储在`x.grad`中。这样,我们就可以使用这个梯度来更新`x`的值,以便最小化损失函数`f`。

梯度计算注意

当对设置 requires_grad=True 的张量使用 numpy 函数进行转换时, 会出现如下报错:

Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.

此时, 需要先使用 detach 函数将张量进行分离, 再使用 numpy 函数。detach 之后会产生一个新的张量, 新的张量作为叶子结点,并且该张量和原来的张量共享数据, 但是分离后的张量不需要计算梯度。

import torchdef func1():x = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.# print(x.numpy())  # 错print(x.detach().numpy())  def func2():x1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# x2 作为叶子结点x2 = x1.detach()# 两个张量的值一样: 140421811165776 140421811165776print(id(x1.data), id(x2.data))x2.data = torch.tensor([100, 200])print(x1)print(x2)# x2 不会自动计算梯度: Falseprint(x2.requires_grad)

7017d1cccb2c45cd845fefae64ed1947.gif

 

这篇关于Pytorch-自动微分模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/919655

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

python urllib模块使用操作方法

《pythonurllib模块使用操作方法》Python提供了多个库用于处理URL,常用的有urllib、requests和urlparse(Python3中为urllib.parse),下面是这些... 目录URL 处理库urllib 模块requests 库urlparse 和 urljoin编码和解码

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录

idea Maven Springboot多模块项目打包时90%的问题及解决方案

《ideaMavenSpringboot多模块项目打包时90%的问题及解决方案》:本文主要介绍ideaMavenSpringboot多模块项目打包时90%的问题及解决方案,具有很好的参考价值,... 目录1. 前言2. 问题3. 解决办法4. jar 包冲突总结1. 前言之所以写这篇文章是因为在使用Mav

SpringBoot实现RSA+AES自动接口解密的实战指南

《SpringBoot实现RSA+AES自动接口解密的实战指南》在当今数据泄露频发的网络环境中,接口安全已成为开发者不可忽视的核心议题,RSA+AES混合加密方案因其安全性高、性能优越而被广泛采用,本... 目录一、项目依赖与环境准备1.1 Maven依赖配置1.2 密钥生成与配置二、加密工具类实现2.1

Python标准库datetime模块日期和时间数据类型解读

《Python标准库datetime模块日期和时间数据类型解读》文章介绍Python中datetime模块的date、time、datetime类,用于处理日期、时间及日期时间结合体,通过属性获取时间... 目录Datetime常用类日期date类型使用时间 time 类型使用日期和时间的结合体–日期时间(