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

PyTorch实现PINN时损失函数未更新的问题求助

解决PINN损失函数无法更新的问题

你的代码存在几个关键问题,导致损失无法有效更新,以下是修正方案:

核心问题分析

  • 损失函数定义错误:你使用了线性求和torch.sum(dydx-4*x),这会导致正负误差相互抵消,优化目标不明确,梯度更新失去方向。PINN的物理约束损失通常需要用均方误差(MSE),即对误差平方后计算均值/求和,保证损失非负且梯度稳定。
  • 梯度计算缺少create_graph=True:torch.autograd.grad中需要设置create_graph=True,才能让损失对模型参数产生可导的计算图,否则梯度无法反向传播到模型参数。
  • 不必要的retain_graph=True:loss.backward()中无需保留计算图,每次迭代会重新构建,多余的保留会占用内存且可能干扰梯度计算。

修正后的代码

import torch
import torch.nn as nn

x = torch.linspace(-1,1,50).view(-1,1)
x.requires_grad = True
y = 2*x*x

class net(nn.Module):
    def __init__(self):
        super().__init__()
        self.fc1 = nn.Linear(1, 10)
        self.fc2 = nn.Linear(10, 1)
        self.tanh = nn.Tanh()
        
    def forward(self, x):
        x = self.fc1(x)
        x = self.tanh(x)
        x = self.fc2(x)
        return x
    
model = net()
optimizer= torch.optim.Adam(model.parameters(),lr=0.01)

for epoch in range(5001):
    optimizer.zero_grad()
    pred = model(x)
    
    # 修正梯度计算:添加create_graph=True,保证可反向传播到模型参数
    dydx = torch.autograd.grad(pred, x, torch.ones_like(pred), create_graph=True)[0]
    
    # 修正损失函数:使用均方误差,替代线性求和
    loss = 0.01 * torch.mean((dydx - 4*x)**2)
    
    loss.backward()  # 移除不必要的retain_graph=True
    optimizer.step()
    
    if epoch%100 == 0:
        print(f'Epoch : {epoch}\tLoss: {loss.item():.6f}')
        print(f"Mean error of derivative: {torch.mean(torch.abs(dydx-4*x)).item():.6f}")

额外优化建议

  • 如果有观测数据,可以加入数据损失(比如data_loss = torch.mean((pred - y)**2)),将物理损失和数据损失加权求和,提升模型拟合效果。
  • 可以尝试调整学习率(比如lr=0.001)或者增加网络层数/神经元数量,提升模型的拟合能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 16:57:26