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: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机

Python3 BeautifulSoup爬虫 POJ自动提交

POJ 提交代码采用Base64加密方式 import http.cookiejarimport loggingimport urllib.parseimport urllib.requestimport base64from bs4 import BeautifulSoupfrom submitcode import SubmitCodeclass SubmitPoj():de

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

python内置模块datetime.time类详细介绍

​​​​​​​Python的datetime模块是一个强大的日期和时间处理库,它提供了多个类来处理日期和时间。主要包括几个功能类datetime.date、datetime.time、datetime.datetime、datetime.timedelta,datetime.timezone等。 ----------动动小手,非常感谢各位的点赞收藏和关注。----------- 使用datet

C8T6超绝模块--EXTI

C8T6超绝模块–EXTI 大纲 控制流程结构体分析EXTI实现按键 具体案例 控制流程 这里是流程框图,具体可以去看我STM32专栏的EXTI的具体分析 结构体分析 typedef struct {uint32_t EXTI_Line; // 中断/事件线EXTIMode_TypeDef EXTI_Mode; // EXTI 模式EXTITrigger_TypeDef EXTI_

1、创建多模块的maven springboot项目

现在的java的项目都是多模块的,这次也跟个风。 目标:实现下述结构 项目AcedBoot, 子模块:         aced-api 对外提供接口,         aced-web 给前端提供接口,         aced-service 服务层,         aced-dao 数据底层,包含数据库mapper和实体类entity,         aced-commo

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl