4. FNO核心架构拆解

要真正用好Fourier神经算子(FNO),不能只把它当成一个“黑箱回归器”。FNO之所以能在网格分辨率变化时保持近似一致的映射能力,关键在于它的数据通路被刻意设计成“提升—频域混合—局部修正—投影”的组合结构。本节沿着一次前向传播的顺序,逐层拆解每个模块的输入输出维度、参数构成和设计意图,并给出一个可直接对照的实现级示例。

一、整体数据通路与维度约定

先约定符号:批大小为 B,输入函数通道数为 d_in,输出通道数为 d_out,输入网格为 n×n(二维情形),隐藏宽度为 w,傅里叶模态截断为 k_max1×k_max2,傅里叶层数为 L。一次前向传播的主干是:输入提升 P 把 (B, d_in, n, n) 映射为 (B, w, n, n);随后 L 个傅里叶块依次处理,每块内部并行包含“频域线性变换 + 局部线性变换”,再经激活;最后由输出投影 Q 把 (B, w, n, n) 压回 (B, d_out, n, n)。

输入函数 a(x) (B, d_in, n, n) 示例 1×1×64×64 输入提升 P 1×1 卷积 / 线性 参数 d_in·w + w 隐藏特征 (B, w, n, n) 示例 w=32 傅里叶块 × L(示例 L=4) 频域分支:FFT → 模态截断 → R 加权 → iFFT 保留低频 k_max1×k_max2(示例 12×12) R ∈ C^(w×w×k1×k2),参数 2·w²·k1·k2 输出 (B, w, n, n) 局部线性变换 W(1×1 卷积) 参数 w·w + w,输出 (B, w, n, n) 作用:补足高频与逐点非线性 + 残差相加后过激活 σ 输出投影 Q 1×1 卷积 参数 w·d_out + d_out 输出 u(x) (B, d_out, n, n)

二、输入提升 P:把函数值变成可混合的特征

输入提升通常是一个 1×1 卷积(等价于逐点的线性映射),把每个网格点上的 d_in 维函数值升到 w 维。它的参数只有 d_in·w + w,示例中 1×32+32=64 个。这一步不做空间混合,只做通道扩张,目的是给后续频域变换提供足够宽的表示空间。若输入是多通道(如速度场 u,v 加压力 p,d_in=3),提升层会把它们融合成统一的隐藏特征。

三、傅里叶层:频域混合的核心

每个傅里叶块内部有两条并行分支。频域分支先对隐藏特征做二维实数FFT,得到 (B, w, n, n/2+1) 的复数谱;然后只保留低频的 k_max1×k_max2 个模态(示例取 12×12),把高频直接丢弃;接着用一个可学习的复数权重张量 R 对保留模态做通道间线性组合,R 的形状为 (w, w, k_max1, k_max2),由于复数实部虚部各一份,参数量为 2·w²·k1·k2,示例为 2×32²×12×12≈29.5万;最后补零到原尺寸并做逆FFT回到物理空间。频域分支的输出仍是 (B, w, n, n)。

这里有两个工程要点。第一,模态截断 k_max 是FNO最重要的容量旋钮:k_max 越大,能表达的频率越高,但参数量和计算量按 k1·k2 增长;对光滑解通常取 n/4 到 n/2 即可。第二,R 与网格分辨率 n 无关,这正是FNO能“训练在粗网格、推理在细网格”的根本原因——同一组低频权重可以直接作用在更高分辨率的谱上。

四、局部线性变换 W 与激活函数

频域分支只处理低频全局信息,会丢失高频细节和逐点非线性。因此每个傅里叶块还并行一条局部分支:一个 1×1 卷积 W,参数 w·w + w,示例 32×32+32=1056。两条分支的输出逐元素相加,再经过激活函数 σ(常用 GELU 或 ReLU),得到该块的输出。可以把它理解为“全局低频修正 + 局部逐点修正”的残差式组合。若把 W 去掉,模型会明显偏向过度平滑;若把频域分支去掉,FNO就退化为普通卷积网络,失去分辨率泛化能力。

五、输出投影 Q 与参数规模核算

经过 L 个傅里叶块后,特征仍是 (B, w, n, n)。输出投影 Q 用 1×1 卷积把它压到 d_out 维,参数 w·d_out + d_out。以示例配置(d_in=1, d_out=1, w=32, L=4, k=12×12)核算:提升层 64,每个傅里叶块约 29.5万 + 1056,四块合计约 118 万,输出投影 33,总参数量约 118 万。可见参数绝大部分集中在频域权重 R 上,调参时应优先关注 w 与 k_max 的乘积。

实现时建议把 R 存成两个实数张量(实部、虚部),用 torch.fft.rfft2 与 irfft2 完成变换;模态截断用切片 [:k1, :k2] 实现,补零用 F.pad,这样既清晰又便于检查维度。
常见错误:把 k_max 设得比 n/2 还大,导致切片越界或补零逻辑失效;以及在频域分支后忘记做逆变换就与局部分支相加,造成物理空间与频域混算。调试时逐层打印张量形状是最快的定位手段。

把这条通路记牢,后续无论是改模态数、换激活函数,还是做多尺度扩展,你都能准确判断改动落在哪一层、影响哪些维度与参数量。