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
相关产品推荐
相关产品推荐

