前言:这段代码最重要的难点就是这里,看懂了这里,你应该就入门了PINN。
重点剖析:
片段1:
def loss_func(self):
u_pred = self.net_u(self.x_u, self.t_u)
f_pred = self.net_f(self.x_f, self.t_f)
loss_u = torch.mean((self.u - u_pred) ** 2)
loss_f = torch.mean(f_pred ** 2)
return loss_u + loss_f
问题提出:为什么这样定义损失函数呢?
解答:先看什么是x_f,t_f,两者是X_f_train的两列,而X_f_train是随机生成在x,t的范围内的数据点。
关键点1:(这是你可能疑惑,①为什么随机点也能拿来做预测 ②怎么判别预测的u结果准确呢?毕竟没有对应的u,这是就依靠u_pred = self.net_u(self.x_u, self.t_u)和loss_u ,这里的x,t都有对应u的,通过让模型学习把loss降到最小,是预测更加准确,也就有了可以和随机生成点对应的u了)
关键点2:其次为了让模型能够学习这个物理方程,引入了loss_f,让模型学习把loss_f降到最小,以至于参数能够学习到物理方程的规律,两者相加(loss_u + loss_f)也就构成了PINN。
片段2: def net_f(self, x, t): u = self.net_u(x, t) u_t = torch.autograd.grad(u, t, grad_outputs=torch.ones_like(u), create_graph=True)[0] u_x = torch.autograd.grad(u, x, grad_outputs=torch.ones_like(u), create_graph=True)[0] u_xx = torch.autograd.grad(u_x, x, grad_outputs=torch.ones_like(u_x), create_graph=True)[0] f = u_t + u * u_x - self.nu * u_xx return f #方程的残差