PyTorch二次调用autograd.grad报错:被微分张量未参与计算图
问题原因及解决方案
报错原因
你当前的模型是纯线性变换(三次Linear层叠加+求和操作),u是x的线性函数。对于线性函数来说,它对自变量x的一阶导数u_x是一个常数张量——完全不依赖于x本身。当你第二次调用autograd.grad求u_x对x的梯度时,x根本没有出现在u_x的计算图中,因此PyTorch会抛出One of the differentiated Tensors appears to not have been used in the graph的错误。
解决方案
要计算二阶导数,必须让u成为x的非线性函数。最简单的方式是在Linear层之间加入非线性激活函数(比如ReLU),这样一阶导数u_x就会依赖于x,二阶导数的计算就能正常进行。
修改后的代码示例
import torch x = torch.randn(10,3).float() x.requires_grad=True y = torch.sum(x,1) y2 = torch.flatten(y) L1 = torch.nn.Linear(10, 50) L2 = torch.nn.Linear(50, 50) L3 = torch.nn.Linear(50, 10) # 加入ReLU非线性激活,让u成为x的非线性函数 u = torch.relu(L1(y2)) u = torch.relu(L2(u)) u = L3(u) # 替换错误的reshape写法,用unsqueeze添加维度更直观 u = u.unsqueeze(1) # 第一次求导正常执行 u_x = torch.autograd.grad(u, x, torch.ones(u.shape), retain_graph=True, create_graph=True)[0] # 第二次求导不再报错 u_xx = torch.autograd.grad(u_x, x, torch.ones(u_x.shape), create_graph=True)[0] print(u_xx.shape) # 输出: torch.Size([10, 3])
额外说明
原代码中u.reshape(u.shape,1)是错误的写法:reshape的参数需要是目标形状的元组,正确的写法可以是u.reshape(-1,1)或者u.unsqueeze(1),后者更适合给张量添加单维度。
内容的提问来源于stack exchange,提问作者Salman
相关产品推荐
相关产品推荐

