为何使用torch.arange生成的张量无法计算梯度?
为什么torch.arange生成的张量无法计算梯度?
核心原因
torch.arange生成的是一个整体张量,当你用for循环迭代它的元素时,每个w_1_value/w_2_value是原张量的索引结果(非叶子节点)——它依赖于原张量存在,并非独立的叶子张量。PyTorch默认只会保存叶子节点的梯度,非叶子节点的grad属性默认是None。
而你直接用tensor(3., requires_grad=True)创建的是独立的叶子节点张量,PyTorch会自动计算并保存它的梯度,所以能正常输出结果。
解决方法
方法一:将迭代元素转为独立叶子张量
在循环中,用.detach().requires_grad_()把每个迭代元素转换成独立的叶子节点,这样就能正常计算并保存梯度:
import torch from torch import tensor def l(w_1,w_2): return w_1*w_2 # 原正常逻辑 w_1 = tensor(3., requires_grad=True) w_2 = tensor(5., requires_grad=True) l_v = l(w_1, w_2) l_v.backward() print(l_v.item(), w_1.grad, w_2.grad) ############# # 修改后的循环代码 for w_1_value in torch.arange(2,4,0.1): # 转为独立叶子张量 w_1_leaf = w_1_value.detach().requires_grad_() for w_2_value in torch.arange(-2,4,0.1): w_2_leaf = w_2_value.detach().requires_grad_() l_value = l(w_1_leaf, w_2_leaf) l_value.backward() print(l_value.item(), w_1_leaf.grad, w_2_leaf.grad)
方法二:批量计算(更高效)
避免循环,利用PyTorch的向量化操作一次性计算所有点的梯度,效率更高:
import torch def l(w_1,w_2): return w_1*w_2 # 生成所有点的网格 w1_range = torch.arange(2,4,0.1, requires_grad=True) w2_range = torch.arange(-2,4,0.1, requires_grad=True) w1_grid, w2_grid = torch.meshgrid(w1_range, w2_range, indexing='ij') # 批量计算损失 l_values = l(w1_grid, w2_grid) # 传入全1张量作为梯度权重,批量计算所有梯度 l_values.backward(torch.ones_like(l_values)) # 查看每个点对应的梯度 print("w1的梯度:", w1_range.grad) print("w2的梯度:", w2_range.grad)
说明:方法一适合小规模场景,逻辑直观但效率低;方法二利用PyTorch的并行计算能力,适合大规模数据的梯度计算。
内容的提问来源于stack exchange,提问作者volperossa
相关产品推荐
相关产品推荐

