ETHZ-科学与工程的人工智能笔记-全-

ETHZ 科学与工程的人工智能笔记(全)

001:课程介绍 🧠

在本节课中,我们将一起了解“科学与工程中的人工智能”这门课程的整体概览。我们将探讨人工智能在当今科学领域产生的巨大影响,理解其背后的驱动力,并初步认识将科学理解与机器学习相结合的新兴领域——科学机器学习。


大家好,欢迎来到“科学与工程中的人工智能”系列讲座的第一讲。我的名字是 Ben Mosley,我将与 Sid Mira 共同教授这门课程。Sid 将在下周五开始讲授他的部分。现在,我将直接开始,为大家介绍这门课程的高层次动机,然后详细讲解课程内容、评估方式和具体安排。

人工智能正在对当今科学产生巨大影响,并推动着许多突破。尤其是在过去一年左右,这些突破开始引起公众的广泛关注。

以下是人工智能在科学领域产生影响的几个例子。

  • 天气预报与气候模拟:英伟达的“FourCastNet”模型、谷歌的“GraphCast”等模型能够训练出准确模拟气候和天气模式的人工智能模型。其精度可与传统数值模拟相媲美,在某些情况下甚至开始超越传统方法。这些模型不仅性能优异,而且比传统数值模型快数个数量级。
  • 核聚变控制:一项与瑞士 EPFL 的合作研究使用神经网络,特别是通过强化学习训练,来控制真实的核聚变反应堆。训练后的神经网络不仅能改变等离子体的形状,还能使其在更长时间内保持稳定。
  • 蛋白质结构预测:谷歌 DeepMind 的 AlphaFold 模型能够根据氨基酸序列准确预测蛋白质的三维结构。这项过去需要在实验室耗费数月甚至数年时间的任务,现在可以在计算机上几秒钟内完成预测,并在药物发现等领域催生了许多下游应用。

那么,为什么人工智能今天能以如此大的方式影响科学?原因在于人工智能本身在过去十年左右经历了爆炸式发展。

如今世界上存在一些非常强大的人工智能技术。你们大多数人现在肯定都熟悉 ChatGPT,这个模型在过去一年左右席卷了全球。更广泛地说,大型语言模型能够与你进行完整对话,并执行总结文档甚至创建完全自主的数字代理等任务。

图像生成领域也取得了令人印象深刻的突破。我们现在可以输入一个文本提示(例如,“一张宇航员骑马的图片”),并从中生成高度逼真的图像。就在上周,OpenAI 发布了 Sora,这是一个从文本生成极其逼真视频的工具。

此外,人工智能领域当前的一个趋势是不仅仅用 AI 执行非常狭窄的任务,而是使其变得更加通用,成为通才代理。例如,Gato 模型不仅能进行图像分类,还能捕捉图像、玩 Atari 游戏,并使用同一个模型与你对话。

我们今天使用人工智能来帮助编码,GitHub Copilot 非常擅长补全代码并为你建议整个代码块。人工智能是自动驾驶汽车背后的基础技术,我们现在也能非常有效地使用人工智能进行翻译,可以在数百种不同语言之间无缝翻译。

如果你查看这些图表,还可以看到人工智能研究出版物的数量一直在快速增长,资金投入也几乎呈指数级增长。最近另一个有趣的趋势是,关于人工智能的法律数量也在增加,我们开始真正思考人工智能背后的伦理问题。

那么,为什么人工智能本身会爆炸式发展?我认为,过去十年或更长时间里,人工智能的大部分进展(约90%)是由深度学习驱动的。

深度学习就是训练深度神经网络。在继续之前,我想解释一下什么是深度学习,以确保我们理解一致。

深度学习关注的是训练深度神经网络。为了简单明了(我认为这对本课程来说也是一种非常有用的描述方式),我将一个深度神经网络简单地描述为一个数学函数:

y = f(x; θ)

其中,函数接收一个向量输入 x,并给出一个向量输出 y。非常重要的一点是,这个函数有一些自由参数,我们称之为权重 θ,这些参数是可调的。我们调整这些参数,使得神经网络的输出与训练数据集中某些期望的输出相匹配。

训练基本上包括拥有网络输入和输出的许多示例,还需要一个损失函数来比较网络的输出与模型的输出,以及一个能够基于该损失调整权重的优化算法。

这就是神经网络或深度神经网络的简单描述。接下来的问题是,那个函数 f(x; θ) 到底是什么?那个函数取决于你使用的特定神经网络架构。虽然有很多不同的选择,但几乎每个神经网络架构都可以用这种简单的方式来描述。

最后一个问题是,什么使它“深”?通常,我们将深度神经网络定义为具有两层或更多层的任何神经网络函数。

那么,为什么深度学习最近才真正爆发?总的来说,它如此流行有三大原因。

以下是主要原因:

  • 数据量指数级增长:世界上某些衡量标准下的数据量呈指数级增长,这使我们能够训练越来越深、越来越复杂的模型。
  • 计算能力增长:计算能力也大致呈指数级增长。或许不是在 CPU 能力方面,但随着 GPU 的出现(事实证明 GPU 对于训练深度神经网络非常出色),我们在计算规模上确实看到了扩展。
  • 成熟的深度学习框架:现在有许多更成熟的深度学习框架,允许我们用几行代码训练神经网络。例如 PyTorch、Keras、TensorFlow 和 JAX 等平台。

除此之外,神经网络训练算法及其架构方面也有许多创新,这是一个非常有趣的研究领域。

我向大家展示了一些人工智能当今真正影响科学的例子。在这里,我试图思考一些人工智能能够真正帮助我们解决的科学重大挑战。科学中存在许多重大问题,如果我们能解决它们,将对世界和人类大有裨益。

以下是四个不同类型的重大挑战,我将解释我认为人工智能如何帮助解决它们。

  • 海量实验数据:当今一些实验产生的数据量巨大。例如,欧洲核子研究中心每月记录数千 PB 的数据。人类不可能手动处理这些数据并从中找出我们寻找的特定粒子相互作用。人工智能可以真正帮助自动化我们的发现过程和数据处理。
  • 数据稀缺与噪声:另一方面,我们进行的某些实验数据非常少,且数据噪声很大。例如系外行星发现。目前最流行的发现方法是凌星法,即观测行星直接从恒星前方经过,导致我们接收到的恒星通量出现非常微小的下降。问题是这种通量变化非常小,可能不到百分之一,并且产生的测量数据噪声非常大。人工智能可以真正帮助我们从噪声中提取信号。
  • 计算昂贵的模拟:许多不同领域的模拟算法通常计算成本非常高。例如,模拟流过飞机机翼的气流,这种多尺度、高保真度的模拟可能需要数百万核心小时和数百万美元来运行。任何能使用人工智能/机器学习加速这些模拟的方法都可能对我们的模拟产生巨大影响。
  • 日益复杂的系统:今天我们进行的许多科学实验或研究的科学系统,随着我们对它们了解得越来越多,正变得越来越复杂。一个很好的例子是 COVID 病毒及其随时间的演变。这实际上是一个超级复杂的问题,本质上是在模拟全球范围内的传播。我们这里有很多数据,人工智能可能能够帮助我们发现那些我们自己难以发现的数据模式。

与其我告诉你们为什么深度学习对科学很重要,我想不如直接问问人工智能本身。我询问了 ChatGPT“在科学中使用深度学习的好处是什么”,ChatGPT 给出了一个非常精彩的回答,基本上总结了我刚才告诉你们的内容。

人工智能可以帮助提高我们科学算法的准确性,也可以帮助我们从科学数据中自动化发现,通过检测我们以前无法看到的模式来增强我们的理解,并且可以提高效率,帮助加速我们一些计算成本高昂的工作流程。

我还有几张幻灯片展示人工智能在科学中的应用,以进一步说服你们这是一项真正具有影响力的技术。

我展示的是跨越许多不同领域的众多应用,我不会详细讲解,但会给你们一个快速总结。

  • 医学影像:人工智能帮助我们拍摄眼睛的图像或扫描,分割这些图像,并能够检测眼睛中的问题或疾病。
  • 天体物理:人工智能能够获取引力透镜星系的图像,消除透镜效应,并重建没有透镜效应的星系图像,实际上非常准确。
  • 粒子物理:人工智能还能够筛选粒子对撞机的数据,并检测该数据中的事件。
  • 神经科学:人工智能可以获取我们神经活动的记录,仅从该神经活动中解码我们所说的语音,帮助我们理解大脑及其工作原理。

以下是另外四个例子。

  • 月球探测:这是我们做的一些工作,使用人工智能窥视月球上永久阴影区域。这些是火山口和其他永久被黑暗覆盖的地形凹陷。图像非常暗且噪声很大,因此我们训练人工智能去除这些图像中的噪声,首次使我们能够看到这些区域内的陨石坑和巨石等物体。
  • 抗体设计:这是一个人工智能实际发现一种针对大肠杆菌(一种细菌)的新抗体的例子。它通过使用消息传递神经网络来实现,该网络经过大量示例训练,可以预测可能导致耐药性的各种分子特性。当它测试新的分子设计时,能够提出这种新抗体。
  • 解决几何问题:人工智能可以解决奥林匹克级别的几何问题,这就是 AlphaGeometry。这非常有趣,因为它结合了大型语言模型和符号推理引擎来执行该任务。
  • 科学工作流程编码:人工智能还可以帮助我们编写科学工作流程的代码,这是 ChatGPT 在编写代码求解二维扩散方程方面做得非常好的一个例子。

我已经大力宣扬了深度学习、人工智能及其在科学中的潜力,现在我想稍微回归现实,告诉你们深度学习也存在一些挑战。认识到这些挑战非常重要,特别是如果我们要将人工智能应用于科学工作流程。

深度学习存在一些众所周知的重大挑战。

我将介绍其中四个。

  • 模型规模庞大:如今我们训练的模型规模非常庞大。例如,早期版本的 ChatGPT 有 1750 亿个参数,训练该模型还需要海量数据,本质上需要爬取整个互联网来寻找训练数据。有一张图表显示了一些已发布的主要机器学习模型的参数量趋势,你可以看到趋势是急剧上升的,我们正在迈向万亿参数模型。因此,即使只是将这些模型存储在计算机内存中并对它们进行推理也可能是一个挑战。
  • 偏见问题:人工智能,或者说深度网络,也存在偏见问题。深度神经网络的一个特性是,如果你的训练数据中存在偏见,这种偏见也会出现在模型的输出中。不幸的是,我们训练深度神经网络的许多数据都包含偏见,例如在进行人脸识别时,性能在不同人群之间存在差异。因此,确保我们训练的人工智能是公平和合乎伦理的,是一个非常重要的考虑因素。
  • 缺乏可解释性:与此相关的是深度神经网络缺乏可解释性。这根本上是因为神经网络在处理输入时使用分布式表示,这使得解释它们在做什么或让它们证明其行为变得非常困难。例如,如果你训练一个神经网络来驾驶汽车,你肯定希望解释它基于输入和上下文为什么向左转或向右转。
  • 网络架构设计:最后一个挑战是实际设计神经网络本身。对于给定的任务,通常并不明显什么才是正确的神经网络架构(即我展示的那个神经网络函数)。我认为,过去十年人工智能的许多进展或研究,就是尝试了许多不同的架构。例如,在图像识别(计算机视觉中的经典任务)中,我们从全连接网络发展到卷积网络,再到 ResNets,再到 Transformer,我们仍在摸索使用哪种架构最好。

我还有两个挑战,我认为这两个挑战对于在科学中使用人工智能尤其突出。

  • 泛化挑战:这是深度神经网络的一个特性。当给它们一个在其训练分布内或接近其训练数据的输入时,它们通常表现非常好。但一旦你给它们一个在其训练分布之外的输入,它们的性能通常会迅速下降。这是我亲自做的一个测试:我拿了一个在 ImageNet 上预训练的 ResNet(包含数千张不同的自然图像)。如果我让它对一张狗的图像进行分类(这是一张在其训练分布内的图像),它不仅能准确识别出是狗,还能告诉我们具体的品种。但一旦我给它一张在其训练分布之外的图像(比如某种太空狗),它就开始真正挣扎,无法直接标记它。
  • 推理挑战:与此相关,或许是一个更广泛的问题是深度神经网络的推理挑战。它们通常难以在输出中表现出常识性推理。这是使用 DALL-E 3(一个最先进的图像生成模型)进行图像生成的例子。我要求它生成“一条绝对没有路灯的街道”。它没有生成我所要求的,反而给了我一条有很多路灯的街道,完全相反。你可以看到,模型在处理陈述背后的逻辑否定时遇到了困难。因此,将更多常识性推理融入神经网络是一个突出的挑战,绝对是当前一个非常热门的研究课题。

我展示了这些挑战,但我是通过传统人工智能任务的视角来讨论的。真正重要的是要理解,当我们将人工智能应用于科学时,这些局限性也会出现在我们使用人工智能的科学工作流程中。

这是我们做的更多工作,我向你们展示我们在哪里发现了这些局限性之一。

我们在这里训练了一个神经网络来进行模拟,特别是模拟地震在地球中的传播。你不需要知道确切的工作流程,但在很高的层次上,我们这里有一个神经网络,它接收地球结构作为输入,特别是地球的速度(这取决于地球的地质情况)。然后它产生一个输出,基本上是沿地球表面的地震响应,即无论你在地球表面何处,地震的强度。我们发现,当我们用许多非常简单的速度模型(只有水平分层和单个褶皱)训练这个神经网络时,如果我们在一个接近其训练数据的速度模型(类似的水平分层速度模型,带有单个褶皱)上测试该神经网络,它能够非常准确地预测地震波场。但一旦我给它一个在其训练分布之外的输入(例如,一个带有曲线或额外褶皱的速度模型),网络的预测就开始真正受到影响,性能会差很多。这就是泛化问题在科学工作流程中的体现。

当我们试图说“好吧,我们将用人工智能取代我们现有的科学工作流程”时,这种问题让许多科学家感到不安,因为我们知道深度学习存在这些缺陷,例如缺乏可解释性,有时难以泛化,并且我们还需要大量训练数据来训练这些算法。这与理解传统科学方式的科学家们的理念不太相符,传统科学方式严重依赖于理论和实验之间的相互作用。

传统的科学方式是提出一个非常可解释的理论,提出一些假设来检验该理论,进行实验,要么验证理论,要么告诉我们需要改进该理论。这是我们通常遵循的迭代改进循环。关于那个理论的一个非常重要的点是,一个好的理论应该是可解释的,并能做出新颖的预测,而这正是深度神经网络难以做到的。

因此,在过去五年左右的时间里,使用人工智能进行科学研究发生了真正的变化。我们现在开始看到“科学机器学习”这个领域出现。科学机器学习的核心论点不是仅仅用机器学习取代我们的科学工作流程,而是将我们现有的科学理解(我们拥有数百年的科学理解可以借鉴)与我们的机器学习工作紧密结合起来。

我们称这些模型为科学机器学习模型。我们希望它们比仅仅用人工智能取代我们现有的工作流程更强大、更稳健、更可解释。

已经提出并正在研究大量的科学机器学习技术,这是一个当前非常热门的领域。你们可能已经听说过其中一些技术,例如物理信息神经网络、可微分物理、神经算子、神经微分方程等。在本课程中,我们将详细涵盖许多这些技术,你们会看到更多相关内容。

这是一个快速发展的领域。在过去两三年里,所有主要的机器学习会议上都举办了关于将机器学习与科学理解相结合的科学机器学习研讨会。

我还做了一个关键词搜索,查看包含这些科学机器学习关键词的出版物数量,例如“物理信息神经网络”、“科学机器学习”、“算子学习”、“可微分物理”等。所有这些关键词在过去一年中收到的出版物数量都呈指数级增长,现在我们真的开始看到这个领域的真正兴起。

刚才我给了你们这门课程非常高层次的动机,并希望已经说服你们,人工智能确实正在对当今的科学产生影响,并且它可能是我们在科学中可以使用的一种变革性工具。

那么,这门课程的总体目标是什么?我们为你们设定了四个大的学习目标。

到课程结束时,我们希望你们能够:

  • 更了解人工智能在科学与工程中的高级应用
  • 更熟悉这些算法背后的具体设计、实现和理论
  • 对何时可以使用人工智能以及何时或许不应该使用人工智能来增强科学工作流程有更现实的认识
  • 不仅理解人工智能技术,还理解如何将科学理解与之紧密结合,从而领会这些关键的科学机器学习概念和最佳实践

这是课程时间表,这张幻灯片上有很多内容,我将为你们讲解。

我们每周有两节课,一节在周三(也就是今天的讲座),另一节在周五,它们都在同一个教室(ML H 44)。除了讲座,我们还有辅导课,这些将由我们的助教负责,包含实践练习(通常是编码练习),以补充我们在讲座中涵盖的所有内容。

我现在不会详细讲解每节课的具体内容,我将在讲座后面再谈课程概述。但为了给你们一个非常高层次的描述,Sid 和我将首先快速回顾深度学习,因为本课程的先决条件是理解机器学习的基础知识,例如优化和监督学习。这将是一个相当快速的回顾,但希望能让每个人都在同一起跑线上。

然后,我们将讨论不同类型的核心科学机器学习技术。我们将首先讨论物理信息神经网络,然后讨论算子学习领域。接着,我们将介绍几种在科学中使用的特定架构或最先进的架构,例如大型语言模型、图神经网络、扩散模型。然后,我们将讨论可微分物理。最后,我们有两场客座讲座,讲师将谈论化学和生物学中的机器学习。

我应该说的另一件事是,这个时间表可能会根据我们讲解材料的速度而改变,我们也在积极添加新材料。这门课程的很多材料都是在过去一两年内研究的,因此我们也在积极调整这门课程。

还有一些关于课程的实用信息。所有材料都将在我们的课程 Google 页面上提供,包括讲座录音和辅导练习。我们还运行 Zoom 会议,以便你们也可以在线参加。

你们可能最感兴趣的是我们如何评估这门课程。需要注意的是,这门课程没有任何考试。我们所有的评估都是通过三个独立的作业来完成的。

这些是要求你们完成的个人作业,每四周提交一次。我们将在 3 月 8 日发布第一个作业,然后在四周后(4 月 5 日)提交。这些作业将与我们讲座和辅导课中涵盖的内容相关。关于每个作业的具体要求和交付内容,将在我们发布作业时给出详细说明。你们也可以与我们的助教交流,他们将帮助我们批改这些作业。

我们这门课程的助教是 Bogdan 和 Victor,他们非常乐意帮助你们。你们也可以通过 Google 联系我们。

我已经讲了很长时间了,所以我们先休息一下,大约五分钟后回来。

那么,这节课的其余部分将如何安排?我刚才给你们讲的是课程动机和概述。现在,我们将用这节课剩余的时间来讨论一些关键的科学任务,这些任务在科学中以非常普遍的方式存在。

然后,我还将尝试向你们解释人工智能或机器学习如何帮助解决这些科学任务。我将在相当抽象的层面上进行讨论,跨越许多不同学科。但事实证明,有许多不同的科学任务是通用的,或者说是跨学科的常见任务。这些任务包括模拟问题、反问题、控制或数据同化问题、方程发现和异常检测。我将一般性地讨论这些任务。

在讲座的最后,我将更多地概述科学机器学习,并告诉你们如何更紧密地将科学理解整合到机器学习中。同时,尝试激发一些我们将在后续课程中更详细研究的关键科学工具和技术。

那么,我们这节课的学习目标是什么?我们有三个目标。

到课程结束时,你们应该能够:

  • 理解为什么人工智能在科学中如此有用及其产生的影响
  • 理解我们尝试使用机器学习解决的典型科学任务类型
  • 理解科学机器学习领域存在的原因,以及为什么将科学理解与机器学习相结合是一个好主意

现在,让我们来讨论一些跨许多不同科学领域都非常常见的关键科学任务。

在讨论科学任务之前,我应该先谈谈微分方程,或者实际上是偏微分方程。这些是科学背后的基石,它们以一种非常优雅的方式决定或描述了我们周围的世界。

从最小的尺度,例如使用薛定谔方程描述原子如何随时间演化,到非常大的尺度,思考黑洞及其动力学(这是爱因斯坦场方程)。它们还帮助我们理解地球,例如我在讲座第一张幻灯片中展示的气候模拟例子,其背后的基本方程是纳维-斯托克斯方程。我们还知道微分方程可以帮助我们理解生物学,特别是反应-扩散方程帮助我们理解动物皮肤生长时图案是如何形成的。

因此,偏微分方程是基础性的。在本课程中,我们将相当重视解决与偏微分方程相关的问题,正是出于这个原因。

现在,让我们开始讨论这些关键的科学任务。

正如我在谈论讲座概述时所说,在讲解过程中,我会给你们具体的科学任务例子,但我真的鼓励你们在更高的抽象层次上思考,也许在你们自己的科学领域,是否有任何类似的任务是你们感兴趣的,或者你们认为在特定领域中难以解决的。

第一个任务是模拟。我将尝试在非常高的层次上描述它。为此,我要说我们有一个物理系统,并且在该物理系统中有一些输入条件,我将其描述为 A。我们还有该系统的物理模型,这通常是一些微分方程组。然后,给定这些输入条件和物理模型,模拟的任务是预测给定这些输入条件的结果属性 B

这显然是对模拟的非常高层次的描述,根据实际任务的不同,底层物理模型在数学上可能复杂得多。

这是一个模拟的例子,是模拟地震通过地球结构的例子。广义上的模拟对于许多不同的科学任务至关重要,对于理解不同的科学现象和预测它们的行为非常重要。模拟通常被用作许多其他科学任务的起点。例如,我们可能想看看这里的地震响应如何根据地震发生的位置在地球表面变化,并且我们可能想基于该模拟进行某种建模或灾害预测。

我在这里运行模拟所依据的底层方程是声波方程,这是一个非常著名和熟悉的方程。

为了更明确地使用我刚才描述的框架来阐述,我们在这里预测 B,在这个例子中,B(模拟结果)是波场,即该微分方程的解,本质上是地震波的压力,作为空间和时间的函数。模拟的输入是速度模型(这是我们对地球结构的模型)以及地震的位置。给定这些输入条件,我们想要预测地震波场。这里的 F 是我们的微分方程(波动方程),但除了知道方程,我们通常还需要一些方法来求解方程,例如,求解波动方程时,一个非常常见的方法是使用有限元求解器。

那么,我们如何解决模拟问题?传统上,我们使用数值方法。大多数偏微分方程,尤其是具有现实输入条件的,无法解析求解,我们必须求助于数值技术。这本身就是一个庞大的领域,已经研究了几十年或更长时间。

我们有许多不同的数值求解微分方程的方法,流行的技术包括有限差分求解器、有限元求解器、谱方法、主成分分解方法等,有很多技术可供选择。

那么,我们今天面临的模拟挑战是什么?我在讲座开始时已经告诉你们,通常模拟的最大挑战是运行这些数值方法(有限元、有限差分求解器)所需的计算成本。

这是 NASA 的一个视频,模拟火箭的排气。这是一个超级复杂的模拟,是一个多物理场、多相模拟。仅仅运行这几秒钟的模拟,就在他们的模拟中使用了 5 亿个网格单元,并在数千个核心上运行了数周,因此运行一次模拟就花费了数百万美元。这限制性很强。我们真正想做的是运行这个模拟数千次,改变火箭的设计,以帮助我们优化系统并制造出高效的火箭,但这在实际中是不可能的,我们只是受到计算的限制。如果我们能用机器学习加速这个过程,可能会彻底改变我们设计这些系统的方式。

还有其他一些重大挑战。像有限元方法这样的方法,我们需要花费大量时间仅为模拟设计一个合适的网格,这可能需要耗费大量人力,可能需要数周时间。除此之外,我们许多成熟的模拟代码(例如非常流行的流体动力学代码 OpenFOAM)有数百万行代码,如果你刚进入这个领域,可能很难在其基础上构建或理解。

现在,我们将转向下一类问题,这类问题是反问题。

那么,在非常高的层次上,什么是反问题?我们有同样的方程,但现在我们关注的不再是预测系统的输出,而是实际上想要预测或推断系统的输入条件,给定系统的一些观测结果。也就是说,给定一些观测 B 和对物理模型的理解,是什么输入条件产生了这些观测?

让我们思考一下将那个地震模拟任务框架化为一个反问题。那么,反问题将是:假设我们有检波器测量地球表面的压力响应,给定波场的观测数据,我们能否找出地震发生的位置,甚至可能找出地球的底层结构(速度模型)?

这些问题跨越许多不同的科学领域。这里有几个反问题的例子:地震成像、MRI 成像是另一个反问题的例子。图像去噪(从图像中去除噪声)可以被认为是一个反问题,或者估计感染率、设计问题等等。

那么,我们如何解决反问题?从根本上说,我们可以将反问题框架化为一个搜索问题:给定 B 的值,尝试寻找或搜索能给出该 B 值的 A 值。通常,将其框架化为一个优化问题特别有用。在优化问题中,我们定义一些目标函数或损失函数,我们试图最小化它。

一个常见的损失函数可能只是给定某个猜测输入条件 A 的预测值与真实观测值 B 之间的 L2 范数。然后,如果这个损失函数是可微的(例如),我们可以评估这个损失相对于 A 的梯度(顺便说一下,这也要求你的求解器 F 也是可微的,即你的有限差分/有限元求解器是可微的)。然后,我们可以使用梯度下降等方法来优化和求解 A。如果我们无法获得梯度,也可以使用许多其他无梯度方法,例如进化算法、贝叶斯优化,在某些情况下,暴力搜索也可能有效。

让我明确地向你们展示使用梯度下降解决反问题的过程。正如我之前所说,我们在顶部有这个目标函数或损失函数。我们所做的是从左上角的模型开始,进行正演模拟以预测 B 的值,得到一些合成数据。我们评估那个损失函数,它决定了该模型的好坏。然后,我们使用梯度下降更新该模型。通过这个迭代循环,我们最终得到对模型是什么的最终猜测。

顺便说一下,这实际上与我们训练深度神经网络所使用的算法完全相同,这实际上很有趣。我们将在课程后面更详细地探讨反问题和训练深度神经网络之间的联系。我们用来训练深度神经网络的许多技巧也可以用来帮助我们解决反问题,反之亦然。

具体对于我描述的那个地震反问题,我们的观测数据将是我之前展示的波场。我们将从对速度模型的某个猜测开始,通常我们只是从一个非常平滑的地球速度近似值开始。我们运行这个训练循环,最终希望得到一个接近真实地球模型的模型。

这实际上是一个真实的梯度下降算法在这个波场数据上运行。我们正在进行这个循环,更新梯度,这就是猜测的速度模型随着我们更新梯度而变化的过程。

在地球物理学中,这实际上被称为全波形反演,这是反问题的名称。你可以看到这里发生了一些相当有趣的事情。首先,它确实对真实速度模型有了一个相当好的猜测,并且基于该猜测速度模型的估计波场也是如此。但有趣的是,它没有更新波场尚未传播到的区域之外的模型。这是有道理的,因为波场尚未传播到的区域没有信息,因此你无法了解那里的速度。另一个有趣的事情是,它很好地捕捉到了右侧的大部分褶皱,但在左侧却表现不佳,并且在估计的速度中产生了一些非常奇怪的异常。

因此,这是反问题的一个挑战。在许多情况下,在许多现实世界的情况下,我们拥有的观测数据并不足以让我们唯一地确定反问题的解。而且,即使你有足够的信息,损失函数仍然可能非常复杂,并且有许多局部极小值,即使你有足够的信息,你可能仍然无法收敛,这可能就是这里发生的情况,我们有很多信息,但损失函数可能非常复杂。

实际上,反问题存在很多挑战,在实践中它们极其难以解决。最大的原因就是我提到的“不适定性”,即观测数据中通常没有足够的信息来唯一地确定解是什么。另一个导致不适定性的问题是观测可能很稀疏,也可能噪声很大,这再次使它们更难解决。最后一点是,当我们运行例如那个梯度下降循环进行优化时,我们必须评估那个正演求解器数千次才能进行反演。我已经告诉过你们,模拟(进行数值模拟)可能非常昂贵,而我们必须运行数千次,因此反问题在许多情况下甚至比模拟更昂贵。

这绝对是一个非常困难的事情。这是左侧反问题的另一个例子,是计算机断层扫描(CT),基本上就是进行 X 光检查。那么,在这种情况下,反问题是什么?我们有一个 X 射线源(实心小点),有一些介质,该射线源将穿过该介质。该介质对 X 射线有一些吸收,这种吸收是空间的函数,因此你身体的不同部位以不同的量吸收 X 射线,你可以将其解释为一张图像,让你看到身体内部。然后,我们沿着许多位置记录这些 X 射线。

你可以看到,如果我们只有一条线,根据我们记录的线数(X 射线穿过的介质数量),这实际上决定了反问题的不适定性。如果我们有很多线,那么我们可以得到一张非常好的图像。但如果我们只有很少的线,那么重建该图像就变得非常困难。你可以看到,我们实际接收到的数据(这些强度)实际上看起来一点也不像之前的信号。我们必须在那个信号上进行反演,这是一个特定的反演后投影算法的例子,它正在做这件事,显然没有得到确切的答案,它是对真实解的一个非常嘈杂的估计。

与反问题相关的是控制和数据同化问题,可以将它们视为不同类别的反问题。

什么是控制问题?控制问题是:给定一个微分方程组,我们能否向这些微分方程中添加一些作用力来控制该系统或系统的状态?一个经典的控制问题是倒立摆。你可以想象一个小车上的摆,任务是移动小车,使得摆最终像这样倒立,这是一个非常不稳定的平衡点。底层的运动方程在这里,我不会详细描述它们,但我们试图做的是改变这里的力,使得最终状态(摆角)趋向于零。

我们可以将其框架化为一个反问题,其中 A 是我们施加给小车的力,F 是运动方程及其求解方式,B 是摆角作为时间的函数趋向于零的条件。

另一类问题是数据同化问题。例如,这是一个任务,我们对摆本身有噪声测量,我们可能想推断摆的起始位置,或者可能是其位置随时间变化的路径。同样,我们可以说这里的 A 是我们想要理解的东西,即摆的起始位置。B 可能是对 xθ 的测量。然后 F 再次是我们拥有的模型,可能还有一个叠加在其上的噪声模型(如果测量有噪声的话)。

最后一类反问题是设计问题。这就是我在谈论设计太空火箭时提到的问题。我们想要做的是,我们有一个物理系统,我们想要优化该系统的设计,以最大化该系统的某些指标。另一个例子是设计翼型的形状,以最大化翼型的升力。我们可以调整的参数可能是翼型的形状和机翼的迎角。这同样可以被认为是一种反问题。

现在,我们将转向最后一类科学任务,这实际上是理解 F 本身。这就是我所说的方程发现或模型发现。我们可能对系统的初始条件有一些观测,也可能对其输出(即它的行为方式)有一些观测,我们可能不完全理解底层的微分方程或模型是什么。这实际上是许多不同科学领域的实际情况,例如实验流体动力学正试图更好地理解流体的底层方程。

那么,我们如何做呢?传统上,它依赖于非凡的人类直觉(我不得不在这里放一张爱因斯坦的照片,因为我们在 ETH)。能够提出一个好的理论,就是我之前描述的在设计理论、进行实验、验证理论之间相互作用的过程,这主要是由人类完成的迭代循环。

从计算的角度,或者在我一直描述的这种框架背景下,你可以将其视为某种反问题,我们再次被给予一些观测数据,我们想要理解系统的某种底层描述。但在这里,我们实际上试图预测模型本身。一个好的模型的标志是:它应该是可解释的,应该是可泛化的,并且应该做出我们可以通过实验验证的新颖预测。

也许模型发现的一个更具体或特定的例子是异常检测。所以这不是发现整个模型,而是进行发现过程的一小部分,即检测数据中的异常,这可能导致你更新或发现一种新的物理现象。例如,异常检测的一个例子是检测系外行星,正如我讨论过的凌星法。但这具有挑战性,原因有几个。我已经解释过,数据中的噪声使得人类很难检测到原子和数据中的异常。如果异常来自我们目前不理解的物理现象(即它们是分布外的或来自无法解释的物理现象),那么检测异常也可能非常困难。而且,异常通常就像大海捞针,非常罕见。例如,想想粒子对撞机中我们正在寻找的特定粒子。

在接下来的部分,我有几个关于深度学习如何帮助完成这些任务的例子。我有一个深度学习改进模拟的例子,一个深度学习改进反问题的例子,然后是一个深度学习帮助我们发现系统底层方程的例子。

在较高层次上,深度学习如何帮助?正如我们之前所见,ChatGPT 为我们总结得很好:它可以帮助我们提高这些技术的准确性,可以提高效率,实现我们科学工作流程的自动化和发现。

这是一个在科学中使用机器学习的例子,也是我已经向你们展示过的使用深度神经网络进行气候模拟或天气模拟的例子。这就是 FourCastNet,我在右侧展示了这个动画。

那么,FourCastNet 到底是什么?FourCastNet 是一个称为傅里叶神经算子的深度神经网络。它只是一种神经网络架构,基于卷积网络。但有趣的是,它在傅里叶域中进行卷积。我们知道,在频域中的卷积本质上就是乘法。傅里叶神经算子与标准卷积网络的不同之处在于,当它进行傅里叶变换时,实际上会裁剪掉一些频率,即它本质上丢弃了输入数据中的一些高频成分。然后,它将其乘以进行卷积的权重矩阵,然后再进行逆变换回来。

这很有趣,关于傅里叶神经算子和算子学习背后的动机有很多可说的,我们将在课程中更多地讨论。但现在,你可以将其视为一种智能的神经网络架构,它只是偏好输入中的低频成分。因此,它有一个先验,认为我们应该更好地模拟低频趋势。事实证明,这个模型在进行天气模拟方面非常出色,最重要的是,它比使用传统数值技术求解纳维-斯托克斯方程或完整的气候模型快四到五个数量级。

现在,让我们谈谈如何使用深度学习来解决反问题?我向你们展示了那个经典的用于解决反问题的梯度下降算法,它经常被使用。

那么,我们如何将机器学习融入这个算法,以尝试提高其性能?有很多不同的方法可以使用机器学习来解决反问题,这只是其中一种特定方式。在课程中,我们将涵盖许多不同的方法。但一种特定的方式是使用神经网络来实际改进梯度的估计,或者你想在梯度下降循环的每次迭代中采取的步骤。

我们知道,当我们在损失函数中估计梯度时,特别是如果反问题是不适定的,那个梯度将会非常嘈杂,并且不会带我们走向解决反问题的正确方向。损失函数的景观将非常复杂,梯度方向可能不是最佳步骤。

这个想法是训练一个神经网络,但让它接受那个梯度并更新它,以便采取更好的步骤。我们如何学习那个神经网络?我们如何学习采取更好的步骤?我们将这个算法写下来,实际上使用自动微分对整个算法进行微分,以训练网络的权重。我们用来训练网络的损失函数是匹配许多示例反问题的最终算法最终模型。

当我们谈论课程后半部分的可微分物理时,我会更多地讨论这个问题。但事实证明,如果你这样做,如果你训练一个神经网络来改进梯度步骤,我们可以开始获得反演算法更好的性能。它开始消除由问题的不适定性带来的一些噪声。

最后要讨论的任务是方程发现。那么,机器学习如何帮助我们发现系统的底层方程?同样,这现在正成为一个完整的领域,这只是众多不同技术中的一个例子。

这个方法非常简单。你可以想象,我们这里有一些物理系统的观测数据。我们还不理解底层的微分方程是什么,我们只知道我们对某个变量 u(方程的解)以及它如何随时间演化有一些观测,这些是我们的噪声测量。

那么,我们如何发现这个 u 所遵循的底层微分方程?这非常简单。首先,我们拟合一个神经网络到这个数据。我们这里有一个神经网络函数 NN(x, t),它直接尝试拟合这个数据,所以它只是对该数据的曲线拟合。下一步是计算那个训练好的神经网络的各种梯度。那个神经网络函数只是一个数学函数,我们可以从该函数获得解析梯度,例如网络输出相对于其输入的导数:∂u/∂t∂u/∂x

我们所做的是,我们在许多不同的随机 (x, t) 位置计算这些梯度的整个库,就像查询整个函数一样。然后,为了在给定这些梯度的情况下发现底层方程,我们只是对这些梯度进行稀疏线性回归。我们假设,例如,∂u/∂t 是所有这些不同梯度的线性组合。这就是我们对系统所做的假设,然后我们将尝试学习基函数的每个系数,以实际发现底层方程。

我不会说这是物理模型的全面发现,它本质上只是线性回归。但这是开始理解或开始发现方程的一种方式。

这是几年前发表在《自然通讯》上的一篇论文。它做得非常好,能够发现这个底层方程,这是流体问题中的 Burgers 方程。

刚才我所做的是,在高层次上告诉你们我们在科学中感兴趣解决的一般科学任务,并让你们初步了解了机器学习如何帮助我们解决这些任务。

现在,我将用讲座的最后一部分来谈谈科学机器学习这个领域,我已经说过,这是一种将我们现有的科学理解与机器学习紧密结合的方式,以产生更强大、更稳健、更可解释的模型。

我将给你们更多关于这个领域的概述。我已经描述过这一点,所以我们知道,当深度学习只是简单地应用于科学工作流程时,存在所有这些问题:缺乏可解释性、泛化能力差、需要大量训练数据。这就是科学机器学习正在做的事情:我们试图将我们的科学理解融入这些算法中。

那么,我们实际上如何做到这一点?人们研究和提出了哪些不同的方法来实际将理解与神经网络(特别是)融合?我喜欢将它们分为非常广泛的类别。

我们将在整个课程中解释这些不同的类别以及每个类别中不同技术的例子。但在非常高的层次上,有三种方法可以将科学理解融入神经网络。

  • 通过损失函数:这是你用来训练神经网络的损失函数。与其仅仅训练网络来重现大量科学数据,你实际上可以将物理约束放入该损失函数中。例如,你可以告诉神经网络它必须守恒质量或能量,或者必须遵守底层的微分方程。这是提高这些模型性能并允许它们依赖更少数据的一种非常强大的方法。关于这一点有很多可说的,物理信息神经网络就是一个具体的例子,它们在过去的五年左右变得非常流行。我们将有三到四节课专门讲物理信息神经网络。
  • 改变神经网络架构:下一类广泛的方法是改变神经网络本身的架构,使其在架构中编码科学先验知识。这是一种硬约束,而改变损失函数中的约束更像是一种软约束。例如,我们可以在神经网络中有特定的层,这些层编码我们在非常深层次上已知的对称性。它们也可以编码能量守恒、旋转不变性等。有很多非常有趣的技巧可以提高我们训练的循环模型的性能。
  • 混合方法:最后一类方法,可能是最广泛的方法,是我称之为混合方法的方法。因此,不是用神经网络(即使它有一些聪明的约束)取代我们传统的科学算法或工作流程,在这种混合方法中,我们实际上尝试将神经网络紧密地结合在传统算法内部。例如,我描述的那个反问题,当我们将神经网络放入该算法的一小部分时。这些方法可能非常强大,也非常可解释。同样,我们将有两到三节课描述这个领域的技术,例如神经微分方程、可微分物理等,这些都可以归类为混合方法。

实际上,我说过科学机器学习是一个快速发展的领域,存在大量的技术,其中一些我们将详细涵盖。

这实际上是我在论文中制作的一个图表,这已经过时了(我在2022年做的),但我认为看到这个图表并以这种方式思考仍然有用。我所做的是,在顶部的表格中,我分解了我们试图执行的这三个不同的科学任务(模拟、反演

002:深度学习导论(第一部分) 🧠

在本节课中,我们将要学习深度学习的基础知识。我们将从宏观上理解什么是深度学习,介绍最基本的多层感知机(MLP)架构,探讨神经网络的通用近似定理,并了解深度学习用于解决的主要任务类型。最后,我们将学习如何使用梯度下降和反向传播来训练深度神经网络。


课程回顾

上一节课我们介绍了本课程的宏观动机。我们探讨了人工智能如何对科学领域产生巨大影响并推动突破,例如用于快速准确的气候模拟与天气预测、帮助控制核聚变反应,以及预测蛋白质的3D结构。

我们还讨论了科学研究中常见的核心任务,以及人工智能如何帮助我们解决这些任务,例如使模拟更高效、解决逆问题以及发现未知物理方程。

此外,我们引入了“科学机器学习”这一前沿领域,其核心思想是将我们已有的科学知识与机器学习紧密结合,以构建更强大、更稳健、更可解释的模型。


什么是深度学习?

在深入探讨之前,让我们将深度学习置于更广阔的人工智能领域中。人工智能、机器学习和深度学习这些术语有时定义模糊。对于本课程,我们可以这样理解:人工智能旨在训练智能体模仿人类行为;机器学习是人工智能的一个子领域,专注于学习世界的规则;而深度学习则是机器学习的一个特定分支,专门使用深度神经网络来学习这些模式或规则。

核心观点:神经网络本质上就是拟合数据的灵活函数

这意味着什么?简单来说,神经网络接收一个输入向量 X,通过一个由网络架构定义的数学函数进行处理。这个函数包含一些可调参数 θ。网络最终产生一个输出向量 Y。训练过程就是通过调整参数 θ,使网络的输出尽可能匹配训练数据。

一个简单的例子是曲线拟合:给定一组带噪声的数据点,神经网络可以学习一个函数来拟合这些数据。


从线性回归到神经网络

假设我们想用多项式拟合数据。经典的方法是线性(多项式)回归:

  1. 假设数据模型:Ŷ = θ₀ + θ₁x + θ₂x² + ...
  2. 通过最小化预测值 Ŷ 与真实观测值 Y 之间的最小二乘误差来估计参数 θ
  3. 对于线性模型,存在解析解。

神经网络回归的思想非常相似:

  1. 我们有一个神经网络函数 f(x; θ)
  2. 同样使用最小二乘目标函数,最小化网络输出与训练数据之间的差异。
  3. 关键区别在于,神经网络函数 f 通常是非线性的且没有解析解。因此,我们使用梯度下降等优化方法来学习参数 θ,即计算损失函数对网络权重 θ 的导数,并沿梯度方向更新参数。

多层感知机

最基本、最经典的神经网络架构之一是多层感知机。一个两层的MLP可以用以下公式定义:

a⁽¹⁾ = σ(W⁽¹⁾ x + b⁽¹⁾)
ŷ = W⁽²⁾ a⁽¹⁾ + b⁽²⁾

其中:

  • x 是输入向量。
  • W⁽¹⁾, b⁽¹⁾W⁽²⁾, b⁽²⁾ 是可学习的权重矩阵和偏置向量。
  • σ 是激活函数(如ReLU)。
  • a⁽¹⁾ 是隐藏层的激活值。
  • ŷ 是网络输出。

更多层的MLP就是这些层函数的简单堆叠(复合)。

为什么选择这种结构?
MLP的设计灵感来源于生物学中的神经元。单个神经元接收来自前一层神经元的输入,进行加权求和,加上偏置,然后通过一个非线性激活函数产生输出。这简化地模拟了生物神经元的工作方式。将许多这样的神经元分层连接,就构成了神经网络。

激活函数的作用
激活函数(如ReLU、tanh)引入了非线性。如果没有激活函数,多层线性变换的复合仍然是一个线性变换,网络将无法学习复杂的非线性关系。正是激活函数使得神经网络能够拟合高度复杂的函数。


通用近似定理

既然简单的多项式回归也能做曲线拟合,为什么还要使用神经网络?

答案在于神经网络的通用近似定理。该定理指出,只要拥有足够的参数(足够宽或足够深),一个神经网络可以以任意精度近似任何复杂度的连续函数。这使得神经网络异常强大,能够应用于图像分类、语音识别等极其复杂的任务,而这些是简单的线性模型无法胜任的。


卷积神经网络

上一节我们介绍了通用的MLP,本节我们来看看一种为特定数据类型设计的架构:卷积神经网络。

考虑图像分类任务。如果将一张128x128的图像展平为向量输入MLP,并且第一隐藏层有100个神经元,那么第一层的权重矩阵将包含超过160万个参数。这参数量巨大,容易导致过拟合。

CNN有何不同?
CNN专为处理网格状数据(如图像)设计。其核心思想是:

  1. 局部连接:每个神经元只与输入图像的一小块局部区域(如3x3的像素块)连接,而非整个图像。
  2. 参数共享:所有神经元使用相同的权重集(即卷积核或滤波器)在其对应的局部区域上进行操作。

这极大地减少了参数量。数学上,卷积操作可以表示为一种特殊的加权求和(交叉相关)。

CNN的优势

  1. 参数效率高:显著减少了模型参数量。
  2. 平移等变性:图像中某个特征(如狗耳朵)无论出现在何处,都会产生相似的激活响应。这使得CNN对物体位置变化具有鲁棒性。
  3. 层次化特征学习:浅层CNN学习简单特征(如边缘、纹理),深层CNN则组合这些简单特征来识别更复杂的模式(如物体部件、整个物体)。网络的深度对于学习这些层次化表征至关重要。

通过将“函数是简单函数的复合”这一先验知识(归纳偏置)编码到网络架构中,CNN能更高效、更有效地处理图像类数据。


深度学习的主要任务

神经网络作为拟合数据的函数,可以应用于多种任务。以下是几种主要类型:

1. 监督学习
监督学习任务中,我们拥有输入数据 X 和对应的标签或目标输出 Y

  • 回归:目标是拟合一个连续函数。常用均方误差作为损失函数。从概率视角看,可以理解为假设数据服从以网络输出为均值的高斯分布,然后进行最大似然估计。
  • 分类:目标是预测离散的类别标签。输出通常表示为每个类别的概率。常用交叉熵损失函数。为确保输出是有效的概率分布,通常在网络最后一层使用Softmax激活函数。

2. 无监督学习
无监督学习任务中,我们只有数据 X,没有明确的标签。

  • 特征学习/自编码器:目标是学习数据的压缩、有意义的表示。网络先将输入编码为低维潜在向量,再解码重建输入。通过最小化重建误差,网络被迫学习数据的关键特征。
  • 自回归模型:目标是基于序列中过去的数据预测未来的数据。例如,预测股票价格或生成文本(如大型语言模型)。循环神经网络是处理此类任务的经典架构之一。
  • 生成模型:目标是学习训练数据的分布,以便从中采样生成新的、相似的数据样本。生成对抗网络是著名的生成模型之一。

训练神经网络:梯度下降与反向传播

几乎所有神经网络训练都涉及最小化一个损失函数,而通常没有解析解。因此,我们使用梯度下降

关键问题:如何高效计算损失函数 L 对海量网络参数 θ 的梯度 ∇L

答案是反向传播算法,它本质上是链式法则在计算图上的高效应用。

  1. 前向传播:计算网络输出,并保存所有中间层的激活值。
  2. 反向传播:从输出层开始,逆向计算损失对每一层参数的梯度。利用链式法则,这些梯度可以表示为已知梯度与局部雅可比矩阵的乘积。

现代深度学习框架(如PyTorch、TensorFlow)的核心——自动微分——正是实现了反向传播算法。我们只需定义网络的前向计算过程,框架会自动计算梯度,从而让我们能够轻松地使用梯度下降来优化网络。


总结

本节课我们一起学习了深度学习的基础知识。

  • 我们建立了核心概念:神经网络是拟合数据的灵活函数
  • 我们介绍了多层感知机的基本数学形式及其生物灵感来源。
  • 我们探讨了神经网络的通用近似定理,这是其强大能力的理论基石。
  • 我们了解了为图像数据设计的卷积神经网络及其优势(局部连接、参数共享、层次化特征学习)。
  • 我们概述了深度学习解决的几类主要任务:监督学习(回归、分类)、无监督学习(特征学习、自回归、生成模型)。
  • 最后,我们学习了训练神经网络的核心方法:梯度下降反向传播

理解这些基础概念,是后续探索更复杂架构(如下一讲将涉及的大型语言模型)及其在科学中应用的基石。

003:深度学习导论(第二部分)

在本节课中,我们将继续深入学习神经网络。我们将探讨训练深度神经网络时遇到的困难,特别是过拟合与欠拟合问题,并学习如何通过正则化来缓解这些问题。我们还将深入研究优化算法,了解它们如何影响网络性能。最后,我们将以ChatGPT为例,了解其背后的神经网络架构和训练原理。

回顾与引言

上一节我们介绍了神经网络的基本概念,核心思想是:尽管神经网络可以极其复杂,但可以简单地将其视为用数据拟合函数。这是一种思考训练神经网络的实用方式。

具体来说,我们有一个输入向量 X,将其通过一个依赖于参数 θ 的神经网络函数,得到一个输出向量 Y。我们通过将网络输出与大量训练样本进行匹配来训练它。这个神经网络函数取决于你选择的网络架构,显然,根据架构的不同,这个函数可以非常复杂。

例如,对于一个多层感知机,其函数相对简单:输入向量乘以权重矩阵,加上偏置向量,通过某个激活函数,并根据MLP的层数重复此过程。

另一个重要概念是通用近似定理。这是神经网络如此强大并被应用于众多任务的原因:只要有足够的参数,它们可以近似任意函数。这使得它们能够完成令人印象深刻的任务,例如对图像进行分类。

我们还讨论了深度学习的任务类型,包括监督学习(如回归、分类)、无监督学习(如特征学习)、生成建模(如图像生成)和自回归(如预测未来值)。但重要的是要记住,在所有情况下,我们都是在用某个损失函数训练网络来拟合数据,只是我们组织和标注数据的方式因任务而异。

此外,我们详细介绍了如何训练神经网络。通常,我们定义一个损失函数来匹配网络输出与训练数据。回归任务中一个非常典型的损失函数是最小二乘误差。99%的情况下,我们使用梯度下降来训练网络,即计算损失函数的梯度,然后沿梯度方向更新权重。我们进一步讨论了如何通过链式法则计算这些梯度。在实践中,我们使用PyTorch或TensorFlow等框架时,自动微分会处理这些计算,而反向传播算法是计算这些梯度的有效算法。我们将在本系列讲座的后半部分讨论可微物理时,更深入地探讨自动微分。

在本节课结束时,我将尝试向您解释ChatGPT在较低层次上是如何工作的。听完这节课,您应该能轻松理解这一点。

过拟合与欠拟合

到目前为止,我们一直在讨论如何训练神经网络,但接下来要讨论的是如何测试其性能,这是一个非常重要的区别。

当我们训练一个神经网络时,我们有一个损失函数,用于将网络输出与一些训练数据点进行匹配。例如,在回归任务中,我们试图基于这些蓝色的训练数据点来训练网络,以拟合这个多项式曲线。

从概率的角度看,我们的训练点是从某个联合分布 P(x, y) 中采样得到的。我们采样了n个值来创建训练数据。

但是,一旦我们训练好网络并想测试其性能时,我们通常不会使用相同的数据集。我们真正应该做的是使用一个测试数据集来验证网络的性能。这与训练不同,我们使用网络未训练过的、新的、未见过的样本来测试网络。因此,我们创建一个测试数据集,这些样本通常来自相同的底层分布。

我们使用某个损失函数(可能是相同的,如最小二乘,也可以是其他指标,如L1损失)来测试它。我们也可以使用不同的指标来评估训练误差。

当你观察训练误差和测试误差之间的差异时,会发生一些非常有趣的事情,这取决于你在此数据上训练的网络类型。

这里展示了我在这些训练数据上训练的三种不同的神经网络。

  • 左侧是一个只有一层且零隐藏单元的模型(即线性模型)。你可以看到模型用一条直线拟合曲线,显然不是一个好模型,准确度不高。训练损失和测试损失都很高。
  • 中间是一个有两层、16个隐藏单元的模型。它似乎拟合得很好,估计了数据的均值。训练误差和测试误差相似。
  • 右侧是一个更大的网络。训练误差和测试误差开始发散。当你观察网络学习的函数时,可以看到它是一个频率更高的函数,非常精确地拟合了训练数据,但对测试数据的拟合效果不佳。

我们说右侧的函数过拟合了我们的训练数据,因此在训练误差和测试误差之间存在差距。从传统观点来看,我们会说这是一个过参数化的模型,参数太多,过于灵活,可以非常紧密地拟合训练数据,从而降低了测试性能。

我们可以更详细地思考网络产生的误差。考虑我们用于训练网络的损失函数,我们使用最小二乘误差,并有一个包含n个端点的训练数据集。

更一般地说,我们使用经验损失来训练神经网络,可以更一般地写为对所有训练样本的损失函数求和。这里的损失函数不一定是最小二乘损失,可以是任何指标。我们的训练数据点是从我们试图建模的联合分布中采样的。

然而,这并非我们真正想要最小化的实际损失函数。一个更好的损失函数是期望损失。它不是在一个有限数量的训练点上评估损失指标,而是希望在整个联合概率分布上对所有可能的(x, y)对进行积分。如果我们这样做,模型就不会过拟合,因为它对测试数据的匹配程度将与对训练数据的匹配程度一样好,因为在积分中我们采样了每一个可能的数据点。

但这在实践中是不可能的。为什么?主要原因是大多数时候,我们只能访问该分布的有限样本。我们甚至无法采样该分布,更不用说计算它了。例如,对于自然图像,我们并没有世界上所有可能的自然图像,我们只有一个有限的集合。

这导致了所谓的估计误差。这是在使用经验损失训练神经网络(仅拟合分布中的有限样本)与能够最小化期望损失的理想神经网络之间的差异。

还有另一个误差来源,称为近似误差。即使你用所有可能的训练点最小化了期望损失,你可能仍然找不到最小化该指标的真正函数。因为神经网络的表达能力可能不足以匹配那个函数。如果这是一个非常复杂的函数,而神经网络只建模了多项式空间,那么你将找不到这个期望损失的真正最小值。

因此,我们需要考虑这两个主要的误差来源,它们会导致欠拟合和过拟合。

一个很好的思考方式是将神经网络训练放置在一个函数空间中。这是一个所有可能函数的空间的图示表示。我们可以在这个空间中定位不同的函数。例如,星号代表我们试图建模的真实函数,它可能位于某个流形上。我在这里画的蓝色边界是神经网络可以表示的可能函数的空间。近似误差表明,网络永远无法建模该区域之外的函数。近似误差是真实函数与神经网络所在边界点之间的差异。但近似误差只是其一,估计误差源于我们不是最小化期望损失,并且我们使用的训练数据的有限性带来了误差。

我们可以用这个函数空间来绘制我训练的这三个不同模型,以帮助你理解。

  • 对于线性模型,其可能空间在函数空间中是一个很小的区域,并且该区域远离真实函数,因此在这种情况下误差会很高。
  • 对于过拟合的情况,我们有一个过参数化的模型,可以建模多种类型的函数,因此它可能包含了真实函数,但使用有限训练数据最小化经验损失的网络可能离得很远。
  • 理想的模型是这样一个模型:我们恰好限制了函数空间,使其包含了我们想要建模的函数,但又不会太大以至于容易过拟合或最小值离得太远。

希望你现在理解了导致过拟合和欠拟合的误差来源。接下来,我将尝试从更概率的角度解释这一点,并分解这个期望损失,向你展示过拟合和欠拟合是如何从这种分解中产生的。

首先,我定义这个函数 h(x; D),其中D是我们的训练数据。这就是训练后的神经网络,它是一个依赖于x和训练数据D的函数。我们可以认为,我只是用D替换了θ,因为θ依赖于D。

我们现在想要理解的是期望损失,即损失指标的期望值,不仅是对所有可能的输入和输出,也是对所有可能的数据集。即,对所有可能用于训练网络的数据集,其平均期望损失是多少?

为了进一步分析,我们必须做一些假设。我们假设使用的指标是最小二乘损失。然后,你可以证明(我不会在本幻灯片中推导,可以查看下面的链接),我们可以将这个项分解为三个独立的项,我们称之为偏差方差不可约噪声。我将更详细地解释这三个术语。

  • 方差:这是特定训练数据集训练的网络的输出与平均模型 之间差异的期望值。 是所有可能训练数据集上神经网络输出的期望值。你可以将其视为平均模型。方差本质上说明了我的网络输出对训练数据的敏感程度。
  • 偏差:这是对所有可能网络输入的平均模型 与平均观测值 之间差异的期望值。 是给定输入x时y的条件均值。这本质上是对随机变量y本身的最佳可能预测器(在使用最小二乘损失的情况下)。
  • 不可约噪声:这是真实随机变量值与其均值之间的差异,我们无法克服这一点。

我们真正想做的是使这个对所有训练数据集平均的期望损失尽可能接近零。然而,我们通常发现,在评估特定神经网络和特定任务时,通常存在一种偏差-方差权衡。这是从统计角度说过拟合和欠拟合之间存在权衡。

我们发现,偏差和方差依赖于模型复杂度(即我们用于训练网络的参数数量)。如果我们有非常少的参数(例如线性模型),我们通常发现方差很低(模型输出不太依赖于训练数据),但偏差很高(平均模型误差很高,不能很好地拟合数据)。随着模型复杂度的增加,我们得到这种权衡:方差开始增加(对训练数据变得非常敏感),而偏差开始下降(我们的平均模型能很好地拟合数据)。我们的目标是尝试找到中间的某个最佳点,在那里我们有较低的偏差和可接受的方差,这基本上对应于良好的测试性能和训练性能。

回到那三个模型:

  • 左侧的模型具有较高的偏差和较低的方差。
  • 右侧的模型具有较低的偏差和较高的方差。
  • 中间的模型在偏差-方差权衡中处于最佳点。

以一种非严格但实用的方式思考,你可以将训练损失视为偏差,将测试损失与训练损失之间的差异视为方差。

希望你现在理解了什么是过拟合和欠拟合,以及它们是如何发生的及其背后的误差来源。

缓解过拟合与欠拟合:正则化

现在我将用本节课剩余的大部分时间讨论如何缓解过拟合和欠拟合,以及不同的方法。

基本上,如果你处于高偏差(欠拟合)或高方差(过拟合)状态,有一些通用的策略。

  • 如果欠拟合:提高测试损失和训练损失的最快方法是增加模型复杂度,即为网络添加更多参数,使其能够建模更复杂的非线性函数。从函数空间的角度思考,这就像向外扩展函数空间。或者,你可以选择新的架构设计,尝试将该函数空间转移到更接近你试图建模的真实函数的位置。
  • 如果过拟合:减少过拟合的一种方法是增加你拥有的训练数据量,这有效地减少了网络输出对训练数据的依赖性。或者,你可以进行某种正则化,这就是我接下来几张幻灯片要讨论的内容。

让我解释一下什么是正则化。我们将考虑这样一种情况:我们有一个非常灵活且倾向于过拟合数据的神经网络架构。当我们认识到深度神经网络过拟合时,我们不是改变网络的表达能力(即函数空间的大小),而是尝试在正则化中偏好函数空间的某些区域而不是其他区域。

因此,正则化是说:我希望网络收敛到一个接近真实函数的函数,我们必须以某种方式引导网络更接近真实函数。你可以将正则化视为一种软约束,而不是改变空间边界的硬约束,它只是改变我们偏好收敛到空间中的哪些部分。

正则化的定义是:限制可能函数的空间(改变函数空间也可以被认为是正则化),或者偏好函数空间的某些区域,或者从概率意义上讲,它是在我们训练网络之前,对我们的神经网络或学习算法施加先验,以偏好某些解决方案。

有很多方法可以正则化神经网络。以下是一些方法:

  • 硬约束版本:我们通过降低模型复杂度或改变神经网络架构来改变函数空间的边界。
  • 增加训练数据量:减少网络对训练数据的依赖性。
  • 权重正则化:在损失函数中添加项。
  • Dropout:随机丢弃一些激活。
  • 早停:在训练过程中提前停止。
  • 添加额外的损失项:使用更复杂的损失函数。

我将逐一详细介绍这些方法。

权重正则化

这是一个非常简单的想法。我们知道过参数化的网络倾向于过拟合数据。因此,我们在损失函数中添加一个软项,试图最小化权重的L2范数。这表示我偏好接近零的权重,而不是大值。你可以将其视为施加一个先验,让网络学习修剪不必要的连接,使其在训练过程中变成一个更精简的模型,这有助于防止过拟合。这也被称为岭回归。我们也可以使用其他范数,如L1范数。

从概率角度解释也很有趣。在进行回归时,我们真正试图做的是估计这个条件分布 P(y|x)。我们假设它是一个正态分布。在上节课中我展示了,如果我们对这个分布使用最大似然估计,我们可以推导出最小二乘误差损失函数。实际上,如果我们改变推导中的假设,我们也可以推导出这个损失函数。

我们假设数据似然是所有数据点的概率。与之前不同的是,我们现在假设网络参数有一个先验分布,例如正态分布。然后,利用贝叶斯规则,参数给定数据集的后验概率依赖于这个先验和给定参数的数据似然。我们不是最大化数据概率(最大似然估计),而是最大化后验概率(最大后验估计)。这允许我们将先验纳入估计。可以证明,最大化后验等价于最小化我们开始时提到的损失函数(带有权重正则化项)。因此,这为权重正则化提供了一个很好的概率解释。

额外的损失项

我们不一定只使用损失函数中这个特定的附加项,我们可以自由选择任何我们想要的附加项。通常,损失函数可以有一个正则化器,试图将网络的解推向某个偏好的解。有很多例子,它们取决于你想要训练网络完成的任务。

例如:

  • 图像生成:一个可能的正则项是结构相似性指数,这是一种启发式的感知图像质量度量,试图对看起来自然的图像赋予高权重。
  • 建模特定频带:如果我们想用神经网络建模数据的某个特定频带(例如在科学研究中),这个额外的损失项可以对网络的输出进行傅里叶变换以获得其频率分量,然后对较高频率分量施加损失。
  • 特征空间损失:我们不一定必须在网络输出的向量空间中有损失,我们可以通过非线性变换将该输出转换到其他向量空间,并在该空间中进行欧几里得距离计算。例如,如果我们有两个图像,并且希望它们在图像的显著表示上匹配,而不是在图像的像素空间上匹配,我们可以使用CNN等特征模型,将网络输出通过该特征模型以获得潜在表示,然后在潜在表示中将训练数据点与模型输出进行匹配。这是一个可以改善性能的好技巧。

总之,我们可以使用许多不同的损失项。

Dropout

这是另一种非常流行的正则化神经网络的技术。这里我们不改变损失函数,而是在训练网络的每个训练步骤中改变神经网络。

在训练过程中,我们随机将网络的一些激活设置为零。例如,在第一个训练步骤中,我们可能丢弃这个神经元、这个神经元和这个神经元的激活,将其关闭。然后我们通过网络传播并仅基于高亮显示的连接进行更新。然后,在下一个训练步骤中,我们将随机丢弃其他激活。

为什么这能正则化网络?以一种宽松的方式来说,它是在说:网络的输出不应该过于依赖于任何特定神经元的输出,或者等效地,单个神经元不应该过于依赖于它所连接的单个前一个神经元。这可以帮助网络学习一个不依赖于特定输入的泛化表示。

实际上,我们是在有效地训练一个模型集合,其中每个模型在网络中都有随机的连接集。你可以更深入地数学解释dropout,并证明这实际上是在估计网络输出的不确定性。在训练网络后,如果你从这个集合的许多不同成员中采样,你可以得到不确定性估计,即网络预测之间的方差。

早停

这里展示的是一个过参数化网络最终过拟合数据并导致泛化能力差的情况。我展示了网络预测如何随着训练步骤演变。绘制训练误差和测试误差随训练步骤的变化非常有趣。你会看到它们开始时非常相似,因为网络初始预测非常平滑,几乎是一个线性函数。然后,在训练过程中,存在某个点它们开始强烈发散,但在中间的某个地方,我们实际上处于一个测试误差低、训练误差低的区域,有一个性能良好的模型。

这被称为早停。也就是说,如果我们在这里停止训练算法,而不是继续训练更多步,我们将得到这个拟合数据良好的平滑模型。

研究为什么会这样真的很有趣。为什么网络在训练中途会有一个很好的平滑近似?至少对于全连接网络,存在一种称为谱偏差的特性,这正是它们倾向于更快学习数据中的低频分量而不是高频分量的属性。这可能是网络内置的一个很好的正则化器,也是为什么过参数化的深度神经网络仍然能很好地泛化并在训练数据点之间进行插值的原因,因为它们倾向于从拟合一个良好的低频近似开始。我们将在讨论物理信息神经网络时谈到谱偏差,实际上这会降低物理信息神经网络的性能,因此在那个讲座中将是一个有趣的讨论。

增加训练数据

正则化深度神经网络的最终方法,如果可能的话,通常是最好的方法,就是增加训练数据的数量。通过拥有尽可能多的我们试图建模的分布的样本,使网络难以过拟合数据。

问题在于,如果我们只能访问该联合分布的少量样本,我们如何做到这一点?我们没有数据来改进。因此,有很多技巧可以增强或改变我们的训练数据来尝试解决这个问题。

想象这样一种情况:我们想训练一个神经网络来进行数字分类。我们有一个数字图像,并希望产生一个分类(是什么数字)。但假设我们只有九张图像。这是一个非常危险的情况。如果我在此数据集上训练一个CNN,我保证它会很快过拟合,并且如果给它一个以前未见过的数字,它的表现不会好。

我们可以采取几种策略来尝试提高性能:

  1. 增强训练数据集:通过某种变换改变输入,但保持相同的标签,并训练网络学习这些变换。例如,我们可能进行一些随机旋转,向图像添加噪声,以任何方式改变输入图像,使网络在更广泛的输入范围内学习。这样做的一个好处是,网络可以对真实世界数据中的噪声和其他扰动更具弹性,这非常有用。
  2. 预训练:这也非常流行,我们有时称之为自监督学习。这意味着在训练网络执行分类任务之前,我们先预训练它执行其他任务,希望这能训练网络学习一些对我们要解决的主要任务有用的特征表示。例如,我们可能给这个分类网络(编码器)附加一个解码器,然后使用一个无监督损失函数(如重建损失)来尝试重建输入图像。这样做,这个网络将学习一个潜在表示或显著表示,然后在后续训练分类任务时会有用。也可以是其他类型的损失函数,例如随机屏蔽输入中的部分数据,并尝试让网络预测答案。所有这些方法都是自监督方法,用于预训练网络,帮助其在仅有的几张图像上泛化。这被称为少样本学习

优化深度神经网络

我们讨论了过拟合和欠拟合,然后尝试讨论通过使用正则化来缓解这两者的方法。我谈到了许多不同的正则化技术。

现在我将讨论本讲座的最后一部分:优化深度神经网络,以及我们选择的优化器对网络性能的巨大影响。我们应该有时间在最后讨论ChatGPT。

我们讨论了这两个误差来源:近似误差(神经网络是否足够表达以建模真实函数)和估计误差(训练网络对训练数据的敏感性,以及我们没有最小化真实期望损失的事实)。但是,还有一个不容忽视的误差来源,即优化误差

到目前为止,我一直假设当我们训练神经网络时,我们最终得到的参数确实最小化了这个经验损失,即这个损失函数的真正最小值。但在实践中,找到这个函数的全局最小值非常困难,我认为对于我们训练的几乎所有神经网络,我们都没有做到。因此,当我们讨论误差时,网络建模的函数的误差,我们还必须考虑优化误差的影响,这是这些误差来源的重要组成部分。

从某种意义上说,我在上节课开始时通过说神经网络具有通用近似定理来激发兴趣,理论上它们可以近似任何函数。但这个定理并没有说明找到那个函数有多容易,我们是否真的可以优化这个损失函数来得到那个函数。

让我们回到函数空间,现在我绘制了所有三个误差来源。这些是训练神经网络时必须考虑的三个误差来源。同样,我们有这里的真实函数,以及网络可以表示的可能函数空间。近似误差是该空间中最接近真实函数的网络函数。估计误差来自训练数据。而这里的优化误差是我们没有最小化经验损失,或者没有找到经验损失的全局最小值,而是找到了损失函数中的其他位置,因此我们有一个额外的误差。

如何缓解这三个误差?

  • 近似误差:增加蓝色区域的大小,增加假设空间。
  • 估计误差:使用正则化,或者如果有训练数据,增加训练数据。
  • 优化误差:改进优化器,使优化器更能找到损失函数的全局最小值。

因此,当你训练神经网络并且发现其测试性能不佳时,我的建议是逐一思考这些问题:我是否有足够灵活的函数?我是否有足够的训练数据?我是否过拟合?我能改进优化过程吗?这些是你应该问自己的三大问题。

损失函数景观

让我们看看损失景观。这是一篇非常有趣的论文,他们试图可视化损失景观。这实际上相当困难,因为这里的损失函数是θ的函数,而θ通常是数百万个值(如果我们训练任何深度神经网络)。因此,在这个非常高维的空间中可视化损失函数实际上非常困难。

他们所做的是一个技巧,以便能够在2D中看到它。为了创建这个图,他们在网络的权重空间(这个高维参数空间)中随机采样了两个向量。然后,你不是绘制整个损失景观,而是只绘制沿这两个向量变化的损失值。因此,你显然没有在这里可视化整个损失景观,但我们可以看到它在一个平面上。这是一个在ImageNet上训练的真实ResNet的损失表面(我认为是分类任务)。你可以看到这个损失景观非常复杂。我们有一个全局最小值(顺便说一下,这是围绕优化器训练后着陆的位置)。实际上,它可能不是全局最小值,可能只是一个局部最小值。它被这些山谷和沟壑包围,你可以看到,如果你身处其中一个山谷,试图找到一个更好的最小值会非常困难。

因此,问题是损失函数非常高维,并且在实践中包含许多局部最小值。

优化挑战

我将讨论优化神经网络的困难或挑战,实际上有很多原因导致损失函数可能非常难以优化。

第一个原因有点违反直觉:实际上很多时候损失函数是完全平坦的。损失函数不是像这样,而是到处都平坦,当我们训练神经网络时,这是一个真正的大问题,因为我们评估损失函数的梯度来更新权重,如果损失函数是平坦的,那么我们将不会移动到任何地方,算法将无法优化网络。

为什么会这样?为什么在训练神经网络时会出现所谓的梯度消失(梯度处处为零)?这里有一个线索:我们使用一个MLP(全连接网络),并且我们在这里使用tanh激活函数。谁能想到为什么如果我们使用tanh激活函数,损失函数的梯度可能会变为零?

当x的幅度非常大(非常负或非常正)时,tanh具有我们称之为饱和的特性,基本上激活会饱和,无论x的值是多少,它都只给出一个值(+1或-1)。所以,如果我们给它一个不大约在-1到1范围内的输入,那么激活的输出将不再依赖于输入。如果你看一下函数,你可以看到这里的梯度是零。当我们评估损失函数相对于参数的梯度时,我们应用链式法则。在那个链的某个点,我们需要评估损失函数的导数,这是网络的一个中间输出。它将是零,因此它将使整个损失函数的梯度归零。

这是一个非常重要的点,经常被忽视。训练神经网络时经常出现的一个错误是我们忘记规范化我们的输入和输出。我们希望确保网络看到的输入大约在-1和1之间,输出也在-1和1之间。这只是一个非常好的实践,即使你不使用tanh激活函数,也绝对推荐这样做。

现在,假设我们已经正确规范化了输入和输出,这样就不会使激活函数饱和,我们仍然可能遇到梯度消失的问题。我们需要思考的是,当我们通过网络越来越深时,每一层的输出值如何变化。

让我们考虑单个神经元的输出,为了简单起见,我们不考虑激活函数,它只是一个MLP。那么单个神经元只是将其输入向量乘以其权重,基本上就是一个线性模型。然后我们做几个更多的假设,我们说神经元的这些输入只是随机变量。假设权重值本身也是随机变量,因此y也是一个计算的随机变量。那么y的方差就是这个对象的方差。如果你再做几个假设,例如每个输入元素是独立同分布的,权重也是如此,你可以证明,y的方差是x的方差乘以权重的方差,再乘以输入的数量(即我们求和的X元素的数量)。

这里展示的是权重的方差选择(即如何初始化权重)如何影响Y的方差在网络中的演变(即输出值如何变化)。这里绘制的是只是一个全连接网络每一层的输出。这个分布只是向你展示每一层输出值的范围。我们假设网络的输入以大约在-1和1之间的值范围开始。然后,当我们通过网络传递向量时,这些值的范围会减小或增加。

这里应用了三个不同的网络:

  • 第一个网络的权重值从均值为0、标准差为0.05的正态分布中抽取。
  • 第二个网络的权重从标准差较大的分布中抽取。
  • 第三个从标准差更大的分布中抽取。

重要的是,这个MLP每一层有100个隐藏单元,所以我们假设输入也是100个值,产生一个有100个值的输出。从这个表达式我们知道,y的方差等于输入数量(这里是100)乘以权重的方差再乘以x的方差。因此,选择权重的方差非常重要,以便我们大致保持这些值在-1和1之间。从这个数学方程中,我们可以看到,如果我们的权重初始化的方差小于1除以输入数量,我们开始得到网络输出的指数级下降。因此,无论输入是什么,最终如果我们有足够的层,网络的输出将总是趋向于零,这是一个非常糟糕的情况。相反,如果我们选择权重的方差大于1除以n,那么我们看到相反的效果,输出呈指数级增长并爆炸。这被称为梯度消失梯度爆炸

最佳点是选择初始化权重,使其方差大约是1除以神经元输入数量的倒数。你可以看到底部情况和顶部情况将导致损失函数为零或损失函数的梯度为零。因为如果所有输出值都为零,那么损失函数可能为零。如果所有输出值趋向于无穷大,那么如果你使用tanh激活函数,你将开始使tanh饱和,并得到我之前谈到的梯度消失。

这种初始化网络的方式被称为LeCun初始化,我认为这是PyTorch中使用线性层时的默认设置。

你可以做同样的事情:我讨论了思考网络输出如何随网络每一层演变,你也可以考虑反向传播时,当我们通过反向传播在网络中反向传播梯度。我们可以进行相同类型的分析。记住我们使用了链式法则,所以 ∂L/∂x = ∂L/∂y * ∂y/∂x,其中这是中间层,层函数是... 你可以做同样的事情,假设这些梯度是随机变量,并对梯度相对于输入的期望与梯度相对于层输出的期望进行相同的方差分析(在梯度下降算法的一步之后)。这实际上给出了相反的结果:权重的方差应该是1除以神经元输出数量的倒数,而不是1除以输入数量的倒数。有趣的是,稳定性取决于我们是向前通过网络还是向后通过网络。因此,我们必须选择某种折衷方案,一个常见的良好折衷方案是在初始化权重时使用这两个初始化策略的调和平均值。这被称为Xavier初始化

批归一化

继续这个趋势,我们真正想确保的是,正如我之前所说,每一层的输出倾向于保持在-1到1的范围内,确保损失函数行为良好非常重要。除了选择权重来确保这一点之外,另一种方法是动态确保每个网络的输出在-1到1的范围内。这就是批归一化

通常,当我们评估神经网络时,我们不只是给它一个输入,而是给它一批输入,特别是当我们做随机梯度下降时(我稍后会谈到)。在批归一化层中,我们只是获取该批次的统计信息,然后根据这些统计信息对层的输出进行归一化。我们取批次中输出值的均值和标准差,然后根据该均值和标准差对层的输出进行归一化。你可以看到,这里的这个对象将大约归一化在-1和1之间。

当我们进行批归一化时,我们还引入了一些可学习的参数,即这里的 γβ。它们是可学习的参数,再次初始化为大约在-1和1之间。但它们可以变化,这给了该层机会,如果学习算法认为这是一个好主意,它可以撤销归一化。

这实际上改变了网络本身的架构,它不仅仅是一个初始化策略。因此,批归一化也经常被认为是一种正则化策略,更详细地理解这一点真的很有趣。另一件事是,一旦我们训练了网络并开始测试,最佳实践是固定这些值,我们不希望根据我们给网络的输入不断改变它们。因此,我们通常为网络的测试阶段保持这些均值和标准差的运行估计。

这里的 ε 只是为了确保数值稳定性,它是一个很小的数,比如10^-12。

残差连接

另一种确保梯度稳定性的方法,特别是当我们讨论梯度稳定性以及梯度在通过网络反向传播时不会消失,是在网络中使用残差连接。这是ResNet的思想。

什么是残差连接或残差连接?它也被称为跳跃连接,是一个非常简单的想法。我们这里有一些层的输入 x。我们不说层的输出只是这个层函数的输出(无论它是什么,带有网络的某些参数),而是说层的输出是这个层函数的值加上原始的 x 值。因此,这里的完整层函数是原始输入 x 加上我们正在学习的灵活函数。

这样,你可以看到该层正在学习对 x 的修正,而不是学习向量的完全改变,它学习向该输入向量添加一些修正项。现在,如果你这样做并思考通过这个函数的传播,例如,∂L/∂x 是什么?再次使用链式法则,我们可以证明它是 ∂L/∂y 乘以这个对象。如果层函数为零(即网络没有学到任何东西),这一项为零,我们最终仍然得到应用函数之前的梯度,因此即使该函数的输出为零,反向传播仍然会有梯度流过该层。

这是一个非常巧妙的想法,在实践中非常有效。ResNet的一个很酷的特性是,你可以训练一个有数百层的ResNet,梯度会很好地流过它,在某个时候,ResNet会学习到它有足够的层,并将后面的层设置为零(至少理论上是这样,我不知道在实践中是否真的这样工作)。你可以将其视为学习通过网络的最佳路径。

在实践中,ResNet对于输入与网络试图学习的输出相似的任务也非常非常好。例如,如果我在做图像去噪,网络的输入是一个有噪声的图像,输出是无噪声图像。根据噪声的特性,它们可能看起来非常相似,因此带有残差连接的ResNet将只学习噪声分量。

ResNet与ODE求解器也有非常深刻的联系,这里的层函数开始看起来像是欧拉步中的单步。我将在本讲座课程的后半部分讨论混合工作流和常微分方程时更多地讨论这一点。

这是原始ResNet论文,他们能够训练非常非常深的模型,具有稳定的梯度流一直反向传播到输入。他们在论文中表明,如果我们在这里使用残差连接,我们可以开始提高深度神经网络的任务性能,而如果没有残差连接,深度神经网络的表现可能不那么好,这可能是因为在训练网络时,反向传播梯度并保持其稳定更加困难。

另一种我们经常使用的残差网络类型,特别是对于科学研究,称为U-Net,这是为医学成像提出的。它只是一个卷积网络,每个卷积层对图像进行下采样到某个非常低维的空间,然后再次上采样以给出最终图像。但在我们计算的每个尺度或中间尺度,我们在U-Net中添加了一个跳跃连接,所以我们有这种U形。这个网络非常有趣,它跨不同尺度学习,并学习输入之间的残差差异,事实证明这对于许多不同类型图像的分割非常有效。

优化器

我讨论了很多关于梯度消失以及确保损失函数是适当的可优化损失函数,以及使用批归一化、ResNet来确保这一点。现在我将讨论我们用于训练神经网络的实际优化器,即用于更新权重的算法。我说过,99%的时间,我们使用梯度下降来训练神经网络。

让我们回顾一下梯度下降是什么。我们有损失函数。我们随机初始化权重,但要确保其方差适合层的大小。我们计算损失函数的梯度,然后通过在该梯度方向采取一小步来更新权重,这里的 γ 是我们的学习率,通常我们将其设置为一个小数,以便在该方向采取一小步。

你可以可视化一下,假设我们在这里学习两个或三个参数,我们实际上可以绘制损失景观。我们可能从这里开始,然后沿着梯度下降方向前进。你可以立即看到,一个标准的开箱即用的梯度下降总是会陷入它找到的任何局部最小值。一旦它到达这个局部最小值,它将无法向上移动,因为它总是沿着梯度向下。

在实践中,有很多技巧或改进标准梯度下降算法的方法,以便能够发现损失函数中更好的最小值。

一种方法是使用更大的学习率。即使我们沿着梯度方向前进,如果我们到达这里,梯度将指向这个局部最小值,但那个局部最小值可能非常小和狭窄。如果我们采取更大的步长,我们可能直接跳过那个局部最小值,落到损失函数的不同区域,然后最终可能将我们带向损失函数更好的最小值。这在某种程度上是有效的,我们可以逃离局部最小值。但问题是,我们也可能逃离其他全局最小值或损失函数中性能更好的部分。因此,如果学习率足够大,它可能非常不稳定。因此,一种抵消这种情况的技巧是使用指数衰减或缓慢减少的学习率,这样它有一个探索阶段,在损失函数中四处碰撞,探索整个空间,然后慢慢缩小并收敛到解。

还有其他关于步长大小的技巧,例如所谓的自适应学习率或智能学习率。我们在这里做的是根据优化器的状态或优化器对其周围损失景观的背景信息来调整我们所采取的步长。例如,你可以根据梯度的大小、局部曲率、学习发生的速度(例如损失函数下降的速度)、权重的值等来调整学习率,有很多不同的方法。

另一种非常非常流行的方法,在训练神经网络的大多数情况下使用,是使用随机梯度下降,也称为小批量梯度下降。我们在这里使用相同的损失函数,但不是评估整个训练数据集上的损失函数(所有训练样本),我们只使用一个随机批次的训练样本来评估损失函数,即数量少得多的样本。根据我们之前关于使训练数据集更小的讨论,你可能会认为我们会真的过拟合,但事实并非如此,它实际上通过使真实损失函数的梯度估计变得嘈杂来帮助优化器。因为我们没有获得所有训练样本的真实梯度值,我们不一定在真实梯度方向上采取一步,我们可能只是采取一些随机偏离。因此,这种嘈杂的梯度估计帮助我们再次在损失函数中碰撞并逃离局部最小值。在实践中,它实际上非常善于将我们引向更好的解。

我强烈推荐这作为你训练深度神经网络时的默认选择。它产生嘈杂的梯度估计,使我们能够逃离局部最小值。另一个单独的原因是,这通常比使用全批量训练更高效。例如,如果我训练一个神经网络来分类图像,并且我有ImageNet,我不想评估相对于我所有训练数据的梯度,那可能是数百万个样本,计算成本太高。因此,我们可以使用数百而不是数百万的批量大小。是的,它在实践中被广泛使用。

Adam优化器

基本上,我会说如今大多数人训练深度神经网络的默认选择是Adam优化器。Adam只是梯度下降的一个变体,它也可以使用小批量进行随机梯度下降。

Adam与标准梯度下降有何不同?算法非常简单。同样,你循环,估计梯度并循环。但为了估计你前进的方向,你首先计算损失函数的梯度。然后,你估计这些称为的量。这两个量本质上是保持梯度随训练步骤的运行平均值,以及梯度平方的运行平均值(对于每个参数)。这里的 β 被称为遗忘因子,表示这个运行平均值应该依赖于先前值与当前梯度值的程度,这是一种平滑平均。然后我们应用一个偏差校正(我稍后会解释这是什么意思),然后我们通过在这个平均方向(或运行平均方向)上采取一步来更新权重,但该步长也由梯度幅度的运行平均值归一化。

为什么这有用?我们为什么使用它?基本上有两个想法使其不同于梯度下降:

  1. 当我们在参数空间中移动时,我们保持一些动量,因为我们采取的梯度步骤依赖于梯度的先前值(因为我们取了这个运行平均值)。所以它给了我们一些动量,如果我们正在下坡,我们可能会保持那个方向的动量,并能够上坡一点以逃离局部最小值。
  2. 第二个想法是自适应步长。这是一个基于梯度幅度的自适应算法。本质上,它做的是归一化梯度,它说这个步长方向在参数值方面大致平均为1。因此,这里的学习率更直观,因为它基本上告诉你平均每个训练步应用于参数的更新幅度。

我之前幻灯片中展示的偏差校正只是为了消除移动平均初始值的影响。

这是一张Adam与梯度下降的对比图。你也可以混合搭配,例如,你可以只使用带动量的梯度下降,或只使用自适应步长的梯度下降。这是标准梯度下降、带动量的梯度下降和Adam(即步长调整加动量项)的对比。你可以看到我们保持了一些动量,并且能够跳过这个凸起并落在函数的全局最小值中。

这绝对是我推荐的最佳起点,使用Adam。

高阶优化算法

我想讨论的最后一种优化算法类型是高阶优化算法。到目前为止我一直在谈论的优化器只使用函数的一阶导数(梯度),但使用损失函数的高阶导数来帮助你探索损失函数可能更强大。

我们知道,如果我们取这个损失函数(只是这个单一权重参数的标量函数),我们可以使用泰勒展开并在某点附近局部近似这个函数。通常我们做的是只估计梯度(这个近似中的一阶项),并使用梯度下降来采取一步。但我们可以做的是,通过使用损失函数的二阶导数,对这个函数进行二阶近似。现在,我们不是用直线拟合这个函数,而是开始用二次函数拟合它。然后当我们采取一步时,我们不只是沿着梯度方向走,而是直接走到那个二次函数的二阶近似的最小值。这就是牛顿法。现在这一步不仅依赖于梯度,还依赖于二阶导数(损失函数的曲率)。

在实践中,我们的神经网络有很多参数,所以输入是一个向量而不是标量。因此,对于多元函数,我们可以做同样的事情,但我们必须使用海森矩阵,采取这一步涉及求这个损失函数的海森矩阵的逆。问题在于海森矩阵本身是一个巨大的矩阵,它是P×P,其中P是参数的数量。所以如果我有一个有一百万个参数的神经网络,计算完整的海森矩阵将是一百万乘以一百万,这是一个巨大的数组,计算量很大。因此,这通常昂贵得令人望而却步,大多数使用高阶优化的现代方法都使用海森矩阵的某种近似,例如保持海森矩阵的运行估计。例如,LBFGS是一种非常常见的方法。事实证明,当我们训练神经网络时,例如物理信息神经网络,高阶优化器可以在这些网络中有所帮助。

ChatGPT的工作原理

我们还有五分钟,我将讨论ChatGPT。我向你保证,在本节课

004:偏微分方程在科学中的重要性 🧮

在本节课中,我们将要学习偏微分方程在科学中的核心地位,理解传统数值方法面临的挑战,并探讨机器学习如何为解决这些问题提供新的思路。

概述:科学研究的范式

上一节我们介绍了深度学习的基础。本节中,我们来看看如何将机器学习应用于科学领域,特别是物理学领域。科学研究的一个核心范式是:对于任何自然现象,我们都可以找到描述其过程的微分方程。正如诺贝尔奖得主赫伯特·西蒙所言:“给定对某种自然现象的描述,找到能产生该现象的过程的微分方程。”换句话说,科学问题的数学建模通常归结为寻找并求解一个偏微分方程。

什么是偏微分方程?

偏微分方程是描述物理量在空间和时间上变化的数学工具。它建立了我们感兴趣的物理量与其导数之间的复杂非线性关系。

公式F(u, ∇u, u_t, ∇²u, ...) = 0

其中:

  • u 是感兴趣的物理量(如温度、速度)。
  • ∇uu 的空间梯度。
  • u_tu 的时间导数。
  • ∇²uu 的拉普拉斯算子(二阶空间导数)。

这个方程将物理定律(如傅里叶热传导定律、牛顿引力定律)编码为数学形式。

无处不在的偏微分方程 🌌

偏微分方程是描述从微观到宏观各种尺度物理现象的通用语言。以下是不同领域的例子:

  • 量子尺度:薛定谔方程是化学和原子物理的基础方程,描述了电子等粒子的波函数行为。
    公式iħ ∂ψ/∂t = - (ħ²/2m) ∇²ψ + Vψ
  • 宇宙尺度:爱因斯坦场方程描述了引力以及黑洞碰撞等天体现象。
  • 全球气候:气候系统由耦合的偏微分方程组描述,包括流体运动的纳维-斯托克斯方程和辐射传输方程。
  • 生物尺度:反应-扩散方程可以描述果蝇翅膀等生物结构的图案形成。

所有这些截然不同的现象,都通过偏微分方程这一共同的数学语言来表达。

传统数值方法:近似求解

由于绝大多数偏微分方程无法用纸笔求得精确解(解析解),我们必须依赖近似方法。这就是传统数值方法的作用,其核心思想是“离散化”。

以最简单的一维热方程为例:
公式u_t = α u_xx, 其中 0 < x < 1, 0 < t < T

以下是数值求解的基本步骤:

  1. 离散化域:将连续的时空域用网格点代替。
    代码x_j = j * Δx, t_n = n * Δt
  2. 离散化解:在网格点上近似解 u(x_j, t_n) ≈ U_j^n
  3. 离散化导数:用有限差分近似导数。
    • 时间导数:u_t ≈ (U_j^{n+1} - U_j^n) / Δt
    • 空间二阶导数:u_xx ≈ (U_{j+1}^n - 2U_j^n + U_{j-1}^n) / (Δx)²
  4. 构建数值格式:将离散导数代入原方程,得到一个可以从已知时间步推进到下一时间步的迭代公式。
    公式U_j^{n+1} = U_j^n + λ (U_{j+1}^n - 2U_j^n + U_{j-1}^n), 其中 λ = α Δt / (Δx)²

这种方法(有限差分法)以及有限体积法、有限元法、谱方法等,构成了过去近百年科学计算的基础,并成功模拟了超新星爆发、云层动力学、海啸传播、飞机绕流等复杂现象。

传统方法的挑战与瓶颈 ⚠️

尽管传统数值方法非常成功,但它们也面临几个重大挑战:

1. 计算成本高昂

数值方法的计算复杂度随问题维度指数增长。对于高维问题(如多粒子薛定谔方程),计算变得不可行。
公式:计算成本 ∝ (1/误差)^(d/2),其中 d 是空间维度。

2. 多次查询问题

在许多实际应用中,需要成千上万次调用PDE求解器,导致总成本极高。

  • 工程设计(如飞机机翼优化):需要反复模拟流动以计算梯度,进行迭代优化。
  • 反问题(如地质勘探):需要迭代求解正问题以匹配观测数据,反推物理参数。

3. 不确定性量化

在湍流等系统中,需要计算统计量(均值、方差),这要求进行大量样本的模拟,成本巨大。例如,一次高分辨率流体的不确定性量化模拟可能需要数十万CPU小时,价值数十万瑞士法郎。

4. 物理知识缺失

对于许多复杂系统(如气候模型中的植被作用、城市交通流、生物体内的流体动力学),我们无法从第一性原理推导出完整的控制方程,存在“物理缺失”的情况。

新方向:融合物理与数据 🤖

上述挑战为我们指明了方向:我们需要发展能够降低可行问题的成本使不可行问题变得可行,并能够利用数据补充缺失物理的新方法。

这正是机器学习,特别是深度学习,可以发挥作用的领域。我们将探索如何将物理定律(以PDE形式)与数据结合起来,创建新的建模和求解范式。

在接下来的课程中,我们将学习:

  • 物理信息神经网络:用神经网络直接求解PDE,替代传统数值求解器。
  • 降阶建模:构建快速、低成本的代理模型,用于优化和不确定性量化。
  • 数据驱动的物理发现:从数据中学习缺失的物理项或本构关系。

总结

本节课中我们一起学习了:

  1. 偏微分方程是描述科学和工程中各类物理现象的通用数学语言。
  2. 传统数值方法通过离散化来近似求解PDE,已成功应用近百年。
  3. 然而,这些方法在应对高维问题多次查询场景不确定性量化物理知识缺失的系统时,面临计算成本过高或根本不可行的挑战。
  4. 这些挑战为机器学习与科学计算的融合提供了契机。在后续课程中,我们将探索如何结合物理原理与数据,开发出更高效、更强大的问题解决方法。

下一讲,我们将开始学习第一个关键工具:物理信息神经网络。

005:物理信息神经网络 - 引言

在本节课中,我们将要学习物理信息神经网络的基本概念。这是一种利用神经网络求解微分方程的新方法,它将物理定律直接融入到神经网络的训练过程中。我们将从高层次概述开始,通过代码演示其实现,并探讨其在正演模拟、反演问题和方程发现等领域的广泛应用。

课程概述

在开始讲解物理信息神经网络之前,我们先回顾一下上周Sid所讲的内容。他谈到了偏微分方程的重要性。偏微分方程确实是我们用来描述和理解许多不同科学现象的基本构建模块。从使用薛定谔方程模拟原子动力学的最小尺度,到使用爱因斯坦方程模拟黑洞的最大尺度,偏微分方程都至关重要。

偏微分方程对于理解地球上发生的现象也极为重要。例如,纳维-斯托克斯方程对于理解气候如何演变及其流体动力学至关重要。令人惊奇的是,一些生物系统也可以用偏微分方程来描述。例如,反应扩散方程可以用来模拟动物皮肤上的图案如何随时间生长而演变。

这就是为什么我们在本课程中如此重视偏微分方程。物理信息神经网络是求解微分方程或解决与微分方程相关问题的一种方法。我将向你们展示物理信息神经网络具体如何做到这一点。这是关于物理信息神经网络的几讲中的第一讲,我们现在真正进入了课程的主体部分,开始深入探讨这些我们一直在谈论的新型科学机器学习技术。

什么是物理信息神经网络?

在具体描述物理信息神经网络之前,我希望你们思考一下如何利用神经网络来求解微分方程。Sid在上次讲座中谈到了所有传统的数值方法,比如有限差分法、有限元法。他讨论了这些方法的优缺点,但物理信息神经网络从根本上不同,它们使用神经网络来求解微分方程。

所以,我想让你们先开始思考,并与同伴讨论:你们能想到哪些使用神经网络来求解微分方程或帮助求解微分方程的方法?

神经网络求解微分方程的初步想法

一种想法是,让神经网络的输入是初始条件,输出是模拟结果,并基于大量来自有限差分模型等示例以监督学习的方式训练它。这确实是一种方法。

另一种想法是,与其生成大量数据来训练网络,不如直接使用波动方程本身来训练网络,并最小化或惩罚其与方程的差异。这是一个很好的起点,让我们开始思考物理信息神经网络。

物理信息神经网络的核心思想

现在,让我们开始思考什么是物理信息神经网络。我将以一个更简单的微分方程为例,这是一个常微分方程,即阻尼谐振子方程。这是物理学中的一个典型问题,它模拟了一个弹簧上的质量块,其位移随时间变化的函数。

我们知道位移 u 是时间 t 的函数,它遵循这个微分方程,其中 m 是振子的质量,μ 是摩擦系数(阻尼项),k 是弹簧常数。根据振子的不同状态,可以有过阻尼、欠阻尼和临界阻尼状态。我们这里展示的是欠阻尼状态,振子随时间缓慢衰减,是一个带有指数衰减的正弦函数。

通常,为了求解微分方程,我们需要给定一组唯一的初始条件和边界条件,以获得一个特解。这里合适的条件是:质量块从位移为1、速度为零开始,这使我们能够唯一地(在本例中是解析地)求解 u(t)

那么,我们如何尝试使用神经网络来求解这个方程呢?这里“求解”的意思是,我们希望能够计算这个函数 u(t)。我们假设不知道它的解析解,因为对于绝大多数偏微分方程,我们确实不知道解析解。

物理信息神经网络的核心思想非常简单:直接用神经网络来近似解。我们说我们的解 u(t) 近似于一个函数 N(t; θ)。记住,神经网络只是拟合数据的函数。它是一个神经网络函数,接收坐标 t(时间值)作为输入,并有一些自由参数 θ

为了更明确,我们通常从多层感知机开始。在这个例子中,MLP有一个标量输入(时间值),然后给出一个标量输出,即位移的预测值。

这里的一个关键问题是:我们通过这种技术得到的解,与例如有限差分模型得到的解有何不同?根本的不同在于,我们这里是在对解进行函数逼近。物理信息神经网络的输出是一个函数,我们可以在任何时间点查询它,它会给出解的近似值。而当我们运行有限差分建模时,我们得到的是解的离散化版本,即在我们使用的网格点上解的值。因此,物理信息神经网络的一个关键特性是它们是无网格的,我们不需要网格来计算解。

损失函数设计

接下来的问题是:我们使用什么损失函数来训练物理信息神经网络?这就是我们将微分方程信息融入损失函数的地方。我们有两个损失函数组成部分:一个称为边界损失,另一个称为物理损失(有时也称为PDE残差)。

边界损失确保神经网络匹配我们的初始条件。它包含两项:第一项表示神经网络在 t=0 时的输出应等于1;第二项表示神经网络对 t 的导数在 t=0 时应等于0(即初始速度为零)。

最重要的部分是物理损失,它计算底层微分方程的残差。我们取神经网络,计算所需的所有梯度(例如对时间的导数),来计算微分方程的左端。如果神经网络是微分方程的精确解,我们期望这个残差的值是多少?是的,是零。我们试图确保这个残差尽可能接近零。如果残差为零,那么神经网络就给出了一个精确解。

我们需要在域内的许多不同点评估这个残差,因此我们在许多不同的时间值上进行采样,以确保在整个解域内,微分方程的残差都很小。

你可以将边界损失视为施加边界条件并确保解的唯一性,而物理损失则确保底层方程在域内所有点都被遵守。

训练过程可视化

下图展示了使用上述损失函数训练一个全连接神经网络的过程。灰色曲线是精确解,蓝色曲线是神经网络在训练步数增加过程中对位移的拟合或预测。图中还绘制了几个点:橙色点是边界点(即 t=0 的点),绿色点是物理损失训练位置(也称为配置点),这些是我们采样物理损失的时间点,以确保微分方程在域内所有点都被遵守。

这张幻灯片对于理解物理信息神经网络的训练方式和定义至关重要,我们在后续关于物理信息神经网络的讲座中讨论的所有内容都将回到这些核心思想。

关于泛化与采样的问题

有人可能会问:如果我们从域外采样呢?如果我们取这个训练好的神经网络,并给它一个域外的时间坐标,它很可能不遵守底层解,因为它超出了网络的训练分布。因此,神经网络的泛化能力在这里仍然是一个问题,我们将在下一讲中讨论。

另一个问题是关于训练步骤和采样。我们像训练普通神经网络一样,使用梯度下降法训练这个网络。我们计算损失函数对权重的梯度,然后更新权重。图中展示的是网络预测随训练步数的变化。

与通常使用小批量训练点的神经网络不同,在物理信息神经网络中更常见的是使用全批量训练,即每个训练步骤都使用所有绿色点和橙色点。这样做通常更有意义,因为它使问题更适定,确保PDE损失在整个域内一致。我们需要能够将边界条件向前传播,如果没有这个边界点,我们可能学到微分方程的任何解,它可能从任何地方开始。因此,拥有所有这些点有助于实现这一点,而不仅仅是随机采样。

配置点与损失权重

如前所述,域内的这些绿点被称为配置点,我们在整个域内对它们进行采样。另一个我尚未提及的是这些 λ 值,它们只是我们应用于损失函数中每一项的权重。我们将它们视为超参数,允许我们缩放或平衡损失函数中各项的贡献。在实践中,这对于确保物理信息神经网络快速收敛非常重要。例如,如果你将边界权重设置得非常低,你可能只会学到微分方程的非特解。

扩展到偏微分方程

我向你们展示了用于阻尼谐振子的物理信息神经网络,但物理信息神经网络之所以强大并成为当今热门研究领域,是因为它们实际上是求解偏微分方程的通用框架。我可以将使用神经网络表示微分方程解并对其进行训练的想法,应用于任何我喜欢的微分方程。

我们可以更抽象地设置物理信息神经网络:给定某个偏微分方程和一些边界/初始条件。我们可以说,偏微分方程通常只是应用于解的某个微分算子,它给出某个函数作为输出。我们有一个D维空间中的域,例如一个包含 xyt 的3D问题。我们有一些边界算子,可能有 K 个,每个算子等于在域边界上评估的某个边界函数。这精确定义了我们想要求解的边值问题。

物理信息神经网络通过直接近似解来训练神经网络以逼近偏微分方程的解,这是解的函数逼近。我们使用刚才描述的两个损失项:边界损失(对每个边界条件有一个单独的损失项)和物理损失(最小化底层微分方程的残差)。

具体示例:Burgers方程

为了使它更具体,并向你们展示物理信息神经网络应用于不同偏微分方程的例子,我将考虑Burgers方程,它模拟流体流动。这是粘性Burgers方程,其中 ν 是粘性参数,u 现在代表流速。我们考虑流体通过一个一维截面随时间的变化,所以解是流速在截面位置和时间的函数。

我们设置这些初始条件:起始流速是 x 的某个正弦函数,然后我们有一些边界条件,说明在域的边缘流速应为零。我们实际上模拟的是流体通过管道的流动,例如,流体开始时具有正弦分布的流速。

然后我们说,解由神经网络近似。然后我们像以前一样,有边界损失,现在边界损失中有三项,对应这三个边界条件。例如,在 t=0 时,对于所有 x 点,我们希望神经网络匹配负的正弦函数。因此,我们需要在评估此项时采样许多可能的 x 值。然后,对于 x = -1 的所有 t 值,我们应确保它为零,对于 x = +1 也是如此。物理损失则是在域内所有可能的 xt 值上评估完整微分方程的残差。

下图展示了这种情况。这是相同的损失函数,但图中黑点和绿点分别代表我们采样边界损失和物理损失的位置。对于一维谐振子,我们只需要一个边界点,但在更高维度,我们需要采样域的子空间。我们在这里沿着域的边缘采样边界损失,绿点是我们采样物理损失的位置。你还可以看到,我们不再进行均匀采样,也可以在域内进行随机采样。实际上,随机或准随机采样实际上可以帮助改善物理信息神经网络的收敛性,我们将在后面讨论。

这是物理信息神经网络的解。你可以再次看到,这是流体通过管道的流动,我们从一个正弦分布的流体流动开始。Burgers方程有趣且值得研究的地方在于,随着时间的推移,流体开始形成激波,你开始看到流体向一个方向流动,然后向另一个方向流动,并在中间形成激波。这对于研究数值方法来说是一个相当有趣的问题,因为当解中存在这些不连续性时,我们可能会开始出现很大的离散化误差。

有趣的是,如果你将精确解与神经网络训练后的预测进行对比,神经网络确实在某种程度上很好地模拟了这种激波,并且与真实解匹配得相当好。这张图直接取自Raissi等人的物理信息神经网络论文,这是该领域的开创性论文。

实现细节

更具体地说,他们使用了10,000个配置点用于物理损失,并且没有使用均匀采样,而是使用了拉丁超立方采样(一种伪随机采样)。然后他们有100个边界点采样。他们使用的网络是一个全连接网络,有9层,每层20个隐藏单元,总共3003个参数。他们使用了 tanh 激活函数和一个二阶优化器(不仅仅是梯度下降,而是拟牛顿优化器)。

关于激活函数的一个有趣问题是:为什么他们选择使用 tanh 激活函数而不是 ReLU?答案是,tanh 是一个连续可微的光滑函数。为什么这很重要?因为我们需要能够评估神经网络对其输入的二阶导数。如果我使用 ReLU 激活函数,它的值会怎样?ReLU 是一个分段线性函数,其梯度是分段常数,二阶导数为零。因此,使用 ReLU 激活函数的神经网络实际上是在进行分段线性逼近。但如果我们使用 tanh 激活函数,那么我们通常有一个连续可微的函数可以拟合。当然,你不必只使用 tanh,也可以使用其他光滑的激活函数近似,如 Swish 函数等。

物理信息神经网络的研究领域

物理信息神经网络已经发展成为一个完整的研究领域。如果你查看每年发表的包含“物理信息神经网络”关键词的论文数量,你会发现其增长非常迅速。这是一个庞大的研究领域,有许多物理信息神经网络的扩展,我们将在接下来的讲座中介绍其中一些。

如果你真的想更深入地了解物理信息神经网络,可以查看这篇综述论文,它对迄今为止物理信息神经网络的整个研究领域进行了相当全面的回顾。有趣的是,物理信息神经网络背后的基本概念——使用神经网络近似解,然后使用微分方程残差训练它——可以追溯到20世纪90年代的论文,例如Lagaris等人的工作。但最著名的物理信息神经网络论文是Raissi的论文,这篇开创性论文使用现代深度学习框架重新实现和扩展了物理信息神经网络,展示了我们可以训练深度全连接网络和其他网络来求解这些微分方程。

训练过程详解与代码演示

希望我已经向你们描述了物理信息神经网络的高层概念。现在,我将更详细地讨论训练过程,其中有很多因素我尚未提及或省略。我将尝试在本节中通过PyTorch的实时编码向你们展示训练物理信息神经网络是多么容易。

让我们更详细地思考物理信息神经网络的训练循环。回到阻尼谐振子这个简单的例子。我们再次有边界损失和物理损失。

训练循环的步骤如下:

  1. 首先采样边界点和物理训练点(配置点)。
  2. 计算网络输出。
  3. 关键步骤:我们需要评估网络对其输入的导数(du/dtd²u/dt²),以便计算物理损失和部分边界损失。
  4. 这使我们能够计算损失函数的值。
  5. 然后我们需要另一个步骤:计算损失函数对神经网络参数的梯度,以便更新参数来学习解。

关键问题是:我们如何计算所需的梯度,例如 du/dtdL/dθ?在一般情况下,神经网络只是一个数学函数,是一系列线性运算加上一些激活函数。我们可以解析地写出网络对其输入的导数。但在实践中,我们不这样做,我们可以使用自动微分和反向传播作为计算这些梯度的有效方法。

重要的是,我们不仅可以使用自动微分来获取损失函数对权重的梯度,还可以使用自动微分来获取网络输出对其输入的梯度。这是相同的算法,相同的自动微分。

让我展示一下我们如何使用自动微分来获取这两种梯度。假设网络是一个MLP,其形式如下。当我们对损失函数关于权重进行微分时,我们使用链式法则来计算该梯度。类似地,我们可以使用链式法则来计算网络对其输入的梯度。我们可以解析地做到这一点,虽然今天没有时间详细推导,但这可以作为一个练习。

一旦我们得到了这个导数,我们如何得到损失函数对权重的导数?我们可以使用自动微分,只需将计算网络对其输入的导数视为扩展我们在使用自动微分时的计算图。自动微分通过创建所有操作的图并跟踪该图,然后通过该图反向传播来提供梯度。网络对时间的导数只是一些额外的计算,你可以将其视为扩展了网络前向图的一部分。这个导数只依赖于激活函数 gh,并通过一些函数(激活函数的导数)并乘以权重。我们可以将其绘制为计算图的额外部分,然后允许我们计算图的最终输出,即损失函数。

一旦我们扩展了计算图,我们就可以对整个组合图调用自动微分,从损失函数反向传播以获取权重的梯度。关键的认识是,我们可以递归地应用自动微分,首先获取网络对其输入的梯度,创建新图,然后获取该图对网络参数的梯度以更新参数本身。

以下是在PyTorch中实现这一点的伪代码。在实践中,你可以直接使用自动微分来获取这些梯度。t 是我们的时间坐标,θ 是网络参数。我们得到网络在给定 t 值下的预测。然后我们计算第一个梯度,即网络输出对时间的导数,我们可以使用 torch.autograd.grad 来做到这一点。我们还需要关于时间的二阶导数来评估物理损失。在PyTorch中,我们做的一件事是设置 create_graph=True,这会扩展计算图,以便我们在最后调用自动微分以获取损失函数对权重的梯度时,可以再次进行微分。

现在,我们拥有了在PyTorch中实际训练物理信息神经网络所需的一切。我将尝试为你们进行一些实时编码。

(代码演示部分展示了如何定义网络、采样点、计算边界损失和物理损失,并使用自动微分获取高阶导数。训练循环成功运行,并动画展示了网络解如何收敛到精确解。)

计算成本与其他考量

重要的是要考虑计算这些导数的成本。正如我所说,它们是可用的,我们可以解析地计算它们,或者等效地使用自动微分。但获取这些导数的成本可能相当高。

如果你只考虑当我们添加这些额外计算来计算关于输入的梯度时所构建的计算图,你会发现这些计算大致使计算图的大小翻倍。更精确地说,给定某个向量函数,计算雅可比向量积所需的时间大约是计算网络前向传播时间的 ω 倍,其中 ω 是介于2和2.5之间的某个值。要真正理解这个推导,可以参考这里的引用。

这听起来不错,我们可以在大约与前向传播相同的时间内计算它。但是,在训练物理信息神经网络时,我们通常需要高阶导数,例如二阶甚至更高阶导数来评估物理损失。计算这种高阶导数的成本随 n 值呈指数增长,具有 ω^N 的计算缩放比例。因此,当你训练物理信息神经网络时,你通常会发现大部分时间不是花在网络的前向部分,而是在计算梯度时。这是物理信息神经网络计算成本的一个关键限制。

还有其他一些重要的考虑因素,我认为我们现在已经基本讨论过了。λ 值确实显著影响收敛性,通常正确定义它们是关键选择。我们还需要确保域内有足够的配置点,以确保我们在整个域内精确约束PDE残差。“足够”很难精确定义。当我们使用有限差分法或有限元法时,我们有非常清晰的收敛准则,例如采样间距应该是多少。你可能会想,这里基本上是一个正弦波,因此我们希望确保采样点低于奈奎斯特采样率,这将是一个合理的起点。同样,我们需要足够的边界点来确保学习的解是唯一的。我们可以随机或均匀地采样这些配置点。

正如有人在最开始指出的那样,物理信息神经网络尽管内部有这种巧妙的物理损失,但归根结底仍然是神经网络,它们仍然遭受我在深度学习导论讲座中谈到的所有误差来源。因此,如果神经网络不够灵活或表达能力不足以表示真实解,它们仍然会有近似误差,不会收敛到该解。如果我们没有选择足够的配置点,它们会有估计误差,不会收敛到最小化真实期望损失的解。还有优化误差,即使我们可能有一个可以给出解的网络,但对于优化器来说,这可能是一个非常复杂的目标函数,它仍然可能不收敛。

实际上,我们将在下一讲中讨论如何在训练物理信息神经网络时克服其中一些限制。

从机器学习视角看物理信息神经网络

在讨论应用之前,最后一种看待物理信息神经网络的方式是从机器学习角度重新构建它。我认为这非常有趣,考虑到本课程是关于科学与工程中的人工智能,处于这两个领域的交叉点,从更纯粹的机器学习角度看待这些技术可能非常有用。

从数学角度来看,我们设置这些神经网络来求解偏微分方程,是对解的函数逼近。但是,从纯粹的机器学习角度——训练神经网络的角度——我们能对物理信息神经网络说些什么?这个损失函数有什么有趣之处?

想象一下,如果我们只是将边界损失解释为监督损失。我们这里有神经网络,我们将其匹配到一些标签训练数据,例如1和0,我们说它应该取这些值。那么物理损失有什么不同呢?它更像是一种正则化项。完全正确,物理损失这里不需要任何标签。如果我们从监督学习与非监督学习的框架来思考,边界损失有这些标签(我们希望解是什么),而物理损失只给出这些时间点(网络的输入),并根据网络的这些输入评估损失函数。

因此,从机器学习角度来看,我们可以将物理损失视为一种无监督的正则化器,它断言了先验知识,为我们提供了一种归纳偏好或正则化项,将网络学习的解的类型推向遵守微分方程的解。

这是一种从机器学习角度思考的非常好的方式,它是一个正则化项。让我说得更清楚一些:这是一种训练物理信息神经网络的不同方式,不是有特定的边界损失,而是假设我们只有一堆解的观测点(橙色点)。那么,如果我仅使用监督损失在这些观测点上训练一个标准神经网络,你可以看到网络在其训练范围内非常拟合数据,但一旦我在这些训练数据点之外查询网络,解就变得平坦,是一个非常差的近似。

现在,我们将物理损失视为基本上添加了额外的正则化,并将配置点扩展到训练点之外。我们可以开始学习一个更通用的解,但需要注意的是,如果我们在这些配置点更远的地方测试它,它的表现不会很好。因此,希望这从机器学习角度讲得通。

然后,如果我退回到更高的层次,思考我在第一讲中谈到的将科学原理融入机器学习的三种广泛类别,我们非常处于左侧:我们正在改变神经网络的损失函数,在物理信息神经网络中我们只是使用标准神经网络架构,并在损失函数中添加一些科学理解来提高网络的性能。

物理信息神经网络的应用

在课程开始时,我向你们解释了什么是物理信息神经网络,并展示了如何训练它,还进行了一些实时编码。现在,我将讨论物理信息神经网络的应用,即我们可以使用物理信息神经网络解决的所有不同类型的科学任务。

到目前为止,我一直专注于模拟任务,即求解微分方程。但我要向你们展示的是,我们也可以使用物理信息神经网络来解决反演问题以及方程发现问题。

让我们回顾一下我们经常想要解决的关键科学任务。这只是使用波动方程的一个例子,例如地震模拟,但你可以取任何偏微分方程,都会有与之相关的类似任务。

正演模拟的任务是:给定系统的一些输入条件,例如地球的速度模型和地震的位置,我能预测该物理系统的输出吗?在这种情况下,就是通过该介质传播的地震波的振幅。因此,我们可以说系统的输出 B 仅取决于系统的某个模型(通常是偏微分方程)和一些系统输入 A

反演问题是尝试做相反的事情:给定系统输出的一些观测值(在这种情况下是波场,地震振幅),我们能否反演出地球的底层结构或地震的位置?

最后一个任务是方程发现,这不仅是发现输入参数的任务,而且是理解所有这些动力学背后的底层微分方程或模型的任务。在这种情况下,你的观测数据可能是波场、震源位置以及地球模型本身,给定所有这些数据和观测,我们能否反演出底层微分方程(在这种情况下是声波方程)?

因此,在本讲座的最后一部分,我将试图说服你们,物理信息神经网络可以解决所有这三类任务,而不仅仅是模拟任务。

正演模拟示例:波动方程

在我转向其他任务之前,再举一个物理信息神经网络进行模拟的例子。这是我们做的一些工作,我们使用物理信息神经网络求解了波动方程。这里的任务是给定一个速度模型(描述地球的速度,这里我假设地球只是一个非常简单的水平层状结构)和背景中的一个震源位置,我能预测地震波如何通过该地球模型传播吗?

这是如果我使用有限差分建模运行模拟时的样子。观察这些波场如何随时间演变非常有趣,发生了许多复杂的物理现象。我们得到了震源向外爆炸的一般情况。但是,当我们遇到速度模型中的这些界面时,我们开始在每个界面处得到这些反射。我们还开始看到波场或子波根据其通过的速度而压缩和扩展,当速度慢时它会挤压在一起。波物理中还会发生许多其他有趣的现象,因此总的来说,这是一个非常有趣的建模问题。

看看物理信息神经网络是否能对这种函数进行建模,这个函数比我们之前看的单个正弦函数复杂得多。我们如何做到这一点?设置与我描述的完全相同。这里我们有一个全连接神经网络,其输出只是一个标量,本质上是地震波的压力。网络的输入是空间二维坐标和时间。为了确保网络学习这个问题的边界条件,我们所做的是将网络与非常少量的有限差分步骤进行匹配,仅用于模拟的最初0.02秒。基本上,我们将这个红色框作为解的有监督示例来匹配网络。然后,我们在整个时空域(一直到时间0.2秒)使用配置点采样物理损失。

结果如下:重要的是这里的物理信息神经网络解。你可以立即看到,物理信息神经网络能够对解进行建模,这非常有趣。不仅如此,它不仅得到了波场向外运动的一般情况,还模拟了这些反射,而它只是基于最小化PDE残差来学习模拟这些反射,在给定的边界条件训练数据中它没有见过这些反射。这真的很酷。

这里我还应用了一个朴素神经网络的输出。这个朴素网络是如何训练的?它非常简单,只使用边界损失而不使用物理损失。这个朴素网络只使用损失函数中的第一项。比较这两种解很有趣:朴素网络显然在它有训练点的地方对边界数据建模得很好,但在没有训练点的地方,它捕捉到了波场向外运动的概念,但不理解波场中的这些反射。因此,你可以真正看到为什么物理信息损失对于获得正确的动力学至关重要。

这个网络的一些数值细节:在这种情况下,有人问我们是否使用全批量,这里我使用了小批量采样,每个训练步骤在域内随机采样500个点,边界点也是如此。这是一个相当大的网络,有10层和10000个隐藏单元,这是一个相当大的网络,能够对这种复杂度的函数进行建模。它使用了 softplus 激活函数,这是 ReLU 的连续版本,并使用 AdamW 优化器。

这里最大的限制,也是物理信息神经网络最常被批评的一点,就是训练这个网络所需的时间。在GPU上训练这个解花了一个小时。如果我将其与有限差分建模进行比较,你认为有限差分解需要多长时间?大约30秒到一分钟。因此,在物理信息神经网络的原始形式中,它完全无法与有限差分建模竞争。我将在下一讲中解释如何克服这个问题,以及如何加速物理信息神经网络以使其更具竞争力。我还将在接下来的幻灯片中尝试证明为什么物理信息神经网络对于反演问题和方程发现仍然有用。

反演问题

现在,让我们继续使用物理信息神经网络解决反演问题。再次明确说明反演问题是什么,我将使用通过地球模拟地震波的相同例子。我有波动方程,现在我有一些波场的观测值。我想要反演的是介质的底层速度,或者甚至震源位置。

传统上我们如何做到这一点?传统上,解决反演问题的一种方法是将其构建为优化问题。我们说我们有观测值 B,以及一个给定底层输入猜测(例如速度模型的猜测)的系统前向模型。然后我们最小化预测输出与真实观测输出之间的差异。如果 F 在这里是可微的(如果这是一个可微的有限差分解算器),我们可以直接对这个目标函数使用梯度下降。

物理信息神经网络有何不同?物理信息神经网络如何以不同的方式解决这个反演问题?我将解释我们如何做到这一点,我们所做的非常简单:我们只是改变用于训练物理信息神经网络的损失函数,这是一个非常简单的改变,使我们能够解决这些反演问题。

再次,这是用于正演模拟的损失函数,我们之前已经看过。这里,这是损失函数的一般形式,但这里的微分算子可能是波动方程。如果我们想解决反演问题,我们这样做:一般来说,我们可以访问这些额外的解观测值,因此我们要做的是添加一个额外的损失项,在这个损失项中,我们说在有解观测值的地方,我们将神经网络输出与该观测值匹配,这是一个我们可以添加到损失函数中的额外监督损失。

这是我们要做的第一个改变。第二个改变是:我们可能不知道问题的边界条件是什么,假设我们无法访问它们,我们只有解的观测值。因此,我们去掉边界损失。然后我们保持物理损失不变,像以前一样在域内采样许多点并评估PDE残差。

另一个关键改变是:这个微分算子有一些我们想要反演的底层参数,例如在波动方程中是这个速度模型 c(x)。为了能够解决这个反演问题并估计这些参数,一个非常简单的技巧是:这些将只是我们在训练物理信息神经网络时的额外自由参数,我们将与网络参数 θ 一起联合优化。你可以想象,当物理信息神经网络训练时,它不仅同时学习正向求解模型,还同时学习底层参数,它正在进行某种问题的联合优化。

这很酷,这与我之前构建反演问题的方式非常不同,之前我们只专注于优化底层参数,而不学习解,我们只是通过解算器进行微分。这是一种思考解决反演问题的非常有趣的方式。在计算上,这可能与使用梯度下降的传统算法具有竞争力,因为我们不再需要评估昂贵的前向解算器,我们只是训练一个网络来拟合数据,因此在反演算法中没有昂贵的前向解。

反演问题示例:振动板

这是一个使用物理信息神经网络解决波动方程反演问题的例子,但这次我们想要了解速度模型是什么。假设我们有一个振动板,我们振动这个板,并测量板随时间的位移。这用于无损检测,例如调查板上是否有裂纹或任何扰动。

你可以看到,当波在板中传播时,这里有一些异常导致反射。我们想进一步研究这一点。给定这些观测值(这是真实数据,这篇论文实际上使用了这个振动板的真实数据),我们将训练网络来匹配这些观测值,然后我们还将在这里添加物理损失,其中包含速度模型,并且我们假设我们不知道这个板的速度模型。

相反,我们要做的是:我们将用另一个具有额外自由参数 φ 的神经网络来近似速度。我们可以这样做,我们可以说速度 c(x) 只是由某个具有参数 φ 的额外神经网络近似。当我们训练神经网络时,我们将同时联合优化 θφ

结果如下:当物理信息神经网络训练时,它逐渐开始拟合解,这是解网络的输出。同时,它训练那个速度模型网络来学习速度,我们可以像查询解网络一样在任何空间点查询速度网络。这是它预测的底层速度,你可以看到它学会了发现板中的这个裂纹,并显示为速度模型中的扰动。

代码演示:反演阻尼系数

我将回到我的实时编码,向你们展示如何使用阻尼谐振子来做到这一点,我们将学习振子的摩擦系数 μ。再次,我将向你们展示这在PyTorch中是多么容易。

(代码演示部分展示了如何修改训练循环,将摩擦系数 μ 作为可学习参数,与网络权重一起优化。训练过程同时拟合观测数据和学习 μ 的值。)

反演问题示例:心脏激活映射

在转向物理信息神经网络的最终应用之前,这是使用物理信息神经网络解决反演问题的另一个例子。这是物理信息神经网络的一个完全不同的用例。这里的目标是能够更好地表征心脏,特别是当你的心脏跳动时,心脏的激活像波一样穿过心脏。你实际上可以绘制心脏表面各点激活发生的时间。这里的底层方程是Eikonal方程,它告诉我们心脏表面的速度与心跳发生时该点激活所需时间之间的关系。

一般来说,能够理解这个速度模型对于医学诊断非常有用,可以寻找心脏的任何问题。因此,目标基本上是:给定心脏各点激活时间的观测值,我能理解心脏表面的底层速度吗?

我们可以暂时将其简化为一个简单的2D版本问题,我们只有一个看起来像这样的速度模型,这只是一个简单的玩具模型。我们可以绘制给定这个速度模型时穿过心脏所需的激活时间。我们要做的是使用物理信息神经网络同时拟合速度和激活时间。我们在这里使用一个物理损失,其中神经网络近似激活时间,并用参数 φ 近似速度。我们只是将近似激活时间的神经网络与观测到的时间点进行匹配。

结果如下:这是精确解,这是物理信息神经网络的结果。物理信息神经网络能够精确地近似这些激活时间,并且对底层速度结构进行了相当好的反演。这里的比较是,如果我们只使用朴素神经网络(仅使用观测时间而没有Eikonal方程残差),你可以看到它在没有损失函数中物理方程理解的情况下,对速度的插值效果要差得多。你还可以将其与仅使用高斯过程插值这些故障点以及线性回归进行比较,很明显,具有额外正则化的物理信息神经网络是更好的模型。

方程发现

在最后五到十分钟,我将继续讨论如何实际使用物理信息神经网络来发现底层微分方程本身,而不仅仅是方程的参数。

这是我们用于使用物理信息神经网络解决反演问题的设置,我们说我们联合优化网络的权重以模拟问题,同时也优化微分方程的底层参数 φ。现在的问题是:我们如何实际学习微分算子 D,而不仅仅是算子的一些参数?

我们要做的是:我们将假设 D 由许多不同的微分算子组成。我们将构建一个算子库,说我们的偏微分方程可以包含这些算子的任何组合,例如解对 x、对 t 的偏导数,二阶导数及其组合。然后我们假设微分算子可以表示为这个 Λ 矩阵,即系数矩阵乘以这个不同算子的库向量。

例如,如果我们要以这种方式表示阻尼谐振子方程,我们将有这个算子库和这个系数矩阵(在这种情况下它只是一个行向量)。你可以看到,我们不需要的算子,我们只需将该矩阵中的系数设为零,因此我们只需要这个库中的前三个系数。

然后,学习方程的目标就变成了学习这个 Λ 矩阵的系数的问题。这就是我们构建损失函数并训练物理信息神经网络进行方程发现的方式。我们将用这个 Λ 矩阵乘以我们可能的算子库来代替微分算子。

一般来说,这比仅仅解决反演问题更难。反演问题在观测数据不足时已经很难解决,而这是一个更难的问题,需要对所有这些算子进行线性组合的回归。是的,我们假设它是线性组合,但如果你知道存在非线性项,你可以在库中包含非线性项,例如 u * ∂u/∂x∂u/∂x * ∂u/∂t。因此,根据你想要建模的可能微分方程空间,你选择相应的库。

我要指出的是,这个可能的微分方程空间呈指数增长,如果你想象所有这些算子的所有组合,那绝对是一个巨大的组合空间。因此,这实际上是一个非常困难的问题。我们通常必须做的是对微分方程的系数施加一些正则化或先验。例如,我们假设稀疏性,我们想找到一个具有最少可能算子数量的微分方程,例如,通过在损失函数中添加一个额外的正则项,说明 Λ 应该是稀疏的,应该趋向于零。这有助于使问题收敛并成为一个更适定问题。除此之外,我们以与反演问题相同的方式进行拟合,我们有解的观测值,我们只是将网络拟合到这些观测值,一旦我们拟合了这些观测值,我们就对梯度进行回归以得到底层方程是什么。

方程发现示例

这是一篇几年前发表在《自然通讯》上的论文,它正是做了我刚才描述的过程。他们有一个数据损失,将网络解与一些观测数据匹配。然后他们有物理损失,最小化PDE残差,但使用这个算子库并尝试学习这些算子的系数。然后它添加了一些稀疏正则化,以尝试最小化我们使用的系数数量。它通过交替训练进行训练:首先学习网络的权重(首先拟合解数据),然后进行学习系数的步骤,这似乎比仅进行联合优化更好。

这是论文中的一个例子,这是物理信息神经网络发现Burgers方程的例子,在系数上进行线性回归。他们的输入数据只是Burgers方程在不同初始条件下解的噪声观测值。仅给定这些观测值并假设算子库,他们能够发现给出与底部真实偏微分方程非常接近的近似系数。

总结

我们已经涵盖了很多内容。我向你们解释了什么是物理信息神经网络以及如何训练它们,我还向你们展示了我们可以在正演、反演和方程发现问题中使用它们。非常重要的一点是,它们是无网格的,因此它们给出解的函数逼近,而不仅仅是离散化版本,这是对解的直接逼近。

下一讲我将讨论物理信息神经网络的局限性,以及人们使用的许多可能的扩展,物理信息神经网络被这些扩展所扩展。好的,我们下一讲再见。谢谢。

006:局限性及其扩展(第一部分) 🧠

在本节课中,我们将要学习物理信息神经网络(PINNs)的局限性,并探讨一系列旨在克服这些局限性的扩展方法。我们将首先回顾PINNs的基本概念,然后深入分析其在计算成本、收敛性和可扩展性方面面临的挑战。本节课的重点将放在如何通过扩展方法来提升PINNs的计算效率。

PINNs 核心概念回顾

上一节我们介绍了PINNs的基本思想,本节中我们再来回顾一下其核心概念。

物理信息神经网络是一种用于求解微分方程或其相关问题的无网格方法。其核心思想是使用一个神经网络直接近似微分方程的解。

核心公式
对于一个待求解的未知函数 u(x),PINN使用一个神经网络 NN(x; θ) 来近似它,即 u(x) ≈ NN(x; θ)。其中 θ 是神经网络的参数。

训练该网络的损失函数通常包含两个主要部分:

  1. 边界/初始条件损失:确保网络输出满足问题的边界或初始条件。
  2. 物理(PDE)残差损失:在域内的一系列配置点上,最小化控制微分方程的残差。

代码概念

# 伪代码示例:PINN 损失函数
def pinn_loss(x_domain, x_boundary, u_true_boundary):
    # 神经网络预测
    u_pred_domain = neural_net(x_domain)
    u_pred_boundary = neural_net(x_boundary)

    # 边界损失(例如,均方误差)
    loss_bc = mse(u_pred_boundary, u_true_boundary)

    # 物理损失:计算PDE残差(需自动微分求梯度)
    residual = pde_residual(u_pred_domain, x_domain) # 涉及对u_pred_domain求导
    loss_physics = mse(residual, 0)

    # 总损失
    total_loss = loss_bc + lambda_ * loss_physics
    return total_loss

PINNs的优势在于其无网格特性、能够联合求解正反问题、拥有可解析的梯度以及通常只需少量数据。

PINNs 的主要局限性

尽管PINNs具有诸多优势,但在实际应用中仍面临一些显著挑战。以下是三个主要的局限性:

1. 计算成本高昂

对于纯正演问题,训练一个PINN通常比运行传统的数值模拟(如有限差分法)要慢得多。一个关键问题是,PINN需要为每一组新的初始条件或边界条件重新训练,而传统方法只需运行一次求解器。

2. 收敛性不佳

PINNs的损失函数景观可能非常复杂和非凸,导致优化困难。其中一个关键因素是边界损失与物理损失之间的权重系数 λ 难以选择。若 λ 太小,网络可能忽略边界条件,学习到PDE的任意解(例如零解);若 λ 太大,则可能无法满足控制方程本身。

3. 难以扩展到复杂问题

PINNs在处理高频率、多尺度或大尺度问题时面临挑战。神经网络的表达能力有限,拟合高频振荡解需要大幅增加网络规模(更多层、更多神经元),这进一步加剧了训练难度和计算成本。

扩展方法一:提升计算效率

针对计算成本高昂的问题,研究人员提出了多种扩展方法。本节我们将重点介绍其中两种:条件PINNs和离散化PINNs。

条件物理信息神经网络

核心思想是,与其为每个新场景重新训练一个网络,不如训练一个能泛化到多种场景的单一网络。实现方法是将变化的参数(如源位置、方程系数、初始条件函数)作为额外的输入提供给神经网络。

网络架构变化
原始PINN输入:NN(坐标 x; θ)
条件PINN输入:NN(坐标 x, 条件参数 c; θ)

训练方式
在训练过程中,不仅要在域内和边界上采样坐标点,还要在条件参数的空间中进行采样。损失函数需在所有采样到的条件参数值上评估。

优势

  • 一次训练后,可快速查询不同参数下的解,适用于灵敏度分析、不确定性量化等任务。
  • 可被视为一个快速的代理模型。

示例
在波方程模拟中,将震源坐标 (s_x, s_y) 作为条件输入,网络便能学会预测任意震源位置下的波场。

离散化物理信息神经网络

这是一种思路上的转变,将PINNs从“函数近似器”拉回到“在网格上预测解”的范式。

核心思想
使用一个神经网络(如卷积解码器)直接输出定义在规则网格上的离散化解。网络的输入可以是一个固定的随机向量或我们希望条件化的参数。

关键区别与训练

  1. 输出:不再是连续函数,而是网格点上的值矩阵。
  2. 梯度计算:不再使用自动微分计算精确的物理损失梯度,而是使用有限差分方法在输出网格上近似计算PDE所需的导数(如 ∂u/∂x, ∂²u/∂t²)。
  3. 边界条件:通常通过硬约束实现,例如在输出网格周围填充已知的边界值。
  4. 训练:使用与PINN类似的物理残差损失(但基于有限差分梯度)进行无监督训练,无需任何模拟数据。

优势

  • 可以利用成熟的CNN等架构高效处理网格数据。
  • 训练可能更稳定,避免了损失函数中平衡权重 λ 的选择问题。
  • 对于其训练分布之外的输入,有时表现出比纯数据驱动模型更好的泛化能力。

局限性

  • 回到了网格依赖的方法,失去了经典PINN的无网格优势。
  • 使用了近似的(有限差分)梯度,精度受网格大小和差分格式影响。

其他加速技巧:使用有限差分梯度

一个更直接的加速技巧是,即使在传统的(连续)PINN中,也用有限差分来近似计算物理损失中所需的网络输出梯度,以替代计算成本高昂的自动微分。这通常能带来2-4倍的训练加速,但代价是引入了梯度近似误差,且差分步长的选择变得重要。

总结

本节课中我们一起学习了物理信息神经网络(PINNs)的主要局限性,并深入探讨了旨在降低其计算成本的扩展方法。

我们回顾了PINNs在计算效率、收敛性和可扩展性方面的挑战。针对计算成本问题,我们介绍了两种有效的扩展:

  1. 条件PINNs:通过将问题参数作为网络输入,训练一个可泛化的模型,避免为每个新场景重复训练。
  2. 离散化PINNs:将网络输出改为网格上的解,并使用有限差分计算物理损失,结合硬边界约束,进行无监督训练。

这些方法显著提升了PINNs在需要多次求解或快速代理建模场景下的实用性。在下节课中,我们将继续探讨如何改善PINNs的收敛性以及将其扩展到更高频率和更复杂问题的方法。

007:局限性与扩展(第二部分)

在本节课中,我们将继续探讨物理信息神经网络的局限性与扩展方法。上一节我们主要讨论了如何降低PINNs的计算成本,本节我们将重点关注另外两个核心挑战:如何改善PINNs的收敛性,以及如何将其扩展到更复杂的多尺度、多物理场问题。


回顾与课程安排

上一节我们介绍了PINNs的三个主要局限性:

  1. 计算成本高昂:训练PINNs,特别是用于正向模拟任务时,通常非常耗时。
  2. 优化困难:梯度下降等优化算法难以收敛到损失函数的全局最小值。
  3. 扩展性差:在处理复杂的多物理场或多尺度问题时,PINNs难以有效扩展。

上一讲我们深入探讨了如何通过条件化PINNs离散化PINNs等方法来应对第一个挑战,即降低计算成本。本讲将聚焦于后两个挑战:改善收敛性提升扩展能力


改善收敛性:损失项间的竞争

在上一讲中,我们展示了一个训练PINN求解波动方程的例子。其收敛曲线呈现出剧烈的震荡行为:在训练的前半段,PINN似乎停滞不前,直到后期才开始收敛。在训练步数为20000时,PINN仅学会了初始条件,而在其他区域输出近似为零。

为什么会出现这种情况?
这是因为损失函数中不同项之间存在竞争。对于波动方程,U = 0 是一个平凡的、易于满足的解(PDE残差损失项为零)。PINN在训练初期,可能会陷入这个局部最小值,因为它能最小化PDE残差,尽管这违反了边界条件。边界条件损失项和物理残差损失项之间需要“沟通”,才能使网络找到既满足边界条件又满足PDE的正确解。

这种竞争关系可以通过损失函数中的权重参数 λ 来调节:
L = λ_BC * L_BC + λ_PDE * L_PDE
然而,手动调整这些标量权重 λ 非常困难且依赖经验:如果 λ_BC 太小,网络学不到唯一解;如果太大,网络可能只满足边界条件而忽略PDE。

接下来,我们将介绍几种方法来缓解这种竞争,帮助网络同时最小化所有损失项。


方法一:硬边界条件

核心思想:重新构建优化问题,使边界条件在数学上被精确满足,从而将其从需要优化的损失项中移除,将约束优化问题转化为无约束优化问题。

实现方式:我们不再让神经网络直接近似解 U(x, t),而是将其作为解表达式的一部分。我们手动设计一个数学表达式(称为Ansatz),使其自动满足边界条件,神经网络则负责学习表达式中的灵活部分。

示例(Burgers方程)
假设边界条件为:U(x, t=0) = sin(πx)U(x=±1, t) = 0
我们可以构造如下Ansatz:
U_θ(x, t) = sin(πx) + t * (1 - x^2) * N_θ(x, t)
其中 N_θ(x, t) 是神经网络。可以验证,当 t=0x=±1 时,无论神经网络输出什么,U_θ 都精确满足边界条件。

优势

  • 消除了边界条件损失项,避免了项间竞争。
  • 训练完全无监督,不需要任何边界条件的训练数据。
  • 可以通过自动微分计算梯度,以评估PDE残差。

局限性

  • 对于复杂的几何形状(如机翼绕流)或不等式边界条件,手动设计满足条件的Ansatz非常困难。

尽管如此,对于许多问题,硬边界条件方法能显著改善收敛。例如,在求解带有收缩管道的不可压缩Navier-Stokes方程时,标准PINN难以收敛,而使用硬约束方法则能成功。


方法二:自适应权重

核心思想:与其手动设置固定的全局权重 λ,不如让算法在训练过程中自适应地调整每个训练点上的权重。

具体方法(自适应性PINNs)

  1. 每一个边界点和配点分配一个独立的权重 λ_i
  2. 在训练神经网络参数 θ 的同时,也学习这些权重 λ
  3. 更新 θ 时,使用梯度下降最小化损失 L
  4. 更新 λ 时,使用梯度上升最大化损失 L

为什么使用梯度上升更新 λ
对物理损失项 L_PDE = Σ λ_i * r_i^2 求导可得:∂L/∂λ_i = r_i^2
因此,梯度上升意味着:在残差 r_i 大的地方,增加其权重 λ_i。这相当于一个“注意力机制”,引导优化器更加关注当前误差较大的区域。

效果:这种方法被应用于求解Helmholtz方程等问题,能够成功收敛。训练完成后,可以观察到 λ 值在解的高振幅区域(如波峰)较大,表明网络确实在重点关注这些难以拟合的区域。


方法三:自适应采样

核心思想:与其调整损失权重,不如动态调整配点的分布,在PDE残差高的区域放置更多的配点。

实现方式

  1. 在训练过程中,评估当前PINN在整个域上的PDE残差 r(x)
  2. 将残差的绝对值归一化,视为一个概率分布:p(x) ∝ |r(x)|
  3. 根据此概率分布采样新的配点,替代或补充原有的配点集。

类比:这类似于传统数值方法中的自适应网格加密。我们根据解的误差分布,动态分配计算资源。

研究结果:实验表明,与均匀网格采样或纯随机采样相比,这种基于残差的自适应采样策略(以及准随机采样)能显著提升多种PDE(如波动方程、Burgers方程、扩散方程)的求解性能。


扩展到复杂问题:应对谱偏差与多尺度挑战

PINNs在简单问题上表现良好,但我们的目标是将其应用于现实世界问题,如全加州地震模拟或全球气候模拟。这涉及到多尺度、多物理场、高频率等挑战。

一个关键障碍:神经网络的谱偏差
谱偏差是指神经网络在训练时,倾向于优先学习低频模式,而学习高频模式的速度很慢。这对于需要精确捕捉高频变化的PDE求解非常不利。

示例:在求解简单ODE du/dx = cos(ωx) 时,PINN能快速收敛于低频(ω=1)解,但当 ω=30 时,收敛变得极其困难,需要大幅增加网络参数,且最终精度仍较差。

除了谱偏差,高频率还意味着需要更多配点、更大网络,这些都使得优化问题更加困难。


扩展方法一:傅里叶特征网络

核心思想:在标准全连接网络之前,加入一个傅里叶特征映射层,将输入坐标显式地映射到一组高频和低频的三角函数空间,为网络提供丰富的频率基。

实现
γ(x) = [cos(2π B x), sin(2π B x)]^T
其中 B 是一个从某个分布(如高斯分布 N(0, σ^2))中采样得到的矩阵。然后将 γ(x) 作为特征输入到后续的全连接网络。

直观理解:这相当于为网络提供了一个包含多种频率的“预处理器”,减轻了网络自身学习高频函数的负担。理论分析(基于神经正切核理论)表明,这可以改善高频成分的收敛速度。

局限性:性能强烈依赖于矩阵 B 中频率的选择(即高斯分布的方差 σ)。需要根据解的先验知识来调整,这本身是一个超参数调优问题。


扩展方法二:结合域分解——有限基PINNs

核心思想:采用“分而治之”的策略。将全局复杂的优化问题,分解为多个子域上较简单的、耦合的优化问题。

早期方法(扩展PINNs):为每个非重叠的子域分配一个独立的神经网络,并在损失函数中添加界面连续性条件作为软约束。问题在于,训练后界面处常出现不连续的跳跃。

改进方法(有限基PINNs, FBPINNs)

  1. 使用重叠的子域分解。
  2. 将解表示为所有子域网络输出的加权和:
    U(x) = Σ_i w_i(x) * N_θ_i(x)
    其中 w_i(x) 是定义在第 i 个子域上的光滑窗函数(在子域外为零),N_θ_i 是该子域的神经网络。
  3. 关键优势:通过数学构造,解 U(x) 在整个域上自动连续可微,无需在损失函数中添加额外的界面约束。可以像训练标准PINN一样,仅使用PDE残差和边界损失进行训练。

其他优势

  • 克服谱偏差:在每个子域内,对输入坐标进行归一化,将子域内可能的高频函数“拉伸”成网络眼中的低频函数。
  • 计算高效:每个子域网络可以非常小(例如1层,8个神经元),因为只需学习局部简单函数。总体计算量远小于训练一个庞大的全局网络。
  • 高度并行:子域网络可以分配到不同的GPU上进行并行训练,只需在重叠区域进行简单的通信,非常适合大规模扩展。
  • 与FEM类比:可以理解为用小型神经网络作为局部基函数,继承了有限元方法的思想,但基函数更灵活。

示例:FBPINNs在求解多尺度波动方程(多个不同频率源)时,表现出比标准PINN更稳定、更快速的收敛,并能扩展到数万个并行子域网络。


其他重要扩展方向概览

PINNs的研究领域非常活跃,有数百种扩展方法。以下是一些重要的方向:

  • 求解更复杂的方程:分数阶微分方程、随机偏微分方程等。
  • 使用不同的方程形式:在损失函数中使用变分形式(弱形式),使其更接近有限元方法。
  • 不确定性量化:贝叶斯PINNs,将权重视为分布,可以给出解的置信区间,特别适用于反问题。
  • 网络架构创新:除傅里叶特征外,还有自适应激活函数、小波层、SIREN(正弦激活网络)等。
  • 优化算法改进:设计专门针对PINNs优化的算法,如基于NTK理论的优化器、因果训练策略等。
  • 软件生态:出现了许多强大的PINNs库,如NVIDIA Modulus、DeepXDE、SciANN等。

两个扩展案例

案例一:贝叶斯PINNs

目标:将PDE求解从确定性任务转变为概率性任务。给定边界条件和PDE源项的噪声观测数据,推断解的后验概率分布,而不仅仅是单个解。

方法

  1. 假设神经网络权重服从某个先验分布(如高斯分布)。
  2. 假设观测数据在给定网络输出时,服从以网络输出为均值的高斯分布(似然)。
  3. 使用马尔可夫链蒙特卡洛等方法,从权重和数据的后验分布中采样。

结果:可以获得解的均值估计以及不确定性范围。当观测数据噪声增大时,解的不确定性区间也会相应变宽。这为基于不确定性的决策提供了信息。

案例二:小波编码器-解码器PINN

动机:针对弹性波方程等具有波动特性的解,将物理先验融入网络架构。

方法

  1. 编码器:一个全连接网络,输入坐标,输出一组小波参数(如位置、尺度、频率)。
  2. 小波求和:根据这些参数计算一系列小波函数,并求和。
  3. 解码器:另一个全连接网络,对小波求和的结果进行非线性变换,得到最终解。

思想:用神经网络学习解的“波形成分”(小波参数),而不是直接学习像素/点值。这为网络提供了更适合波动问题的表示空间。

结果:在弹性波方程模拟中,这种定制化架构比标准全连接PINN误差更低,收敛更好。


总结

本节课我们一起深入探讨了物理信息神经网络在收敛性扩展性方面的核心挑战及其扩展方法。

  • 改善收敛性:我们介绍了硬边界条件自适应权重自适应采样三种策略,它们通过不同方式缓解了损失函数中各项间的竞争,引导优化过程更有效地进行。
  • 提升扩展性:为了应对多尺度高频率问题,我们学习了傅里叶特征网络来缓解神经网络的谱偏差;并深入探讨了有限基PINNs这一基于域分解的强大框架,它通过“分而治之”和并行计算,显著提升了PINNs处理复杂大规模问题的能力。
  • 广阔的研究图景:我们还简要浏览了PINNs的其他众多扩展方向,如贝叶斯PINNs、定制化网络架构等,表明这是一个充满活力且快速发展的领域。

尽管标准PINNs存在局限性,但蓬勃发展的研究正在不断提出创新的解决方案。理解这些方法及其背后的思想,将帮助我们根据具体问题选择合适的工具,推动科学机器学习在更复杂、更真实的场景中的应用。

008:物理信息神经网络 – 理论第一部分 🧠

在本节课中,我们将要学习物理信息神经网络的理论基础。我们将探讨PINNs为何有效,以及为何有时会失效。课程将从回顾PINNs的基本概念和算法开始,然后深入分析其背后的理论机制,包括可行性、稳定性以及误差估计。


回顾与符号定义

上一节我们介绍了PINNs在求解偏微分方程方面的应用。本节中,我们来看看如何用更精确的数学语言来描述PINNs,为理论分析做准备。

我们关注PDE的正问题。目标是近似求解以下抽象偏微分方程的解:
公式: D(u) = f

其中:

  • D 是一个微分算子。
  • u 是PDE的解,属于某个函数空间 X
  • f 是输入(包含边界/初始条件),属于某个函数空间 Y
  • 这些函数定义在某个域 𝒟 上(可以是空间或时空域)。

一个具体的例子是热方程:
公式: ∂u/∂t - Δu = f


PINNs算法简述

PINNs使用深度神经网络来近似PDE的解 u

一个深度神经网络 u_θ 定义为一系列层的复合:
公式: u_θ(y) = (σ_L ∘ A_L ∘ ... ∘ σ_1 ∘ A_1)(y)
其中每一层的仿射变换为 A_k(z) = W_k z + b_kσ_k 是光滑的激活函数(如双曲正切)。参数 θ 包含所有权重 W_k 和偏置 b_k

PINNs的目标是找到参数 θ,使得神经网络 u_θ 近似真实解 u。它通过最小化PDE残差的某个范数来实现,而无需真实解 u 的标签数据。

PDE残差定义为:
公式: ℛ_θ = D(u_θ) - f

我们最小化该残差的 L^p 范数作为损失函数。在实践中,我们通过数值积分(求积法)来近似这个积分。损失函数为:
公式: ℒ(θ) ≈ ∑_{i=1}^N w_i |D(u_θ(y_i)) - f(y_i)|^p
其中 {y_i} 是域 𝒟 中的求积点,{w_i} 是对应的权重。然后使用随机梯度下降等优化算法来最小化 ℒ(θ)


理论核心问题

尽管PINNs在实践中取得了一些成功(例如在高维热方程中误差随维度线性增长,而非指数增长),但它们有时也会失败。这就引出了核心的理论问题:PINNs何时有效?为何有效?又为何会失效?

我们可以通过一个误差传递的框架来系统分析这个问题。我们关心三种误差:

  1. 总误差 ℰ_T:神经网络近似解与真实解之间的误差。这是我们最终想最小化的量。
    公式: ℰ_T = ||u_θ - u||
  2. 泛化误差/残差 ℰ_G:PDE残差的范数。这是PINNs在训练中直接控制的量(的连续版本)。
    公式: ℰ_G = ||D(u_θ) - f|| = ||ℛ_θ||
  3. 训练误差 ℰ_T^*:损失函数的 p 次方根,即泛化误差的离散(求积)近似。
    公式: ℰ_T^* ≈ [ℒ(θ)]^{1/p}

我们的目标是:通过使训练误差 ℰ_T^* 变小,能否保证总误差 ℰ_T 也变小?这需要回答三个层次的问题:

问题一:可行性

是否存在神经网络参数 θ,使得训练误差 ℰ_T^* 和泛化误差 ℰ_G 在理论上可以任意小?否则我们的优化问题可能是无解的。

问题二:从训练误差到泛化误差

如果我们通过优化得到了一个小的训练误差 ℰ_T^*,这是否意味着泛化误差 ℰ_G 也小?这关系到求积近似的精度。

问题三:从泛化误差到总误差

如果泛化误差 ℰ_G(即PDE残差)很小,这是否意味着总误差 ℰ_T 也很小?这关系到PDE本身的性质。

接下来,我们将逐一探讨这些问题。


问题一:可行性分析

首先,我们需要确认问题在理论上是可解的,即存在神经网络能使误差任意小。

PDE的解 u 通常是光滑的(具有一定阶数的导数)。PINNs的残差可以估计为:
公式: ℰ_G = ||D(u_θ) - f|| ≤ C * ||u_θ - u||_{W^{s,p}}
其中 ||·||_{W^{s,p}} 是索伯列夫范数,要求函数本身及其直到 s 阶的导数都接近,阶数 s 取决于微分算子 D 的阶数。

因此,要使残差 ℰ_G 小,只需要存在神经网络 u_θ,使其在足够高阶的索伯列夫范数下逼近光滑的真实解 u。这正是通用近似定理的推广形式:对于光滑函数,存在神经网络不仅可以逼近函数值,还可以同时逼近其各阶导数。这意味着存在 θ 使 ℰ_G 任意小。

对于训练误差 ℰ_T^*,它是积分 ℰ_G 的数值近似。只要被积函数(残差)足够光滑,并且使用足够多的求积点(例如蒙特卡洛方法),数值积分误差就可以任意小。因此,存在 θ 和足够多的求积点,使得 ℰ_T^* 也可以任意小。

结论:PINNs所求解的问题在理论上是可行的,并非在“干草堆里找不存在的针”。


问题三:从泛化误差到总误差(稳定性)

现在假设我们已经有了一个小的泛化误差 ℰ_G,如何推导出总误差 ℰ_T 也小?这依赖于PDE的一个关键性质:强制性

强制性本质上是PDE解算子的稳定性。考虑两个PDE:

  1. D(u) = f (原问题)
  2. D(ū) = f̄ (扰动后的问题)

强制性是指,如果输入 f 很接近,那么输出 uū 也会很接近:
公式: ||u - ū|| ≤ C * ||f - f̄||

如何将此应用于PINNs?注意到神经网络 u_θ 满足的方程是:
公式: D(u_θ) = f + ℛ_θ
这正是原PDE (D(u)=f) 的一个扰动,扰动项正是残差 ℛ_θ。将强制性性质应用于 u (真实解) 和 u_θ (神经网络解),我们得到:
公式: ℰ_T = ||u_θ - u|| ≤ C * || (f + ℛ_θ) - f || = C * ||ℛ_θ|| = C * ℰ_G

这个不等式至关重要!它表明,只要PDE具有强制性,最小化PDE残差(ℰ_G)就能直接保证总误差(ℰ_T)变小。这是PINNs能够工作的一个核心机制。


问题二:从训练误差到泛化误差(求积误差)

在实践中,我们无法直接计算连续的泛化误差 ℰ_G,只能通过有限个求积点计算训练误差 ℰ_T^*。那么,小的 ℰ_T^* 能否代表小的 ℰ_G

这属于数值分析中的求积误差估计。对于许多求积规则(如蒙特卡洛),有如下形式的误差界:
公式: ℰ_G ≤ ℰ_T^* + C_q * N^{-α}
其中 N 是求积点数量,α > 0 是收敛速率(例如蒙特卡洛的 α = 1/2),C_q 是与神经网络光滑性相关的常数。

这个不等式告诉我们:

  1. 我们需要成功训练网络,使训练误差 ℰ_T^* 尽可能小。
  2. 我们需要使用足够多 (N 足够大) 的求积点,以使求积误差项 C_q * N^{-α} 可忽略。

当这两点都满足时,我们就能保证泛化误差 ℰ_G 很小。


理论框架总结

本节课中我们一起学习了分析PINNs的理论框架。我们可以将成功运行PINNs的条件总结为以下三步流程:

  1. 成功优化:通过训练算法,找到使训练损失 ℰ_T^* 足够小的神经网络参数 θ
  2. 充分采样:使用足够多的求积点 N,以确保离散的训练误差能够代表连续的泛化误差,即 ℰ_G 也小。
  3. PDE稳定性:所求解的PDE需具有强制性等稳定性条件,从而能将小的残差 ℰ_G 转化为小的总误差 ℰ_T

这个框架也清晰地指出了PINNs可能失败的几种模式:

  • 优化失败:无法将训练误差降到足够低(例如陷入局部极小值)。
  • 采样不足:求积点太少,导致求积误差主导。
  • 问题病态:PDE缺乏强制性或常数 C 非常大,导致残差的小变化引起解的大变化。

在下一讲中,我们将通过具体例子,来考察这些理论条件在实际中是否满足,并深入探讨PINNs面临的挑战,如“频谱偏差”等。


本节课中我们一起学习了 PINNs理论分析的基石。我们明确了评估PINNs性能需要关注的三种误差,并建立了从可优化的训练误差,到PDE残差,最终到我们关心的解的总误差之间的理论联系。理解这个基于可行性求积逼近PDE强制性的框架,是诊断和改善PINNs应用的关键。

009:物理信息神经网络 - 理论(第二部分)🚀

在本节课中,我们将深入探讨物理信息神经网络的理论基础,特别是理解PINNs何时有效、何时失效。我们将通过具体的偏微分方程例子,分析其成功与失败背后的数学原理,并探讨训练过程中的关键挑战。


概述

上一节我们介绍了分析PINNs的理论框架,其核心在于三个关键条件:精确解的光滑性、PDE的稳定性(强制性)以及足够的训练点。本节中,我们将通过具体的PDE实例来检验这些条件,并深入探讨训练过程本身的内在挑战。


回顾理论框架

首先,我们快速回顾上一讲的核心理论框架。对于一个抽象的PDE问题:

[
\mathcal{D}(u) = f
]

其中 (\mathcal{D}) 是微分算子,(f) 包含了系数、初始条件和边界条件等信息。我们的目标是给定 (f),求解 (u)。

我们使用一个参数为 (\theta) 的神经网络 (u_\theta) 来近似解。由于没有直接的监督标签,我们通过计算PDE残差来构建损失函数:

[
\mathcal{L}(\theta) = \int_\Omega |\mathcal{D}(u_\theta) - f|^2 , dx
]

在实践中,我们通过数值积分(如蒙特卡洛采样)来近似这个积分,并使用梯度下降等优化算法最小化损失。

理论分析表明,总误差(近似解与真实解之差)可以通过以下三个量来界定:

  1. 训练误差:与损失函数相关。
  2. PDE残差:也称为泛化误差。
  3. 总误差:近似解与真实解之间的差异。

只要满足三个条件,PINNs就能成功:

  1. 精确解的光滑性:确保神经网络能够以任意精度逼近真实解。
  2. PDE的稳定性(强制性):确保小的PDE残差能导致小的总误差。
  3. 足够的采样点:确保通过数值积分计算的训练误差能够准确反映PDE残差。

最终,我们得到一个误差估计式,它表明总误差受训练误差、采样点数量以及PDE本身性质的影响。


成功案例:线性抛物型方程

现在,我们来看看理论框架在具体PDE上的应用。首先是一类重要的线性抛物型方程,它包含了热传导方程和金融中的布莱克-斯科尔斯方程等。

这类方程的一般形式为:

[
u_t = \text{Tr}(\sigma \sigma^T \text{Hess}_x u) + \mu \cdot \nabla_x u
]

当漂移项 (\mu = 0) 且波动率 (\sigma) 为单位矩阵时,我们就得到了标准的热传导方程 (u_t = \Delta u)。

理论分析要点

对于这类方程,理论分析给出了积极的结论:

  • 逼近性:存在规模多项式依赖于维度(而非指数依赖)的神经网络,能够以任意精度逼近真实解。这从原理上克服了“维数灾难”。
  • 稳定性:这类PDE具有强稳定性。我们可以通过一个简单的论证来说明:如果两个函数 (u) 和 (\hat{u}) 满足相同的初边值条件,但 (\hat{u}) 对应的PDE存在残差 (r),那么它们的差 (w = u - \hat{u}) 满足一个受迫热方程。通过能量估计和Gronwall不等式,可以证明:
    [
    |w(t)|{L^2} \leq C \int_0^t |r(s)| , ds
    ]
    这意味着只要残差 (r) 小,误差 (w) 也小。
  • 采样误差:使用蒙特卡洛采样时,PDE残差与训练误差之间的差异以 (1/\sqrt{N}) 的速率衰减((N) 为采样点数),且此速率与维度无关。

数值实验验证

理论预测在实践中得到了验证:

  • 对于热传导方程和布莱克-斯科尔斯方程,即使在高达100维的情况下,PINNs也能在合理时间内(例如一小时)获得约1-2%的误差,误差随维度增长非常缓慢(甚至低于线性增长)。
  • 训练误差与总误差之间存在明确的相关性:训练误差小,则总误差也小。误差大致按训练误差的平方根缩放,这与理论估计一致。

另一个成功案例是辐射传输方程,这是一个在气候、天体物理等领域重要的七维方程。传统数值方法求解极其昂贵,但PINNs在六维简化问题上,仅用一小时就达到了2%的误差,而传统方法可能需要数天。

结论:对于这类具有良好稳定性的线性或轻度非线性PDE,只要能够有效降低训练误差,PINNs就能提供高维空间中的高效近似解。


挑战案例:非线性方程与复杂解

然而,并非所有PDE都如此“友好”。当解具有复杂结构或方程具有强非线性时,PINNs会遇到挑战。

纳维-斯托克斯方程

流体力学的基本方程——纳维-斯托克斯方程是一个著名的非线性PDE系统:

[
u_t + u \cdot \nabla u = -\nabla p + \nu \Delta u, \quad \nabla \cdot u = 0
]

  • 理论分析:即使解是光滑的,误差估计中的常数项 (C) 会依赖于解本身的性质,特别是涡量 (\omega = \nabla \times u)。
    [
    \text{总误差} \leq C(|u|, |\omega|) \times \text{(训练误差项)}
    ]
    如果流动变得复杂,涡量很大,这个常数 (C) 会变得非常大,使得即使训练误差很小,总误差也可能很大。
  • 数值实验:对于简单的涡旋流动,PINNs可以很好地近似。但是,随着涡旋强度增加、结构变复杂,近似质量会显著下降。对于更复杂的流动(如高雷诺数下的圆柱绕流),目前的PINNs方法难以处理。

粘性伯格方程

这个方程结合了非线性传输和扩散效应:

[
u_t + u u_x = \nu u_{xx}
]

  • 理论分析:误差估计中的常数项依赖于速度梯度 (|u_x|)。我们知道,当粘性系数 (\nu) 很小时,梯度可能很大(量级约为 (1/\sqrt{\nu}))。
  • 数值实验:当 (\nu) 较大时,PINNs近似效果很好。但当 (\nu) 非常小(趋于0)时,方程趋向于无粘的冲击波形成。在这种情况下,PINNs完全无法捕捉解的结构,误差急剧增大。然而,对于另一种解(稀疏波),即使 (\nu) 很小,PINNs也能很好近似,因为其梯度没有剧烈增长。

核心教训:PINNs的成功与否强烈依赖于PDE解的性质。当解出现大梯度、强涡量或其他奇异结构时,理论估计中的常数会膨胀,导致方法失败。在应用PINNs时,必须评估所解问题的内在复杂性。


打开黑箱:训练动力学的挑战

到目前为止,我们假设“训练误差可以做得足够小”。但这是一个非平凡的假设。训练一个神经网络最小化物理信息损失本身就是一个挑战。本节中,我们尝试从理论上理解训练过程。

梯度下降与线性化

我们使用梯度下降及其变种来优化损失函数 (\mathcal{L}(\theta))。更新规则为:
[
\theta_{k+1} = \theta_k - \eta \nabla_\theta \mathcal{L}(\theta_k)
]

为了理解训练动态,我们考察神经网络函数本身在训练过程中的变化,而非参数。围绕初始参数 (\theta_0) 进行泰勒展开,并经过推导(详见相关论文),可以得到一个简化的梯度下降动态。

在训练初期,如果神经网络的海森矩阵(二阶导数)很小,即函数行为接近线性,那么训练动态主要由一个格拉姆矩阵 (G) 主导。这个阶段称为神经正切核(NTK)区域

关键发现:条件数问题

分析表明,收敛速度取决于格拉姆矩阵 (G) 的条件数 (\kappa(G))。条件数越大,收敛越慢。

进一步分析发现,对于物理信息训练,这个格拉姆矩阵 (G) 在数学上关联于一个微分算子 (\mathcal{A}):
[
\mathcal{A} = \mathcal{D}^* \mathcal{D}
]
其中 (\mathcal{D}) 是PDE中的微分算子,(\mathcal{D}^*) 是其伴随算子。算子 (\mathcal{A}) 被称为赫尔米特平方

  • 与监督学习的对比:在监督学习中,损失函数直接比较网络输出与标签,相当于 (\mathcal{D}) 是恒等算子 (I),因此 (\mathcal{A} = I^* I = I),条件数相对良好。
  • 物理信息学习的挑战:在物理信息学习中,(\mathcal{D}) 是微分算子(如拉普拉斯算子 (\Delta))。那么 (\mathcal{A} = \Delta^* \Delta)。对于泊松方程((-\Delta u = f)),由于 (-\Delta) 是自伴的,我们有 (\mathcal{A} = (-\Delta)^2),即双拉普拉斯算子
    • 拉普拉斯算子的特征值按 (k^2) 增长((k) 为波数)。
    • 双拉普拉斯算子的特征值则按 (k^4) 增长。
    • 因此,条件数 (\kappa(\mathcal{A})) 随问题中高频模式(大 (k))的数量急剧恶化(呈 (k^4) 增长)。这使得训练变得极其缓慢,甚至无法收敛。

根本原因:物理信息训练的本质是强制网络满足微分方程,这引入了微分算子本身的条件数。高阶导数会导致更严重的条件数问题。

实例说明

  1. 泊松方程:即使使用简单的傅里叶特征模型(而非深度网络)去求解 (u_{xx} = f),当解包含高频模式时,无预处理训练完全失败。条件数随模式数 (L) 呈 (L^4) 增长。
  2. 对流方程:对于方程 (u_t + \beta u_x = 0),对流速度 (\beta) 越大,条件数越差。当 (\beta = 30\pi) 时,无预处理训练无法得到有意义的解。

解决方案:预处理

改善训练的关键是预处理。思路是修改梯度下降更新式:
[
\theta_{k+1} = \theta_k - \eta , P , \nabla_\theta \mathcal{L}(\theta_k)
]
其中 (P) 是一个预处理矩阵,理想情况下近似于 (G^{-1}) 或 (\mathcal{A}^{-1})。

在上述简单例子中,由于我们知道条件数恶化的精确形式(与 (k^4) 或 (\beta^2) 相关),可以设计精确的预处理器。应用预处理后,训练在几十步内就能达到机器精度。

当前局限:对于复杂的非线性PDE(如纳维-斯托克斯方程),我们无法精确知道或轻松计算所需的预处理器。如何为复杂问题设计有效的预处理器,是一个活跃的研究领域。


总结

本节课中,我们一起学习了PINNs理论更深入的内容:

  1. 成功条件:对于线性抛物型方程等具有良好稳定性的PDE,PINNs理论完备,并能有效克服维数灾难,在高维问题上表现出色。
  2. 失败模式:当PDE的解具有大梯度、强涡量等复杂结构,或方程本身强非线性时,误差估计中的常数项会膨胀,导致PINNs失败。这源于PDE本身的性质。
  3. 训练挑战:物理信息训练过程本身存在内在挑战。由于损失函数涉及微分算子,训练动态的条件数取决于算子 (\mathcal{D}^* \mathcal{D}) 的条件数,这通常比监督学习差得多,尤其是对于包含高频模式的问题,会导致训练缓慢或失败。
  4. 改进方向预处理是加速和稳定训练的关键技术。对于简单问题,可以设计精确的预处理器;对于复杂问题,如何设计有效的近似预处理器是当前的研究重点。

总而言之,PINNs为高维PDE求解提供了强大的新工具,但其应用需要谨慎。必须考虑PDE和解的数学特性,并意识到训练过程可能存在的数值困难。在下一讲中,我们将探讨当单纯物理信息不足时,如何结合数据来增强模型。

010:算子学习导论(第一部分) 🧠

在本节课中,我们将要学习一种新的、用于求解偏微分方程的数据驱动方法——算子学习。我们将探讨其核心概念、基本框架,以及它与之前学习的物理信息神经网络有何不同。

课程回顾与背景

上一节我们介绍了物理信息神经网络及其优缺点。PINNs 在数据稀缺时表现良好,但其训练过程可能因微分算子条件数等问题而变得困难和昂贵。此外,对于解具有多尺度、高频特征的复杂偏微分方程,PINNs 可能面临挑战。

因此,当有更多数据可用时,我们需要探索替代方案。从本节课开始,我们将视角转向监督学习,即利用现有数据来求解偏微分方程。

求解偏微分方程意味着什么?

在深入数据驱动方法之前,让我们重新思考:求解一个偏微分方程究竟意味着什么?

考虑一个简单的椭圆型偏微分方程原型:

[
-\nabla \cdot (a(x) \nabla u(x)) = f(x), \quad x \in \Omega
]

其中,u(x) 可以是温度、压力等物理量;a(x) 是系数(如热导率、渗透率);f(x) 是源项。

我们可以将偏微分方程视为一个系统:它接收输入,经过处理,产生输出。

  • 输入:系数 a(x) 和源项 f(x)(以及边界条件、定义域等)。
  • 输出:方程的解 u(x)

因此,求解这个偏微分方程,等价于找到或计算一个解算子 G,它完成了从输入函数到输出函数的映射:

[
G: a \mapsto u
]

关键在于,这里的输入 a(x) 和输出 u(x) 都是函数,是无限维的对象。解算子 G 是将一个无限维空间映射到另一个无限维空间的算子。这是算子学习与经典机器学习(处理有限维向量)的根本区别。

另一个例子是时间依赖的偏微分方程,如可压缩欧拉方程。其解算子将初始条件函数映射到未来某个时刻的解函数。这同样是一个无限维到无限维的映射。

我们可以将问题抽象化:设输入函数空间为 X,输出函数空间为 Y,存在一个由偏微分方程定义的解算子 G: X -> Y。我们的任务是基于数据样本来学习这个算子 G

算子学习问题定义

假设我们有一个输入函数的数据分布 μ。我们从该分布中采样得到 N 个输入函数 {a_i},并通过(可能是数值的或实验的)方法得到对应的输出函数 {u_i = G(a_i)},可能带有噪声。

给定数据集 {a_i, u_i}_{i=1}^N,算子学习的目标就是学习解算子 G

一种“取巧”的方法:参数化PDE

直接处理无限维映射是一个挑战。一种“取巧”的方法是限制输入/输出函数的空间,将其投影到有限维,从而将算子学习问题转化为标准的函数逼近问题。

具体做法是,假设我们的输入函数来自一个由有限个参数描述的特定函数族。例如,输入函数是有限项正弦级数的和:

[
a(x) = \sum_{k=1}^{10} \alpha_k \sin(k\pi x), \quad \alpha_k \in [-1,1]
]

这样,输入就由10维参数向量 α 完全决定。同样,我们可以将输出解 u(x,t) 视为关于空间 x、时间 t 和参数 α 的函数。于是,无限维的算子 G 被简化为一个从有限维参数空间(如 R^{12},包含时间和参数)到输出值(如 R)的函数

以下是这种方法的一个工程实例:

  • 问题:飞机机翼的气动外形设计。
  • 参数化:机翼截面(翼型)的形状由一组(如20-50个)设计参数 y 控制。
  • 求解目标:对于给定的形状参数 y,计算绕该翼型的流场(速度、压力等分布),进而计算升力、阻力等关键指标。
  • 转化:问题转化为学习一个函数 L(t, x, y) -> (流场物理量),其中输入是空间坐标 x 和形状参数 y,输出是物理场。这是一个标准的回归问题。

一旦完成这种转化,我们就可以使用熟悉的普通深度神经网络来学习这个映射。网络接收拼接后的输入向量(如 [t, x, y]),通过带有权重、偏置和激活函数(如ReLU)的层,输出预测值。我们使用随机生成的参数样本进行模拟,获得训练数据,然后通过优化损失函数(如均方误差)来训练网络。

理论考量与挑战

从理论上讲,只要目标函数是连续的(甚至可测的),深度神经网络的通用近似定理保证了我们可以用足够大的网络以任意精度逼近它。

然而,我们需要关注几个误差来源:

  1. 近似误差:网络结构逼近真实映射的能力。对于一般的函数,逼近误差可能随维度 d 指数增长(维度灾难)。但幸运的是,偏微分方程的解通常具有特殊的规律性和可压缩性,使得其逼近误差的缩放比例远优于指数级(可能是线性或多项式级),这缓解了维度灾难。
  2. 优化误差:训练过程中未能找到全局最优解带来的误差。
  3. 泛化误差:模型在未见数据上的表现。当训练数据是随机采样时,泛化误差通常以 ~ C / sqrt(N) 的速率衰减,其中 C 是与问题复杂度相关的常数,N 是样本数。

核心挑战在于数据稀缺性。为了达到1%的误差,若 C≈1,则需要约 N ≈ 10000 个样本。在科学与工程中,每个样本(即一次高保真物理模拟)的计算成本极高(从几分钟到数千小时不等)。因此,我们通常处于一个数据相对贫乏的 regime,这与图像、文本等领域的大数据成功范例形成对比。

总结与展望

本节课中我们一起学习了算子学习的基本概念。我们认识到求解偏微分方程本质上是寻找一个将无限维输入函数映射到无限维输出函数的解算子。为了应用现有的深度学习工具,我们介绍了一种通过参数化将问题“降维”到有限维空间的取巧方法,并将其转化为标准的神经网络回归问题。

然而,这种方法受限于数据获取的高昂成本,我们往往只能获得少量样本。在下一讲中,我们将探讨当这种“取巧”方法因数据不足而受限时,如何发展更先进的算子学习方法,以直接且高效地处理无限维的函数到函数映射。

011:算子学习导论(第二部分)🚀

在本节课中,我们将继续学习算子学习。上一节我们介绍了算子学习的基本概念和参数化偏微分方程方法。本节中,我们将探讨如何改进数据采样策略以应对“数据饥渴”问题,并介绍如何利用训练好的算子模型进行下游任务,如不确定性量化和形状优化。最后,我们将深入探讨参数化方法的局限性,并引出构建真正能处理函数到函数映射的“神经算子”的必要性。

回顾与挑战:数据需求问题 🔄

上一节我们介绍了参数化偏微分方程的方法。其核心思想是将无限维的函数空间映射问题,通过有限个设计参数(例如,描述机翼形状的20个参数)近似为有限维问题。我们进行了初步的理论分析,发现即使一切顺利,总误差的收敛速度受限于蒙特卡洛采样率。

总误差 大致遵循以下规律:

总误差 ∝ 1 / √N

其中 N 是训练样本数量。

这意味着,为了获得1%(即 10^-2)的误差,我们需要大约 N = 10,000 个样本。这带来了巨大的数据生成成本,因为每个样本(即一次高保真CFD模拟)可能需要数十分钟。

这种高数据需求主要源于随机采样。在图像或文本领域,数据通常是随机收集的。然而,在科学计算中,我们并非随机地求解偏微分方程,而是有目的地进行设计。因此,我们可以利用数据的结构来设计更高效的采样策略。

改进采样:低差异序列 📊

为了减少所需样本数量,我们可以采用更具结构性的采样方法,而不是纯粹的随机采样。一种有效的方法是使用低差异序列

以下是低差异序列与随机采样在二维单位正方形中的对比:

  • 随机采样(蓝点):点分布不均匀,存在聚集和空白区域。无法保证每个小方格内都有样本点。
  • 低差异序列(橙星,如Sobol序列):点分布更加均匀、分散,能更好地覆盖整个区域。它们具有拟均匀分布的性质。

低差异序列是拟蒙特卡洛方法的基础,就像随机点是蒙特卡洛方法的基础一样。在代码中,我们可以像调用随机数生成器一样,调用拟随机数生成器(如Sobol序列、Halton序列)来生成这些点。

低差异序列的优势

使用低差异序列进行采样,并在满足一定条件(如目标映射具有有界Hardy-Krause变差,激活函数光滑)下,总误差的收敛速度可以得到显著改善。

误差收敛率对比

  • 随机采样误差 ∝ 1 / √N
  • 低差异序列采样误差 ∝ (log N)^D / N,其中 D 是参数维度。

关键改进在于分母从 √N 变成了 N。虽然存在一个与维度 D 相关的对数项 (log N)^D,但在维度不太高(例如 D < 50)时,1/N 的主导作用能带来巨大收益。

实例说明
为了达到1%的误差:

  • 随机采样需要约 10,000 个样本。
  • 使用低差异序列可能只需要约 100 个样本。

当每个样本的生成成本很高时(例如10分钟/样本),这种数据量的减少意味着计算时间从超过160小时缩短到约17小时,节省是巨大的。

应用实例:机翼绕流预测 ✈️

让我们回到机翼绕流的例子。这里,输入是20个描述机翼形状的参数,输出是整个流场(或升力、阻力等观测量)。

  • 训练设置:使用128个训练样本(通过高精度CFD模拟生成,每个约40分钟),训练一个中等规模的神经网络(约10,000参数)。
  • 结果:神经网络在预测升力、阻力乃至整个流场时,达到了1-2%的误差。
  • 推理速度:训练完成后,使用神经网络进行预测(推理)的速度极快:
    • 预测升力/阻力:约 10^-5 秒。
    • 预测整个流场:约0.1秒。
  • 对比实验:如果使用随机采样代替Sobol序列采样,预测误差会显著增大(例如阻力误差达到23%),这凸显了结构化采样的重要性。

这种训练好的、能够快速替代昂贵物理仿真的模型,被称为代理模型

下游任务一:不确定性量化 ❓

拥有一个准确的代理模型后,我们可以高效地执行下游任务。第一个任务是不确定性量化

问题描述:在实际工程中,系统的输入参数(如来流马赫数、攻角)并非精确值,而是存在不确定性(通常用概率分布描述)。我们关心的是,这种输入的不确定性如何通过物理模型(即解算子)传播到输出(如升力、阻力)。

传统方法(蒙特卡洛):从输入分布中抽取大量样本(如 M=10,000),对每个样本运行一次昂贵的仿真,然后统计输出的分布(如直方图)。这需要 M 次仿真,成本极高。

基于代理模型的方法

  1. 使用少量样本(如 N=128)训练一个准确的神经网络代理模型。
  2. 从输入分布中抽取大量样本(如 M=10,000)。
  3. 使用训练好的代理模型(推理速度极快)对这 M 个样本进行预测。
  4. 基于这 M 个快速预测结果,统计输出的分布。

优势

  • 精度:由于代理模型本身很准确,得到的统计结果与高保真方法接近。
  • 速度:即使包含训练时间,相比直接使用蒙特卡洛方法,也能获得两个数量级的加速。即使与更先进的拟蒙特卡洛方法相比,也能有一个数量级的加速。

下游任务二:偏微分方程约束优化 🎯

另一个关键下游任务是形状优化。以机翼设计为例:

目标:在保持升力不变(或在一定范围内)的前提下,最小化机翼的阻力。
数学形式

最小化 J(y) = C_D(y) + λ_1 * (C_L(y) - C_{L,ref})^2 + λ_2 * (结构约束)

其中 y 是形状参数,C_D 是阻力系数,C_L 是升力系数。

传统梯度优化方法

  1. 计算目标函数 J(y) 的梯度 ∇J(y)
  2. 更新参数:y_{k+1} = y_k - η * ∇J(y_k)
  3. 重复直到收敛。
    难点在于梯度计算。通常需要求解伴随方程,每次迭代都需要运行正演和伴随仿真,在二维情况下可能就需要一小时,在三维下成本无法承受。

基于代理模型的优化

  1. 训练一个能准确预测 C_D(y)C_L(y) 的神经网络代理模型。
  2. 优化过程在代理模型上进行。计算梯度只需对神经网络进行反向传播,成本极低。
  3. 利用快速的梯度计算,可以高效地运行优化算法(如梯度下降)。

挑战与改进:简单的随机或均匀采样可能无法在最优解所在的区域提供足够的训练数据,导致代理模型在该区域不准确,从而优化失败。解决方案是采用主动学习自适应采样策略:在优化过程中,迭代地增加对最优解潜在区域的采样,从而用更少的仿真次数获得更好的优化结果。

结果示例:通过这种基于代理模型和自适应采样的优化框架,仅使用约80次高保真仿真(用于训练代理模型),就找到了一个最优机翼形状,将阻力降低了近50%,而传统的优化方法需要超过4000次仿真才能达到类似效果。

参数化方法的局限性 🚧

尽管参数化方法在特定问题上很有效,但它存在根本性局限:

  1. 难以构造:好的参数化需要深厚的领域知识和工程经验,并非总是可得。
  2. 缺乏唯一性与泛化性:同一个物理对象可以有无数种参数化方式(例如,用20个基函数或30个基函数描述一个接近的形状)。在一个参数化下训练的模型,无法直接应用到另一个不同的参数化上,即使它们描述的对象非常相似。这违背了机器学习泛化的核心目标。

示例:一个在20维参数空间上训练的机翼流场预测模型,无法处理一个需要30维参数描述的、形状略有不同但物理上很接近的新机翼。因为输入维度都变了。然而,如果我们将机翼视为连续的函数(轮廓线),这两个形状在函数空间中是接近的。

因此,我们需要回归问题的本质:学习一个函数到函数的映射(即算子),而不是有限维向量到向量的映射。

迈向真正的算子学习:连续-离散等价性 🔗

要处理函数,我们必须在计算机上进行离散化。一个朴素的方法是:在网格上采样函数值作为输入向量,用CNN等网络处理,输出网格上的值,再插值回连续函数。

问题:这种方法学到的不是算子,而是特定离散化下的近似。如下图所示,在64x64网格上训练的模型,在更细(128x128)或更粗(32x32)的网格上测试时,误差会急剧增加,说明它没有学会独立于网格分辨率的底层规律。

解决方案核心:构建无混叠的神经算子
我们需要构建一种架构,使得无论在连续函数空间操作,还是在任何足够精细的离散网格上操作,其结果在数学上是等价的。这要求每个网络层都满足连续-离散等价性

框架

  • 编码器 E:将连续函数 f 映射到离散表示 v(如网格采样)。
  • 重构器 R:将离散表示 v 映射回连续函数 f(如 sinc 插值)。
  • 离散算子 G:在离散表示上进行的操作(如神经网络层)。

我们希望对于连续算子 L,有:L = R ∘ G ∘ E。这样,在离散域计算 G,就等价于在连续域计算 L。如果每一层都满足此性质,整个网络就成为一个表示等价的神经算子

关键例子:带限函数与 sinc 插值
对于一类重要的函数——带限函数(即其傅里叶展开中频率成分有限),存在完美的连续-离散等价性。

  • 采样定理:如果采样网格足够密(采样频率大于最高频率的两倍),则函数的连续形式与其在网格上的采样值包含完全相同的信息。
  • 编码 E:在网格点上采样。
  • 重构 R:使用 sinc 函数进行插值,可以无损失地恢复原函数。

在这个框架下,我们可以分析为何传统CNN不是表示等价的:
CNN的卷积核在不同分辨率的网格上操作时,作用于完全不同的像素值,其离散操作无法通过 RE 与某个唯一的连续卷积操作对应起来,因此会引入混叠误差。当网络有多层时,这些误差会累积,导致模型无法在不同分辨率间泛化。

总结 📝

本节课中我们一起学习了:

  1. 改进采样策略:使用低差异序列(如Sobol序列)可以显著减少训练算子模型所需的数据量,提高样本效率。
  2. 代理模型的应用:训练好的神经网络代理模型不仅能快速预测,还能高效赋能下游任务:
    • 不确定性量化:快速统计输入不确定性导致的输出分布。
    • 形状优化:结合自适应采样,能以极低成本完成昂贵的优化设计。
  3. 参数化的局限:参数化方法缺乏泛化性,难以应对不同的、非预定义的函数表示形式。
  4. 算子学习的正确路径:需要构建表示等价的神经算子。其核心是保证网络架构在连续函数空间和任何足够精细的离散网格上的操作是数学等价的,从而真正学会函数到函数的映射,并具备跨分辨率泛化的能力。我们以带限函数和sinc插值为例,说明了这一原理,并指出了传统CNN在此框架下的不足。

在接下来的课程中,我们将深入探讨如何构建这种具有连续-离散等价性的神经算子架构。

012:傅里叶神经算子

概述

在本节课中,我们将学习算子学习中的一个核心概念——连续-离散等价性,并深入探讨一种重要的神经网络架构:傅里叶神经算子。我们将理解为何传统的卷积神经网络在算子学习中存在局限性,以及FNO如何通过利用傅里叶变换来解决这些问题。


算子学习回顾与问题定义

上一讲我们介绍了算子学习的基本框架。我们面临的核心问题是学习一个算子 G,它将一个函数空间 X 映射到另一个函数空间 Y。具体来说,对于偏微分方程,输入可能是系数 a 和源项 f,输出是解 u

G: (a, f) → u

关键点在于,我们无法在有限维子空间上参数化这个算子,必须处理某种意义上的无限维或高维空间。

然而,由于计算限制,我们必须在离散层面工作。这就引出了一个核心矛盾:我们需要处理连续的函数空间,但计算只能在离散的网格上进行。因此,建立一个连续-离散等价的框架至关重要。


连续-离散等价框架:Reno表示等变神经算子

为了解决上述矛盾,我们引入Reno表示等变神经算子的框架。其核心思想是通过编码(Encoding)和重建(Reconstruction)操作,在连续空间和离散空间之间建立精确的对应关系。

以下是该框架的关键组成部分:

  • 编码器 E: 将无限维的连续函数映射到有限维的离散表示(例如,在网格点上采样函数值)。
  • 重建器 R: 将有限维的离散表示映射回无限维的连续函数空间(例如,使用sinc函数进行插值)。
  • 离散算子 G̃: 在离散空间(如网格)上操作的神经网络(如CNN或MLP)。

理想情况下,我们希望下图交换,即无论我们走哪条路径,结果都相同:

  1. 路径一(理想):直接在连续空间应用算子 G
  2. 路径二(实际):先编码(E),再应用离散算子(G̃),最后重建(R)。

如果两条路径等价,即 G = R ∘ G̃ ∘ E,那么我们说没有混叠误差。混叠误差 A 定义为:

A(G̃) = G - R ∘ G̃ ∘ E

我们的目标是设计 ER,使得在每一层网络运算中,混叠误差 A 都为零。这样,在离散层面学到的操作就能精确地反映连续层面的操作。


网格无关性与分辨率外推

一旦建立了连续-离散等价性,一个直接的好处就是网格无关性分辨率外推能力。

假设我们有两个不同的离散表示(网格)G̃‘,它们都通过各自的编码器 EE‘ 和重建器 RR‘ 与同一个连续算子 G 等价。

如果我们已经在网格 上训练好了模型,现在想在新的、更细的网格 G̃‘ 上评估,我们可以通过以下步骤实现:

  1. 将新网格 G̃‘ 上的数据,通过其重建器 R‘ 映射到连续空间。
  2. 在连续空间,通过编码器 E 映射回旧网格
  3. 在旧网格 上应用训练好的离散算子。
  4. 将结果通过重建器 R 映射回连续空间。
  5. 最后,通过编码器 E‘ 映射到新网格 G̃‘ 上。

这个过程可以形式化为:G̃‘ = E‘ ∘ R ∘ G̃ ∘ E ∘ R‘

由于整个框架是等价的,这个操作是精确的,从而实现了在不同分辨率网格间的无缝转换。


实例说明:带限函数与香农采样定理

为了更好地理解,我们来看一个一维例子。我们选择带限函数作为连续函数空间,即函数的傅里叶展开在某个截止频率 K 之外为零。

  • 编码 E: 在足够密集的网格点上对函数进行采样。根据香农采样定理,如果网格点密度至少是最高频率的两倍(奈奎斯特频率),那么采样值可以唯一确定原带限函数。
  • 重建 R: 使用sinc函数对采样值进行插值,可以完美重建原连续函数。
  • 离散算子 G̃: 在采样网格上定义的任何操作。

在这个设定下,只要离散算子 的设计能保持带限性质(即不产生高于截止频率 K 的新频率),那么连续-离散等价性就成立,混叠误差为零。在不同分辨率网格间转换时,我们只需进行“sinc插值 → 在旧网格上操作 → sinc插值”的流程。


为何卷积神经网络(CNN)不是真正的神经算子?

上一讲我们尝试用CNN解决算子学习问题,但发现在训练分辨率下表现良好,一旦改变分辨率(测试分辨率),性能就急剧下降。

原因在于,CNN的离散卷积操作不具备连续-离散等价性。CNN的卷积核是在特定网格上训练得到的。当网格改变时,同样的卷积核作用在了不同的物理位置上。

例如,在粗网格上,一个网格点代表其周围一个区域的平均;在细网格上,卷积核作用在了更精细的位置上,其接收到的输入值与原粗网格点不同,因此输出自然会产生误差。CNN没有内置的机制(如上述的sinc插值)来保证其操作在连续意义下的一致性,因此它学习到的是特定离散网格到特定离散网格的映射,而非函数到函数的映射


神经算子的通用框架

为了构建真正的神经算子,我们需要将普通神经网络的概念推广到无限维函数空间。一个标准的神经网络层可以写成:

z = σ(W * y + b)

其中 y 是输入向量,W 是权重矩阵,b 是偏置向量,σ 是非线性激活函数。

神经算子的目标是将输入和输出从向量推广为函数。因此,一个神经算子层 N 作用于函数 v(x),产生函数 w(x)

w(x) = N(v)(x)

我们需要对三个成分进行无限维推广:

  1. 偏置 b: 推广为偏置函数 b(x)。这很直接。
  2. 矩阵乘法 W*y: 推广为积分算子。在函数空间,线性算子通常表示为积分形式:
    ∫ κ(x, y) v(y) dy
    其中 κ(x, y) 是核函数。离散化后(例如用蒙特卡洛积分),这就变成了矩阵乘法。
  3. 激活函数 σ: 推广为逐点非线性激活。即:
    σ(w)(x) = σ(w(x))
    在每一个空间点 x 上独立地应用标量激活函数。

因此,一个基础的神经算子层可以表示为:
w(x) = σ( b(x) + ∫ κ(x, y) v(y) dy )

学习参数隐藏在核函数 κ(x, y) 和偏置函数 b(x) 中。


计算挑战与傅里叶神经算子(FNO)的引入

上述基础神经算子框架有一个严重的计算瓶颈:积分算子 ∫ κ(x, y) v(y) dy

离散化后,如果网格有 N 个点,计算该积分(矩阵乘法)的复杂度是 O(N²)。在 d 维空间中,N ~ m^d(m是每维点数),因此复杂度是 O(m^(2d)),随着维度指数增长,难以承受。

傅里叶神经算子 的核心思想是利用卷积定理来大幅降低计算成本,并同时提升网格无关性。

关键步骤是假设核函数是平移不变的,即 κ(x, y) = κ(x - y)。这样,积分算子就变成了卷积:
w(x) = (κ * v)(x) = ∫ κ(x - y) v(y) dy

根据卷积定理,函数卷积的傅里叶变换等于函数傅里叶变换的乘积:
ℱ(κ * v) = ℱ(κ) · ℱ(v)

因此,我们可以在傅里叶空间进行高效计算:

  1. 计算输入函数 v 的傅里叶变换 ℱ(v)
  2. 在傅里叶空间中,与一个可学习的傅里叶乘子 R(即 ℱ(κ) 的参数化形式)进行逐元素乘法。
  3. 将结果进行逆傅里叶变换,回到物理空间。

这样,昂贵的卷积运算被转换成了傅里叶变换、点乘和逆傅里叶变换。而傅里叶变换可以利用快速傅里叶变换O(N log N) 时间内完成,极大提升了效率。


FNO架构详解

一个完整的FNO层通常包含以下组件(为简洁,忽略层索引和偏置):

w = σ( ℱ⁻¹( R · ℱ(v) ) + W * v )

让我们分解一下:

  • 提升算子 P: 将低维的物理特征(如温度、压力)通过一个线性层或小型MLP映射到高维的隐藏特征空间。这为模型提供了更多可学习的特征通道。
  • 傅里叶层:
    • ℱ(v): 对输入函数进行FFT,得到傅里叶系数。
    • R · ℱ(v): 与可学习的复数张量 R(傅里叶乘子)相乘。R 通常只作用于保留的低频模式上,高频部分被截断,这既是降维也是正则化。
    • ℱ⁻¹(…): 进行逆FFT,回到物理空间。
  • 权重矩阵 W: 一个逐点操作的线性层,用于混合特征通道。它作用于物理空间,提供残差连接。
  • 激活函数 σ: 逐点非线性激活(如ReLU, GELU)。
  • 投影算子 Q: 在最后一层,将高维隐藏特征映射回目标输出维度。

通过堆叠多个这样的傅里叶层,FNO能够学习复杂的函数到函数的映射。


FNO的等变性(Reno性质)与局限

FNO的卷积部分(傅里叶层)在特定条件下满足连续-离散等价性。如果我们选择周期性带限函数作为函数空间,并且离散化满足奈奎斯特采样条件,那么傅里叶变换、截断低频、与乘子 R 相乘、再逆变换这一系列操作,在不同分辨率的网格之间是等变的。因为无论网格多细,我们最终都投影到相同的低频傅里叶模式上进行操作。

然而,FNO并非完全严格的神经算子,其非线性激活函数 会引入混叠误差

问题在于,逐点非线性激活(如ReLU)会产生新的高频成分。例如,对正弦函数平方会产生倍频。这些新产生的高频可能超出我们预设的带限范围,也无法被后续的傅里叶层(只处理预设的低频)正确处理。当网格变化时,这些未被解析的高频成分就会导致误差,破坏严格的等变性。

实验表明:

  1. 在故意构造的、高频信息重要的问题中,FNO和CNN一样,在分辨率外推时误差会显著增大。
  2. 在实际的偏微分方程问题(如纳维-斯托克斯方程)中,由于方程本身往往具有耗散性(阻尼高频),非线性激活产生的高频影响被部分抑制,因此FNO表现优于CNN,分辨率外推能力更强,但理论上仍存在瑕疵。


总结

本节课我们一起深入探讨了算子学习的核心挑战——实现连续-离散等价性。

  1. 我们首先明确了传统方法(如CNN)的局限:它们学习的是固定网格间的映射,缺乏分辨率外推能力。
  2. 接着,我们引入了Reno表示等变神经算子的理论框架,通过编码器和重建器在连续与离散空间之间建立精确对应,目标是消除混叠误差。
  3. 然后,我们介绍了神经算子的通用形式,即将神经网络的权重矩阵、偏置和激活函数推广到函数空间。
  4. 为了克服基础神经算子计算量大的问题,我们重点学习了傅里叶神经算子。FNO利用卷积定理和FFT,将卷积运算转换到傅里叶空间进行高效计算,并通过学习傅里叶乘子来捕获全局依赖。
  5. 最后,我们分析了FNO的优点与不足:其傅里叶层部分在带限函数假设下具有良好的等变性,但逐点非线性激活会引入高频混叠,使得它在理论上并非完美的神经算子,不过在多数实际科学计算问题中表现优异。

FNO是算子学习领域一个里程碑式的模型,它平衡了表达力、计算效率和一定的网格无关性。理解其原理和局限,为我们后续探索更严格的神经算子架构奠定了基础。

013:谱神经算子与深度算子网络

在本节课中,我们将要学习两种重要的神经算子架构:谱神经算子和深度算子网络。我们将探讨它们如何从传统数值方法中汲取灵感,以及它们各自在解决算子学习问题上的优势和局限性。

概述与背景

上一节我们介绍了傅里叶神经算子,并讨论了其在处理不同分辨率数据时面临的混叠误差问题。本节中,我们来看看两种旨在解决此问题的新方法。

我们继续之前的内容。在最近几讲中,我们一直在研究算子学习,其基本设置是相同的:给定一个抽象的偏微分方程,并关联一个将函数空间映射到函数空间的解算子。换句话说,它接收输入系数和源项,并返回解。由于问题本质上是无限维的,我们必须考虑如何离散地表示它。我们需要思考连续与离散的等价性,这是算子学习的核心概念。

我们引入了神经算子的表示等价性概念。其核心思想是,我们无法直接处理这个算子,即使我们想学习它。我们必须拥有该算子的有限维表示或近似,而两者之间的联系真正定义了算子学习。

具体来说,如果下图可交换,即无论你直接在连续层面操作,还是从连续函数空间开始,映射到网格(离散化),在网格层面进行操作(如CNN等),然后再映射回来,如果整个过程完全相同,那么这个图是可交换的,你就没有混叠误差。两者之间的差异就是混叠误差。只要没有混叠,你就可以进行真正的算子学习。这是我们当前所处的框架。

我们之前看到,卷积神经网络打破了这种等价性。

傅里叶神经算子回顾

在上一讲中,我们花了大部分时间学习傅里叶神经算子。

让我们回顾一下傅里叶神经算子,以便加深印象。

我们有一个输入 a 和一个输出 u。其处理过程包含不同的层。首先是提升层,你简单地增加更多特征通道,从而不是处理物理变量(如密度、压力),而是处理这些特征的某种更抽象的表示。提升之后,你还会进行投影。这两层通常是线性层或MLP。但所有核心操作都发生在通过傅里叶层进行的处理中。

以下是傅里叶层的示意图:你从一个函数开始,对其进行傅里叶变换(如果在网格上,则使用快速傅里叶变换)。然后你截断傅里叶模式的数量,并进行傅里叶乘子运算(这是可学习的参数)。这里发生两件事:首先,你以某种方式变换傅里叶系数;其次,你截断它们,只保留部分谐波。然后,你通过逆傅里叶变换回到物理空间。接着,你通过所谓的残差连接保留部分信号,这有助于训练并保留一些空间信息。最后,你应用逐点非线性激活函数。这个过程会重复多次。

但正如我在上一讲末尾解释的,FNO存在一个问题:激活函数(非线性)打破了交换图。因为最终,这些空间之间必须存在清晰的对应关系。

如果你将这些空间视为带限函数空间,并应用一个非线性函数,那么这种等价性就被打破了。一旦等价性被打破,你就会遇到像上次展示的随机分配那样的例子:你可以在特定网格上训练并获得非常好的结果,但一旦稍微改变表示(例如分辨率,即使只改变一个点),误差就会开始变大。这是因为条件不满足,你总会遇到混叠。

这在处理实际问题时得到强化。例如,回到纳维-斯托克斯方程,这是一个我们课程中主要研究的方程。其算子接收一个速度场并输出另一个速度场。我们通过涡量来可视化它。你可以看到初始的剪切层导致了涡旋的脱落。

如果你使用FNO,在训练分辨率下表现良好,但在不同网格的测试分辨率下,当你降低分辨率但仍保持在带限内时,会出现较大误差。这再次表明它不具备表示等价性,存在混叠误差,这将影响解的质量。问题在于,有时高频分量在问题中被阻尼掉,而在其他情况下高频分量会保留。

因此,我们面临的挑战是:需要设计一种能够规避此问题的神经算子,它能够在不同网格之间进行处理,能在任何分辨率下操作,从而学习到真正的算子,而不仅仅是获取特定有限维表示并输出另一个有限维表示的映射。

从传统数值方法中汲取灵感

在今天的讲座以及下一讲中,我们将看到一些例子。

对于今天的讲座,我们从传统数值方法中汲取了一些灵感。正如我在课程一开始所说,存在多种数值方法,如有限差分法、有限体积法、有限元法和谱方法等。从某种意义上说,这些方法也必须在相同的范式中工作,因为无论你是通过机器学习还是数值建模来近似解算子,最终都是在近似一个算子。因此,你本质上是在处理一个无限维的问题。

例如,如果我想用谱方法(它生成真实解)来解决这个问题,我需要将其投影到某个网格或某个基上,用该基进行处理,然后继续。

这是如何完成的呢?

同样的图再次出现,符号略有变化。事实上,数值方法可以非常相似地用与机器学习方法相同的范式来表示或解释。同样,你有一个算子(这里用 A 表示以区别于学习近似 G),但本质上,你希望近似这个算子 G,它将输入函数空间映射到输出函数空间。

所有这些方法都依赖于相同的原理:你从一个无限维函数空间开始,将其投影到有限维空间,在有限维空间中工作(例如时间步进或求解刚度矩阵),然后通过某种插值回到无限维空间。

以有限差分法为例。对于热方程 U_t - U_xx = 0,你在空间和时间上取一个网格。要计算某个时间步 U^{n+1} 在点 j 的值,公式是:
U_j^{n+1} = (ΔT/Δx^2) * U_{j-1}^n + (1 - 2ΔT/Δx^2) * U_j^n + (ΔT/Δx^2) * U_{j+1}^n
我取这三个点,然后演化到下一个时间步,并持续进行。这里的数值格式(近似器 A)取代了图中 G 的角色。因为它基于物理第一性原理,你可以访问方程并求解它。

类似地,一旦你有了点值,你总是可以使用多项式插值。这部分是插值器 R。编码 E 只是点值求值。有限元法也是完全相同的原理:你有一个由有限元函数组成的基,然后取节点值作为系数,对它们进行一些操作(例如求逆刚度矩阵),然后通过伽辽金基回到无限维空间。谱方法对傅里叶系数做同样的事情。

这里的要点是,当你有一个无限维问题时,你将其简化为有限维。在最一般的情况下,这可以是某个基的系数,甚至可以是点值(即我在上一讲中介绍的sinc基的系数)。所有这些本质上都是:编码 E 是某种基投影,重建 R 是基重建。如果你有一个基(无论是有限元基、分段常数基还是傅里叶基),你投影到该基上,在另一侧你取系数并形成基展开。所有数值方法都以某种方式落入这个方案。在这之间是物理发生作用的地方:你拥有方程的离散版本,并传播它,但你始终使用这些基系数。

这与FNO的做法不同。FNO我们做了一些提取,但同时保留了它的一些元素,我们将其学习为某种函数到函数的映射,而不是直接处理某些基本元素。

谱神经算子

事实证明,你可以模仿刚才介绍的方案,并最终得到一类机器学习或算子学习方法。

这些方法可以统称为谱神经算子。其思想与之前完全相同:就像数值方法一样,我们将事物降维到一个基,然后使用该基将其投影回来。在这之间,我们不是使用数值方法,而是严格地使用一些深度神经网络(如MLP)。现在不能是CNN,因为CNN基于像素等,而这里只基于某种MLP。

让我重复一下。这里有一些数学,但在特定例子中相当简单。让我给你一个非常简单的想法。你有一些输入 a,我将其表示在某个基上:a = Σ_j a_j ψ_jψ_j 是我要选择的某个基。现在我访问向量 a_jj 从1到 n)。我取一个神经网络(称之为 L),输入 a_j,输出一些 u_jj 从1到 m)。你直接使用基工作,忘记我们之前所有的空间概念,忘记这些是函数的一部分,你只处理这些离散系数,并通过你的DNN处理它们。最后一步,你取 u ≈ Σ_j u_j ψ_j。假设输入和输出的基完全相同。

这就是谱神经算子中所做的。根据你选择的基,你会得到不同类别的函数。请注意,FNO并不完全在这个框架内,因为它不一定总是有这种表示;你仍然有空间的概念。同样,对于CNN,你仍然有空间的概念。在这里,你完全移除了这一点,将这些对象作为离散对象处理。你期望这些信息(即它们来自一个函数)以某种方式被表示,例如,如果你有一个光滑函数,傅里叶系数将具有某种衰减。

这个方案清楚了吗?看看它与我们之前所做的区别:之前我们处理整个图像或整个像素,这里我们不这样做;我们取一个函数(图像),先取前20个傅里叶系数,在神经网络中处理它们,得到另外20个系数,然后返回。这与我们之前所做的有细微差别,之前我们是直接操作图像并对其进行处理。

只要有一个特定的实现(由这里的人们完成),你会发现有好有坏。使用傅里叶基是最简单的想法,特别是对于周期性问题,很自然地用正弦和余弦(傅里叶基)来表示。当然,你需要处理带限函数,否则空间太大无法执行此程序。然后是这个构造。因为我们总是处理傅里叶系数,我取复数值,但在实践中我们取实数值,虚部会抵消。

其思想正是我在这里所说的。TT' 只是算子,告诉你可以将事物降维到一个基并重建它们。但关键思想是,当然,这是一个神经算子,因为这里的一切都是在有限维方式下完成的,意味着没有空间的概念。

想象它的最简单方式是:如果你有两个不同的网格,这并不重要,因为我从一个网格取函数,简单地将其投影到固定数量的傅里叶系数上;我从另一个网格取函数,将其投影到相同数量的傅里叶系数上;然后我进行处理和重建。对我来说,函数是在细网格还是粗网格上并不重要,只要我不改变傅里叶系数的数量。当然,关键在于,如果你有一个粗网格上的函数,并将其投影到20个系数上,这可能是一个很好的表示;另一方面,当你在细网格上时,你可能想将其投影到更多傅里叶系数,但这里你没有这种灵活性。

它在某种意义上并非完全不同,但这里的参数(你稍后会看到)可以扩展以覆盖非严格参数化的情况,因为之前你从未能以某种方式使用函数。这增加了一个额外的层。现在它告诉你的是,你从一个函数开始,将其投影到一些固定数量的参数上;之前你是直接处理那些参数,所以你甚至不需要这第一步。所以你多了一个额外的层,但在某种意义上,它遭受了与参数化表示相同的一些问题。我并不是说所有问题都将通过这种方法解决,但这是解决一个问题的一种特定方式:你拥有网格上的不同信息,你不在乎,因为你将其投影到一个有限的基上。当然,这非常有限,因为它告诉我们,我们必须给自己套上一个紧身衣,这并不好。

深度算子网络

有一个推广或变体,你也可以称之为泛化。

这是最早引入的算子学习架构之一,尽管当时还没有这个名字,它叫做深度算子网络。这实际上可以追溯到90年代两位中国计算机科学家的工作,但其现代版本只有三、四年的历史。其思想是:这里的问题是,我们需要提供基,这需要一些专家知识。我们说,好吧,这些是周期函数,所以用傅里叶基;或者这些是其他结构,用更一般的基;或者这些是在球面上,用球谐函数。这需要一些我们将要使用的专家知识。这些研究者提出的论点是:如果你也学习基,而不仅仅是系数,会怎样?这似乎是更聪明的做法,以获得那种能够学习基的泛化能力。这就是深度算子网络所做的。

让我相当快地解释一下,以便你也能了解这个主题的一些历史。

你会看到它有自己的问题,但你可以看到它的来源。它与之前的图完全相同。

这里有两件事:系数(类似于之前的 G)和基(称为主干网络)。系数则是一个分支网络。

乍一看,这似乎是一个非常复杂的构造,但实际上是一个相当简单的想法,只是你现在有了一个可学习的基。首先,从你拥有的数据中,你学习一个基,或者同时学习基和系数。这两件事是同时完成的。当然,你可以想象这似乎是一个聪明的想法,但它也有自己的问题,因为可能同时学习的东西太多了。

让我用这张图来解释。抱歉符号有些混乱,因为我从某处复制了图片。这是你的输入(这里称为 u)。编码由逐点求值给出,即传感器评估。这些是点值。

其启发式是:假设这是你的输入温度,你想预测六小时后的温度(就像我们在天气预报中所做的那样)。你将通过使用一些传感器来观测这个温度,这些传感器正是温度的逐点值。在这种情况下,这些点值甚至不必位于网格上,它们可以是随机点,这不是问题。然而,对于不同的实现,这些必须是相同种类的传感器或相同的点。所以,点求值提取了这些输入系数,就像我们做卷积时一样,只是这里的灵活性在于,只要你为每个样本保持相同的传感器(例如,你现在在相同的传感器处测量温度,六小时后在相同的传感器处测量,等等),你就可以拥有任意的点集合。这是一种限制,但这是第一件事。

然后你将处理这些系数,就像我们在谱神经算子中所做的那样,将它们输入一个神经网络,该网络输出一些输出系数。这与之前完全相同,没有什么特别的。但现在,基呢?我们也必须学习表示函数所用的基。基就是这些 τ 函数。它们代表基。我们如何学习它们?记住,基现在是一个函数。每个基函数都是一个函数。让我分离出其中一个,称之为 τ*。它是 y 的函数,y 属于作用发生的域 B。当然,这个函数的输入将是你评估函数的坐标。我们将形成一个函数。

例如,假设你的域是 [0,1]。我需要评估一个函数。我所做的是,输入任何值,输出提取的值。你必须为 m 个基函数都这样做(10个或更多,取决于你的问题)。你将有一些基函数,这将是一个通用函数,不应该是正弦、余弦、切比雪夫多项式或有理函数等。现在,这就是神经网络的普适性发挥作用的地方:在之前的一讲中,你看到神经网络是通用的,任何连续函数、可测函数、可积函数都可以用神经网络近似。这些研究者的想法是:好吧,让这些成为神经网络。

因此,这些 τ 中的每一个都是DNN或MLP。可以有更多的结构,也可以是CNN等,但在这种情况下,最简单的是将其设为MLP(多层感知器)。现在你将有 m 个神经网络来表示你的基,同时有 m 个神经网络来表示你的系数。它们并行运行,具有不同的语义和启发式,它们之间存在差异。

现在的近似完全是根据我们在这里提取的系数完成的,就像在SNO中一样,然后重建是根据这些基函数完成的。记住,这里发生了两层:系数被近似,但表达它的基也同时从数据中学习。这两件事都是可行的,这不是一个不可行的问题。最终,你形成求和,得到一个神经算子。

这个构造本身非常简洁,因为你有一个可学习的基和可学习的系数,这些空间将在其中表达。这与统计学中的主成分分析有些相似。在PCA中,你也学习基,这些基基于你给定数据的统计结构的主成分。这有点像那样,只是你使用神经网络而不是主成分,因为原则上神经网络可以近似任何东西。

这个构造本身在这个意义上是简洁的:你有一个可学习的基和可学习的系数,这些空间将在其中表达。

深度算子网络的问题与局限性

关于这个构造有任何问题吗?……好的。

有一个区别,因为PCA更偏向于这个时期……我也可以快速描述一下。PCA是,如果你有数据(我不在这里过多细节,因为需要介绍协方差算子/矩阵),PCA所做的就是查看你拥有的数据,从数据的结构中提取基,它不处理数据,只是从数据的结构中提取基。例如,你有这些输入 u_i,我不知道如何表达它们,假设有1000个数据对(1000个例子)。你把它们放在一起,计算它们的协方差(这是一个矩阵),有一些有效的算法来提取其特征值和特征向量。然后你将任何输入 a 重写为 a = Σ_j a_j p_j,其中 p_j 是输入的PCA基。你在输出层做同样的事情,只是查看数据并提取输出的PCA基。这在一定程度上是预处理。然后在这之间,你需要 a_ju_j 之间的联系,这由一个神经网络提供。

从某种意义上说,你也在使用学习,但只是在输入和输出端使用统计学习,在中间使用神经网络。这里的区别在于,你不是同时学习基和系数,而且这里输入和输出可能有不同的基,而使用DeepONet,你试图学习相同的基。它们在精神上有些内在联系,因为我当然可以用神经网络近似我的PCA函数,或者用PCA函数近似我的神经网络。

它们与我们之前所做的略有不同,之前我们是直接处理图像或函数,即函数的空间结构。在这里,你只是取函数,将其放入一袋系数中,这些系数隐含地表示函数,你处理它们,然后返回。所以你只是在非常并行的层面上进行所有处理。这清楚了吗?

那么,它的好处是什么?当然,你可以像训练FNO一样训练它,事实上人们已经这样做了。好处是,这些也是无混叠的,因为同样的原理:现在你总是将事物限制在某个有限维空间中,无论你查看什么网格,因为它只是一组固定的传感器。当然,这里没有问题。事实上,有一些条件,例如,即使你将其训练为一个基……对于PCA,如果有无穷多个样本,那么它将是一个基,这是有保证的。另一方面,这里没有这样的保证;你只是试图拥有基的语义,并且你认为你的学习问题将为你提供一个基,它不一定是一个基。在实践中,这些函数看起来根本不像基,但也不必是基。事实上,理论表明,使用所谓的框架就足够了,这些不是基函数而是框架。当然,因为你在非均匀网格、随机网格等上操作,所以会有一些来自那里的混叠误差。如果你在均匀网格上操作,则没有混叠误差,因为尼奎斯特条件得到满足。

我说过,这不必是一个基,因为没有理由强加正交性等。这是目标,但在训练过程中我们没有这样做。我们可以在训练过程中强加它,我们可以说我们将强加一些正交性条件,但这不公平,因为你不知道从数据中你将使用什么内积。所以在这个意义上,它并不那么清晰。

你明白了吗?所以这只是一个我们始终可用的选项,在某种意义上,它是一个基线。但它做了它所做的,即它能够表示来自不同网格的数据,仅仅因为它将它们投影到某个特定的袋中然后处理它们。所以在这方面,存在一些“作弊”。

那么,这有什么问题呢?这个构造清楚了吗?问题是什么?它们在实践中有效吗?在某些情况下当然有效。然而,我将给你一个非常简单的例子,说明这种方法的一些问题出现的地方。

你能想到的最简单的非线性PDE是所谓的伯格斯方程。它是由伯格斯作为纳维-斯托克斯方程的模型发明的,结果证明它是一个很好的模型。方程本身由这种形式给出,它是一个一维时空方程。有时人们添加粘性,但这里不重要。让我们看看无粘形式(无粘性伯格斯方程),然后我们有一些初始数据 a(x),它来自某个概率测度 μ

这是一个非常简单的设置。在这个特定情况下,我们的初始数据选自所谓的高斯随机场。高斯随机场是布朗运动对函数的简单推广。本质上,这些是噪声。你从某种有色噪声开始,高斯随机场,但这只是给你一个具体的数值例子,其他例子也同样有效。你从高斯随机场作为初始数据开始,然后让解演化到某个时间,比如 t=1

典型的高斯随机场函数可能具有以下形状(类似噪声)。你将其放入非线性中,对于来自流体力学的人来说,这很明显,非线性会使其变陡。因此,一段时间后,如果你有这样的初始数据,这些小的噪声结构会清除,你会形成所谓的激波(尖锐前沿)。例如,当飞机以超音速飞行时,发出的声波会突破音障并产生激波。解看起来像这样(橙色是真实解,由数值方法生成)。现在我们使用DeepONet进行训练,我不记得用了多少样本,也许大约1000个。然后你可以开始看到问题所在:当然,它提供了一些答案,但有几件事是错误的。它没有得到不连续点的正确位置,当然,一旦位置错误,幅度也就错误。在这个特定情况下,误差非常大,大约30%。相对误差的百分比并不像你在图片上看到的那么重要,有时如果问题非常困难,30%是可以接受的,但这是一个非常简单的问题,误差很大。所以很明显,尽管所有这些保留结构的好属性都得到了满足,但有些地方出了问题,否则我们就解决了问题。

这在某种程度上得到了回答,因为现在我们将其与FNO进行比较。FNO不具有这种结构保留属性,但这并不意味着结构保留不好,它只是你评估事物的一个维度。例如,我的实验室有一些理论,我们做的是在理论上比较两者(一个非常简单的问题)。同样的也可以用于伯格斯方程。

如果你取线性平流方程:u_t + c u_x = 0。你知道解将是什么:u(x,t) = a(x - ct)。例如,如果你从一个这样的凸起开始,你只是平移它。你从一个稍微不同的凸起开始,你将其平移到相同的位置,只是形状不同,这取决于初始数据。在这种情况下,人们可以严格地数学证明,原则上假设你可以完美训练(这从未发生),但即使在完美训练的假设下,为了获得一定量级的误差 ε,使用DeepONet你需要参数数量与误差的平方成比例。为了获得1%的误差(即1/100),你需要大约10,000个参数(粗略计算)。有一些常数,但大约是10,000的数量级。

而FNO对于同样的问题,你可以严格证明其复杂度按对数缩放。所以它不仅是线性的,你不需要100个,你需要10个,你需要log(100)。这是一个严格的证明,表明对于解决完全相同的问题(尽管是一个非常学术的问题),FNO需要对数复杂度,而DeepONet需要平方复杂度。因此,即使你试图学习基等,它在准确性方面并没有真正得到回报。你保留了一些结构,很好,但它在准确性方面没有回报,因为你离你想做的还很远。

这也被展示出来(我想这是针对平流方程)。即使对于这个非常简单的问题,你也可以看到DeepONet给出大约8%的误差,而FNO给出其十分之一。对于相同的大小,你得到十分之一的误差。当然,这个定理就是这样,它很简洁,但有常数,并且很难评估常数。

所以这告诉你,保留结构只是故事的一部分。FNO也有它自己的优势。通过将所有东西放入一个固定的基或一个可学习的基,你并没有真正解决问题,因为一些重要的信息丢失了。这就是为什么DeepONet在实践中表现非常差的原因。

这里有一个我们之前见过的相同问题的例子:这是真实解,这是FNO的预测,相当合理,虽然有一些干扰和问题,但误差我记得FNO大约是4%(下一讲你会看到)。CNN(我们之前见过的那个)存在混叠,但也做了合理的工作。看看DeepONet发生了什么:它只是预测了整个样本的平均值。它根本没有性能。在这个特定情况下,误差是12%或15%,但它根本没有以任何合理的方式工作。

这主要是因为,当然,有一些定理告诉你哪里出错了,但直观上发生的是,我们通过将其放回仅仅一组固定参数中而失去了问题的某些结构,这正是你所说的观点。在参数方面有什么区别?在某种意义上没有太大区别,但道德上你在做同样的事情:你并没有真正保持无限维结构,你解决了一个问题,但创造了另一个问题,即你失去了表达能力。

所以挑战仍然存在:我们需要设计一些真正有效的东西。我想说这仍然是一个挑战。

我们还没有以任何方式解决这个问题,但在下一讲中,我将开始向你展示在这个方向上走得更远的架构,它们既保留了结构,同时也能工作。

但了解存在哪些东西、什么有效、什么无效也很重要。所以这是今天的主要目标。

好的,我们在这里停止。我们几乎准时。下周我们继续这个主题。

014:卷积神经算子 🧠

在本节课中,我们将学习一种称为卷积神经算子的新型架构。我们将探讨它如何通过精心设计的卷积和非线性操作,在保持连续-离散等价性的同时,有效地学习函数空间之间的映射。

概述 📋

我们的核心任务与之前相同:求解一个偏微分方程,其解算子 $\mathcal{G}$ 将输入函数(如系数或源项)映射到输出函数(解)。由于我们处理的是函数空间之间的映射,我们必须遵循连续-离散等价性原则。这意味着,通过离散空间(如网格上的函数)进行操作时,整个流程应与连续空间的操作精确对应。

之前我们了解到,卷积神经网络和傅里叶神经算子都不是真正的表示等价神经算子。今天,我们将介绍卷积神经算子,它旨在保留卷积的优点(如局部性和计算效率),同时通过创新的设计确保表示等价性。

背景与动机 🎯

在视觉变换器和扩散模型兴起之前,卷积是视觉任务中的核心模型。卷积具有局部性,即它考虑邻近点之间的关系,并且计算高效(卷积核对应的矩阵是稀疏的)。此外,卷积与求解偏微分方程的有限差分法有内在联系。

然而,之前的方法(如CNN和FNO)未能保持连续-离散等价性。CNN的卷积操作本身不保持结构,而FNO的非线性操作破坏了结构。因此,我们需要同时调整卷积非线性这两个组件。

卷积神经算子的核心构建块 🧱

卷积神经算子的目标是构建一个算子 $G^*$,它在带限函数空间之间进行映射。带限函数是指其傅里叶变换的支撑集限定在某个频率范围内的函数。这允许我们在连续函数和离散网格点值之间建立精确的对应关系。

以下是架构的主要组成部分:

1. 提升与投影操作

首先,我们通过提升操作 $P$ 将输入函数嵌入到更高维的特征空间(增加通道数),为学习算法提供更好的坐标系统。处理完成后,通过投影操作 $Q$ 将结果映射回原始的输出通道数。$P$ 和 $Q$ 通常是简单的线性映射,它们不改变空间结构,因此是表示等价的。

2. 卷积操作

与CNN在离散空间进行卷积不同,CNO在连续空间对带限函数进行卷积,但使用一个离散的卷积核 $K_w$。这个核由一组定义在网格点上的离散权重 ${K_j}$ 构成。

关键技巧在于:我们固定卷积核的大小,而是通过重采样来调整输入函数的“尺寸”。具体来说,当在不同分辨率的网格上应用相同的卷积核时,我们先将输入函数通过sinc插值“提升”到连续空间,然后根据卷积核的网格进行重采样,应用卷积,最后再插值回目标网格。这个过程确保了在不同分辨率下操作的一致性,从而满足了表示等价性。

3. 非线性操作

非线性操作(如ReLU)会引入新的高频成分,破坏函数的带限性质,进而破坏连续-离散等价性。

CNO的解决方案是:在应用非线性之前,先进行上采样,人为地提高函数的允许带宽(例如,将带宽加倍)。然后应用逐点非线性函数。最后,通过下采样(低通滤波)将函数带限恢复到原始范围。

  • 对于多项式或有理函数非线性,只要上采样的带宽足够高(例如,对于平方操作,带宽需加倍),这个过程是精确的,并且是表示等价的。
  • 对于像ReLU这样的非线性,这是一个近似过程,但通过上采样可以显著减少混叠误差。

上采样和下采样操作在连续层面是平凡的(只是在新点求值),在离散层面则通过sinc插值实现。

完整的CNO架构 🏗️

基本的“卷积+非线性”块可以堆叠,但为了获得最佳性能,特别是处理多尺度信息,CNO采用了类似U-Net的编码器-解码器结构,并加入了残差连接。

以下是架构中的关键模块:

  • 不变块: 基础的“卷积+非线性”处理块。
  • 下采样块: 包含卷积、非线性和下采样操作,用于降低空间分辨率、处理更粗尺度的特征,同时增加通道数。
  • 上采样块: 包含卷积、非线性和上采样操作,用于提高空间分辨率、融合多尺度特征,同时减少通道数。
  • 残差连接: 遍布网络,用于缓解深度网络中的梯度消失/爆炸问题,并帮助保留高频信息。
  • 跳跃连接: 在编码器和解码器对应尺度之间,将编码器的特征图与解码器的特征图拼接,确保不同尺度的信息得以融合。

这种设计使得CNO能够有效地进行多尺度信息处理,这是从计算机视觉领域借鉴的成功经验。

理论性质与实验验证 📊

理论性质

  • 表示等价性: 通过上述卷积和非线性组件的设计,CNO在理论上(对于多项式/有理非线性)或近似上是一个表示等价神经算子。
  • 通用逼近定理: 可以证明,CNO能够以任意精度逼近紧致集上连续的函数空间之间的算子。

实验验证

我们在多个PDE问题上测试了CNO,并与FNO、U-Net(无上/下采样的CNO变体)、DeepONet等进行了比较。

  1. 分辨率不变性: 在满足奈奎斯特条件的网格上,CNO的误差几乎保持机器精度,而FNO和U-Net则因混叠误差导致误差显著上升。
  2. 分布外泛化: 当测试数据分布(如初始条件的扰动幅度、位置或频率成分)与训练分布不同但相近时,CNO通常表现出比FNO和U-Net更好的泛化能力。
  3. 计算效率: 训练完成后,CNO的推理速度极快(比传统数值求解器快多个数量级),训练时间与FNO等基线模型相当。

具体实验包括:

  • 纳维-斯托克斯方程: CNO能准确预测涡旋的演化,且无明显混叠伪影。
  • 泊松方程: CNO在输入函数频率成分变化时表现稳健。
  • 输运方程: CNO展现了良好的平移不变性,而FNO由于在傅里叶空间操作,平移不变性较弱。
  • 可压缩欧拉方程(翼型绕流): CNO能快速、准确地从翼型形状预测流场,在分布外形状上也有不错表现。

总结 🎓

本节课我们一起学习了卷积神经算子。我们了解到:

  1. 核心思想: 通过固定离散卷积核并对输入函数进行重采样,以及通过上/下采样机制控制非线性引入的频率,CNO实现了连续-离散等价性
  2. 架构特点: CNO结合了卷积的局部性、计算效率优点,并采用U-Net式多尺度结构进行有效的信息处理。
  3. 优势: 与FNO、U-Net等相比,CNO在分辨率不变性分布外泛化方面通常表现更优,同时保持了极高的推理速度。
  4. 应用: 在多种PDE求解任务中,CNO都展示了其作为高效、准确神经算子的潜力。

CNO为我们提供了一种强大的工具,用于学习科学和工程中复杂的函数间映射关系。然而,像所有模型一样,它也有其局限性和挑战,我们将在后续课程中继续探讨。

015:时间依赖的神经算子 🕐

在本节课中,我们将要学习如何处理时间依赖的偏微分方程。我们将探讨传统神经算子在处理这类问题时的局限性,并介绍一种新的方法——时间条件化,它能够更有效地利用时间序列数据,并实现连续时间预测。


课程回顾与引言

上一节我们深入探讨了卷积神经算子,它具有良好的理论性质和实践表现。本节中,我们来看看如何将神经算子的概念扩展到时间依赖的问题上。

首先,我们面临的是求解抽象偏微分方程的问题,其形式通常为:
[
\partial_t u = L(u)
]
其中 ( L ) 是微分算子,例如热方程中的拉普拉斯算子。我们的目标是学习一个解算子 ( S ),它接收初始条件 ( u_0 ) 和时间 ( t ),并输出在时间 ( t ) 的解 ( u(t) ):
[
S: (u_0, t) \mapsto u(t)
]
这个算子具有半群性质,体现了时间的因果性。


传统方法的局限性

在深入新方法之前,我们需要理解现有神经算子(如FNO和CNO)在处理时间依赖问题时的三个主要局限。

以下是三个关键问题:

  1. 对规则网格的依赖:FNO和CNO等算法主要在规则网格(如矩形)上操作。虽然可以通过插值和掩码策略处理不规则域(如机翼绕流),但这并非其原生设计,在处理复杂几何或随机传感器数据时效率可能不高。
  2. 时间依赖PDE的挑战:时间依赖问题的数据天然是轨迹或视频形式的,即一系列时间快照。而传统神经算子通常被训练为从初始条件直接预测某个固定终态时刻的解,未能充分利用轨迹中的连续时间信息。
  3. 数据规模问题:机器学习模型的性能通常随训练数据量增加而提升(即“缩放定律”)。然而,在科学计算中,生成高保真模拟数据成本高昂。我们需要高效利用有限的轨迹数据来提升模型性能,这是下一讲的重点。

时间依赖问题的学习任务

对于时间依赖的PDE,理想的学习任务是:给定初始条件、边界条件、域和介质属性等,模型应能预测未来所有时刻的解轨迹。这比仅预测单个终态时刻的解更为复杂。

这与许多基于“流数据”(如天气预报)的方法不同,后者假设可以访问历史时刻的数据来预测下一时刻。在通用科学计算场景中,我们通常只能从初始条件开始进行时间推进,这与传统数值求解器的设定一致。


自回归预测及其缺陷

一种直接的方法是使用神经算子进行自回归预测。其核心思想是训练一个算子 ( G ),使其能够根据当前时刻的解 ( u(t_k) ) 预测下一固定时间步长 ( \Delta t ) 后的解 ( u(t_{k+1}) ):
[
u(t_{k+1}) \approx G(u(t_k))
]
在推理时,从初始条件 ( u_0 ) 开始,反复应用该算子,即可“滚动”预测出整个时间序列。

以下是自回归方法的几个主要问题:

  • 离散时间输出:只能预测预先定义的离散时间点上的解,无法实现连续时间评估。
  • 需要均匀时间步长:算子 ( G ) 隐含学习了特定的时间增量 ( \Delta t ),难以适应可变时间步长。
  • 误差累积:在长时程滚动预测中,每一步的微小误差会不断累积,导致预测结果逐渐偏离真实解。
  • 训练困难:训练时需要沿时间反向传播(BPTT),长滚动步数会导致梯度消失或爆炸问题,因此通常只能使用短序列进行训练,这可能影响模型在长时预测上的泛化能力。

时间条件化方法 🆕

为了克服自回归方法的缺陷,我们引入“时间条件化”这一新思路。其核心是将预测时间 ( t ) 本身作为模型的一个显式输入,而不仅仅是隐含在算子结构中。

具体实现包含两个关键部分:

  1. 时间作为输入通道:将目标时间 ( t ) 作为一个额外的通道(类似于温度、压力等物理场),与初始条件一起输入给神经算子。这使得模型能够直接学习从 (初始状态,目标时间)目标时刻状态 的映射,理论上支持连续时间评估。
  2. 条件归一化:仅在输入层加入时间信息可能不足,因为经过深层网络后,时间信息的影响会减弱。因此,我们在网络的每一层都引入时间条件。这通常通过修改层归一化或批归一化操作来实现。

标准归一化形式为:
[
\text{Norm}(x) = \frac{x - \mathbb{E}[x]}{\sqrt{\text{Var}[x] + \epsilon}}
]
在条件归一化中,我们引入依赖于时间 ( t ) 的可学习缩放因子 ( \gamma(t) ) 和偏置项 ( \beta(t) ):
[
\text{ConditionalNorm}(x, t) = \gamma(t) \cdot \frac{x - \mathbb{E}[x]}{\sqrt{\text{Var}[x] + \epsilon}} + \beta(t)
]
其中 ( \gamma(t) ) 和 ( \beta(t) ) 可以是简单的仿射变换,也可以是小型的神经网络。这样,每一层的特征分布都受到当前目标时间的调制,使得时间信息能够贯穿整个网络的前向传播过程。


总结与展望

本节课中我们一起学习了处理时间依赖PDE的神经算子方法。我们首先回顾了传统神经算子的框架,然后指出了其在处理时间问题上的局限性,特别是自回归预测方法的缺陷。接着,我们介绍了一种更有前景的方法——时间条件化,它通过将时间作为显式输入并在网络各层进行条件归一化,来实现连续时间的直接预测,并有望更高效地利用轨迹数据。

下一讲,我们将深入探讨时间条件化神经算子的具体训练策略、如何利用其处理轨迹数据,并进一步分析模型性能与数据规模之间的“缩放定律”,这是提升科学机器学习实用性的关键。

016:大规模神经算子

概述

在本节课中,我们将学习如何将神经算子应用于时间依赖的偏微分方程求解。我们将重点介绍一种称为“前导时间条件化”的技术,它允许神经算子将时间作为输入,从而能够预测任意时刻的解。此外,我们还将探讨两种不同的训练策略:“逐一训练”和“全对全训练”,以及它们在提升模型性能和利用数据方面的优势。最后,我们将初步了解Transformer架构及其核心组件——注意力机制,为后续深入学习打下基础。


时间依赖问题与解算子

上一节我们介绍了多种算子学习算法。本节中,我们来看看如何处理时间依赖的问题。

时间依赖问题基于时间依赖的偏微分方程。其抽象形式如下:

∂u/∂t = F(u, t)

其中,u 是未知函数,t 是时间,F 是某个微分算子。

一个典型的例子是热方程:

∂u/∂t - ∇²u = 0, u(x,0) = u₀(x)

另一个例子是波动方程,它可以通过引入新变量(如速度)转化为一阶时间导数的系统形式。

对于时间依赖的PDE,我们感兴趣的是学习解算子 G。这个算子将初始条件 u₀ 和时间 t 映射到该时刻的解 u(t)

G: (u₀, t) → u(t)

在实际中,我们通常拥有的是解在离散时间点上的轨迹数据。


前导时间条件化

为了将时间信息整合到神经算子中,我们采用前导时间条件化技术。其核心思想是:不仅将时间作为初始输入的一部分,还要将其信息贯穿到网络的每一层。

具体操作分为两步:

  1. 初始输入:将时间 t 作为一个额外的输入通道,与初始条件 u₀ 一起输入神经算子 S*
  2. 层间条件化:在网络的每一层(特别是归一化层)中,将时间 t 作为条件输入,以调制该层的输出。

神经网络的归一化层(如实例归一化、批归一化、层归一化)通常形式为:

输出 = γ * ( (输入 - μ) / σ ) + β

其中 μ 是均值,σ 是标准差,γβ 是可学习的缩放和平移参数。

在时间条件化中,我们将这些参数 γβ 改为时间 t 的函数,通常通过一个小型多层感知机(MLP)来实现:

γ(t) = MLP_γ(t), β(t) = MLP_β(t)

这样,时间信息就能优雅地“烙印”在整个神经网络的每一层中,使网络能够学习与时间演化过程相关的特征。


训练策略:逐一训练与全对全训练

在训练时间依赖的神经算子时,我们有两种主要的策略可以利用轨迹数据。

逐一训练

在逐一训练中,对于每条轨迹,我们使用初始条件 u₀ 和不同的目标时间 t_k 来生成多个训练样本。

损失函数构造如下。对于第 i 条轨迹,其损失 L_i 为:

L_i = (1/K) * Σ_{k=1}^{K} || u_i(t_k) - S*(u_i(0), t_k) ||^2

其中 K 是时间步数。总损失是所有轨迹损失之和。

这种方法的优点是简单直接,每条轨迹提供了 K 个训练样本。

全对全训练

全对全训练则更充分地利用了PDE解算子的因果性(或半群性质)。其思想是:从轨迹上的任何一个时间点 t_i 出发,都可以预测其之后任意时间点 t_j (j > i) 的解。

因此,对于一条有 K 个时间点的轨迹,我们可以构造的训练样本对数量从 K(逐一训练)大幅增加到 K(K+1)/2

损失函数相应地变为:

L_i = Σ_{i=1}^{K} Σ_{j>i}^{K} || u_i(t_j) - S*(u_i(t_i), t_j - t_i) ||^2

全对全训练通过利用解算子的内在性质,实现了数据的“免费”扩增,通常能带来更好的模型性能,尽管训练成本会更高。


推理策略

训练好时间条件化的神经算子后,在推理(预测)阶段我们有多种策略可以选择:

  1. 直接推理:直接将目标总时间 T 和初始条件 u₀ 输入算子,一步得到最终时刻的解。这种方法最廉价,但可能因预测步长过长而误差较大。
  2. 自回归推理
    • 单步自回归:从 t=0 开始,反复使用算子预测下一个时间步的解,并将预测结果作为下一步的输入,直到达到目标时间 T。这种方法误差可能累积,但每一步的预测任务相对简单。
    • 多步跳跃自回归:结合直接推理和自回归的优点。例如,先做几个大时间步的预测,再在接近终点时用小步长细化。这种启发式方法通常在精度和成本之间取得较好平衡。

选择哪种推理策略取决于具体问题、对误差的容忍度以及计算预算。


数值实验与结果分析

我们以Shear Layer流问题为例,展示了上述方法的有效性。

关键观察结果如下:

  • 数据缩放律:随着训练轨迹数量的增加,测试误差以可预测的速率下降(例如,指数约为-0.33)。这种缩放律在不同目标时间上都成立,尽管误差常数会随时间增长而增大。
  • 连续时间预测:模型能够预测训练时未见过的中间时刻(如t=0.5, 0.7)的解,实现了真正的连续时间预测能力。
  • 训练策略对比:全对全训练 consistently 优于逐一训练,因为它利用了更多的数据对。
  • 推理策略对比:多步跳跃自回归推理策略通常能在直接推理和单步自回归之间找到最佳平衡点,显著降低预测误差。

这些结果表明,通过时间条件化架构、全对全训练策略以及灵活的推理方式,神经算子在处理复杂时间依赖PDE问题时表现出强大的能力和良好的可扩展性。


迈向Transformer:注意力机制简介

观察到神经算子在数据与模型规模上存在一致的缩放规律后,我们受到自然语言处理领域成功的启发,开始探索Transformer架构在科学计算中的应用。其核心是注意力机制

注意力机制原理

与卷积神经网络(CNN)的局部感受野不同,注意力机制是全局且数据依赖的。

考虑一个离散的输入序列(例如,空间离散化后的函数值)V = [v1, v2, ..., vK],每个 vi 是一个 n 维特征向量。

注意力层的输出 U 在位置 k 的值 u_k 计算如下:

u_k = Σ_{j=1}^{K} ( softmax( (Q v_k)^T (K v_j) / √d ) ) * (V v_j)

其中:

  • Q, K, V 是可学习的线性变换矩阵(查询、键、值)。
  • softmax 函数将点积分数转化为权重,表示位置 j 对位置 k 的“关注”程度。
  • 求和是对所有位置 j 进行的,实现了全局信息混合。

函数视角下的注意力

从连续函数的角度看,注意力可以看作一个非线性积分算子:

(Attention(v))(x) = ∫ κ(x, y; v) v(y) dy

其中核函数 κ 本身依赖于输入函数 v,通过查询 Q 和键 K 的运算实现:

κ(x, y; v) ∝ exp( ∫ (Q v(x))(z)^T (K v(y))(z) dz )

这使得注意力机制比固定的卷积核更灵活、更强大。

Transformer块的基本结构

一个标准的Transformer编码器块通常包含以下组件:

  1. 多头自注意力:将上述注意力机制并行执行多次(多个“头”),每个头学习不同的关注模式,最后将结果拼接或求和。
  2. 层归一化:对每个位置的特征向量进行归一化,稳定训练过程。公式为:
    LayerNorm(x) = γ * (x - mean(x)) / std(x) + β
    
    在时间依赖问题中,γβ 可以成为时间的函数。
  3. 前馈神经网络:一个应用于每个位置的点式多层感知机(MLP),提供非线性变换能力。
  4. 残差连接:将每个子层(MSA, MLP)的输入加到其输出上,有助于梯度流动和深层网络训练。
  5. 位置编码:由于注意力机制本身是排列不变的,我们需要注入位置信息。通常是在输入特征上加上一个与位置相关的编码向量 PE(pos)。可以是固定的(如正弦/余弦函数),也可以是可学习的。

一个Transformer块的计算流程可简述为:

U = LayerNorm( v + MSA(v) )
输出 = LayerNorm( U + MLP(U) )

总结

本节课中我们一起学习了处理时间依赖PDE的先进神经算子方法。我们掌握了如何通过前导时间条件化将时间整合到网络架构中,并深入探讨了逐一训练全对全训练两种策略,后者通过利用解算子的因果性显著提升了数据利用效率。我们还分析了不同推理策略(直接、自回归)的权衡。实验结果表明,这些方法在复杂流体力学的预测任务中表现出了良好的缩放规律和精度。最后,我们引入了Transformer架构和注意力机制的基本概念,为构建更强大、可扩展的神经算子奠定了基础。在接下来的课程中,我们将进一步探索如何将Transformer有效地应用于科学计算问题。

017:注意力机制作为神经算子

在本节课中,我们将学习如何将Transformer架构应用于算子学习,并深入探讨其核心组件——注意力机制。我们将从上一讲的内容出发,理解注意力如何作为一种数据依赖的非线性核函数工作,并分析其计算复杂性。最后,我们将介绍两种应对计算挑战的主流方法:基于图像块的视觉Transformer和基于窗口的注意力机制。

从算子学习到Transformer

上一讲我们介绍了使用Transformer进行算子学习的目标。我们不会重复算子学习的定义,因为过去十讲已多次讨论。我们想使用Transformer的关键原因在于可扩展性,即我们希望模型和数据规模都能有效扩展。

我们从上讲的一个总结开始。输入可以视为一个函数 V(x)。我们可以将所有操作解释为函数与函数之间的算子,而不仅仅是向量或矩阵之间的运算。

我们需要位置编码,因为否则所有输入都是置换不变的。本质上,Transformer有三个核心元素:

  1. 多层感知机
  2. 层归一化
  3. 注意力机制——这是Transformer中最重要的新元素。

注意力机制详解

为了重申其原理,即使在离散网格上操作,我们也可以在函数层面理解注意力。多头注意力只是对多个注意力头的输出求和。

以下是其结构。本质上,它是一种点对点的连接。想象我们有一些称为“标记”的点,代表这些位置的值。为了更新某一点的值,我们会考虑所有其他点传递给该点的相对信息。然后,通过一个Softmax函数来确定来自所有点的信息的相对权重。

在积分版本中,这由特定项给出;在离散求积版本中,则由经典公式给出。

因此,注意力是一个非常直观的机制,因为它考虑了输入不同部分之间的相关性或相对贡献。当将其视为核函数时,这一点尤为明显。与FNO等模型不同,在FNO中,核函数通常是平移不变的、固定的或从数据中学习的,但在推理时是固定的。而在注意力机制中,由于考虑了每个标记(点)的相对贡献,最终得到的是一个数据依赖的非线性核

注意力作为数据依赖的核

这就是Transformer在某些方面具有理想特性的原因。我们可以这样理解:与其使用一个内置的、基于先验知识(如平移不变性)的核函数,不如让模型从数据中学习这个核。注意力机制为这种学习提供了广阔的空间,因为所有数据点都会做出贡献。

数据可能赋予邻近点更大的权重。在这种情况下,注意力机制会自然地倾向于局部性,邻近点的注意力权重会接近100%,而远处点的权重会迅速衰减。因此,它可以从这种全局结构中恢复出局部性。当然,对于其他问题,局部性可能不是正确的归纳偏置,模型也能理解并学习相应的模式。这最初是从自然语言处理的角度提出的,在语言中,注意力机制非常合理。在视觉和PDE求解中,直觉稍弱,但如果将其视为非线性核,直觉就会更强。

注意力机制是Transformer的关键,其他如逐点操作的MLP和层归一化则相对次要。

计算复杂性与挑战

这一切听起来很好,但我们必须付出代价。代价是什么?我们已经提到过,为了计算相对权重,我们需要进行额外的计算。我们固定一个点,然后通过广播计算所有点对该点的贡献。如果有K个标记,就需要进行K次操作,因此计算复杂度是关于标记数量的二次方

即使在单次推理中,计算成本也是二次的。在机器学习中,训练过程涉及在大量数据上反复进行推理,因此训练成本更高。计算成本大致是标记数量的二次方,这具有严重的影响。

考虑一个具体例子:在二维不可压缩流体流动中,未知数是速度V,有两个分量,所以输入特征维度 n=2。即使我们将特征提升到隐藏维度 M=100,这个成本也相对温和。但标记数量 K 呢?如果我们有一个128x128的图像,每个点对应一个标记,那么 K = 128^2 = 2^14。单次推理的复杂度约为 M * K^2,即约 100 * 2^28,这是一个超过十亿的巨大数字。在三维中,如果分辨率是128^3,K = 2^21,成本将达到 2^42 的数量级,即使是最大的计算设备也难以承受。

这就是Transformer在应用于图像或科学数据集时面临的问题:二次方的计算成本

并行化的优势与局限

Transformer的一个出路是极致的并行化。这意味着计算过程中的不同部分可以被拆分,并发送到不同的处理线程或GPU上。事实上,Transformer中只有O(1)的串行操作,许多计算可以独立进行。例如,计算查询、键、值以及Softmax中的指数运算都可以完全并行。只有点积运算需要组合信息,但这与矩阵向量乘法的计算量相比是轻松的。

因此,尽管计算量可能很大,但通过并行化可以显著加速。此外,Transformer具有最短的路径长度(为1),因为每个点都直接连接到其他所有点(包括自身),这有利于利用硬件优势。

然而,并行化并不能完全解决计算量本身巨大的问题。在二维中或许可行,但实践中即使对于图像,也很少有人直接使用点对点注意力,因为计算量仍然过大,且可能并非必要。

视觉Transformer:基于图像块的高效方案

我们需要利用科学数据集中存在的规律性来降低计算成本。与文本不同,图像或物理场数据在局部变化缓慢,具有更多规律性。

视觉Transformer提出的解决方案非常直观:将图像划分为不重叠的块。例如,将128x128的图像划分为16x16的块,那么标记数量就从16384个减少到64个。在每个块内,我们聚合附近点的特征,形成一个“视觉标记”。这相当于用单个特征(或属性)来代表整个块的信息。

当然,这可能会导致信息丢失。为了弥补,我们不是简单地取平均,而是使用可学习的特征提取。我们对块内的值进行加权平均,权重在所有块之间共享,并且可以学习。然后,我们将这些聚合后的特征嵌入到一个更高的潜在维度中。这样,我们既减少了标记数量,又通过增加通道维度保留了部分信息。

最终,我们得到一组数量大大减少的标记,每个标记代表了原图一个块的学习特征。这些标记被送入Transformer进行注意力计算。现在,注意力是在这些“块级”标记之间进行的,而不是原始的像素级标记。

位置编码与架构细节

我们仍然需要位置编码,因为块标记本身没有位置信息。我们简单地将可学习的位置编码向量加到每个块标记的嵌入向量上。

视觉Transformer的架构块通常按以下顺序组织:首先进行层归一化,然后进行多头自注意力,接着是残差连接。重复此过程:再进行层归一化,通过一个MLP,最后再加一个残差连接。这与原始Transformer的顺序可能略有不同,这种顺序调整通常是为了优化梯度传播,是经验性的选择。

在最后,我们需要将块级别的特征上采样回图像分辨率,这是一个简单的反向操作。

现在,计算复杂度如何?假设图像分辨率为 H x H,块大小为 P x P,那么标记数量 N = (H/P)^2。标准点对点注意力的成本是 O(H^4)。使用块后,成本变为 O((H/P)^4)。对于 H=128, P=16,这带来了巨大的计算节省。

然而,这里存在一个权衡:块越大,计算效率越高,但可能损失更多细节信息。对于图像分类等任务,16x16的块可能足够好。但对于需要更精细定量预测的科学计算问题(如温度场计算),可能需要更小的块(如4x4或8x8)。这会再次增加计算成本,因为 (H/P)^2 会变大。

窗口注意力:另一种高效方案

当需要较小块尺寸时,另一种目前表现优异的方法是窗口注意力。其思想是引入另一个层级:在划分块之后,再将图像划分为更大的窗口。每个窗口包含多个块。

注意力计算只在每个窗口内部进行。这意味着当更新某个块的特征时,它只关注同一窗口内的其他块,而不是全局所有块。这极大地减少了计算量,因为注意力成本现在是窗口内块数量的二次方,而不是全局块数量的二次方。

但这样会丢失全局信息。为了解决这个问题,方法是在不同的网络层中移动窗口的位置。例如,在第一层,窗口按一种方式划分;在下一层,将窗口整体平移一定距离,形成新的划分。通过这种跨层的窗口移动,信息最终可以在整个图像中传播。这是一个简单而优雅的想法,能有效平衡计算效率和模型表现。

总结

本节课中,我们一起学习了:

  1. Transformer的核心——注意力机制,可以理解为一种数据依赖的非线性核函数,它通过Softmax加权聚合全局信息。
  2. 标准点对点注意力的计算复杂度是标记数量的二次方,这限制了其在细粒度科学数据上的直接应用。
  3. 为了应对计算挑战,我们介绍了两种主要策略:
    • 视觉Transformer:通过将输入划分为图像块,显著减少标记数量,并使用可学习的特征提取来保留信息。
    • 窗口注意力:在块的基础上引入窗口,注意力仅限于窗口内部,并通过跨层移动窗口来实现全局信息交流。
  4. 我们始终需要位置编码来为标记提供空间顺序信息。
  5. 在模型设计时,需要在计算效率表征细节之间进行权衡。

这些方法使我们能够将强大的Transformer架构应用于大规模的科学与工程问题中。

018:窗口注意力与缩放定律

在本节课中,我们将学习如何通过引入窗口注意力机制来改进Transformer模型的计算效率,并探讨不同神经网络算子(如FNO、CNO和Transformer)在求解偏微分方程时的性能与缩放定律


回顾:Vision Transformer与计算挑战

上一节我们介绍了Vision Transformer及其通过图像分块来降低计算成本的方法。然而,即使分块后,注意力机制的计算复杂度仍然是二次方的,即 O(N^2),其中 N 是块(token)的数量。对于高分辨率图像或三维问题,这依然计算量巨大。

核心创新:窗口注意力

为了进一步降低计算成本,我们引入窗口注意力机制。其核心思想是将图像块进一步分组到非重叠的窗口中,并限制注意力计算仅在每个窗口内部进行。

以下是窗口注意力的数学描述。对于传统注意力,我们计算所有点对之间的关联:

Attention(Q, K, V) = softmax(QK^T / sqrt(d_k)) V

在窗口注意力中,对于位于点 x 的查询,我们只考虑位于同一窗口 W(x) 内的点 y

WindowedAttention(Q, K, V) = softmax( Q(x) * K(y)^T / sqrt(d_k) ) * V(y), 其中 y ∈ W(x)

这种方法将计算复杂度从全局的 O(N^2) 降低到了 O(M * (N/M)^2),其中 M 是窗口数量。这显著提升了计算效率。

窗口注意力的潜在问题与解决方案

然而,只在一个窗口内计算注意力会限制信息的全局混合能力。为了解决这个问题,我们采用了一个非常自然的想法:在连续的层之间移动窗口的位置

具体操作如下:

  • 在第一个Transformer块中,我们使用一种窗口划分方式。
  • 在下一个块中,我们将整个窗口网格进行平移(例如,向右下角移动半个窗口大小)。
  • 通过这种层间的窗口移动,原本在不同窗口中的块在后续层中进入了同一个窗口,从而建立了信息传递的路径。

这个过程有效地减少了信息在不同块之间传播所需的路径长度,使得模型在保持计算高效的同时,仍能整合全局信息。

Swin Transformer 块架构

结合了窗口注意力与窗口移动机制的Transformer块被称为Swin Transformer块。其工作流程如下:

以下是Swin Transformer块的单层数据处理流程:

  1. 输入经过层归一化
  2. 进行窗口多头自注意力计算。
  3. 与输入进行残差连接
  4. 再次进行层归一化
  5. 通过一个多层感知机
  6. 再次进行残差连接,得到输出。
  7. 将输出传递给下一层,并在下一层移动窗口后重复上述过程。

为缩放而做的改进

为了构建更大、更强大的模型,研究人员对基础注意力机制做了一些改进以优化缩放性能:

以下是几项关键的改进措施:

  • 缩放余弦注意力:用余弦相似度替代点积,实现自动归一化。公式为 CosineSimilarity(A, B) = (A·B) / (||A|| * ||B||)
  • 相对位置编码:不再使用绝对坐标,而是对块之间的相对位置取对数进行编码,这有助于模型更好地理解空间关系。
  • 层归一化位置:根据具体问题调整层归一化在残差连接中的位置(前置或后置),以改善训练稳定性。

构建多尺度层次化架构

正如我们在CNO中看到的,对于科学计算问题,多尺度信息处理至关重要。我们将Swin Transformer块嵌入到一个层次化的编码器-解码器架构中,形成了可缩放算子Transformer

以下是该架构的关键组件:

  • Patch Merging:在编码器部分,将相邻的小块合并成更大的块,从而降低空间分辨率,同时增加通道数,以捕获更抽象的特征。
  • Swin Transformer Blocks:在多个分辨率级别上应用Swin Transformer块进行特征处理。
  • Patch Expansion:在解码器部分,执行与合并相反的操作,提升空间分辨率减少通道数,以重建高分辨率输出。
  • 跳跃连接:在不同尺度之间添加连接,确保细节信息不会丢失。

这种设计使得模型能够像CNO一样,有效地在不同尺度上处理和融合信息。

性能实验与缩放定律分析

我们在多个PDE问题上测试了FNO、CNO和可缩放算子Transformer的性能,主要关注它们随训练数据量增加的误差下降趋势(即缩放定律)。

以下是几个关键实验的观察结果:

泊松方程

  • 问题-∇²u = f,学习从源项 f 到解 u 的映射。
  • 结果:Transformer模型(SCOTT)在数据量足够大时,性能与CNO相当或略优,但明显优于FNO。在小数据量下,CNO更具样本效率。

亥姆霍兹方程

  • 问题-∇²u + c²(x)u = 0,学习从系数场 c(x) 到解 u 的映射。
  • 结果:几种模型性能相近,Transformer并未显示出决定性优势。所有模型都需要相当数量的数据才能达到较低误差。

波动方程

  • 问题u_tt - c²(x)∇²u = 0,学习从系数 c(x) 和初始条件到时空解 u(x,t) 的映射。
  • 结果:CNO和Transformer性能相似,且都优于FNO。在数据量较大时,Transformer显示出略好的缩放趋势。

艾伦-卡恩方程与纳维-斯托克斯方程

  • 观察:在这些更复杂的非线性时间演化问题上,几种先进的算子学习方法(CNO和Transformer)表现处于同一水平,它们都显著优于基础的FNO,但彼此之间没有数量级的差异。

核心结论:在当前的数据规模下,引入Transformer架构并未带来性能上的颠覆性突破。其优势在于高度并行化的计算,但模型性能仍然严重受限于训练数据的数量和质量

未来方向:物理信息与基础模型

为了突破数据瓶颈,我们探索了两个方向:

  1. 物理信息神经算子:在损失函数中同时加入数据拟合项和物理方程残差项。然而,这与PINNs类似,存在训练困难的问题,尚未根本解决。
  2. 基础模型:这是目前最有希望的方向。其理念是:
    • 预训练:在大规模、多样化的PDE数据集(不同类型方程、不同参数分布)上训练一个超大型模型。
    • 微调:在面对特定新任务时,只需使用少量样本对这个预训练模型进行微调,即可快速获得高性能。

初步实验表明,一个在多种流体问题上预训练的大型Transformer模型,在微调后,仅用8个样本就能达到与之前用2048个样本训练的小型模型相近的性能。这展示了基础模型在提升样本效率方面的巨大潜力。


本节课中我们一起学习了如何通过窗口注意力机制构建高效的Swin Transformer,并将其应用于PDE求解。我们通过实验对比发现,尽管Transformer在计算上具有优势,但其在算子学习领域的性能与CNO等模型相当,且都受限于数据。最后,我们展望了通过构建PDE基础模型来实现少样本高效学习这一充满前景的未来研究方向。

019:混合工作流导论(第一部分)

在本节课中,我们将学习一种新的科学机器学习技术——混合工作流。我们将首先回顾之前学过的物理信息神经网络和神经算子等方法的局限性,从而引出为何需要采用混合方法。接着,我们将详细探讨什么是混合工作流,并了解其不同的类型。最后,我们将深入理解自动微分这一关键技术,它是训练所有科学机器学习模型(包括混合工作流)的核心工具。

回顾现有科学机器学习技术的局限性

上一节我们介绍了课程的整体结构,本节中我们来看看之前学过的两种主要技术:物理信息神经网络和神经算子。了解它们的优缺点将有助于我们理解为何需要转向混合方法。

物理信息神经网络

物理信息神经网络使用神经网络来求解偏微分方程。其核心思想是,神经网络直接近似PDE的真实解,并通过损失函数进行训练。损失函数包含两项:一项确保边界条件得到满足,另一项则强制PDE在定义域内处处成立。

优势:

  • 无网格方法:无需创建网格即可求解微分方程,对于网格生成成本高的问题非常有益。
  • 适用于复杂问题:在同时拥有观测数据并希望学习PDE信息或求解方程本身的问题上表现良好。
  • 主要无监督:通常不需要带标签的训练数据,仅需定义域内的坐标点(配置点)即可训练。

局限性:

  • 训练成本高:尤其是仅用于模拟时,训练可能非常昂贵。
  • 优化困难:不保证总能收敛到损失函数的局部或全局最小值。
  • 难以扩展:受神经网络频谱偏差影响,难以求解高频问题。

神经算子

神经算子学习一个将函数映射到函数的算子。例如,在求解PDE时,可以将初始条件或某个场(如达西定律中的渗透率场)映射到另一个函数(通常是PDE的解)。

优势:

  • 推理速度快:一旦训练完成,神经算子通常比传统模拟方法快数个数量级,可作为高效的代理模型。
  • 快速预测:给定新输入(如新的渗透率场),可以快速预测响应。

局限性:

  • 需要大量训练数据:作为监督学习的神经网络,通常需要大量训练数据。
  • 泛化能力有限:当输入超出训练分布时,性能可能显著下降。
  • 离散化假设:在将连续函数离散化以进行计算时,需要对所映射函数的正则性做出假设。

何时在科学工作流中使用深度神经网络?

基于以上回顾,我们需要审慎思考何时应在科学工作流中使用深度神经网络。这并非总是最佳选择。

深度神经网络的优势在于其速度快,并且能够学习高度非线性函数。然而,其局限性也很明显:需要大量训练数据、优化困难、难以解释、泛化能力弱。即使我们将科学理解融入机器学习算法(如通过损失函数或网络架构),这些局限性依然存在。

以下是关于在科学工作流中使用深度神经网络的一般性建议:

  • 用于加速工作流:当工作流非常缓慢时(例如有限元或有限差分模拟),可以考虑使用深度神经网络来加速。
  • 用于理解不足的部分:当对模型中的某些物理过程理解不足,或不确定如何离散化模型时,可以用神经网络来学习这些部分。

如果无法明确规划深度神经网络在工作流中的具体作用,那么使用它可能并非明智之举。必须批判性地权衡其优势与劣势。

混合科学机器学习工作流简介

上一节我们讨论了深度神经网络的适用场景,本节中我们来看看混合科学机器学习方法的核心思想。

混合方法的核心在于,不抛弃传统的科学工作流(如模拟算法、反演算法、去噪算法等),而是将神经网络紧密地嵌入到这些算法的某个部分中,而不是用神经网络完全替代整个流程。

我们可以将科学机器学习方法视为一个光谱:最左端是没有任何科学理解的纯机器学习方法,最右端是不使用任何机器学习工具的传统方法。混合方法则更靠近右侧,即在传统工作流中巧妙地融入机器学习组件。

最简单的混合工作流:残差建模

让我们从最简单的混合工作流开始,即残差建模方法。

假设我们有一个物理模型(可以是任何模型),它接收输入 X 并产生输出 Y(例如,X 是模拟的初始条件,Y 是模拟的输出)。我们面临的情况是,可能对模型中的某些物理关系理解不完全,或者完整的物理模型运行成本太高。

残差建模的思路是:用神经网络来建模我们未知的物理关系或 YX 之间的残差。我们将最终解表述为物理模型的输出加上神经网络的输出:

Y_hat = Y_physics + NN(X)

这种方法在以下情况有用:

  1. 对物理过程理解不完整。
  2. 完整物理模型运行成本过高,可以使用一个更快速但近似的模型。

与朴素的端到端机器学习相比,这是一个更简单的任务。因为神经网络只需要学习物理模型输出与真实解之间的残差,这通常比学习从输入到输出的整个复杂映射要容易得多。此外,残差方法通常比单一的黑箱模型更具可解释性。

如何训练残差模型?

训练方法与训练普通神经网络类似:使用带标签的训练数据来匹配整个工作流的输出。

假设我们有一些真实的 (X, Y) 数据对。我们使用一个简单的损失函数(如均方误差)来匹配预测值 Y_hat 和真实值 Y

Loss = MSE(Y_hat, Y) = MSE(Y_physics + NN(X), Y)

整理后,损失函数变为匹配神经网络输出与残差 (Y - Y_physics)。这意味着我们可以预先计算物理模型的预测和残差,然后将其作为训练数据来训练神经网络。

实例:机翼升力预测

我们设计一个残差建模方法来估计机翼上的升力。这是一个重要的设计任务,输入包括机翼形状(由N个坐标指定)、攻角和雷诺数。目标是预测升力。

传统的高保真方法(如CFD模拟)非常昂贵。我们可以使用一个更快但更近似的物理模型(如Hess-Smith面板法)来获得初步的升力预测。

残差模型将近似物理模型的预测、机翼形状、雷诺数和攻角作为神经网络的输入,网络输出一个修正值,与物理模型预测相加得到最终的升力预测。

训练数据:使用少量高保真CFD模拟数据作为真实标签。
损失函数:均方误差残差损失。

研究结果表明,与不使用物理模型预测作为输入的纯黑箱神经网络相比,残差模型的预测精度更高,并且通过集成方法估计的预测不确定性也更小。

值得注意的是,在这个实例中,神经网络并未与物理模型预测直接相加,而是将物理预测整合到了网络的最后一个隐藏层中。这提供了比简单相加更灵活的非线性组合方式。

更复杂的混合工作流:在算法内部嵌入学习组件

上一节我们介绍了最简单的残差建模,本节中我们来看更复杂的混合工作流。我们不再将物理模型视为黑箱,而是打开现有工作流,将神经网络直接插入到工作流的中间环节。

我们将以求解不可压缩纳维-斯托克斯方程的有限差分求解器为例,展示如何嵌入可学习组件以改进低精度求解器的准确性。

传统求解器概述

不可压缩纳维-斯托克斯方程描述了流体的运动。求解目标是在给定初始条件下,预测流速和压力随时间的变化。

一种流行的求解方法是算子分裂法。其算法伪代码的核心是一个时间步进循环:

初始化 U_0, P_0
for t in range(num_steps):
    # 步骤1:计算中间速度 U_star (基于当前时间步的U_t, P_t)
    U_star = compute_U_star(U_t, P_t, rho, nu)
    # 步骤2:求解压力泊松方程,得到下一时间步压力 P_{t+1}
    P_{t+1} = solve_pressure_equation(U_star, P_t)
    # 步骤3:更新速度,得到下一时间步速度 U_{t+1}
    U_{t+1} = compute_U_next(U_star, P_{t+1}, P_t)

数值模拟的精度强烈依赖于离散化网格的精细程度。使用粗网格(低精度)模拟速度快但误差大;使用细网格(高精度)模拟精度高但计算成本急剧增加(可能耗时数千倍)。我们的目标是:创建一个既保持低精度求解器速度,又具有高精度求解器准确性的模型

设计混合求解器

我们通过在传统求解器的每个时间步后添加一个残差修正来构建混合求解器。

算法流程:

  1. 执行一个标准的低精度时间步,得到 (U_t_low, P_t_low)
  2. 将低精度步的结果输入一个神经网络,网络学习一个修正量。
  3. 将修正量加到低精度步的结果上,得到更接近高精度解的 (U_t_corrected, P_t_corrected)
  4. 将此修正后的结果作为下一个时间步的输入,重复此过程。

伪代码修改如下(新增部分已高亮):

初始化 U_0, P_0
for t in range(num_steps):
    U_star = compute_U_star(U_t, P_t, rho, nu)
    P_{t+1} = solve_pressure_equation(U_star, P_t)
    U_{t+1} = compute_U_next(U_star, P_{t+1}, P_t)
    # --- 新增:神经网络残差修正 ---
    [U_{t+1}, P_{t+1}] = [U_{t+1}, P_{t+1}] + NN_theta([U_{t+1}, P_{t+1}])

如何训练混合求解器中的神经网络?

训练的关键在于损失函数的设计,这关系到网络在推理时的稳定性。

方案一:逐时间步匹配(可能不稳定)

  • 训练数据:收集许多时间步的样例。对每个样例,从同一个初始状态 S_t 出发,分别进行低精度步和高精度步,得到 S_{t+1}_lowS_{t+1}_high
  • 损失函数:让神经网络学会将 S_{t+1}_low 修正到 S_{t+1}_high
    Loss = MSE(S_{t+1}_low + NN(S_{t+1}_low), S_{t+1}_high)
  • 问题:网络在训练时只看到纯低精度步的输出。但在实际推理(混合求解器运行)时,网络的输入是已经被之前网络修正过的低精度步输出。这种训练与推理的输入分布差异会导致误差随时间累积和放大。

方案二:多时间步展开训练(更稳定)

  • 方法:不是孤立地训练单个时间步,而是将混合求解器在多个时间步上展开,并将最终(或所有)输出与高精度求解器对应时间步的输出进行比较。
  • 损失函数:例如,Loss = MSE( Hybrid_Solver(S_0, steps=N), HighFidelity_Solver(S_0, steps=N) )
  • 优势:在这种端到端训练中,神经网络在训练阶段就会看到“已被修正过的”输入,从而学会了纠正其先前步骤产生的误差,减少了分布偏移,使得长时间模拟更加稳定。

实现训练的关键:自动微分

无论采用哪种训练方案,要优化混合求解器中的神经网络参数 θ,我们需要计算损失函数 L 关于 θ 的梯度:dL/dθ

混合求解器包含复杂的传统数值步骤(如矩阵求解)。为了获得梯度,我们需要能够对整个工作流进行微分或反向传播。这正是自动微分 的威力所在。

现代深度学习框架(如PyTorch、JAX)的自动微分机制不仅限于神经网络,它是一个通用工具,可以微分我们定义的几乎任何函数或算法。

类比神经网络训练:

  1. 定义前向函数(对于神经网络是 y = f_NN(x, θ),对于混合求解器是 y = f_hybrid(x, θ))。
  2. 计算损失 L = loss(y, y_true)
  3. 调用 autograd.grad(L, θ) 获取梯度。

从框架的角度看,f_NNf_hybrid 都是将输入 (x, θ) 映射到输出 y 的函数。只要前向计算中的每个操作都是可微的,自动微分就能通过链式法则计算梯度。这使得我们可以像训练神经网络一样,训练包含复杂物理模拟的混合工作流。

混合求解器结果与局限性

采用“端到端多时间步展开训练”的混合方法(如论文“Solver-in-the-Loop”所示)能够有效提升低精度求解器的准确性,同时保持其速度。

局限性:

  • 分辨率固定:混合求解器通常针对特定网格分辨率进行训练和运行。
  • 泛化能力:如果初始条件或流动参数与训练分布差异很大,网络的性能仍会下降。误差仍会随时间累积,尽管端到端训练使其比逐时间步训练更稳定。

自动微分深入解析

上一节我们看到了自动微分在训练混合工作流中的关键作用,本节中我们将更深入地了解自动微分的工作原理,理解其为何如此强大和高效。

自动微分是训练所有科学机器学习模型(PINNs、神经算子、混合工作流)的核心使能技术。它允许我们微分复杂的损失函数,并通过任意算法反向传播梯度。

将程序视为向量值函数

大多数科学计算程序都可以看作向量值函数。它将一个输入向量 x(可能由多个输入拼接、展平而成)通过一系列基本操作(如加、乘、三角函数、矩阵运算等)的复合,映射到一个输出向量 y

数学上可写为:y = f(x) = f_n( ... f_2( f_1(x) ) ... )

我们的目标是计算该函数输出 y 关于输入 x 的梯度,即雅可比矩阵 J,其元素为 J[i,j] = dy_i / dx_j。对于复合函数,我们可以应用多元链式法则来计算雅可比矩阵,即一系列雅可比矩阵的乘积。

向量-雅可比积与雅可比-向量积

自动微分库高效计算的两个核心量是:

  1. 向量-雅可比积:给定向量 v,计算 v^T · J
  2. 雅可比-向量积:给定向量 u,计算 J · u

在训练神经网络时,我们想要标量损失 L 关于参数 θ 的梯度 dL/dθ。根据链式法则:
dL/dθ = (dL/dy) · (dy/dθ)
其中 dL/dy 是一个行向量,dy/dθ 是雅可比矩阵。这正是一个向量-雅可比积!因此,反向传播本质上就是计算一系列向量-雅可比积。

计算效率:计算顺序与雅可比稀疏性

计算链式法则时,乘法的顺序会影响计算和内存成本。

  • 从右向左计算(反向模式):即先计算 (dL/dy) · (dy/dg) 得到一个行向量,再与 (dg/dθ) 相乘。这始终进行向量-雅可比积,避免了早期出现巨大的矩阵-矩阵乘法,通常更高效,尤其当输出维度远小于输入维度时(如损失函数是标量)。
  • 利用雅可比稀疏性:许多基本操作的雅可比矩阵是稀疏的或具有特殊结构。例如,对于线性层 g = W·x,雅可比 dg/dW 非常稀疏。高效的自动微分库不会构造完整的雅可比矩阵,而是直接实现该操作的、利用其稀疏性的向量-雅可比积核函数。例如,g = sin(x) 的雅可比是对角阵 diag(cos(x)),其向量-雅可比积就是向量 vcos(x) 的点乘,复杂度为 O(n) 而非 O(n²)。

正是通过反向模式计算和利用雅可比稀疏性,自动微分才能高效地训练拥有数百万甚至数十亿参数的模型。

前向计算图与自动微分实践

在使用PyTorch等框架时,当我们定义前向函数并执行涉及可微分张量的运算时,框架会在背后构建一个计算图,记录所有基本操作及其依赖关系。

每个基本操作(如加法、乘法、sin)不仅定义了前向计算规则,还定义了其高效的向量-雅可比积(用于反向模式)和雅可比-向量积(用于前向模式)实现。

当调用 loss.backward() 时,框架从损失节点开始,沿着计算图反向传播,在每个节点处执行相应的向量-雅可比积,通过消息传递的方式高效地计算所有参数的梯度。

总结

本节课中我们一起学习了混合科学机器学习工作流的基础知识。

我们首先回顾了物理信息神经网络和神经算子的局限性,认识到需要更精细地整合机器学习与科学计算。然后,我们引入了混合工作流的概念,其核心思想是将神经网络嵌入到传统科学算法中,而非完全替代。

我们探讨了最简单的混合形式——残差建模,并通过机翼升力预测的实例加以说明。接着,我们深入研究了更复杂的混合工作流,以纳维-斯托克斯方程求解器为例,展示了如何在算法循环内部插入神经网络进行残差修正,并讨论了端到端训练的重要性。

最后,我们深入剖析了实现这一切的关键技术——自动微分。我们了解到自动微分通过将程序视为可微的向量值函数,利用反向模式和雅可比矩阵的稀疏性,能够高效地计算任意复杂算法的梯度,从而使得训练包含物理模拟的混合模型成为可能。

这为我们后续学习可微分物理和更高级的混合工作流奠定了坚实的基础。

020:混合工作流导论(第二部分)

在本节课中,我们将继续学习混合工作流。我们将深入探讨自动微分(Autograd)的机制,并通过一个具体的物理问题(最速降线问题)的代码演示,展示如何将神经网络嵌入科学计算流程中。最后,我们将介绍一个更高级的混合工作流应用:解决计算机断层扫描(CT)中的逆问题。

自动微分(Autograd)回顾与深入

上一节我们介绍了混合工作流的基本概念。本节中,我们首先来回顾并完成关于自动微分的讨论。

在上一讲中,我未能完全讲完自动微分,因此我想继续解释并完成这一部分。

我在这里准备了一些回顾内容。周三我试图向你们展示或解释的是,我们编写的大多数科学程序虽然可能非常复杂,但可以简单地视为向量函数。程序通常接收许多参数,但这些参数通常只是向量、矩阵、标量等。其输出也类似,可能是标量、向量或张量。

因此,从数学上讲,我们可以将整个科学程序写为一系列向量函数的复合。我们输入一个向量 x,顺序应用许多函数,最终得到输出向量 y

我们称这些中间函数为原始函数。即使在这个例子中(例如我们看过的混合斯托克斯求解器)包含许多复杂的矩阵求解等操作,我们也可以将其分解为最基本的操作,通常是乘法、除法、三角函数变换等。因此,这里的 n 通常是一个非常大的数字。

我在周三告诉你们的是,自动微分是通过深度学习库开发的一个超级强大的工具,它允许我们高效计算以下两个量:

  • 向量-雅可比积:即 v^T * J,其中 J 是雅可比矩阵。
  • 雅可比-向量积:即 J * v

我真正想告诉你们的是,虽然我们开发自动微分主要是为了训练神经网络,但它在科学机器学习中如此强大的原因在于,我们也可以使用自动微分来对这些复杂的科学程序进行微分,从而开始学习这些程序中的组件。

例如,这是一个学习混合斯托克斯求解器的伪代码。这是一个用于进行流体模拟的传统数值求解器。但在求解器内部,我们有一个神经网络,它应用一些可学习的修正。为了训练那个神经网络,我们只需使用自动微分来获取某个损失函数相对于网络参数的梯度,并将网络参数视为这个科学程序的额外输入。

那么,这个 torch.autograd.grad 块在幕后做什么呢?它正在计算这个有效的雅可比积。在这种情况下,dL/dθ 不是一个完整的雅可比矩阵,因为 L 只是一个标量值。因此,这个量的向量-雅可比积只是一个数字乘以那个向量。

接着,我讨论了如何计算这些向量-雅可比积,即自动微分实际上是如何工作的,其背后的机制。我们得到向量-雅可比积的方法是利用链式法则将雅可比矩阵分解,从而得到所有这些中间原始操作的雅可比矩阵。

实际的算法工作方式非常简单。你从一个向量开始,然后在这里从左到右进行所谓的反向模式微分,应用许多向量-雅可比积。这些现在是这些原始操作的向量-雅可比积。

因此,要编写一个自动微分包或库,你需要做的首先是定义所有这些原始操作的前向传播路径。然后,我们需要定义如何应用向量-雅可比积,以便在反向传播通过计算图时迭代计算链式法则。

我谈到的另一个技巧是,我们通常不需要完全填充或显式计算这些雅可比矩阵。通常原始操作非常简单,它们的雅可比矩阵是稀疏的,我们可以利用这一点来设计一个高效的自动微分求解器。

这就是我讲到的地方,我在描述我们实际上如何进行自动微分实践。像 PyTorch、TensorFlow 和 JAX 这样的自动微分框架是这样工作的。

例如,让我们考虑通过一个神经网络层或两层进行微分或反向传播。你要做的第一件事是,当你在 PyTorch 或 TensorFlow 中定义这个函数并运行前向传播时,它会计算这些操作的有向图。你可以把这个函数看作一个有向图,其中所有中间元素都有线连接,取决于先前的哪些向量或张量计算了它们。

然后,正如我所说,这些包为我们应用的每个原始操作定义了高效的向量-雅可比积和雅可比-向量积版本。

然后,根据你是在计算向量-雅可比积(进行反向模式自动微分),还是在计算雅可比-向量积(进行前向模式自动微分),你通过这个图进行消息传递,以迭代计算整个函数的向量-雅可比积。

对于反向模式,它看起来是这样的:你从某个传入向量开始,记住我们是从左到右反向进行,所以我们只是进行一些消息传递,然后将该向量与 dy/dbdy/dW2 相乘,然后继续向后通过图,直到最终得到输出相对于第一个权重的梯度。

这是前向模式,完全相同,只是我们通过网络向前传播。我们再次从某个传入向量开始,然后当我们进行计算时,我们同时进行该计算的向量-雅可比积,就像这样,当我们通过计算的前向部分时更新这个向量。

我认为讨论关于自动微分内存需求的问题非常有趣。我有一个问题:有谁能回答,所需内存如何随着前向计算的深度而缩放?对于反向模式和前向模式,内存缩放方式是否不同?

让我再展示一下这些动画。当我们进行反向传播时,为了能够计算例如 dy/dW,我们需要知道之前 y 的值,因为那是雅可比矩阵的一部分。类似地,当我们向后通过图时,我们需要存储 HbW1 的值,以便能够向后通过图。

因此,要进行反向模式自动微分,我们需要在开始反向传播之前计算并存储图中所有的中间计算结果。这对大家来说有道理吗?那么,在这种情况下,内存如何随深度缩放呢?是的,所需的内存量取决于前向计算的深度,因此是线性相关的。

现在,如果我展示前向模式的图,有谁能告诉我内存有何不同?现在我们向前进行,我们从一个向量开始,进行第一组原始操作,更新向量-雅可比积,然后继续。在这种情况下我们需要多少内存?是的,我们不需要存储这些中间激活值,因为我们已经在向前传播的同时更新了乘积。

所以,一个并不总是被认识到但非常有趣的点是:当我们进行反向传播时,我们必须存储中间计算结果,并且这与深度线性相关;而当我们进行前向模式时,我们完全不需要依赖深度来存储中间值。这是一个非常有趣的差异,可以非常有效地利用,特别是当我们有非常长的计算函数时,根据你想要的梯度,有时前向模式可能比反向模式更好。

所以,我已经详细解释了自动微分是什么。但在实践中,你不需要担心这些东西,对吧?我们可以把这些交给 PyTorch 或 TensorFlow。这些深度学习库如此惊人的地方就在于,它们在幕后处理所有这些事情。在 PyTorch 中,这等价于调用 loss.backward(),它会为我们更新梯度。

如果你查看 torch.autograd.grad 的文档,你可以看到它做的正是我们一直在讨论的事情。它计算输出相对于输入的向量-雅可比积,而这里输出的 grad 就是我们在该计算中使用的向量。

希望现在你们能完全理解这个函数是如何工作的了。另外,关于自动微分是什么或不是什么,还有一些其他误解,现在你们应该明白了:自动微分绝对不是符号微分,它也不是在做有限差分。当我们运行自动微分时,我们得到的是精确梯度。它只是一种高效计算精确梯度的方法。

这个向量就是你应用的那个向量。当你进行这个向量-雅可比积时,它就是那个传入的消息。记住,回到第一张幻灯片。一般来说,我们有一个向量函数,然后自动微分得到向量-雅可比积。这可以给你一个向量输出。但实际上,当我们通常想要损失相对于 θ 的梯度时,你可以将其视为一个雅可比矩阵,但它只有一行,因为损失是一个标量值,对吧?单行的向量-雅可比积只是那个标量乘以该行。在 PyTorch 中调用 loss.backward() 时,我们总是选择那个标量为 1。通常我们甚至不指定它,因为它被假定为 1。

但是,如果你要微分的输出不是标量,而是一个向量,那么你需要定义一个实际的向量来计算向量-雅可比积。通常,当我们做 loss.backward() 时,它只是 1。在我们继续之前还有其他问题吗?

混合方法:动机与示例

好的。在上次讲座中,我介绍了混合方法。我说过,到目前为止,在整个课程中,我们主要专注于用神经网络替换我们的科学工作流,该神经网络通过损失函数或架构对科学理解有一些有趣的认识。

但现在我们真正关注这些混合方法,我们保留传统算法,而是将可学习组件非常紧密地放入这些算法中。我在上一讲中向你们展示了如何使用自动微分来端到端地训练这些可学习组件。

那么,我们为什么要这样做?为什么混合方法有用?正如我所说,深度神经网络当然有其优势,但它们也有一些很大的缺点,例如,它们需要大量难以优化的训练数据等。

因此,这些混合方法的关键思想是:我们为什么不直接将神经网络或某些可学习组件纳入我们的算法中,以加速工作流程,或者学习我们不了解的算法部分,或者也许允许我们学习尚未纳入程序的不完整物理知识?

我还向你们展示了这个混合纳维-斯托克斯求解器。我们研究了模拟流体,并意识到传统数值算法存在离散化误差问题。或者换句话说,这些模拟的精度强烈依赖于你使用的网格单元数量。因此,使用少量网格单元,我们会得到非常不准确的模拟。

因此,我们研究了这个混合方法,我们采用了低保真度求解器,但添加了一个可学习组件来尝试提高其精度。该可学习组件所做的只是将神经网络放入混合求解器的内部循环中。网络接收每个低保真度步骤,并尝试学习一个修正,使其看起来更像对应的高保真度步骤。

是的,这是混合求解器的伪代码,它在代码中间有一个神经网络,我们使用自动微分通过整个算法进行微分,端到端,使用一个损失函数,该函数将混合求解器的最终输出与一些真实的高保真度模拟进行匹配。

是的,这就是混合技术的关键思想。我们也称之为可微分物理,即使用自动微分进行微分和学习物理算法。希望现在你们能完全理解并领会这个关键思想。

实践混合方法:四步指南

那么,在实践中我们如何做到这一点?或者,你如何将其推广到任何你想学习的科学程序?这超级简单,这是我给许多想自己尝试混合方法的人的建议,基本上只需要四个步骤。

第一步是获取你的传统科学算法,并将其重写到一个自动微分框架中。这通常是最困难的步骤,根据你的传统代码,这可能需要很长时间。例如,考虑到高性能代码很多是用 Fortran 或 C++ 等编写的,因此这可能需要很多努力,但一旦完成,你会获得很大的收益。例如,PyTorch 或 JAX(我们将在接下来的讲座中介绍 JAX)。

第二步是打开这个算法,使其更加灵活。我的意思是在该算法中的某个地方放入可学习组件。例如,学习离散化数值求解器的修正,或者甚至更简单,可能只是学习单个标量值,比如时间步长值等。

第三步,获取一些训练数据,即你期望该算法输出的数据。这是你的真实世界数据进入实践的地方,我们需要从某种数据中学习这些算法。

第四步,使用自动微分训练你的算法。只需计算输出的损失函数,然后让自动微分为你获取梯度。

还有一个额外的好处。所有这些深度学习库都设计用于执行并行矩阵运算,它们在 GPU 上运行得更好。好处是,一旦你重写了传统工作流,它也将在 GPU 上运行,并且根据执行的计算类型,它可能比 CPU 实现快一个数量级,有时甚至更多。

是的,混合方法在传统算法中插入可学习组件,而自动微分不仅是混合方法的关键推动者,也是我谈到的所有其他科学机器学习方法的关键推动者。

实例演示:最速降线问题

现在我将继续讲解混合工作流的第二部分,这部分由两部分组成。

首先,我将进行一些实时编码,向你们展示在 PyTorch 中编写科学程序、通过它进行微分以及学习科学过程的某些方面是多么容易。

然后,我还有另一个混合工作流的例子,它更复杂,真正展示了混合建模的极限。这个工作流用于解决逆问题,即我们不进行前向模拟,而是尝试学习系统的一些底层参数。

如果这次讲座讲不完,我们将在下次讲座继续。希望到这部分结束时,你们应该能够使用代码自己在 PyTorch 中尝试混合方法,并理解高级混合方法。

那么,我要做的是切换到我的屏幕标签。我想确认一下 Zoom 里的人能看到我的 Jupyter 笔记本吗?好的,很好。你们可以看到这里,好的。

我们要做的是研究这个问题。以前谁见过这个问题?它被称为最速降线问题。好的,几乎所有人都见过。我猜它在网上出现很多,这是一个很好的交互式演示,可以用来教人们。

这是一个非常有趣的问题,即:如果一个球要通过沿斜坡滚下来从一点到达另一点,斜坡的形状应该是什么,才能使球在最短的时间内到达第二个位置?在我看来,这并不直观明显,比如应该是直线、非常陡峭的线还是中间的某种线。

长话短说,有一条特殊的曲线叫做摆线,就是这里的这个形状,它能让球最快到达那里。有一些非常漂亮的数学可以用来证明这一点或推导出那条曲线的形状。

但我们在这里要做的是,我们说,好吧,我们没有那条曲线的方程,我们只想尝试使用神经网络来近似那条线来学习它。

是的,问题再次出现:一条曲线是什么形状,使得一个从静止开始、受重力加速的球在无摩擦的情况下从一点滚到另一点所用的时间最少?

我们要做的是,我们说我们不知道这条曲线是什么,我们称之为 yx 的函数,在这个二维设置中。我们让初始位置为原点,第二个位置为 (x2, y2)

是的,我们的方法将是尝试用神经网络学习这个函数是什么。我们将说神经网络直接近似球行进的那条线。

那么我们如何训练这个网络?你将如何训练或尝试学习这样一个网络?答案就在那里。是的,没错。我们要最小化我们想要最小化的东西,即模拟的时间。这很重要,对吧?我们不会给网络提供线的示例。我们将最小化我们真正关心的另一个量,即从那条线计算出来的某个量。

这就是混合建模的来源。我们要做的是,给定一条线,我们将使用物理求解器计算球沿着那条线滚动所需的时间,然后通过该求解器进行微分来学习网络。你可以看到这个五步方法是如何设计的。

那么我们如何计算任意线的总行进时间?我们只需使用距离等于速度乘以时间,但我们需要进行积分,因为线不是直线。我不会详细讨论这个,但推导行进时间关于 f(x) 的一种方法就是使用能量守恒,代入并重新整理这个积分,最终得到行进时间就是这个积分,它取决于线的梯度、线本身以及重力常数。

因此,我们需要做的是能够在 PyTorch 中评估这个积分,给定网络的输出。以便能够计算行进时间,然后通过整个计算进行微分,以学习网络的权重。在我讨论代码之前,关于整体方法还有什么问题吗?我们使用的损失函数有意义吗?是的。损失函数是网络值和梯度的某种积分,这有意义吗?好的。

关于损失函数有几个有趣的地方:我们不仅需要线的值,还需要梯度,那么我们如何计算呢?自动微分,是的,实际上我们将使用两次自动微分:我们将使用自动微分来获取线的梯度,并且我们还将使用自动微分来获取假设的梯度。就像我们在物理信息神经网络中看到的那样,我们可以以组合方式使用自动微分,多次应用它,这非常强大。

是的,精确解,如果你感兴趣,可以在之后点击这个链接。有一个参数化解。我们将在得出结果时与之比较。

首先,我们将导入 torch,并定义一个摆线,以便与精确解进行比较。然后我想做的第一件事是定义这个表示球将要行进路径的灵活函数。

我们将使用一个神经网络。这条线直接由网络近似。因此,网络应将 X 坐标作为输入,并给我 Y 值作为输出,对吧?这就是它给我的线。

我有一个简单的全连接网络,它有一个输入(X 值)和一个输出(Y 值),带有多个层。现在在我的前向调用中,给定 X 值,它将返回 Y。

我在这里还做的是给前向调用 x2y2 的值,这是球最终要到达的点。这只是为了归一化我的输入,记住我们必须确保为神经网络提供良好的归一化输入,所以这将帮助我归一化 X。

现在我要做一些比直接说 Y 等于 X 的神经网络更聪明的事情。实际上,我将使用一个残差模型。就像我们在混合方法中讨论的那样,如果我们对线应该是什么样子有假设,我们不必学习整个东西,我们可以只学习线的残差部分。

那么,一个好的初始猜测是什么?例如,如果我不知道这条线是什么,我可以说,好吧,让我们从一条直线开始,然后让网络学习对该直线的修正,也许这比学习整条线更容易。

因此,我们将线的假设表述为这样:我们将假设线是线性的,然后我们将以加法方式让网络学习一些残差修正。这其实很简单。首先,我们只计算我们的线性线会是什么。给定球从原点开始,它只是梯度乘以 x:y = m*x + c。这就是这里的线性部分。

然后我们需要计算网络将要学习的残差部分,即对线性线的修正。然后我们只需将 X 通过我们的神经网络。我在这里犯了一个错误。然后到最后,我们只需将线性模型加到网络输出值上。你可以看到我们是如何应用这种修正的。

我们需要做一些其他技巧来确保它快速收敛。首先,我要确保网络的输入是归一化的。目前,根据我定义的问题,x 的范围将从 0 到 x2。我们应该将神经网络的输入归一化到什么范围?是的,-1 到 1。所以我可以这样做:x_norm = 2 * (x / x2) - 1。现在你可以看到,当 x 从 0 到 x2 时,我已将其归一化到 -1 到 1。我认为只要数量级正确,一半也可以。

然后我要做的最后一件事是这个:我将最终输出乘以 torch.tanh(x) * torch.tanh(x - x2)。有谁能猜出这是做什么的?为什么这是一件有用的事情?为什么这有意义?我取网络的残差预测,并将其乘以 tanh(x)tanh(x - x2)。为什么不呢?

好的,这样做是为了断言我们问题的条件,对吧?我们知道球必须通过 (0,0),并且必须结束于 (y2, x2)。我们设计了我们的线性线,记住,我们说线是线性线加上神经网络修正。我们已经设计了线性线,使其通过 (0,0) 和 (x2, y2),只需使用这个线性线方程。那么网络在起点和终点需要添加什么值?零,是的。那么这在 x = x2x = 0 时做什么呢?是的,更准确地说,它只是说,无论网络在 x = x2 时的输出是什么,这个因子都将是 0,在 x = 0 时,这也将是 0。所以它将强制这个残差修正需要为零。很好的发现,谢谢。

让我接受这个,我认为除了这里都很好。好的,我们创建了那个。

现在我们要做的是训练网络。我在这里设置的是一个简单的 PyTorch 训练循环,就像你们之前说的那样。创建模型,我们有 8 个隐藏状态和 2 层,所以这是一个非常小的网络。我们创建一个 Adam 优化器来训练网络,这都是标准的东西。

现在我们需要做的就是计算行进时间,因为记住,我们将最小化行进时间相对于网络的权重,以尝试学习这条曲线。所以我们必须想出一种方法来计算这个积分。那么我们如何评估一个积分?我们如何数值计算这个?有谁有什么想法吗?是的,求积法。是的,我们需要离散化它以便计算。我可以使用梯形法则,这是一个更简单的方法,当然你也可以用更好的方法。

我这里要做的是,我们将在整个范围内采样 x 以计算那个积分,我们需要采样许多 x 值。所以我们将对 x 进行线性采样。然后我们将计算模型的输出,这是整条线的预测。

这里我们需要做的是计算行进时间。我需要的第一个东西是 dy/dx,也就是 torch.autograd.grad。所以是 y 和 x,然后我们需要雅可比积的因子,所以我们将对 x 使用 ones_like。我必须获取该输出的第零个输出。

这就是我们使用自动微分在时间值中获取 dy/dx 的地方。一旦我们得到了这个,我们就需要计算我们正在积分的函数。我将写这个平方根。我们将说 f = torch.sqrt((1 + (dy/dx)2) / (2 * g * y))**,像这样。然后我们将使用梯形法则进行积分,或者基本上将 X 的值相加。在这种情况下解析的?是的,很可能,如果你能解析地写出它,那当然更好。否则,求积法、蒙特卡洛采样或其他方法,还有其他计算方式。

好的,我们将使用梯形法则。torch 有一个叫做 torch.trapezoid 的函数,这使得它超级简单。它只计算梯形法则,所以它将用这些点来近似那个积分。我只需要做 t = torch.trapezoid(f, x, dim=0)。我认为这差不多就是全部了,剩下的只是调用 t.backward(),进行反向传播以获取网络的梯度,然后我们进行优化器步骤,我们在循环中这样做,然后我们将绘制学习过程中的曲线。

我漏掉了一件事,那就是我们需要创建图,以便我们也可以微分那个梯度图。看看它是否运行。我认为运行得不错,好的。我这里有两个图。一个是整条线的预测,这是线性模型加上神经网络修正。这非常有趣,这是在我们进行任何训练步骤之前。所以你可以看到,它看起来像一个线性模型,这就是为什么我们将线性模型作为初始猜测。这里有一个小凸起,所以也许网络从其随机初始化中做了一点修正。而且它通过了那两个点,所以我们做了这些硬边界约束,这非常好,所以无论网络学到什么,它总是会通过这两个点。

橙色曲线是摆线,这是精确解。然后你还可以绘制球行进时的速度,看起来很有趣。是的,当我们优化网络时,我们减少了它所花费的行进时间,这是我们正在优化的东西,我们开始越来越接近这个精确解。

就是这样,这是一个在物理工作流中使用神经网络的例子,一个计算行进时间的工作流,并通过整个工作流进行微分以学习该程序的一个组件。

是的,概括来说。是的,我认为我们应该测试一下,这可能取决于拉格朗日量,但有趣的是,如果你编写一个通用代码,可以接受任何拉格朗日量作为输入。顺便说一下,有一些叫做哈密顿神经网络的东西,它们试图学习哈密顿量,这是一个完全不同的主题,但人们也在尝试在这种更高层次的抽象上学习,我认为这些技术非常有趣。

还有其他问题吗?好的。

高级混合工作流:解决逆问题

我们还剩五分钟,所以我要开始下一部分,但如果没有讲完,我们将在下周三继续。

我们要做的是描述最后一个混合方法,可能是我要告诉你们的最先进的混合方法。我们将设计一个混合算法来解决这个问题,这是计算机断层扫描。谁以前见过这个?或者这种一般性问题?好的。

这是一个逆问题,目标是,计算机断层扫描用于医学诊断,可能每个人一生中都做过 X 光扫描。当我们看到扫描图像时,是这些图像,但这实际上不是仪器在你进行 X 光扫描时记录的东西。

仪器实际记录的是这些称为正弦图的东西,这些非常有趣的波浪状图像。那么 X 光或计算机断层扫描中实际发生了什么?你有一些介质,例如某人的头部或身体的其他部位,你有一个 X 射线源,你可以将其视为一个点源。这些 X 射线沿着介质的直线传播,最终在某个屏幕上被检测到。我们实际检测到的是 X 射线穿过整个介质后在屏幕上的强度。

这个正弦图显示的就是沿这个轴的强度。我们在实验中做的另一件事是旋转介质,并记录强度随旋转的变化,所以这是这个图像的另一个维度,即旋转角度。这个小图展示了如果你记录通过该介质的强度,你会得到什么。

我们记录的强度是变化的,它只取决于介质本身的吸收。你可以认为大脑的每个部分对 X 射线的吸收不同。我们最终想要得到的是这个吸收图像,所以这个吸收是 x 和 y 的函数。我们可以利用我们对物理的理解用数学来写这个,我们知道强度实际上只是吸收函数或吸收图像沿 X 射线行进路径的简单积分,即线积分。

这个问题以及我们想要如何解决它,从这些观测数据到我们想要的实际底层图像,有意义吗?好的。

是的,这就是逆问题,正如我所描述的,前向问题只是跨所有这些线和角度对图像进行积分。但逆问题是,给定一些观测到的正弦图,我们能否回到图像?这并不总是容易的,事实上很多时候非常困难。

是的,我在第一讲中谈到了这种高级框架,我说,许多问题都可以归结为这样:我们有一个物理系统,有一些输入/初始条件,我们有一个该系统的前向模型,然后我们得到一些结果属性/速度。

逆问题是给定 B 来确定 A 是什么或找出 A 是什么。我将告诉你们我们传统上如何做到这一点,然后在下次讲座中讨论混合方法。

传统上,我们通常将逆问题框架化为优化问题,从根本上说是一个搜索问题。给定 B,我们想要找到可能的 A 值,使得 F(A) 接近 B

我们可以将其写为一个优化问题,只是一个最小化问题,我们尝试猜测 A 是什么,对系统进行一些前向模拟,并尝试使其与观测数据匹配。这是一个目标函数或损失函数,我们可以像训练神经网络一样使用梯度下降来学习 A,获取这个损失函数相对于 A 的梯度,然后进行梯度下降步骤来学习 A

这要求我们的前向模型(即如果我给你一个图像,你有一个产生正弦图的算法,执行 X 射线的前向模拟)必须是可微分的,以便我们可以通过 F 进行微分,以获取损失函数相对于 A 的梯度。

我们将使用自动微分通过我们的前向求解器进行微分,就像我们之前做的那样,就像我之前描述的那样。到目前为止大家都跟得上吗?好的。

让我把它画成一个图表,这是同样的事情,梯度下降画成图表。我们从图像的某个初始猜测开始,然后使用简单的前向模拟进行前向建模,然后我们有一些从实验中观察到的真实数据,在我进行 X 光之后,这是我们实际接收到的数据。然后我们创建损失函数,将我们的预测图像与真实数据匹配,然后我们获取损失函数相对于图像的梯度,然后更新图像。

我们这样做数百次,也许数千次,最终得到一些最终模型。我认为我就停在这里,我们将在下次讲座中讨论如何改进这个工作流并学习其中的某些东西。

是的,也许这个标签有点多余,它只是模拟的输出。是的,你可以只有这个框。好的。谢谢大家,下周三见。

021:神经微分方程

在本节课中,我们将要学习神经微分方程。这是一个在科学机器学习领域非常流行的方向。其核心思想是将神经网络融入传统的科学工作流程中。你会发现,这与我们在前几节课中讨论的混合科学机器学习工作流密切相关。

什么是神经微分方程?

首先,我们来定义什么是神经微分方程。神经微分方程是指微分方程(可以是常微分方程或偏微分方程)中的某些项由神经网络表示。

例如,考虑一个经典的捕食者-猎物模型——洛特卡-沃尔泰拉系统。其常微分方程如下:

dx/dt = αx - βxy
dy/dt = δxy - γy

其中,xy 分别代表猎物和捕食者的种群数量。传统上,系数 αβδγ 是固定的。然而,这个模型包含了许多假设(例如,捕食者完全依赖猎物生存),可能无法反映真实的生物系统。

神经微分方程的思路是:我们并不完全确定方程右侧的函数形式。因此,我们可以用可学习的神经网络来替代其中某些项。例如,我们可以将方程改写为:

dx/dt = f_θ(x, y)
dy/dt = g_φ(x, y)

其中,f_θg_φ 是神经网络,θφ 是它们的参数。这样,整个微分方程系统就变成了一个神经微分方程。

如何求解与训练神经微分方程?

上一节我们介绍了神经微分方程的概念,本节中我们来看看如何数值求解并训练它们。

数值求解

即使方程中包含了神经网络,我们仍然可以使用传统的数值方法来求解。以最简单的欧拉方法为例。对于常微分方程 du/dt = f(u, t),其离散化形式为:

u_{n+1} = u_n + Δt * f(u_n, t_n)

f 是一个神经网络时,求解过程完全一样:在每个时间步,我们调用神经网络来计算 f(u_n, t_n),然后更新状态 u。从代码角度看,这只是一个在循环中调用神经网络的前向传播过程。

训练方法

训练神经微分方程需要数据。假设我们有一些系统状态随时间变化的观测数据。训练的目标是调整神经网络的参数,使得微分方程数值解的输出与观测数据相匹配。

因此,我们可以定义一个简单的损失函数,例如均方误差:

Loss = Σ ||u_pred(t_i) - u_obs(t_i)||^2

其中,u_pred(t_i) 是神经微分方程求解器在时间 t_i 的预测输出,u_obs(t_i) 是观测数据。

关键之处在于,我们可以使用自动微分技术,通过求解器反向传播梯度来更新神经网络的参数。这使得训练包含复杂数值求解过程的模型成为可能。

神经微分方程与神经网络架构的深刻联系

我们已经了解了神经微分方程的基本概念和训练方法。现在,让我们探讨一个非常深刻的见解:神经微分方程的解算器与标准的神经网络架构之间存在直接对应关系。

考虑使用欧拉方法求解神经常微分方程 du/dt = f_θ(u)。其单步更新公式为:

u_{n+1} = u_n + Δt * f_θ(u_n)

如果我们忽略时间步长 Δt(可以将其吸收到网络参数中),这个公式变成了:

u_{n+1} = u_n + f_θ(u_n)

这正是残差网络(ResNet)中一个残差块的计算形式!其中,u_n 是当前层的激活值,f_θ 是一个神经网络层(如全连接层或卷积层)。

因此,一个使用欧拉方法求解的神经常微分方程,等价于一个深度残差网络。更一般地说,不同的数值求解器(如龙格-库塔法)对应着不同的、更复杂的神经网络架构。

这种联系是双向的:

  1. 从微分方程到网络设计:我们可以利用对微分方程性质(如稳定性、收敛性)的理解,来设计具有优良特性的神经网络架构。
  2. 从网络到微分方程:我们可以将成功的网络架构(如Transformer)解释为某种微分方程的离散化,从而用新的视角理解其工作原理。

应用示例:耦合振荡器RNN用于人类活动识别

上一节我们建立了微分方程与神经网络的理论联系,本节中我们来看一个具体的应用案例:使用神经微分方程设计一个用于时间序列分类的递归神经网络。

任务背景

人类活动识别任务要求根据智能手表加速度计记录的时序数据 (a_x, a_y, a_z)(t),判断人的活动类型(如走路、上楼)。

处理时序数据的经典方法是递归神经网络。一个标准的RNN单元按以下方式更新隐藏状态 h_t

h_{t+1} = σ( W * [h_t, input_t] + b )

其中 σ 是激活函数。但选择何种内部结构(如简单RNN、LSTM、GRU)通常依赖于经验和调优。

基于物理的架构设计

我们观察到人体运动(如走路)具有振荡特性。因此,我们可以尝试用一个耦合阻尼谐振子的微分方程来构建RNN单元,将物理直觉融入架构设计。

耦合谐振子系统方程可以写为(经过一些简化和非线性化):

M * d²x/dt² + C * dx/dt + K * x = F_ext

将其转化为一阶系统并离散化(例如用欧拉法),我们可以得到一个更新公式,用于计算下一时间步的位置 x 和速度 v

以下是该更新计算的关键特性:

  • xv 共同构成了RNN的隐藏状态 h_t = [x, v]
  • 外部驱动力 F_ext 对应于RNN的输入 input_t(即当前时刻的加速度)。
  • 方程中的质量 M、阻尼 C、刚度 K 等矩阵成为了可学习的权重参数

这样,我们就得到了一个名为“耦合振荡器RNN”(coRNN)的定制化RNN单元。它的设计受到了物理系统的启发。

优势与性能

这种基于微分方程设计的架构具有一些理论优势:

  • 可控的动力学:谐振子系统具有能量守恒或耗散的特性,这有助于防止RNN训练中常见的梯度爆炸或消失问题。
  • 可解释性:隐藏状态 [x, v] 具有明确的物理意义(位移和速度),其演化过程可以直观理解为振荡过程。

在人类活动识别等时序分类任务上,coRNN展示了与LSTM、GRU等先进模型相媲美的性能。这表明,将领域知识(如系统的振荡特性)通过微分方程的形式编码到神经网络架构中,是一种有效且具有解释性的模型设计方法。

总结

本节课中我们一起学习了神经微分方程的核心内容。

我们首先定义了神经微分方程,即用神经网络表示微分方程中的未知部分。接着,我们讲解了如何使用数值方法求解神经微分方程,并利用自动微分和观测数据来训练它们。

随后,我们探讨了神经微分方程与深度学习架构之间深刻的理论联系,认识到残差网络等结构本质上是特定微分方程求解器的离散化形式。这一桥梁使得我们可以利用微分方程理论来设计网络,或通过网络理解微分方程。

最后,我们通过“耦合振荡器RNN”的案例,展示了如何将物理知识(谐振子方程)转化为一个新颖的、用于时间序列分类的递归神经网络单元,并取得了良好的效果。

神经微分方程巧妙地将物理建模的严谨性与神经网络的灵活性结合在一起,为科学机器学习和可解释的AI模型设计提供了强大的工具。

022:扩散模型入门 🧠

在本节课中,我们将要学习扩散模型的基本概念。扩散模型是目前最先进的图像生成模型之一,例如DALL-E和Stable Diffusion。我们将探讨扩散的物理和数学定义,理解其如何与神经微分方程相关联,并学习如何训练一个扩散模型来生成图像。最后,我们将看到一个扩散模型如何被应用于解决科学问题,例如计算机断层扫描(CT)图像重建。


扩散模型的基本概念 🌪️

上一节我们介绍了神经微分方程及其与神经网络架构的联系。本节中,我们来看看什么是扩散模型。

扩散是粒子从高浓度区域向低浓度区域的随机运动过程。例如,气体粒子在容器中随机碰撞并扩散到更大的空间。在图像处理中,我们可以将每个像素值视为一个“粒子”,通过向其添加高斯噪声来模拟扩散过程。这意味着,从任何一张图像开始,经过足够长时间的噪声添加,最终都会得到一个简单的分布(通常是高斯分布)。


扩散的数学描述 📐

为了更精确地描述应用于图像的扩散过程,我们需要使用概率分布和随机微分方程。

我们从一个数据分布 ( P_0(x) ) 中采样得到初始图像 ( x_0 )。通过一个扩散过程,我们最终得到一个简单的先验分布 ( P_T(x) ),例如高斯分布。这个过程可以用一个随机微分方程来描述:

[
dx = f(x, t) dt + g(t) dW
]

其中:

  • ( dx ) 是像素值的微小变化。
  • ( f(x, t) ) 是漂移函数,描述确定性变化。
  • ( g(t) ) 是扩散函数,控制噪声的强度。
  • ( dW ) 是维纳过程,代表每一步添加的高斯噪声。

逆向过程与图像生成 🔄

一个非常了不起的数学结果表明,存在一个对应的逆向随机微分方程。如果我们从先验分布(噪声)中采样,并沿着时间反向求解这个方程,就可以得到一个来自原始数据分布 ( P_0(x) ) 的图像样本。

更进一步的发现是,还存在一个对应的常微分方程。求解这个逆向ODE同样可以从噪声生成图像,并且这个过程是确定性的。其形式如下:

[
dx = \left[ f(x, t) - \frac{1}{2} g(t)^2 \nabla_x \log p_t(x) \right] dt
]

这个方程与逆向SDE相似,但少了随机项。其中,( \nabla_x \log p_t(x) ) 被称为分数函数,它是概率分布对数关于 ( x ) 的梯度。


训练扩散模型:学习分数函数 🎯

上一节我们看到了逆向生成过程依赖于分数函数 ( \nabla_x \log p_t(x) )。然而,这个函数非常复杂,我们无法直接获得。

因此,训练扩散模型的核心目标就是:使用一个神经网络 ( s_\theta(x, t) ) 来近似这个分数函数。网络的输入是带噪图像 ( x_t ) 和时间步 ( t ),输出是一个与 ( x_t ) 维度相同的“图像”,即估计的分数。

那么,如何训练这个网络呢?以下是训练一个扩散模型的关键步骤:

  1. 收集数据:获取大量你想要建模的图像(例如自然图像、医学图像)。
  2. 定义前向过程:选择一个具体的SDE形式来描述扩散过程,并推导出其转移概率 ( p(x_t | x_0) )。
  3. 定义损失函数:一个常用且有效的损失函数是去噪分数匹配。经过推导,它可以简化为一个非常直观的形式:让网络预测添加到图像上的噪声。
  4. 训练网络:通过最小化损失函数来优化神经网络的参数 ( \theta )。
  5. 生成图像:训练完成后,从先验分布(如高斯分布)中采样一个随机噪声图像,然后使用训练好的分数网络 ( s_\theta(x, t) ),通过求解逆向ODE或SDE来生成新图像。

扩散模型在科学中的应用:CT图像重建 🏥

扩散模型不仅是强大的生成工具,还能用于解决科学中的逆问题。我们以CT图像重建为例。

在CT扫描中,我们观测到的是正弦图数据,目标是重建出内部的吸收图像。传统的逆问题求解方法可能面临不适定性或需要强先验。

一种新颖的方法是将预训练的扩散模型作为图像先验。具体流程如下:

  1. 在大量CT图像上训练一个无条件扩散模型,使其学会生成逼真的CT图像。
  2. 在生成(推理)阶段,我们不仅进行逆向扩散去噪,还在每个时间步穿插一个优化步骤
  3. 这个优化步骤计算当前中间图像 ( x_t ) 对应的预期正弦图实际观测数据之间的误差梯度,并用它来“微调” ( x_t ),使其更符合观测数据。

这样,生成过程同时受到两个力的引导:一是扩散模型将其拉向逼真的CT图像分布(先验),二是数据一致性项将其推向阳满足观测结果。这种方法将生成模型与传统优化巧妙地结合在一起。


总结 📝

本节课中我们一起学习了扩散模型的核心思想。我们从扩散的物理概念出发,理解了其数学描述——随机微分方程。我们看到了如何通过学习和求解逆向过程(无论是SDE还是ODE)来从噪声生成图像,其关键在于用神经网络近似分数函数。最后,我们探讨了扩散模型如何超越单纯的生成任务,通过引入数据一致性约束,应用于像CT重建这样的科学逆问题,展示了其强大的灵活性和潜力。扩散模型建立了与神经微分方程的深刻联系,是当前人工智能在科学与工程应用中的一个重要前沿。

023:JAX 入门教程 🚀

在本节课中,我们将要学习 JAX,一个用于科学计算和机器学习的 Python 库。我们将了解其核心概念、功能,以及它如何通过加速数组计算和强大的程序变换能力,帮助我们高效地构建和训练科学机器学习模型。


什么是 JAX?🤔

JAX 是一个 Python 库,它主要做两件事:

  1. 加速数组计算:它允许在 GPU 和 TPU 等加速器上高效执行线性代数运算,充分利用现代硬件的并行能力。
  2. 程序变换:这是 JAX 设计的核心。它可以将一个 Python 函数变换成另一个具有新功能的函数,例如自动求导或向量化。

这两个特性结合在一起,使得 JAX 非常适合构建高性能、可扩展的科学机器学习算法,甚至是传统的科学计算任务。


为什么选择 JAX?💡

JAX 已被用于构建一些最大规模的机器学习模型和前沿的科学计算项目,例如:

  • Gemini:谷歌的大型语言模型,使用 JAX 在数千个 GPU 上进行训练。
  • AlphaGo:DeepMind 的围棋算法,其底层实现使用了 JAX。
  • AlphaFold:用于预测蛋白质三维结构的模型。
  • Brax:用于机器人强化学习的刚体模拟库。
  • 气候模拟:使用 JAX 在 16 个 A100 GPU 上 24 小时内完成海洋表面流速的大规模模拟。

这些例子展示了 JAX 在解决大规模、高性能计算问题方面的强大能力。


加速数组计算 ⚡

JAX 可以简单地看作是“运行在 GPU 上的 NumPy”。其核心模块 jax.numpy 的语法与 NumPy 几乎完全相同,但代码可以自动在 GPU 上运行。

CPU 与 GPU 的差异

为什么 GPU 上的矩阵乘法比 CPU 快得多?

  • CPU:拥有少量(如 16 或 32 个)但非常强大的核心,擅长串行计算(顺序执行任务)。
  • GPU:拥有数千个较小的核心,专为并行计算设计,非常适合同时处理大量相同的简单运算(如矩阵元素相乘)。

深度学习中的大部分计算(如矩阵运算)都是高度并行的,因此 GPU 能极大地加速这些任务。

实际案例:波动方程模拟

考虑一个使用有限差分法模拟波动方程的科学计算代码。原始的 NumPy 实现涉及大量的数组操作。

通过 JAX 加速,我们只需:

  1. import numpy as np 替换为 import jax.numpy as jnp
  2. 使用 JAX 的 jax.lax.scan 等原语替代 Python 原生的 for 循环,以便更好地编译。

性能对比结果如下(在同一台设备上):

  • 优化后的 NumPy (CPU):8 秒
  • JAX 编译后 (CPU):1.5 秒 (提速约 5 倍)
  • JAX 编译后 (GPU):0.065 秒 (提速约 123 倍)

这个例子表明,即使是纯粹的数值模拟,JAX 也能通过 GPU 并行和编译优化带来巨大的性能提升。


程序变换:JAX 的核心魔法 ✨

上一节我们介绍了 JAX 如何加速数组计算。本节中,我们来看看其更强大的特性:程序变换。这是 JAX 区别于其他库(如 PyTorch)的关键。

什么是程序变换?

程序变换是指将一个函数作为输入,并返回一个新函数的操作。这个新函数实现了原始函数的某种变换。

一个最经典的例子是自动求导(grad)。

定义原始函数

def f(x):
    return x ** 2  # 计算 x 的平方

应用 grad 变换

from jax import grad
grad_f = grad(f)  # grad_f 是一个新函数

现在,grad_f(x) 不再计算 x**2,而是计算其梯度 2*x。你可以像调用普通函数一样在任何点 x 上调用 grad_f 来获取该点的梯度。

与 PyTorch 的差异

在 PyTorch 中,你通常需要:

  1. 设置张量 x 并指定 requires_grad=True
  2. 执行计算 y = f(x)
  3. 调用 y.backward() 来计算梯度,梯度会存储在 x.grad 中。

PyTorch 的自动微分与特定的计算图和张量值绑定。而 JAX 的 grad 变换直接给你一个可以随处调用的梯度函数,这在概念上更清晰,也更容易组合。

变换的底层原理

JAX 通过以下步骤实现变换:

  1. 将 Python 函数转换为一个中间表示(JAXPR),这是一种更底层的函数描述。
  2. 将变换规则(如求导规则)应用到这个中间表示上。
  3. 生成一个新的、变换后的函数(及其新的中间表示)。

这本质上是一种“元编程”:程序能够生成新的程序。

变换的组合

JAX 的强大之处在于,这些程序变换可以任意组合。例如,你可以对梯度函数再次求导,以获得二阶导数(Hessian)。

from jax import grad
grad_f = grad(f)      # 一阶导数函数:2*x
grad_grad_f = grad(grad_f) # 二阶导数函数:2

其他重要的程序变换 🛠️

除了 grad,JAX 还提供了其他强大的变换,它们共同构成了其灵活性的基础。

向量化变换 (vmap)

vmap(向量化映射)用于自动并行化一个函数。假设你有一个处理单个样本的函数,但你想批量处理许多样本。

定义处理单个样本的函数

def layer(w, b, x):
    # w: 权重矩阵, b: 偏置向量, x: 单个输入向量
    return jnp.dot(w, x) + b

使用 vmap 进行向量化

from jax import vmap
# 指定对 `x` 的第0轴进行批处理,其他参数不变
batched_layer = vmap(layer, in_axes=(None, None, 0))

现在,batched_layer 可以接受一个批量的 x(形状为 [batch_size, ...]),并返回批量的输出。JAX 会自动将其重写为高效的矩阵运算,而不是低效的 Python 循环。

即时编译 (jit)

jit(即时编译)将你的函数编译成针对目标硬件(CPU/GPU/TPU)高度优化的版本,通常能显著提升运行速度。

编译带来的优化

  • 内核融合:将多个连续的小操作融合成一个大的操作,减少内存读写开销。
  • 其他优化:利用 XLA(加速线性代数)编译器进行各种底层优化。

使用方式

from jax import jit
compiled_func = jit(my_slow_function)
result = compiled_func(my_input) # 第一次调用会编译,后续调用极快

注意:编译有初始开销,因此通常只对需要反复调用的函数(如神经网络训练循环中的梯度更新步骤)使用 jit


综合示例:使用 JAX 进行线性回归 📈

现在,让我们将学到的所有概念——gradvmapjit——组合起来,解决一个简单的线性回归问题。

我们的目标是拟合一条直线 y = w*x + b 到一组数据点。

步骤 1:定义模型和损失函数

import jax
import jax.numpy as jnp

# 1. 前向模型(单样本)
def forward(w, b, x):
    return w * x + b

# 2. 使用 vmap 对模型进行批处理
batched_forward = jax.vmap(forward, in_axes=(None, None, 0))

# 3. 损失函数(均方误差)
def loss(params, x_batch, y_batch):
    w, b = params
    y_pred = batched_forward(w, b, x_batch)
    return jnp.mean((y_pred - y_batch) ** 2)

步骤 2:获取梯度函数

# 4. 获取损失函数关于参数 (w, b) 的梯度函数
grad_loss = jax.grad(loss)
# value_and_grad 可以同时返回损失值和梯度
loss_and_grad = jax.value_and_grad(loss)

步骤 3:定义梯度下降更新步骤并编译

# 5. 定义单次梯度下降更新函数
def update_step(params, x_batch, y_batch, lr):
    current_loss, grads = loss_and_grad(params, x_batch, y_batch)
    # 使用树映射更新参数元组 (w, b)
    new_params = jax.tree_map(lambda p, g: p - lr * g, params, grads)
    return new_params, current_loss

# 6. 编译更新函数以提升速度
compiled_update_step = jax.jit(update_step)

步骤 4:运行训练循环

# 初始化参数
params = (1.0, 0.0)  # (w, b)
learning_rate = 0.01

for epoch in range(100):
    params, current_loss = compiled_update_step(params, x_data, y_data, learning_rate)
    if epoch % 20 == 0:
        print(f"Epoch {epoch}, Loss: {current_loss:.4f}")

通过这个例子,你可以看到 JAX 如何以清晰、可组合的方式,将自动微分、向量化和编译无缝集成到一个简洁的工作流中。


JAX 在科学机器学习中的应用 🧪

JAX 的上述特性使其成为科学机器学习(SciML)的理想工具。SciML 旨在将机器学习与传统的科学计算(如求解微分方程)紧密结合。

已经有许多优秀的库构建在 JAX 之上:

  • 优化optax(梯度下降优化器库)。
  • 神经网络Flax, Haiku(定义和训练神经网络)。
  • 微分方程Diffrax(求解常微分方程/随机微分方程,支持可学习组件)。
  • 概率编程NumPyro(贝叶斯推断)。
  • 物理信息机器学习DP-CFD
  • 分子动力学JAX, MD
  • 计算流体动力学JAX-CFD

示例:波动方程反问题

一个典型的 SciML 问题是反演。例如,在地球物理中,给定观测到的地震波场,推断地下介质的速度模型。

使用 JAX,我们可以:

  1. 用 JAX 编写波动方程的正向模拟器(如前所述)。
  2. 定义损失函数,衡量模拟波场与观测波场的差异。
  3. 使用 jax.grad 计算损失函数关于速度模型的梯度。
  4. 使用 optax 中的优化器(如 Adam)更新速度模型。

关键优势在于,只需在正向模拟代码基础上增加约10行代码,就能实现这个复杂的反演流程,并且整个过程受益于 GPU 加速和自动微分,无需手动推导复杂的梯度公式。


总结 🎯

本节课中,我们一起学习了 JAX 的核心概念:

  1. 加速数组计算:JAX 提供了类似 NumPy 的接口(jax.numpy),但能自动在 GPU/TPU 上运行,极大加速了科学计算。
  2. 程序变换:这是 JAX 的灵魂。通过 gradvmapjit 等变换,我们可以轻松实现自动微分、自动向量化和即时编译。
  3. 组合性与清晰性:这些变换可以任意组合,使得代码既强大又易于理解和维护。
  4. 科学机器学习:JAX 的设计非常适合 SciML 任务,有丰富的生态系统支持,能够高效地将机器学习与科学模拟相结合。

JAX 通过将“函数变换”作为一等公民,为研究人员提供了构建下一代高性能、可微分科学计算应用的强大工具。

024:符号回归与模型发现

在本节课中,我们将要学习符号回归与模型发现。我们将了解什么是模型发现,如何定义它,以及符号回归作为解决模型发现任务的一种方法。我们将深入探讨符号回归面临的挑战,以及为什么这是一项艰巨的任务。我们还将讨论函数发现这一概念上更简单的任务,并了解当前最先进的模型发现系统。课程结束时,你将理解符号回归算法的工作原理、设计要点以及其中的重要概念和挑战,并掌握如何将符号回归用于函数和模型发现。


模型发现的愿景

上一节我们介绍了课程背景,本节中我们来看看模型发现的宏伟目标。

爱因斯坦的场方程是物理学中最著名的方程之一。它描述了时空曲率与其中物质、能量和动量之间的关系。这节课要探讨的核心问题是:未来,人工智能能否帮助我们做出这类突破性的物理发现?虽然目前我们尚未达到这一水平,但这仍是一个激动人心的领域,我们正朝着利用人工智能帮助发现物理或其他基本科学现象的目标迈进。

人工智能在科学发现中可能非常有用,原因有二:

  1. 当今实验产生的数据量巨大,例如欧洲核子研究中心每月记录的数据量已达数千太字节,人类无法手动处理。
  2. 我们研究的科学问题日益复杂,例如新冠病毒的演化,其中可能隐藏着人类难以察觉的模式。

那么,人工智能能否帮助我们处理这些数据和问题呢?


任务定义:模型发现与函数发现

上一节我们提出了愿景,本节中我们来具体定义两个任务。

我们将定义两个利用机器学习帮助我们的任务。第一个是模型发现

  • 给定对一个科学或物理系统的观测(例如阻尼谐振子的位置随时间变化),目标是找到描述该系统的底层模型(例如一个常微分方程),而不仅仅是对曲线的函数拟合。

第二个是概念上更简单但仍具挑战性的函数发现

  • 给定某个函数的一些观测样本(假设该函数具有解析表达式),目标是找出其实际的数学表达式,这与标准的函数拟合不同。

以下是物理学中一些著名的函数表达式示例:

  • 理想气体定律:PV = nRT
  • 相对论性能量:E = mc²
  • 普朗克黑体辐射定律
  • 欧姆定律
  • 斯涅尔定律
  • 费米-狄拉克分布

符号回归的挑战

上一节我们定义了任务,本节中我们来看看实现这些任务的主要方法——符号回归,以及它为何如此困难。

我们通过一个猜函数游戏来引入。给定函数在区间 [-3, 3] 上的图像,其实际表达式为 y = x * cos(π * x²)。人类可能会通过观察振荡频率随x增加而增加、振幅线性增长等特征来猜测。

这里需要明确符号回归函数拟合的区别:

  • 函数拟合:假设一个数学表达式的形式(如神经网络),仅学习其中的系数(权重和偏置)。
  • 符号回归:目标是发现完整的数学表达式,包括运算符和结构。

那么,为什么符号回归通常比函数拟合更难?原因如下:

  1. 需要学习整个表达式,而不仅仅是系数,且表达式的长度可能未知。
  2. 搜索空间通常是指数级的。如果将数学表达式视为由基本运算符组成的字符串,那么所有可能的组合数是 S^n,其中 S 是运算符库大小,n 是表达式长度。
  3. 搜索空间通常是不可微的。如何对运算符(如加法、除法)进行微分?这没有明确意义。
  4. 给定有限数量的观测点,可能存在许多有效的表达式,这导致问题是不适定的,容易过拟合。

表达式的树形表示

上一节我们了解了挑战,本节中我们来看看如何通过选择合适的表示来帮助搜索。

为了高效搜索,选择合适的表示至关重要。一种有效的方法是将数学表达式视为

  • 根节点:代表整个表达式,对其进行求值可得到结果。
  • 内部节点:代表运算符(如 +, *, cos, ^)。
  • 叶节点:代表系数或变量(如 x, 2, π)。

例如,表达式 x * cos(π * x²) 可以表示为以下树结构:

        (*)
       /   \
      x    (cos)
            |
           (*)
          /   \
         π    (^)
              / \
             x   2

大多数运算可以分解为单目或双目运算。树的深度是一个重要属性。

即使对于深度仅为2、且运算符库非常有限(仅包含 x, +, *, ^2, +)的树,可能的表达式数量也已达到约65个。随着深度或运算符库的增加,搜索空间将急剧膨胀至无法遍历的程度。


简化搜索:剪枝与假设

上一节我们看到搜索空间巨大,本节中我们来看看如何通过剪枝和假设来简化问题。

我们无法以组合方式枚举所有可能的表达式并测试其与数据的匹配度。因此,必须对树的结构做出假设以剪枝搜索空间。这本质上是在概率上定义一个先验,即我们期望表达式满足的所有可能结构中的某个子集。

这引出了奥卡姆剃刀原则:最简单的解释通常是最好的。在机器学习中,这类似于偏差-方差权衡:随着模型复杂度增加,误差可能下降,但过拟合风险(方差)上升。我们需要选择模型复杂度的“最佳点”。

因此,成功解决符号回归问题需要两个高层级要素:

  1. 对表达式结构的假设:以避免组合式搜索。
  2. 高效的搜索算法:能够在定义的可能结构空间中搜索并收敛到拟合数据的表达式。

这是一个广阔的研究领域,有许多关于搜索算法和先验假设的创新。


利用隐藏的简洁性:AI Feynman 方法

上一节我们讨论了通用策略,本节中我们来看一个具体的先验假设方法:寻找函数中隐藏的简洁性。

AI Feynman 是一种在运行搜索算法之前,先寻找函数底层简化规律的方法。以牛顿万有引力定律为例:
F = G * m1 * m2 / r²
这个函数有哪些简洁性?

  1. 量纲一致性:等式两边的物理量纲必须匹配。利用量纲分析,我们可以将函数重写为一个无量纲常数乘以一个变量更少的无量纲函数,从而减少搜索变量数。
  2. 平移对称性:力仅取决于两物体间的距离 r,而非绝对位置。通过变量代换(如 dx = x2 - x1),可以减少函数依赖的变量数。
  3. 乘法可分离性:函数可以写成几个只依赖于部分变量的函数的乘积。例如,F ∝ (m1*m2) * (1/r²)。这允许我们对更简单的子函数进行独立搜索。

AI Feynman 算法的工作流程如下:

  1. 从一个神秘函数(如 F(G, m1, m2, x1, y1, z1, x2, y2, z2))开始。
  2. 依次进行量纲分析、对称性测试、可分离性测试,逐步简化函数形式,减少变量。
  3. 对最终简化后的函数(变量数已大大减少)使用搜索算法(如暴力搜索)来发现其数学表达式。
  4. 将所有简化步骤反向代入,得到原始变量的最终表达式。

该算法中,神经网络仅用于拟合观测数据以提供任意点的函数查询(插值),便于进行上述测试,其本身并不直接发现符号表达式。

此方法的局限在于,如果目标函数不具备这些隐藏的简洁性,则测试会失败,最终仍需依赖暴力搜索。


遗传算法搜索

上一节我们讨论了如何通过先验简化问题,本节中我们来看看一种更智能的搜索算法:遗传算法。

除了暴力组合搜索,我们可以使用启发式方法更有效地搜索树空间。遗传算法是一种受进化论启发的梯度自由搜索方法。

核心思想是:如果某个表达式树能较好地拟合数据,那么通过对其施加小的遗传操作,可能得到更接近真实解的表达式。主要遗传操作有:

  1. 变异:随机改变树中的一个节点(运算符或叶节点)。例如,将 + 变为 *
  2. 交叉:随机选择两棵树的子树进行交换。这类似于在数学抽象层面进行重组。

遗传搜索算法的伪代码如下:

1. 初始化:随机生成一个表达式树种群。
2. 循环直到满足收敛条件:
   a. 选择:根据适应度(如测试误差)选择当前种群中最优的树。
   b. 遗传操作:对选出的树应用变异和交叉操作,产生新树。
   c. 淘汰:移除适应度低(或“年老”)的个体。
   d. 更新种群:将新生成的树加入种群。

一个著名的符号回归库 PySR 就使用了遗传算法,并进行了改进,例如在循环中随机加入常数优化步骤。该算法还支持并行化,多个线程独立演化子种群,然后进行交叉,形成更复杂的演化策略。


其他搜索算法概览

上一节我们深入了解了遗传算法,本节中我们快速浏览一些其他有潜力的搜索算法。

目标仍然是给定数据集 D 寻找函数 f

  • 直接学习:不进行显式循环搜索,而是直接将观测数据作为输入,训练一个模型来输出表达式。Transformer 模型很有潜力,因为数学表达式可以看作一种具有语法(运算符)的语言,Transformer 的注意力机制可以处理这种结构。
  • 强化学习:将构建树的过程建模为一个环境,智能体根据当前树的状态和测试误差等,选择添加下一个节点(运算符)。智能体通过最终是否匹配表达式获得奖励进行训练。
  • 经典树搜索算法:如深度优先搜索、广度优先搜索等,但需注意这里的搜索目标是构建整棵树,而非在固定树中搜索节点。

这些方法各有优劣,选择取决于具体问题。


从函数发现到模型发现

上一节我们聚焦于函数发现,本节中我们将其扩展到更复杂的模型发现。

模型发现的目标是发现支配系统的实际模型(如微分方程),而不仅仅是静态函数。我们仍然可以使用符号回归方法,但需要在运算符库中加入微分算子(如 d/dt),这使得问题更加复杂,通常需要添加额外的领域约束来帮助收敛。

一个著名算法是 SINDy。它用于发现形式为 dx/dt = f(x) 的动力系统方程。其关键假设是:我们拥有系统状态 x 及其导数 dx/dt 的许多观测数据。这样,问题就转化为寻找向量值函数 f,这可以看作一个符号回归任务。

SINDy 进一步对 f 的结构做出强假设:它假设 f 可以由一个预设的函数库(如多项式、三角函数等)的线性组合构成。设 Θ(X) 为库函数矩阵,Ξ 为系数矩阵,则有 dX/dt = Θ(X) Ξ。由于 Θ(X) 可以从数据 X 计算,dX/dt 已知,因此求解 Ξ 就变成了一个稀疏线性回归问题(如 LASSO),因为我们期望只有少数库函数是活跃的。

SINDy 的扩展甚至可以从原始观测(如摆锤的视频)中自动学习状态编码,并同时发现动力学方程。


课程总结

在本节课中,我们一起学习了符号回归与模型发现。我们探讨了如何利用人工智能从数据中发现数学表达式和物理模型,理解了符号回归的巨大挑战(如指数级搜索空间、不可微性),并介绍了应对这些挑战的策略,包括利用隐藏简洁性(如 AI Feynman)、高效的启发式搜索算法(如遗传算法),以及针对微分方程等特定模型的发现方法(如 SINDy)。

回顾整个课程,我们涵盖了科学机器学习中的众多主题:物理信息神经网络、算子学习、Transformer、混合工作流、可微分方程与模型发现。贯穿始终的核心思想是,可以将科学理解以多种方式融入机器学习工作流,例如通过损失函数、架构设计,或更紧密地集成到传统科学工作流程中。

使用深度学习存在利弊,需要谨慎评估而非盲目使用。但总体而言,将科学理解融入机器学习通常会提升我们解决科学问题的能力。

展望未来,在科学与人工智能交叉领域,有两个高层次的核心方向具有巨大研究潜力和影响力:

  1. 搜索与优化:许多科学问题(反问题、模型发现、控制)和AI问题(规划、推理、学习)本质上都是搜索优化问题。设计具有良好先验知识的高效搜索算法至关重要。
  2. 表示学习:在科学中,选择何种近似表示(如PDE的基函数、网格离散化)对计算效率和精度有根本性影响。在AI中,表示学习(如LLM的抽象推理、分层规划)同样是核心挑战。深入思考表示问题将对这两个领域产生深远影响。

希望本课程能为你提供启发,并鼓励你在这一充满活力的领域继续探索。

025:人工智能在化学与生物学中的应用(第一部分)

在本节课中,我们将学习人工智能如何应用于蛋白质和小分子的工程化设计。我们将从基础知识开始,了解蛋白质和小分子的基本概念,然后探讨基于文本和基于结构的AI模型如何帮助解决这一领域中的关键挑战,例如新药开发和酶设计。

蛋白质与小分子简介

首先,我们需要了解蛋白质和小分子的基本概念,以便为后续讨论奠定共同的基础。

小分子是有机化合物,分子量较低,通常由少于100个原子组成。生物体可以产生小分子,例如作为代谢物或信号分子。例如,皮质醇是一种应激激素,可以驱动我们的新陈代谢。这些小分子通常可以轻松地穿过细胞膜,并与蛋白质相互作用,从而影响其功能。因此,大多数药物都是小分子,因为它们可以进入细胞并与蛋白质相互作用,从而改变某些疾病通路。由于小分子结构简单,通常可以在化学实验室中进行合成。

蛋白质是由一组固定的构建单元组成的大型链状分子。这些链会折叠成一个确定的三维结构,称为蛋白质的天然构象。这种结构决定了蛋白质的功能。蛋白质可以是酶(催化特定化学反应的蛋白质)、结构成分、信号分子或转运蛋白。总的来说,蛋白质是生命的基本组成部分,在几乎所有生命必需的过程中都扮演着关键角色。

蛋白质由氨基酸构成,共有20种标准氨基酸。所有氨基酸都有一个共同的骨架(氨基和羧基),它们通过这个骨架连接成链。不同氨基酸之间的区别在于它们的侧链,侧链决定了氨基酸的化学性质。

我们的DNA决定了蛋白质的氨基酸序列。DNA被读取并转录成RNA,然后RNA被翻译成氨基酸链。一旦氨基酸链合成,它就会折叠成一个有序的三维结构,从而定义蛋白质的生物学功能。这种折叠是由氨基酸及其侧链之间的相互作用(例如疏水相互作用、氢键或范德华力)引导的自发能量最小化过程。

描述蛋白质时,我们可以考虑三个结构层次:

  1. 一级结构:氨基酸在链中的序列。
  2. 二级结构:由氢键稳定的规则重复的局部结构,例如α螺旋或β折叠。
  3. 三级结构:这些二级结构在三维空间中的空间关系。

蛋白质通常以卡通图的形式展示,这种图可以很好地可视化二级结构(如螺旋和折叠),但只显示氨基酸骨架的位置,而不显示侧链。

蛋白质与小分子工程的目标

上一节我们介绍了蛋白质和小分子的基础知识,本节中我们来看看工程化设计它们的目标是什么。

正如前面提到的,大多数药物是小分子,它们可以结合蛋白质并影响生物过程。这些小分子的化学结构和组成决定了它们的功能和结合偏好。因此,小分子药物通常被设计用于与特定的目标相互作用,通过结合来抑制或调节疾病通路。例如,小分子可以抑制酶或阻断受体。工程化小分子通常通过改变这些有机化合物的大小和组成来获得所需的性质和结合偏好。

在蛋白质工程中,核心是改变氨基酸链的序列,以实现特定功能。例如,在生物催化领域,可以改变酶的氨基酸序列,使其能够接受新的底物。在治疗领域,一个常见的例子是改变抗体的序列,使其能够结合特定的目标,例如新冠病毒的刺突蛋白。

以下是几种常见的蛋白质工程策略:

  • 理性设计:利用对蛋白质或系统的详细知识来进行有针对性的改变。
  • 半理性设计:在认为重要的氨基酸位点上,尝试所有可能的氨基酸替换,构建一个组合变体库。
  • 定向进化:从一个已有功能的蛋白质开始,引入随机突变,从生成的变体池中筛选出功能最好的,然后重复这个过程,这是一种加速的进化过程。

然而,这些工程任务的主要挑战在于优化蛋白质和氨基酸序列的搜索空间极其巨大。对于一个长度为100的氨基酸链,考虑到有20种天然氨基酸,可能的序列数量是 20^100。而蛋白质通常由数百甚至数千个氨基酸组成。这就是人工智能可以发挥作用的地方,AI可以帮助更好地导航和过滤这个巨大的搜索空间。

基于文本的AI模型

现在,我们开始讨论基于文本的AI模型。之所以称为“基于文本”,是因为这些模型的输入是蛋白质和小分子的文本表示。

对于蛋白质,文本表示非常直接,就是氨基酸序列。对于机器学习,氨基酸序列可以被编码成数值表示,例如使用独热编码或其他标记化方法,将每个氨基酸视为一个单独的标记,类似于文本处理中的单词。

对于小分子,情况稍微复杂一些。常用的表示方法是SMILES代码,这是一种使用字符表示分子结构的线性符号。原子用其化学符号表示,单键通常省略,双键用等号表示,分支用括号描述,环用数字表示连接点。对于机器学习,这些SMILES代码同样会被标记化并映射到一个固定的词汇表。

你可能已经注意到,这种标记化和文本表示听起来很像自然语言处理。这些方法对该领域产生了巨大影响,因为语言的构建单元与蛋白质和小分子的构建单元之间存在类比关系。蛋白质序列有自己的“语法”,也包含长程依赖关系。SMILES代码也是由固定词汇组成的线性序列,并遵循特定的书写规则。因此,蛋白质序列和SMILES代码都与设计用于处理此类线性序列的语言模型架构兼容,这就是为什么NLP的方法经常被应用于蛋白质和小分子。

接下来,我们来看一个具体的例子。这是一个由苏黎世联邦理工学院的化学家开发的Transformer模型,用于预测分子的温度依赖性极限活度系数。输入是溶质和溶剂的SMILES代码,输出是预测的活度系数。SMILES代码被标记化并嵌入为输入矩阵,温度信息也被添加到这个输入矩阵中。然后,Transformer块转换这个输入嵌入,并将新的表示输入到一个回归头中,输出代表预测活度系数的单个值。该模型在实验数据上进行了监督训练,并且能够很好地泛化到未见过的分子。

另一个著名的例子是ESM模型,它是由Meta公司训练的。这是一个基于掩码语言模型目标在蛋白质序列上进行自监督学习的模型。它使用了2.5亿个蛋白质序列进行训练。模型的工作原理是:输入序列的一小部分氨基酸被掩码替换,然后模型需要预测哪些氨基酸被掩码了。如果模型能持续在这个任务上表现良好,就意味着它必须了解很多关于蛋白质序列和结构的知识。事实证明,在这个模型生成的隐藏状态表示中,编码了大量的内在生物学特性和蛋白质结构信息。这使得这些表示对于下游应用(如蛋白质功能预测、突变效应预测、蛋白质稳定性预测甚至3D结构预测)非常有用。通过微调,可以将这个预训练的语言模型应用于特定的、可能数据量较小的监督学习任务。

蛋白质结构预测

上一节我们提到了蛋白质结构,现在让我们过渡到蛋白质结构预测这个主题。

首先,我们需要了解为什么蛋白质结构如此重要。简单来说,蛋白质结构指的是蛋白质在其折叠状态下所有原子的三维坐标。了解结构非常重要,因为它能帮助我们更好地理解蛋白质,正如之前所说,结构决定了功能。了解结构有助于我们发现蛋白质的生物学作用。在药物发现中,了解蛋白质结构可以帮助我们识别一些活性位点或口袋,这些位点可能是小分子药物的靶点。

然而,多年来,研究人员一直依赖非常耗时的实验方法(如X射线晶体学或核磁共振)来解析蛋白质结构。最近发布的深度学习模型在无需实验程序的情况下预测结构方面取得了巨大进展。

从序列预测蛋白质折叠是一项极其困难的任务,因为氨基酸在其骨架键和侧链键周围有很多旋转自由度,即使是一个很小的蛋白质,其可能的结构数量也是天文数字。折叠还受到氨基酸侧链之间各种相互作用(如氢键、疏水相互作用、范德华力)的驱动,这些相互作用很难建模。此外,还存在长程依赖关系,即折叠可能受到序列中相距很远但在三维折叠中却靠得很近的氨基酸之间的相互作用的影响。

由于这个任务非常重要,有一个名为“蛋白质结构预测关键评估”的比赛每隔几年举行一次,邀请研究人员和机器学习专家尝试从序列预测蛋白质折叠。AlphaFold2在第14届比赛中以很大优势获胜。其预测的Cα原子(每个氨基酸骨架三角的尖端)的均方根偏差仅为0.96埃(碳原子的宽度约为1.4埃),预测非常精确。这是一个结构生物信息学领域的突破。

接下来,我们简要了解一下AlphaFold的架构。模型的输入是想要折叠的蛋白质序列。模型首先在遗传数据库中搜索相似序列,生成多序列比对。同时,它还在结构数据库中搜索已知结构的类似蛋白质作为模板,并基于这些模板生成氨基酸对之间距离的初步猜测。然后,模型从多序列比对和成对距离矩阵生成MSA表示和配对表示。这两个表示被传递到Evoformer(AlphaFold架构的核心),这个Transformer模型通过注意力机制和类卷积操作更新这些表示。更新后的表示被传递到结构模块,该模块将其转换为空间坐标,预测所有残基对之间的距离和蛋白质中的键角,从而构建蛋白质的3D模型。模型还应用了“回收”概念,这是一个迭代精炼过程,结构模块的输出被多次反馈回Evoformer,以帮助改进预测。模型训练使用了多个结构目标损失项,以及一个额外的“蒸馏”目标(随机掩码部分多序列比对并要求网络重建)。此外,还应用了自蒸馏原则:首先在已知结构的实验数据集上训练模型,然后用训练好的模型预测大量未知结构蛋白质的序列,将预测结构与实验结构合并,从头开始重新训练模型,这可以重复多次,有效利用了未标记的序列数据。

在休息之前,我们谈到了用AlphaFold预测蛋白质结构。现在,让我们回顾一下之前提到的ESM模型。这个自监督模型在2.5亿个序列上以掩码语言模型目标进行训练。作者表明,在这个模型生成的隐藏状态表示中,也包含了蛋白质结构的信息。模型无法直接观察蛋白质结构,但结构是影响序列模式的隐藏变量,因此模型仍然可以从序列中学习到蛋白质结构的信息。他们通过一个简单的逻辑回归分类器,使用隐藏状态表示作为输入,来预测每个氨基酸属于哪种二级结构(螺旋、折叠或卷曲),并取得了很高的分类准确率,这证明了这一点。

随后,发布了ESM模型的第二个版本ESM2。他们在ESM模型的基础上增加了一个“折叠头”,可以从ESM模型的隐藏状态表示中提取原子坐标。他们在这个预训练模型上进行了微调,添加了折叠Transformer块,也应用了类似AlphaFold的回收策略,并在30万个实验确定的PDB蛋白质结构上进行了训练,达到了与AlphaFold相似的预测精度。这个模型的显著之处在于,它移除了AlphaFold中最耗时的部分:不需要访问数据库寻找模板或进行多序列比对。这使得模型预测蛋白质结构的速度比AlphaFold快约60倍,并且是完全独立的,只需输入序列即可输出结构。

在性能比较方面,两个模型在预测骨架原子位置上都表现得很好,AlphaFold通常略好一些。在预测侧链原子位置方面,两者性能都有所下降,因为侧链通常更灵活,AlphaFold在定位侧链方面通常仍然表现更好。因此,如果对骨架和侧链的高精度要求至关重要,建议使用AlphaFold。但如果需要对大量蛋白质进行快速预测,ESM和ESMFold提供了非常有价值的工具。总的来说,获得蛋白质结构因这些模型而变得容易得多。但需要注意的是,它们仍然只是接近实验精度,并且对于动态的蛋白质,这些模型通常给出的是一个平均构象,可能无法捕捉到蛋白质的灵活性。

基于结构的AI模型:3D CNN与图神经网络

现在我们已经知道如何用深度学习预测蛋白质结构,接下来我们来讨论使用结构信息作为输入的AI模型。首先,我们将讨论3D卷积神经网络,然后是图基模型。但在讨论这些之前,我们需要先简要介绍一下图和图神经网络的基础知识。

如果我们有一个包含几百个氨基酸的蛋白质,用AlphaFold预测结构可能需要15分钟左右,而用ESM可能不到一分钟,对于小蛋白质可能只需几秒钟。

首先,重复一下关于蛋白质结构的概念。蛋白质结构决定了其功能,蛋白质折叠成复杂的形状,使其能够与其他分子相互作用。单独的蛋白质序列不提供原子在三维空间中实际排列的信息。因此,结合了结构信息的模型在需要理解残基物理位置的任务(如相互作用预测或酶活性预测)上应该更优越。然而,使用结构数据也存在挑战,例如结构数据的可用性较低,而基于序列的方法通常更简单、计算效率更高。

关于3D CNN,我们解释一下一般流程以及如何用它处理蛋白质。要将原子坐标转换为适合3D CNN的形式,需要将蛋白质周围的空间划分为体素的网格。然后,可以使用不同类型的原子属性来定义输入数据中的多个通道(例如碳通道、氮通道、氧通道)。接着,使用卷积和池化从这些三维网格中提取相关信息。最后,通过全连接层进行全局预测。这类3D CNN已被证明在蛋白质稳定性预测等任务中表现良好。

这里有一个例子是苏黎世联邦理工学院研究人员开发的3D CNN,用于预测蛋白质-配体亲和力。配体指的是结合到蛋白质上的小分子。亲和力指的是这种相互作用的强度。他们的做法是:以配体的几何中心为中心建立一个网格,将每个原子的位置映射到一个体素中,并使用额外的化学属性定义更多通道。然后使用卷积神经网络将这个3D网格缩减为一个代表亲和力预测的pKd值。这类3D CNN是首个在基于结构的亲和力预测上超越基于序列方法的模型。

然而,3D CNN也有一些缺点。模型参数量通常比2D CNN大得多,且随着网格分辨率和尺寸的增加,参数量呈立方增长。稀疏性也是一个问题,网格中的许多体素可能代表空的或均匀的区域,不包含有意义的信息,但模型仍然会处理这些体素,导致效率低下。此外,旋转不变性也是一个问题,为了实现与输入数据中3D物体空间方向无关的预测,通常需要以多种方向呈现物体,这使得模型训练的计算成本更高。因此,3D CNN通常需要大型训练数据集来避免过拟合,并且训练和推理需要大量的内存和处理能力。

图神经网络是3D CNN的一个潜在替代方案。图描述了一组称为节点的对象以及这些对象之间的连接(称为边)。图中的信息可以存储在每个节点和每条边中,还可以有一个与整个图相关的全局上下文向量。这是一种非常强大的数据表示形式,特别适用于非欧几里得和无序的数据,例如社交网络、引文网络或分子中的原子。图神经网络就是为处理此类图结构而开发的神经网络。

将图传递给神经网络时,需要将节点特征、边特征、连接性和全局上下文信息转换为矩阵格式。节点特征存储在节点特征矩阵中,每个节点的特征占据一行。连接性通常用邻接矩阵表示,但由于连接通常远少于矩阵中的条目数,邻接矩阵通常非常稀疏。因此,更常用的是一种更节省内存的表示方法:边索引(一种邻接列表),它只列出相连的节点对。边特征可以按照边索引的顺序存储在边特征矩阵中。全局上下文向量也以矩阵格式存储。

图神经网络可以解决多种任务:

  • 图级任务:预测整个图的单个属性(例如,一个分子是否是抗生素)。
  • 节点级任务:预测图中每个节点的属性(例如,社交网络中每个成员的忠诚度预测)。
  • 边级任务:预测图中边的属性或是否存在(例如,Facebook的好友推荐)。

图神经网络本质上是对图所有属性的可优化变换,它遵循“图进图出”的原则,逐步转换节点、边和全局上下文的嵌入,而不改变图的连接性。如果要进行节点级的预测,可以对变换后的节点嵌入应用线性分类器。

为了更新和变换节点、边和全局上下文向量中的特征,图神经网络通常应用消息传递神经网络框架。相邻的节点或边相互交换信息,并影响彼此更新后的嵌入。这使得学习到的嵌入能够感知图的连接性和节点的邻域信息。消息传递分为三个步骤:从目标节点的邻居那里收集消息,使用聚合函数(如求和)聚合这些消息,然后通过一个更新函数(通常是一个小型神经网络)生成节点的新嵌入。这个过程与图像上的卷积有相似之处,都是聚合和处理元素邻居的信息来更新元素的值。因此,图上的消息传递过程也被称为图卷积。与CNN类似,我们可以堆叠多个图卷积层,这样经过几层之后,一个节点就能获得距离它几步之遥的节点的信息。

常用的图卷积层有几种类型,每种都有不同的聚合函数。例如,图卷积网络层使用一个包含归一化项的公式来更新节点特征。图注意力网络层则使用基于两个节点特征及其之间边的特征计算出的注意力分数来加权聚合邻居信息。

基于图的AI模型应用示例

现在,我们继续讨论基于图的AI模型,并给出一些应用示例。

这是一篇2020年的优秀论文,研究人员训练了一个图神经网络来预测分子是否具有抗生素效果。这是一个图级的二元分类任务。他们为数据集中的分子生成图表示,并将化学数据添加到节点和边中。节点特征包括原子类型、电荷等信息;边特征包括化学键类型(单键、双键、是否在环内等)。他们使用这些带有化学信息的图表示来训练一个图神经网络。训练集包含2560个结构多样的药物分子,其中120个已知对大肠杆菌有生长抑制作用(即已知抗生素)。他们对这些分子进行简单的图卷积操作,然后进行全局池化,将所有节点和边的特征聚合成一个单一表示,再输入到一个神经网络中,输出预测的抑制概率。训练好模型后,他们将其应用于一个包含6000个分子的大型药物分子库进行推理。在模型预测概率最高的99个分子中,有51个确实显示了对大肠杆菌的生长抑制。而在模型预测概率最低的63个分子中,只有2个显示抑制。这是一个非常显著的结果。这项研究还导致了一种名为Halicin的新抗生素的发现,它对多种细菌具有杀菌作用。有趣的是,这种新抗生素与已知抗生素的结构相似性较低,这表明模型具有一定的泛化能力,能够发现新的抗生素化学结构。

这项研究将小分子建模为图,但理论上也可以扩展到蛋白质,因为蛋白质本质上是由固定构建单元组成的大分子。你可以将整个蛋白质建模为图。上面这个例子是在原子级别进行图建模,但接下来这项研究采用了一种不同的、更粗粒化的方法。这是一个用于预测蛋白质功能的图卷积神经网络。它接收蛋白质结构,并将其建模为氨基酸的点云(将每个氨基酸简化为其Cα原子)。然后,如果两个Cα原子之间的距离小于10埃,就将它们连接起来,从而得到一个表示蛋白质结构的互连图(一种接触图)。他们使用从蛋白质语言模型(如ESM)获得的嵌入来特征化这些氨基酸节点。然后,他们使用带有跳跃连接的三层图卷积,接着进行全局自适应池化,将所有节点的表示聚合成一个单一的表示向量,最后输入到一个全连接神经网络中,输出蛋白质属于各个功能类别的概率。这个简单的GCN在许多蛋白质功能分类的机器学习工具中表现优异。据推测,其主要原因是这种对蛋白质结构的图建模使得卷积能够在序列上相距很远但在三维结构中靠得很近的残基之间传递消息,从而使模型对蛋白质结构有更好的感知。

图神经网络为建模和处理三维物体(如分子)提供了许多优势。它们可以处理定义在不规则域中的数据,而无需将其映射到规则网格上。图表示对平移和旋转具有不变性。与之前讨论的体素网格相比,图表示更加稀疏。此外,图神经网络在数据集成方面有很多可能性,可以将数据保存在节点、边和全局上下文向量中,并在更新机制中整合这些信息。因此,图卷积神经网络在理解数据结构和互联性至关重要的任务中表现良好,并且通常可以用相对较少的参数取得很好的效果。

总结

本节课中我们一起学习了人工智能在蛋白质和小分子工程中的应用。

基于文本的AI模型方面,蛋白质和小分子可以用文本表示,并可以用自然语言处理方法高效处理。在这些文本表示上训练的语言模型可以生成信息丰富的潜在空间表示,甚至能够预测蛋白质结构。

基于结构的AI模型通常在需要空间位置信息的任务中表现更好。图是建模和处理此类非欧几里得、无序数据(如分子和社交网络)的理想选择。

总的来说,蛋白质和小分子的工程化设计极具挑战性,因为搜索空间极其巨大。本节课展示的这类AI模型,现在以及未来,将极大地帮助导航这个搜索空间,并加速新药或新功能酶等开发过程。

在下节课(周五),我们将讨论关于蛋白质从头设计的、非常新的生成式AI模型,例如使用扩散过程从零开始生成新的蛋白质结构。

026:AI在化学与生物学中的应用(第二部分)🎯

在本节课中,我们将学习用于蛋白质从头设计的生成式人工智能模型。我们将首先回顾理解这些模型所需的核心概念,然后深入探讨用于蛋白质骨架设计的RF扩散模型,以及用于序列设计的Protein MPNN模型。最后,我们将通过一个简短的演示来展示这些模型的强大能力。

回顾:蛋白质结构与预测模型

上一节我们介绍了蛋白质的基本知识,本节中我们来看看理解新模型所需的关键背景。

蛋白质是由氨基酸组成的链,它们根据氨基酸间的相互作用折叠成复杂的三维结构。一个蛋白质的骨架由相连的N、Cα和C原子三角形构成。所有20种氨基酸的区别仅在于连接在Cα原子上的侧链,而这个N-Cα-C三角形是所有氨基酸共有的。

我们还学习了AlphaFold2等折叠模型,它们能够从氨基酸序列预测蛋白质结构。AlphaFold的流程是:输入序列 -> 进行遗传数据库搜索(生成多序列比对)和结构数据库搜索(生成初始结构预测)-> 利用复杂的模型架构生成最终精修的结构预测。

此外,我们了解了图神经网络,它非常适合建模像蛋白质或蛋白质骨架这样的无序数据。在图神经网络中,通过图卷积进行消息传递,可以转换存储在节点和边中的数据,最终生成的节点和边嵌入将包含关于节点或边的连接性和邻域信息。

上周课程主要关于蛋白质工程,即通过修改现有天然蛋白质的序列来探索蛋白质空间,以优化其特性。工程化得到的蛋白质通常与起始蛋白质共享大部分序列,并且在结构上也相似。

蛋白质从头设计简介

今天,我们将讨论蛋白质从头设计。这指的是从零开始设计全新的序列,不依赖于天然蛋白质序列,而是使用计算方法来设计可能与所有现有蛋白质都大不相同的序列。

有一个著名的观点认为,进化只探索了所有可能存在的蛋白质中一个极小的子集。因此,在氨基酸所有可能的组合空间中,只有一小部分已经存在,还有巨大的空间可以用来生成从未见过或表征过的新蛋白质。

RF扩散模型:用于骨架设计的扩散模型

现在,我将开始解释用于骨架设计的RF扩散模型。

首先,快速回顾一下我们在之前课程中学到的关于扩散模型的原理。这些模型在图像生成领域已展现出最先进的性能。其基本思想是:从图像开始,经过多个时间步逐渐增加噪声,最终得到与原始输入毫无相似性的纯噪声图像。然后,训练一个神经网络来逆转一步去噪过程。如果成功,就可以从已知的高斯分布中采样纯噪声,输入模型,经过反复去噪步骤,最终得到一个与训练数据分布高度相似的输出,即生成一张逼真的图像。

同样的概念可以应用于蛋白质结构。具体流程是:以蛋白质结构作为训练数据,对这些从蛋白质数据库获取的结构添加噪声,然后训练模型从带噪声的输入中恢复真实结构。如果成功训练了这些模型,就可以通过从随机噪声开始的迭代去噪过程生成新的结构。

为了理解RF扩散模型,我们需要讨论如何向蛋白质结构添加噪声。AlphaFold和RF扩散都使用了一种基于框架的蛋白质骨架建模方法。在这种方法中,我们将骨架视为由N、Cα、C原子组成的三角形。每个这样的三角形都可以用一个平移向量和一个旋转矩阵来描述。因此,一个蛋白质骨架本质上就是L个平移和L个旋转的集合,其中L是蛋白质的长度或氨基酸数量。

然后,我们可以向平移向量添加三维高斯噪声(即扰动Cα坐标),并在旋转矩阵流形上使用布朗运动。这种加噪策略将原本沿蛋白质骨架整齐排列的三角形集合,转变为随机分布和随机朝向的状态。接着,训练一个神经网络来逆转这个过程,目标是从这些结构的噪声版本中恢复原始的蛋白质结构。

以下是RF扩散的一个训练步骤:在每个时间步t,模型以当前坐标X_t(初始为随机噪声)作为输入,直接预测真实结构X_0。然而,模型下一时间步的坐标输入并不是这个预测的真实结构,而是X_tX_0之间的一个插值。模型沿着其真实预测的方向前进一步。这个插值结果被传递到模型的下一个时间步。同时,这个真实预测也不会被丢弃,它也会被传递到下一个时间步。这就是所谓的自条件策略,模型既可以使用当前时间步的坐标位置,也可以使用前一时间步预测的真实坐标。这种策略显著提高了RF扩散的性能。

另一个有趣的点是,该模型基于一个名为RosettaFold的蛋白质结构预测模型(折叠模型)。它的思路与AlphaFold非常相似,也能从输入序列准确预测蛋白质结构。其背后的想法是,通过利用这些蛋白质结构预测模型中所蕴含的对蛋白质结构的深刻理解,我们可以获得改进的蛋白质设计扩散模型。因此,RF扩散是通过微调RosettaFold结构预测网络而开发的。

RosettaFold的输入与AlphaFold非常相似:它接收需要折叠的输入序列,在数据库中搜索同源蛋白质以获取模板结构,并基于这些同源蛋白质生成初步的蛋白质结构预测(以残基对距离矩阵和基于框架的骨架表示形式)。然后,它输出该序列的预测结构。

RF扩散几乎原封不动地重用了这个架构,只有两点改变:

  1. 输入到折叠模型的序列现在被掩码,因为我们不再有输入序列。
  2. 原本初步的基于框架的骨架表示,现在被扩散坐标(即噪声坐标)所取代;而原本的残基对距离矩阵,则被来自自条件的、前一时间步预测的真实坐标X_0所取代。

因此,这原本是一个结构预测模型,但现在使用相同的架构进行微调,以预测蛋白质结构,但输入是噪声坐标。

RF扩散模型是一个用于蛋白质骨架的生成模型。从随机噪声开始,它确实可以生成高度多样化的蛋白质骨架。许多不受约束的设计与训练中见过的结构相似性很低,这表明该模型能够真正泛化到其训练数据之外。实验表征也表明,大多数这样生成的蛋白质确实稳定且可溶。

条件化设计与应用示例

目前解释的只是非条件化设计。RF扩散可以通过添加外部势能和微调模型,针对特定的设计挑战进行条件化定制。这就像在迭代去噪过程的每一步中,引导轨迹朝向特定的设计目标。

例如,RF扩散曾以一个硫氧还蛋白桶状蛋白的结构作为条件,从而能够生成具有大致相同整体拓扑结构的多样化设计。

另一个有趣的实验是构建支架或骨架来承载一个期望的基序。以P53蛋白为例,它是一种抑制癌症生长的蛋白质。在癌细胞中,MDM2蛋白经常过度表达,它会结合P53并阻止其启动细胞死亡。他们面临的设计任务是设计一种能与MDM2结合的竞争性蛋白质,使得MDM2无法再结合P53。

他们的做法是:将P53中与MDM2结合的螺旋结构固定在他们的新设计中。然后,使用在蛋白质复合物上微调过的RF扩散模型,并条件化其包含这个螺旋。最终,他们生成了能够强效结合MDM2的设计,这有可能成为一种候选抗癌药物。

从骨架到完整蛋白质:序列设计问题

有些人可能会疑惑,因为以上都是关于骨架设计的。一个骨架还没有氨基酸,我们只是设计了骨架的结构,但它还不包含任何特定的氨基酸序列。

为了完成蛋白质设计,我们需要找到一个能够真正折叠成这个骨架结构的氨基酸序列。流程如下:首先设计一个骨架,然后运行一个模型为该骨架设计序列,最后用AlphaFold进行验证——将设计出的序列输入AlphaFold生成结构,看这个由序列衍生的结构是否真的具有所设计的骨架。

能够解决为特定骨架设计序列这一任务的模型,就是Protein MPNN模型。

Protein MPNN:用于序列设计的生成模型

Protein MPNN也是一个生成模型,但用于序列设计。它遵循从结构到序列的目标,即输入一个固定的骨架,设计一个能折叠成该骨架的序列。这被称为逆折叠问题

该模型在其架构内部也使用了基于图的骨架结构表示。它将骨架结构建模为一个图:

  • 节点代表固定结构中(未知的)氨基酸,更具体地说是Cα原子的位置。
  • 连接每个节点与其32个最近邻节点。
  • 节点特征初始化为零。
  • 边特征包含一系列距离信息,这些距离计算自连接的两个氨基酸三角形之间的各种原子间距,编码了这些氨基酸的空间取向。

模型的第一部分是消息传递神经网络(图卷积)。通过在图结构上进行消息传递(本例中循环三次),关于节点空间环境的信息被编码到其节点特征中,边特征也同样被更新。

模型的第二部分是解码器,它执行一种自回归分解。它运行次数与氨基酸数量相同。每次,它都利用边特征、节点特征以及已预测出的部分序列,为下一个氨基酸位置预测一个20种氨基酸的类别概率分布,并从中采样。

该模型的训练数据是已知序列和实验解析结构的蛋白质。从这些解析结构中移除侧链,只保留骨架,然后由Protein MPNN重新发现氨基酸身份。训练损失基本上是所有氨基酸位置的分类交叉熵。

该模型的训练性能(序列恢复率)约为50%。虽然这个数字看起来很低,但必须记住,对于蛋白质结构中的许多位置,可能有几种氨基酸都是可能的解决方案。因此,关键步骤是进行结构验证:将Protein MPNN生成的序列,通过AlphaFold预测其结构,并检查预测结构是否与输入骨架匹配。

演示与工作流程整合

以下是一个演示工作流程:

  1. 输入一个结构(例如癌症示例中的MDM2蛋白)。
  2. 提取其骨架,移除所有侧链。
  3. 使用Protein MPNN为这个骨架重新设计氨基酸身份(生成多个新序列)。
  4. 将这些新序列输入AlphaFold2,预测其结构。
  5. 比较AlphaFold预测的结构与原始输入骨架的匹配程度。

演示表明,即使生成的序列与原始MDM2蛋白的序列同一性只有约44%,AlphaFold预测的结构仍然与期望的骨架结构高度吻合。这证明了不同序列可以折叠成相同的三维结构。

同样,在Protein MPNN中也可以包含期望的基序,只需将序列的一部分固定即可。回到P53-MDM2相互作用的例子:使用RF扩散生成包含该螺旋的骨架结构后,在使用Protein MPNN设计序列时,可以固定该螺旋区域的氨基酸,让模型只设计固定部分周围的序列,以确保其仍能结合MDM2。

总结与展望

本节课中我们一起学习了:

  • RF扩散是一个用于蛋白质骨架的生成模型,能够从随机噪声生成高度多样化的蛋白质骨架。
  • Protein MPNN是一个用于序列设计的生成模型,能够为特定结构找到能折叠进去的序列。

RF扩散和Protein MPNN的结合,是蛋白质从头设计的一种强大方法。它们允许包含期望的基序或拓扑结构,从而能够针对特定应用设计蛋白质,这使得它们更具吸引力。

需要指出的是,本讲座绝非对该领域的详尽概述。蛋白质设计领域发展极其迅速,新论文层出不穷。但这两个模型非常有趣,因为它们效果很好,并且对所有人公开可用。


本节课中我们一起学习了用于蛋白质从头设计的两种关键生成式AI模型:RF扩散用于骨架生成,Protein MPNN用于序列设计。它们的结合为创造具有特定功能的全新蛋白质提供了强大的计算工具。

posted @ 2026-03-26 08:20  布客飞龙II  阅读(0)  评论(0)    收藏  举报