新鲜 / 健康 / 便利 / 快速 / 放心
很多时候,我们会希望对一个系统的参数进行优化,此时系统所遵循的物理规律(一般用PDE形式表示)我们是知道的。这类问题称为PDE-constrained optimization,有许多应用场景。解决这类问题的一类方法称为adjoint method,这篇文章会简单介绍这种方法的基本思想。
首先明确问题:系统的所有参数记为 ,场变量记为 (都是向量),并且我们知道它们满足关系 。在此基础上,希望优化 使loss函数 最小化:
如果函数 比较复杂,那么一个很自然的想法是基于梯度进行优化,也就是找出 ,然后对参数 进行梯度下降。但是这个导数怎么求呢?
一个非常暴力的做法是,每次对 的一维 加一个小扰动,近似地求出 ,重复多次。思路很直接,可惜很多时候函数 的形式可能比较复杂,甚至规律本身是用PDE来表示的,那么对于给定的参数 我们解 的过程(也就是所谓的simulation)就会比较耗时。在这种情况下,为了一步梯度下降而进行多次simulation,是不现实的——算不动。
所谓adjoint method,就是针对这个问题而诞生的。让我们先看一个比较特殊的情形:
(1) ,也就是说我们不对参数进行额外的惩罚。我们仍然要使用拉格朗日乘子法:定义 又由于函数 ,因此 那么我们就得到(下角标是求偏导的意思):
然后我们不是很喜欢这个 ,所以我们将乘子取为满足:
那么 梯度求完了。下面看稍普遍一点的情形。
(2) 与 有显式的关系,我们发现最终的结果其实也很简单:
相当于考虑对参数的惩罚之后,其实在梯度的表达式中体现为直接加了一项。
下面考虑一类更加复杂但更加有用的优化问题:
记时间为 ,我们考虑在时间段 内的优化。
系统: 也就是说确定初始状态 ,后续 的演化遵循一个ODE。
Loss function: 这是一个对时间的积分。
类似地,我们定义拉格朗日函数:
求导得到:
但是我们不想看到 或者 ,所以要化简一下。
考虑到:
我们有:
所以继续化简 :
最终得到:
我们可以取乘子 和 使得两个中括号中的项都为零。
所以完整的优化过程中,单次梯度下降只需要三个步骤:
(1)对于当前的 ,根据 计算出 ,再通过 解所有 。
(2)根据两个中括号为零的条件,写出乘子所满足的ODE,解之得到 和 。注意这里解ODE在时间上是反向求解。
(3)计算梯度 其中乘子已经在第二步中算出来了,然后就可以梯度下降了。
这样,对于每一步梯度下降,我们只需要做少数几次simulation,外加解几个ODE,就足够了。虽说计算量还是挺大,但已经在可接受的范围内了。
adjoint method解带约束的优化问题,其应用主要有两方面:
(1)我们拿到一个参数未知的系统,可以通过收集到的输入输出数据,对系统的参数进行估计。loss体现的是系统输出与测量到的实际输出的差异。
(2)我们希望设计一个系统,达到某种特定的功能,这个时候与目标功能是否契合就体现在loss里,然后我们优化系统的参数,完成inverse design。以我粗浅的了解,造桥、造飞机、造光学器件等领域都有在用这种方法。
后记:之所以想起来写adjoint method是因为,从暑研的时候他们设计器件就一直用这种方式,但当时数学细节没有时间抠得很仔细。最近看了相关方向的文章,顺手整理一下,内容基本上是照着https://cs.stanford.edu/~ambrad/adjoint_tutorial.pdf抄的,其实大家可以直接看那个tutorial。另一方面,等我有时间了可能会把跟光学neural network相关的几个工作整理在专栏里(目前了解的包括MIT Marin组、Stanford Shanhui组、Wisconsin Yu组)。
其实time-dependent的adjoint method也可以用来解最优控制问题(下一篇文章应该会谈一谈控制)。如果控制问题本身的状态转移比较复杂,无法写出闭式解(一个很经典的能写出解的例子是,转移是线性的,loss是quadratic的),那么在考虑约束的前提下进行梯度下降应当是一个不错的选择。另一方面,最优控制中我们可以考虑系统转移时有随机性,那么adjoint method显然也可以把类似的随机性考虑在内,不知道有什么实际应用没。