PINN 讲义第 4 章:损失函数、优化与自动微分

3356 字
17 分钟
PINN 讲义第 4 章:损失函数、优化与自动微分

本文属于“PINN 入门讲义”系列:第 4 章。如果你是第一次阅读,建议先从 总目录 开始。

阅读说明#

这份讲义面向希望系统理解 Physics-Informed Neural Networks 的读者,尽量从微分方程、数值近似和神经网络函数表示的基本语言讲起,再逐步进入 PINN 的残差构造与训练过程。

上一章把神经网络看成一个带参数的函数 uθu_\theta。这个观点解决了“用什么表示未知解”的问题,但还没有解决“如何选择参数”的问题。一个网络结构确定之后,可能对应无数个不同的函数;不同的参数 θ\theta 会给出不同的输入输出关系。训练神经网络,就是在这些函数中寻找一个符合要求的函数。

要完成这件事,需要三个基本概念。第一,损失函数用来衡量当前网络函数有多不好,或者说它距离目标有多远。第二,优化算法根据损失函数调整参数,使损失尽量减小。第三,自动微分负责高效计算优化所需的导数。对普通监督学习而言,自动微分主要用于计算损失对参数的导数;对 PINN 而言,它还要计算网络输出对输入变量的导数,从而构造微分方程残差。本章围绕这条训练闭环展开。

4.1 损失函数定义了训练目标#

设神经网络为 fθf_\theta,其中 θ\theta 表示所有权重和偏置。如果给定一组训练数据

(x1,y1),,(xN,yN),(\mathbf{x}_1,y_1),\ldots,(\mathbf{x}_N,y_N),

我们希望网络在每个输入 xi\mathbf{x}_i 处的输出 fθ(xi)f_\theta(\mathbf{x}_i) 尽量接近目标值 yiy_i。这种“尽量接近”需要一个可计算的量来衡量。最常见的选择之一是均方误差:

L(θ)=1Ni=1Nfθ(xi)yi2.\mathcal{L}(\theta) = \frac{1}{N} \sum_{i=1}^{N} \left|f_\theta(\mathbf{x}_i)-y_i\right|^2.

这个公式由两层含义组成。对每个样本,先计算预测值与目标值的差 fθ(xi)yif_\theta(\mathbf{x}_i)-y_i,再平方,使正负误差都变成非负量;最后对所有样本取平均,得到网络在训练集上的总体误差。若 L(θ)\mathcal{L}(\theta) 很小,说明网络在这些样本上预测得较好;若它很大,说明当前参数对应的函数还不合适。

损失函数不是自然界给出的唯一对象,而是人为设计的训练目标。不同任务会使用不同损失。例如回归问题常用均方误差,分类问题常用交叉熵。Goodfellow 等《Deep Learning》在讨论优化时也强调,深度学习训练通常是在最小化某个训练目标或替代损失,而这个目标未必等同于我们最终关心的全部性质。对 PINN 来说,这一点尤其重要:我们不只是关心数据拟合,还关心方程残差、边界条件和初值条件。因此,PINN 的损失函数会比普通监督学习更复杂。

先看普通监督学习中的情况。若 θ\theta 固定,fθf_\theta 就是一个确定函数,损失 L(θ)\mathcal{L}(\theta) 也有一个确定值。训练时,输入数据不变,目标值不变,真正被调整的是参数 θ\theta。所以损失函数也可以看成一个关于参数的函数:

θL(θ).\theta\longmapsto \mathcal{L}(\theta).

训练的数学形式就是

minθL(θ).\min_{\theta}\mathcal{L}(\theta).

这个写法非常短,却概括了神经网络训练的核心:在参数空间中寻找一个使损失较小的参数。后续 PINN 也是同样的形式,只是 L\mathcal{L} 中会包含更多物理约束项。

4.2 梯度下降:沿着损失减小的方向调参数#

如果损失函数只有一个参数,例如 θ\theta 是一个实数,那么可以把 L(θ)\mathcal{L}(\theta) 画成一条曲线。导数 L(θ)\mathcal{L}'(\theta) 表示曲线在当前点的斜率。若斜率为正,向右移动会使函数值增加,向左移动则可能使函数值减小;若斜率为负,向右移动可能使函数值减小。梯度下降的基本思想就是沿着导数指示的下降方向更新参数:

θnew=θoldηdLdθ(θold).\theta_{\mathrm{new}} = \theta_{\mathrm{old}} - \eta \frac{d\mathcal{L}}{d\theta} (\theta_{\mathrm{old}}).

这里 η>0\eta>0 称为学习率,控制每一步走多远。学习率太小,训练会很慢;学习率太大,参数可能越过低损失区域,导致震荡甚至发散。

在神经网络中,参数通常不是一个数,而是大量权重和偏置组成的向量。此时导数推广为梯度:

θL(θ)=(Lθ1,Lθ2,,Lθm).\nabla_\theta \mathcal{L}(\theta) = \left( \frac{\partial \mathcal{L}}{\partial \theta_1}, \frac{\partial \mathcal{L}}{\partial \theta_2}, \ldots, \frac{\partial \mathcal{L}}{\partial \theta_m} \right).

梯度的每个分量告诉我们:若单独改变某个参数,损失会怎样变化。梯度下降更新式写成

θnew=θoldηθL(θold).\theta_{\mathrm{new}} = \theta_{\mathrm{old}} - \eta\nabla_\theta\mathcal{L}(\theta_{\mathrm{old}}).

这条公式说明,训练每一步都需要两个动作:先计算当前损失对参数的梯度,再沿负梯度方向更新参数。MIT 6.390 的梯度下降笔记也采用类似视角:梯度是多维参数空间中导数的推广,它为最小化目标函数提供局部下降方向。

实际训练中,常常不会在每一步使用全部训练数据计算损失和梯度,而是使用一小批样本,称为 mini-batch。这样得到的是随机梯度下降或其变体。它的每一步梯度带有噪声,但计算成本较低,适合大规模数据和大网络。常见优化器如 SGD、Momentum、Adam 等,都是围绕梯度信息设计的更新方法。对本讲义来说,暂时不需要深入比较这些优化器,只要理解它们都在利用损失对参数的导数来调整网络函数。

梯度下降也不是万能工具。神经网络损失函数通常是非凸的,可能有许多局部低谷、平坦区域和陡峭区域。优化过程可能收敛慢,也可能停在不理想的位置。PINN 的优化往往更难,因为它的损失由多个项组成,不同项可能尺度不同、梯度方向冲突,甚至某一项下降时另一项上升。后续讨论 PINN 局限时会再回到这个问题。

4.3 反向传播与自动微分#

既然梯度下降需要 θL(θ)\nabla_\theta\mathcal{L}(\theta),下一个问题就是:这个梯度如何计算?神经网络由许多层函数复合而成,直接手工展开导数既繁琐又容易出错。反向传播和自动微分正是为了解决这个问题。

先看一个非常小的计算链。设

z=wx+b,y^=z2,L=(y^y)2.z=wx+b,\qquad \hat{y}=z^2,\qquad \mathcal{L}=(\hat{y}-y)^2.

这里 L\mathcal{L} 依赖 y^\hat{y}y^\hat{y} 依赖 zzzz 又依赖参数 wwbb。若要求 Lw\frac{\partial \mathcal{L}}{\partial w},可以使用链式法则:

Lw=Ly^y^zzw.\frac{\partial \mathcal{L}}{\partial w} = \frac{\partial \mathcal{L}}{\partial \hat{y}} \frac{\partial \hat{y}}{\partial z} \frac{\partial z}{\partial w}.

神经网络虽然规模更大,但原理仍然是链式法则。反向传播就是在计算图上从输出损失开始,沿着计算依赖关系向前面各个参数传递梯度。Stanford CS231n 的反向传播材料也强调,它的作用是高效计算损失函数关于参数的梯度,从而训练神经网络。

自动微分比“手工求导”更适合现代深度学习框架。以 PyTorch 为例,torch.autograd 会记录张量运算形成的计算图,并根据链式法则自动计算梯度。PyTorch 官方文档将 torch.autograd 描述为自动微分引擎,它支持对计算图自动求梯度。用户只需要用张量写出前向计算,框架就可以在反向传播时计算相关导数。

这里要区分三种容易混淆的求导方式。符号求导试图得到一个解析表达式,例如把 x2x^2 求导为 2x2x。数值差分通过小扰动近似导数,例如

f(x)f(x+h)f(x)h.f'(x)\approx \frac{f(x+h)-f(x)}{h}.

自动微分既不是单纯的符号化简,也不是用差分近似导数。它把程序中的计算分解为基本运算,并对这些基本运算应用链式法则,因此在很多深度学习场景中既精确又高效。

在普通神经网络训练中,自动微分最常见的用途是计算

θL(θ),\nabla_\theta\mathcal{L}(\theta),

也就是损失对网络参数的梯度。这个梯度用于优化器更新权重和偏置。PINN 也需要这一步,因为它同样要最小化损失函数;但 PINN 还多了一层需求:它还要计算网络输出对输入变量的导数。

4.4 对参数求导与对输入求导#

PINN 初学中最容易混淆的地方,是把两类导数混为一谈。第一类导数用于训练网络参数:

Lθ.\frac{\partial \mathcal{L}}{\partial \theta}.

它回答的问题是:如果改变网络参数,损失函数会怎样变化?这个导数决定优化器如何更新权重和偏置。

第二类导数用于构造 PDE 残差:

uθx,uθt,2uθx2.\frac{\partial u_\theta}{\partial x}, \qquad \frac{\partial u_\theta}{\partial t}, \qquad \frac{\partial^2u_\theta}{\partial x^2}.

它回答的问题是:如果改变输入变量,网络输出会怎样变化?这些导数不直接更新参数,而是用来检查网络函数是否满足微分方程。

以热方程为例,PINN 的残差为

rθ(x,t)=uθt(x,t)α2uθx2(x,t).r_\theta(x,t) = \frac{\partial u_\theta}{\partial t}(x,t) - \alpha \frac{\partial^2u_\theta}{\partial x^2}(x,t).

要计算这个残差,必须对输入 ttxx 求导。随后,为了训练网络,还要把残差平方组成损失,例如

LPDE(θ)=1Nri=1Nrrθ(xi,ti)2.\mathcal{L}_{\mathrm{PDE}}(\theta) = \frac{1}{N_r} \sum_{i=1}^{N_r} \left|r_\theta(x_i,t_i)\right|^2.

现在这个损失又是参数 θ\theta 的函数。优化器更新参数时,需要计算

θLPDE(θ).\nabla_\theta \mathcal{L}_{\mathrm{PDE}}(\theta).

所以在 PINN 中,求导有一个嵌套结构:先对输入求导构造残差,再对参数求导优化损失。自动微分框架能够处理这种计算链,但概念上必须分清它们的作用。

例 4.1
设网络函数暂时简化为

uθ(x)=ax2+b,u_\theta(x)=ax^2+b,

其中 θ=(a,b)\theta=(a,b)。若方程是

u(x)=2x,u'(x)=2x,

那么残差为

rθ(x)=duθdx(x)2x.r_\theta(x)=\frac{du_\theta}{dx}(x)-2x.

由于

duθdx(x)=2ax,\frac{du_\theta}{dx}(x)=2ax,

所以

rθ(x)=2ax2x=2(a1)x.r_\theta(x)=2ax-2x=2(a-1)x.

这里 duθdx\frac{du_\theta}{dx} 是对输入 xx 的导数,用于构造残差。若在若干点上计算 rθ(xi)2|r_\theta(x_i)|^2 并求平均,得到损失函数,它又依赖参数 aa。训练时再计算损失对 aa 的导数,用来调整 aa。这就是 PINN 中两类导数的简化模型。

4.5 PINN 损失函数的预告#

前面讨论的监督学习损失只来自数据,而 PINN 的损失通常由多项组成。一个典型形式是

L(θ)=λrLr(θ)+λbLb(θ)+λiLi(θ)+λdLd(θ).\mathcal{L}(\theta) = \lambda_r\mathcal{L}_r(\theta) + \lambda_b\mathcal{L}_b(\theta) + \lambda_i\mathcal{L}_i(\theta) + \lambda_d\mathcal{L}_d(\theta).

这里 Lr\mathcal{L}_r 是 PDE 残差损失,Lb\mathcal{L}_b 是边界条件损失,Li\mathcal{L}_i 是初值条件损失,Ld\mathcal{L}_d 是数据损失。系数 λr,λb,λi,λd\lambda_r,\lambda_b,\lambda_i,\lambda_d 是权重,用来调节不同损失项的相对重要性。

这条公式现在还不需要完全展开,但它已经显示出 PINN 与普通监督学习的差别。普通监督学习通常只问“预测是否接近标签”;PINN 还问“函数是否满足方程”“边界条件是否满足”“初始状态是否正确”。这些要求全部通过损失函数进入训练过程。

这种设计同时带来优势和困难。优势在于,方程和边界条件可以在数据之外提供额外约束,使网络不只是拟合观测点。困难在于,不同损失项可能数值尺度差别很大。如果 PDE 残差损失远大于边界损失,训练可能主要降低残差却忽略边界;反过来,如果边界项权重太大,网络可能在边界上表现很好,但区域内部方程满足得不好。因此,损失设计是 PINN 中非常关键的问题,后面会单独讨论。

本章暂时只需要建立训练闭环:先定义损失函数,再用自动微分计算梯度,最后用优化算法更新参数。下一章将在这个基础上正式写出 PINN 的完整形式。

本章小结#

神经网络训练可以理解为在参数化函数族中选择一个函数。损失函数定义了选择标准,梯度下降等优化算法根据损失对参数的导数调整权重和偏置,自动微分则负责高效计算这些导数。普通监督学习中,损失通常衡量预测与标签的差距;PINN 中,损失还要包含 PDE 残差、边界条件、初值条件和观测数据。

对 PINN 而言,自动微分有双重作用。它一方面计算损失对参数 θ\theta 的导数,用于训练网络;另一方面计算网络输出 uθu_\theta 对输入变量 x,tx,t 的导数,用于构造微分方程残差。分清这两类导数,是理解 PINN 训练过程的关键。

习题#

  1. fθ(x)=ax+bf_\theta(x)=ax+b,训练数据为 (0,1)(0,1)(1,3)(1,3)。写出均方误差损失 L(a,b)\mathcal{L}(a,b)
  2. 对一元损失函数 L(θ)=(θ2)2\mathcal{L}(\theta)=(\theta-2)^2,写出梯度下降更新式,并说明当学习率 η\eta 很大时可能发生什么。
  3. 对计算链 z=wx+bz=wx+by^=z2\hat{y}=z^2L=(y^y)2\mathcal{L}=(\hat{y}-y)^2,用链式法则写出 Lw\frac{\partial \mathcal{L}}{\partial w} 的结构。
  4. 解释 PINN 中 uθx\frac{\partial u_\theta}{\partial x}Lθ\frac{\partial \mathcal{L}}{\partial \theta} 的区别。
  5. 为什么 PINN 的总损失中通常需要多个权重系数 λr,λb,λi,λd\lambda_r,\lambda_b,\lambda_i,\lambda_d

延伸阅读#

  1. I. Goodfellow, Y. Bengio, and A. Courville, Deep Learning, Chapter 8 “Optimization for Training Deep Models”: Deep Learning Book
  2. PyTorch 官方文档:torch.autograd
  3. PyTorch 教程:Automatic Differentiation with torch.autograd
  4. Stanford CS231n, “Backpropagation”: CS231n Optimization 2
  5. MIT 6.390, “Gradient Descent”: MIT IntroML Gradient Descent

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

PINN 讲义第 4 章:损失函数、优化与自动微分
https://sciml.com.cn/posts/pinn-lecture-04/
作者
星飞帆
发布于
2026-06-24
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
星飞帆
西北工业大学24级研究生 | SciML · PINNs · 神经算子 · PDE 约束学习
欢迎
欢迎来到星飞帆的 SciML 研究笔记:这里记录论文阅读、数学推导、代码复现、实验踩坑,也分享研究生阶段可能用得上的资料。
分类
标签
站点统计
文章
21
分类
4
标签
69
总字数
70,675
运行时长
0
最后活动
0 天前

文章目录