当前位置: 首页 > news >正文

PyTorch_自动微分模块

自动微分 (Autograd) 模块对张量做了进一步的封装,具有自动求导功能。自动微分模块是构成神经网络训练的必要模块,在神经网络的反向传播过程中,Autograd 模块基于正向计算的结果对当前的参数进行微分计算,从而实现网络权重参数的更新。


梯度基本计算

使用 backward 方法,grad 属性来实现梯度的计算和访问。

import torch 
import numpy as np # 标量的梯度计算
def test01():# 对于需要求导的张量,需设置 requires_grad = Truex = torch.tensor(10, requires_grad=True, dtype=torch.float64)# 对 x 的中间计算f = x ** 2 + 20  # 求导获得 2x# 自动微分f.backward()# 访问梯度print(x.grad)# 向量的梯度计算
def test02():x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)# 定义变量的计算过程y1 = x ** 2 + 20 # 注意:自动微分的时候,必须是一个标量y2 = y1.mean()  # 对 y1 / 4 的操作# 自动微分,求导y2.backward()print(x.grad)# 多标量梯度计算
def test03():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 * x2 # 自动微分y.backward()# 打印梯度值print(x1.grad)print(x2.grad)# 多向量的梯度计算
def test04():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 * x2 # 将输出结果变为标量y = y.sum()# 自动微分y.backward()# 打印张量的梯度值print(x1.grad)print(x2.grad)if __name__ == "__main__":test04() 

控制梯度计算

当 requires_grad = True 时,张量在某些时候计算不进行梯度计算。

import torch 
import numpy as np # 控制梯度计算
# 训练时才用到梯度计算
def test01():x = torch.tensor(10, requires_grad=True, dtype=torch.float64)print(x.requires_grad)# 1. 第一钟方法with torch.no_grad():y = x**2print(y.requires_grad)#2. 针对函数# 第二种方式@torch.no_grad()def my_func(x):return x ** 2 y = my_func(x)print(y.requires_grad)#3. 第三种方式: 全局的方式torch.set_grad_enabled(False)y = x ** 2 print(y.requires_grad)# 梯度累加和梯度清零
def test02():x = torch.tensor([10, 20, 30, 40], requires_grad=True, dtype=torch.float64)# 当我们重复对x进行梯度计算的时候,是会将历史的梯度值累加到 x.grad 属性中# 不要取累加历史梯度for _ in range(3):# 对输入x的计算过程f1 = x ** 2 + 20# 将向量转换为标量f2 = f1.mean()# 梯度清零if x.grad is not None:x.grad.data.zero_()# 自动微分f2.backward()print(x.grad)# 梯度下降优化函数
def test03():x = torch.tensor(10, requires_grad=True, dtype=torch.float64)for _ in range(100):# 正向计算y = x ** 2# 梯度清零if x.grad is not None:x.grad.data.zero_()# 自动微分y.backward()# 更新参数x.data = x.data - 0.001 * x.grad # 打印 x 的值print('%.10f' % x.data)if __name__ == "__main__":test03() 

梯度计算注意点

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

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

此时,需要先使用 detach 函数将张量进行分离,再使用 numpy 函数。

注意:detach 之后会产生一个新的张量,新的张量做为叶子节点并且该张量和原来的张量共享数据,但是分离后的张量不需要计算梯度。

import torch 
import numpy as np # 错误方式
def test01():x = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead.# print(x.numpy())# 正确的做法print(x.detach().numpy())# 共享数据
def test02():# x 是叶子节点x1 = torch.tensor([10, 20], requires_grad=True, dtype=torch.float64)# 使用 detach 函数来分离出一个新的张量x2 = x1.detach()print(id(x1.data), id(x2.data))# 修改分离后产生的新的张量x2[0] = 100 print(x1)print(x2)# 通过结果我么发现,x2 张量不存在 requires_grad = True # 表示:对 x1 的任何计算都会影响到对 x1 的梯度计算# 但是,对 x2 的任何计算不会影响到 x1 的梯度计算print(x1.requires_grad)print(x2.requires_grad)if __name__ == "__main__":test02() 

相关文章:

  • linux tar命令详解。压缩格式对比
  • C++访问MySQL
  • 联邦学习的深度解析,有望打破数据孤岛
  • 3.5/Q1,GBD数据库最新一区文章解读
  • rollout 是什么:机器学习(强化学习)领域
  • 【C/C++】各种概念联系及辨析
  • Socket 编程 TCP
  • 2025年PMP 学习五
  • Qt天气预报系统更新UI界面
  • 电路研究9.3.3——合宙Air780EP中的AT开发指南:HTTP(S)-HTTP GET 示例
  • 逆向常见题目—迷宫类题目
  • 【AI大模型学习路线】第一阶段之大模型开发基础——第四章(提示工程技术-1)In-context learning。
  • android-ndk开发(5): 编译运行 hello-world
  • 机器人强化学习入门学习笔记
  • EPSG:3857 和 EPSG:4326 的区别
  • 雷电模拟器-超好用的Windows安卓模拟器
  • 百度golang开发一面
  • Red Hat6.4环境下搭建DHCP服务器
  • llama_factory0.9.3微调Qwen3
  • DGI数据治理框架的最佳实践
  • 实探北京楼市:“好房子”卖点十足,二手房持续回稳
  • 莫斯科一机场实施临时限制措施
  • “五一”假期国铁集团计划日均开行旅客列车超1.2万列
  • 李在明回应韩国大法院判决:与自己所想截然不同,将顺从民意
  • 新华时评:需要“重新平衡”的是美国心态
  • 北方旱情持续,水利部:大中型灌区春灌总体有保障