为何PyTorch计算球坐标系度量张量雅可比矩阵恒为零?
问题根源
你代码中雅可比矩阵全为零的核心原因是:metric_tensor函数里用torch.tensor()直接包裹混合普通浮点数(如1.、0.)和输入依赖张量(如r**2)的列表,切断了输出张量与输入coord的计算图连接。
当你将r**2(带梯度的张量)和1.(纯Python浮点数)放入同一列表并传给torch.tensor()时,PyTorch会创建一个全新的张量,其中的元素只是原数据的副本,并未保留与输入coord的梯度追踪关系,导致自动微分无法计算非零导数。
修正方案
由于球坐标系的度量张量是对角矩阵,推荐两种保留计算图的实现方式:
方式1:用torch.diag构建对角矩阵
# initial coordinates r0, theta0, phi0 = (3., torch.pi/2, 0.1) coord = torch.tensor([r0, theta0, phi0], requires_grad=True) print("r, theta, phi coordinates: ",coord.data) def metric_tensor(coords): r = coords[0] theta = coords[1] # 显式用张量形式定义所有对角元素,保留梯度连接 diag_elements = torch.stack([ torch.tensor(1.0, device=coords.device, dtype=coords.dtype), r ** 2, r ** 2 * torch.sin(theta) ** 2 ]) return torch.diag(diag_elements) jacobian = torch.autograd.functional.jacobian(metric_tensor, coord, create_graph=True) print(jacobian)
方式2:初始化零矩阵后填充元素
# initial coordinates r0, theta0, phi0 = (3., torch.pi/2, 0.1) coord = torch.tensor([r0, theta0, phi0], requires_grad=True) print("r, theta, phi coordinates: ",coord.data) def metric_tensor(coords): r = coords[0] theta = coords[1] # 创建与输入同设备、同 dtype 的零矩阵 g = torch.zeros((3,3), device=coords.device, dtype=coords.dtype) g[0,0] = 1.0 g[1,1] = r**2 g[2,2] = r**2 * torch.sin(theta)**2 return g jacobian = torch.autograd.functional.jacobian(metric_tensor, coord, create_graph=True) print(jacobian)
效果验证
修正后的代码会输出非零的雅可比矩阵,例如:
g[1,1]对r的导数为2rg[2,2]对r的导数为2r*sin²θ,对theta的导数为2r²*sinθ*cosθ
这些导数会正确体现在雅可比矩阵的对应位置。
内容的提问来源于stack exchange,提问作者JS4137
相关产品推荐
相关产品推荐

