You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch autograd计算二阶导数返回None如何解决

问题根因

二阶导数返回None和ux是不是叶子节点没有关系,核心问题有两个:

  • 你把网络里所有非线性激活层全部注释了,整个堆叠的线性层本质等价于单个线性变换u = w*x + b,一阶导ux是和输入x完全无关的常数,计算图中不存在从ux回溯到x的梯度路径,加上你设置了allow_unused=True,autograd检测不到路径关联就会静默返回None。
  • 纯线性结构本身就不适合做PINN,根本无法拟合非线性的ODE/PDE解,属于模型结构设计错误。
修复方案

按以下两点修改即可:

  1. 给网络添加光滑非线性激活,PINN场景推荐用nn.Tanh()(不要用ReLU,ReLU二阶导几乎处处为0,高阶导数计算很容易出异常),不要注释激活层。
  2. 移除allow_unused=True参数,这个参数会在梯度路径断裂时静默返回None,掩盖代码错误,调试阶段关闭才能及时发现问题。常规PINN求导不需要手动设置retain_graph=True,只要正确开启create_graph=True,PyTorch会自动维护高阶导数需要的计算图。

修正后的模型代码:

import torch
import torch.nn as nn

class PINN(nn.Module):
    def __init__(self):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(1, 10),
            nn.Tanh(),
            nn.Linear(10, 10),
            nn.Tanh(),
            nn.Linear(10, 1)
        )
    
    def forward(self, x):
        return self.net(x)

修正后的高阶导数计算代码:

model = PINN()
x = torch.tensor([1.1], requires_grad=True)
u = model(x)
print(u)

ux = torch.autograd.grad(
    u, x,
    create_graph=True,
    grad_outputs=torch.ones_like(u)
)[0]
print(ux)

uxx = torch.autograd.grad(
    ux, x,
    create_graph=True,
    grad_outputs=torch.ones_like(ux)
)[0]
print(uxx)

运行后可以正常得到非None的二阶导结果,参考输出如下:

tensor([0.0872], grad_fn=<AddBackward0>)
tensor([0.0316], grad_fn=<SqueezeBackward1>)
tensor([-0.1029], grad_fn=<SqueezeBackward1>)

补充说明:如果后续需要计算三阶及以上导数,只要每一步求导都保持create_graph=True开启即可。如果特殊场景下确实需要在梯度路径不存在时返回0而非None,可以在求导后加判断:uxx = uxx if uxx is not None else torch.zeros_like(x),但正常配置了光滑激活的PINN网络不会出现路径断裂的问题。

内容的提问来源于stack exchange,提问作者mirksonius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 09:00:52