param.grad、requires_grad、grad_fn、grad/梯度为None?

news2024/9/26 1:22:27

基本概念 

1)is_leaf

叶子节点和非叶子节点的区别:计算图中的节点分为叶子节点和非叶子节点,叶子节点可以理解成没有其他tensor再利用它进行计算(例如b = a+1,那么b需要a进行计算,那么a就不是叶子结点,b是叶子节点),但是需要注意若tensor是由用户创建,则该tensor为叶子节点(即使有别的tensor利用它进行计算)。

是否是叶子结点

  • 所有requires_grad为False的tensor都是叶子节点,也即is_leaf属性返回true。
  • 若tensor是由用户创建,则该tensor为叶子节点。而叶子节点经过进一步计算得到的变量叫非叶子节点,叶子节点的梯度值不为None。非叶子节点的梯度值没有保存在内存中,所以对非叶子节点进行求梯度则为None。
import torch

# 若tensor是由用户创建,则该tensor为叶子节点
x = torch.tensor([1.0, 2.0, 3.0, 4.0], requires_grad=True)
print(x.is_leaf)

# 叶子节点经过进一步计算得到的变量叫非叶子节点
x = x.view(2,2)
print(x.is_leaf)

out = x.sum()
print(out.is_leaf)

out.backward()
# 非叶子节点的梯度值没有保存在内存中,所以对非叶子节点进行求梯度则为None
print(x.grad)
  • 由requires_grad为False的节点通过operation产生的节点还是叶子节点,此时设置requires_grad为true,不影响是否为叶子节点,但会影响后续节点是否为叶子节点。猜想这么设计的原因是:由于无法判断是否是由operation产生的节点,因此通过设置requires_grad也就无法更新是否为叶子节点。

2)grad

这是保存参数的梯度值。在进行反向传播后,对于具有 requires_grad=True 的参数,梯度会被计算并存储在 param.grad 中。对于没有梯度的参数或未计算梯度的参数,param.gradNone。你可以使用 param.grad 获取参数的梯度值,进而执行自定义的操作,如参数更新或梯度剪裁。

当计算梯度的时候,只有叶子节点才会保留梯度,所有中间节点(非叶子节点)的grad在计算完backward()的时候为了节约内存都会被清除掉

在使用backward()函数进行反向传播计算tensor的梯度时,并不是计算所有的tensor的梯度,而是计算满足下面这几个全部条件的tensor的梯度,

  • 类型为叶子节点、
  • requires_grad==True
  • 依赖该tensor的所有tensor的require_grad为True

3)grad_fn

记录变量是怎么来的,例如:y = x*3,grad_fn记录了y由x计算的过程。所以:

  • 当grad_fn为None时:无论requires_grad为True还是False,都为叶子变量即只要是直接初始化的都为叶子变量
  • 当grad_fn不为None时:requires_grad = False为叶子变量,requires_grad = True为非叶子变量

4)requires_grad

这是一个布尔值属性,指示是否计算参数的梯度。默认情况下,所有模型参数的 requires_grad 属性都设置为 True,以便在进行反向传播时计算梯度。如果你想冻结参数或防止其梯度更新,可以将其设置为 False。当你冻结参数时,梯度计算会被停止,这意味着该参数不会在后续的训练迭代中更新。

按照惯例,所有属性requires_grad=False的张量是叶子节点(即:叶子张量、叶子节点张量).

对于属性requires_grad=True的张量可能是叶子节点张量也可能不是叶
子节点张量而是中间节点(中间节点张量).  如果该张量的属性requires_grad=True,
而且是用于直接创建的,也即它的属性grad_fn=None,那么它就是叶子节点.
如果该张量的属性requires_grad=True,但是它不是用户直接创建的,而是由其他张量
经过某些运算操作产生的,那么它就不是叶子张量,而是中间节点张量,并且它的属性
grad_fn不是None,比如:grad_fn=<MeanBackward0>,这表示该张量是通过torch.mean()
运算操作产生的,是中间结果,所以是中间节点张量,所以不是叶子节点张量.
判断一个张量是不是叶子节点,可以通过它的属性is_leaf来查看.

一个张量的属性requires_grad用来指示在反向传播时,是否需要为这个张量计算梯度.
如果这个张量的属性requires_grad=False,那么就不需要为这个张量计算梯度,也就
不需要为这个张量进行优化学习.

在PyTorch的运算操作中,如果参加这个运算操作的所有输入张量的属性requires_grad都
是False的话,那么这个运算操作产生的结果,即输出张量的属性requires_grad也是False,
否则是True. 即输入的张量只要有一个需要求梯度(属性requires_grad=True),那么得到的
结果张量也是需要求梯度的(属性requires_grad=True).只有当所有的输入张量都不需要求
梯度时,得到的结果张量才会不需要求梯度.


对于属性requires_grad=True的张量,在反向传播时,会为该张量计算梯度. 但是pytorch的
自动梯度机制不会为中间结果保存梯度,即只会为叶子节点计算的梯度保存起来,保存到该
叶子节点张量的属性grad中,不会在中间节点张量的属性grad中保存这个张量的梯度,这是
出于对效率的考虑,中间节点张量的属性grad是None.如果用户需要为中间节点保存梯度的
话,可以让这个中间节点调用方法retain_grad(),这样梯度就会保存在这个中间节点的grad属性中.
 

训练过程中params.grad为NoneType(值是None)

首先这并不是空,而是根本不存在,原因有很多种,比如:

  1. params并不是叶子节点
  2. params的requires_grad属性为False
  3. 在网络定义的时候,定义了某层网络,在前向传播时并没有用到,在输出网络梯度时,由于没有前向传播(即 def _init__(self):里面写了, 但def forward()时没有用到上面的某一层,就会有grad为NoneType的情况下,有可能是这个原因),所以没有进行反向传播,自然没有梯度信息,也就出现了nonetype类型。
  4. 调用backward()函数前,叶子/非叶子节点的grad属性均为none,无论是否设置了requires_grad=True(叶子节点),或者调用了retain_grad()(非叶子节点)

情况一:

import torch

a = torch.ones((2, 2), requires_grad=True).to("cuda")
b = a.sum()
b.backward()

print(a.is_leaf)
print(a.grad)

输出:False、None

原因:

由于.to(device)是一次操作,此时的a已经不是叶子节点了

修改为:

import torch

a = torch.ones((2, 2), requires_grad=True)
c = a.to("cuda")
b = c.sum()
b.backward()

print(a.is_leaf)
print(a.grad)

情况二:

定义参数相乘应该将所有的操作放在torch.nn.Parameter()内,而不是在外面再乘

错误:

self.miu = torch.nn.Parameter(torch.ones(self.dimensional)) * 0.01

应该为

self.miu = torch.nn.Parameter(torch.ones(self.dimensional) * 0.01)

grad为NoneType(值是None)怎么办?

打印全部网络的参数梯度(model.named_parameters()),查看哪层开始出现梯度消失问题:https://blog.csdn.net/weixin_43135178/article/details/131754210?

发现是这里的问题: 

 分别搜索“q_proj”、“.key_value”、“query_key_value”,发现它们都使用了“mpu.ColumnParallelLinear + mpu.RowParallelLinear ”,那么应该是它们这两个类的问题

 

[注]主要查看是否有装饰了torch.no_grad()或者detach()函数,该装饰器会使得该函数内保留梯度

Debug解决思路有以下几种:

1. 检查该变量的梯度是否为0或者为None, 对于pytorch的中间变量,输出梯度的方式见博客: pytorch获取中间变量的梯度

如果是None或者0,说明梯度没有传到该变量,顺着代码往下一直输出变量的梯度,直到梯度出现为止,然后检查为啥梯度消失了。

2. 输出梯度后, 检查梯度乘上学习率是否过小, 比如梯度为5e-2,学习率为1e-4,而变量的值只保留五位小数,那么此时由于学习率过小使得更新被变量忽略,需要把学习率调高。

3. 最重要的是, 检查参数所在的类,是否加入了optimal的优化参数序列中.

(不然梯度虽然回传了,但优化器并不会对你的参数产生反应。 (本次,我代码出现问题的原因便是如此)

4. 检查该变量是否在optimal step函数之前被替换, 即梯度回传之后, step函数之前,该参数被重新赋值。(不常见)

注意: 如果是一个模型类的列表: 请不要用list类型,使用nn.ModuleList , 如果一个list中包含了三个A类, 把list作为B类的参数的时候(在init函数中赋值),那么这个list里面所有的参数(A类中的参数)都不会被优化, 使用nn.ModuleList可以避免这一点。

Pytorch中自定义网络参数,存在梯度但不进行更新 - 知乎

pytorch损失反向传播后梯度为none的问题_python_脚本之家

pytorch计算图、梯度相关操作、固定参数训练以及训练过程中grad为Nonetype的原因 - 知乎

Torch requires_grad / backward / is_leaf 的一些坑 - 简书

pytoch 设置了requires_grad=True,但是计算梯度(grad)为none_requires_grad=true 但是没有梯度_AINLPer的博客-CSDN博客

https://www.cnblogs.com/Monster1728/p/15865708.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/809684.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服务器介绍

本文章转载与b战up主谈三国圈&#xff0c;仅用于学习讨论&#xff0c;如有侵权&#xff0c;请联系博主 机架型服务器 堆出同时服务百万人次机组 刀型服务器 服务器炸了 比如用户访问量暴增 超过机组的峰值处理能力&#xff0c;进而导致卡顿或炸服&#xff0c; 适合企业的塔式…

xilinx FPGA 除法器ip核(divider)的使用(VHDLVivado)

一、创建除法ip核 vivado的除法器ip核有三种类型&#xff0c;跟ISE相比多了一个LuMult类型&#xff0c;总结来说就是 LuMult&#xff1a;使用了DSP切片、块RAM和少量的FPGA逻辑原语&#xff08;寄存器和lut&#xff09;&#xff0c;所以和Radix2相比占用fpga资源更少&#xff…

CS_SAVEBITS 这个样式有什么作用?

简单来说&#xff0c;如果你在创建窗口的时候在窗口类中指定了 CS_SAVEBITS 标志&#xff0c;则窗口管理器会尝试保存此窗口所遮盖的区域的位图数据。 但是&#xff0c;这里比较关键的问题是&#xff1a;为什么要这样做&#xff1f;只有明白了这其中的原理&#xff0c;你才会在…

2023.07.13力扣6题

931. 下降路径最小和 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列&#xff08;即位…

Python批量将Excel内指定列的数据向上移动一行

本文介绍基于Python语言&#xff0c;针对一个文件夹下大量的Excel表格文件&#xff0c;对其中的每一个文件加以操作——将其中指定的若干列的数据部分都向上移动一行&#xff0c;并将所有操作完毕的Excel表格文件中的数据加以合并&#xff0c;生成一个新的Excel文件的方法。 首…

走进Linux世界【七、Linux网络及快照和克隆】

Linux系统学习 走进Linux世界【一、Linux概述】 走进Linux世界【二、VM与Linux安装】 走进Linux世界【三、Linux文件与路径】 走进Linux世界【四、Linux基本命令一】 走进Linux世界【五、Linux基本命令二】 走进Linux世界【六、Linux编辑器vim】 走进Linux世界【七、Lin…

Nest grpc 实践之调用 python ddddocr 库

我曾经写过一个项目 ddddocr_server&#xff0c;使用 fastapi 提供 http 接口&#xff0c;以此来调用 ddddocr 库。 其他语言想要调用的话&#xff0c;则是通过 http 协议的方式来调用。然而 http 协议的开销不小&#xff0c;而 Websocket 调用又不灵活&#xff0c;此时针对这…

【计网】TCP在可靠传输中都干了啥

文章目录 1、概述2、校验和3、序列号和确认应答机制4、重传机制4.1、介绍4.2、超时重传4.3、快速重传 5、滑动窗口协议5.1、介绍5.2、发送方的滑动窗口5.3、接收方的滑动窗口 6、流量控制7、拥塞控制7.1、介绍7.2、慢开始7.3、拥塞避免7.4、快重传和快恢复 1、概述 TCP 是面向…

Day45 算法记录| 动态规划 12

股票问题 309. 买卖股票的最佳时机含冷冻期714.买卖股票的最佳时机含手续费 309. 买卖股票的最佳时机含冷冻期 这个视频讲解的很好 309.最佳买卖股票时机含冷冻期 class Solution {public int maxProfit(int[] prices) {int day prices.length;int [][] dp new int[day][2…

【雕爷学编程】MicroPython动手做(14)——掌控板之OLED屏幕

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

IOS UICollectionView 设置cell大小不生效问题

代码设置flowLayout.itemSize 单元格并没有改变布局大小&#xff0c; 解决办法如下图&#xff1a;把View flow layout 的estimate size 设置为None&#xff0c;上面设置的itemSize 生效了。

【Spring Boot】实战:实现优雅的数据返回

实战&#xff1a;实现优雅的数据返回 本节介绍如何让前后台优雅地进行数据交互&#xff0c;正常的数据如何统一数据格式&#xff0c;以及异常情况如何统一处理并返回统一格式的数据。 1.为什么要统一返回值 在项目开发过程中经常会涉及服务端、客户端接口数据传输或前后台分…

不同路径 II

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish”&#xff09;。 现在考虑网格中有障碍物。那么从左上角到右下角…

Android 面试题 ANR 五

&#x1f525; 什么是 ANR &#x1f525; ANR(Application Not Responding )应用无响应的简称&#xff0c;是为了在 APP卡死时&#xff0c;用户 可以强制退出APP的选择&#xff0c;从而避免卡机无响应问题&#xff0c;这是Android系统的一种自我保护机制。 在Android中&#xf…

Vue基础 --- 动态组件 插槽 自定义指令

1. 动态组件 1.1 什么是动态组件 动态组件指的是动态切换组件的显示与隐藏。 1.2 如何实现动态组件渲染 vue 提供了一个内置的 <component> 组件&#xff0c;专门用来实现动态组件的渲染。示例代码如下&#xff1a; data() { <!-- 1.当前要渲染的组件名称 -->…

ad+硬件每日学习十个知识点(13)23.7.24(MOS管纠错!!!)

1.MOS管到底怎么接&#xff1f;&#xff08;我一直都错了&#xff09; 2.MOS管的非饱和区 答&#xff1a; 3.MOS管的饱和区 答&#xff1a; 4.MOS管的截止区和击穿区 答&#xff1a; 5.做开关&#xff0c;让三极管工作在饱和区&#xff0c;让MOS管工作在非饱和区&…

rocketmq rsqldb 简单记录

GitHub 地址 https://github.com/alibaba/rsqldb/tree/main&#xff0c;是和目前stream sql化看齐的Rocketmq的sql&#xff0c;类似还有kafka的sqlDB 和flink sql。 目前版本0.2 &#xff0c;主要提供rest模式调用&#xff0c;controller类为public class RsqlController支持的…

SQL server 文件占用硬盘过大 日志 读写分离同步文件过大清理 DBCC收缩数据库 分发数据库distribution收缩

一顿操作猛如虎 又省出好几十G硬盘空间 小破站又能蹦跶了 目标&#xff1a;实例库日志压缩清理,分发数据库压缩清理 采用SQL 脚本收缩数据库 截断事务日志 backup log [数据库名] with no_log收缩数据库 dbcc shrinkdatabase ([数据库名]) 4.以上操作都不行的话&#xff0…

联发科CEO:未获准向华为供货,换机潮已过去,手机需求不会更差

据钜亨网报道&#xff0c;联发科近期召开了业绩说明会。蔡力行&#xff0c;该公司副董事长兼首席执行官&#xff0c;表明当前手机市场需求保持稳定&#xff0c;并且随着过去两年用户更换潮的过去&#xff0c;对手机市场明年有一定期望。 根据蔡力行的指示&#xff0c;联发科正在…

计算机和医学的交叉融合到底有多强呢?

目录 简介 人工智能在医学诊断中的应用 计算机辅助药物研发 计算机技术在基因组学研究中的应用 数字病理学 穿戴式医疗设备 虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;技术在医学教育中的应用 机器人手术 区块链技术在医学领域的应用 遥…