【Torch】解决tensor参数有梯度,weight不更新的若干思路

本文详细介绍了如何排查并解决在PyTorch中nn.Parameter参数权重不更新的问题,涉及梯度检查、学习率调整、参数序列检查等关键步骤,帮助开发者定位并修复此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

           在torch类里面用nn.Parameter声明了一个可学的Tensor参数, 结果每次梯度回传之后,可以看到变量梯度,但是该参数的weight始终不变,一直保持着初始值。

思路:

遇到某参数的weight一直不更新,解决思路有以下几种:

1.   检查该变量的梯度是否为0或者为None, 对于pytorch的中间变量,输出梯度的方式见博客:  https://www.jianshu.com/p/ad66f2e38f2f

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

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

 

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

 

4. 最重要的是, 检查参数所在的类,是否加入了optimal的优化参数序列中:(, 不然梯度虽然回传了,但优化器并不会对你的参数产生反应。 

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

 

大概尝试的思路就这么多, 有遗漏的请路过大佬在评论区指正。

如上

 

### 如何在TensorFlow或PyTorch中计算损失函数的梯度 #### 在TensorFlow中计算梯度 为了在TensorFlow中计算损失函数相对于模型参数梯度,可以利用`GradientTape`上下文管理器。此方法记录操作以便稍后自动微分。 ```python import tensorflow as tf # 定义变量w和b以及输入x与标签y w = tf.Variable(0.3, dtype=tf.float32) b = tf.Variable(-0.3, dtype=tf.float32) x = tf.constant([1.0]) y_true = tf.constant([0.0]) with tf.GradientTape() as tape: y_pred = w * x + b # 前向传播过程 loss = tf.reduce_mean(tf.square(y_pred - y_true)) # 计算均方误差作为损失函数 gradients = tape.gradient(loss, [w, b]) # 自动求导得到[w,b]对应的梯度 print(gradients) # 输出梯度值 ``` 这段代码展示了如何定义简单的线性回归模型,并使用`tf.GradientTape()`来跟踪前向传播中的运算,从而能够计算出关于权重`w`和偏置项`b`的梯度[^1]。 #### 在PyTorch中计算梯度 对于PyTorch而言,其动态图机制允许更灵活的操作。下面的例子说明了怎样创建张量、设置requires_grad=True属性以启用追踪历史记录的功能,进而完成同样的任务: ```python import torch # 创建可训练参数tensor对象 weights = torch.tensor([0.3], requires_grad=True) bias = torch.tensor([-0.3], requires_grad=True) input_data = torch.tensor([1.0]) target = torch.tensor([0.0]) output = weights * input_data + bias # 进行预测 loss_fn = (output - target).pow(2).mean() # MSE Loss function loss_fn.backward() # 反向传播计算梯度 print(weights.grad.data, bias.grad.data) # 打印weight和bias的梯度 ``` 这里的关键在于调用了`.backward()`来进行反向传播,之后可以直接访问各个叶子节点(即具有`requires_grad=True`标记的张量)上的`.grad`属性获取相应的梯度信息。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值