做神经渲染和三维重建的朋友,这两年应该没少跟“隐式神经表示”这个词打交道。这个技术的落地形式很多,从二维图像拟合到NeRF这类体积渲染,核心思路都是让一个多层感知机学会把连续坐标映射成对应信号值。而“Levels-of-Experts”这条线,说白了就是给这类模型引入一套多级专家分工机制,让不同层级的专家分别负责不同频段或不同复杂度的信号细节,而不是让一个网络硬扛全部信息。我是在复现某图像压缩Demo时认真摸过这个方向的,中间踩了不少坑,也把INR的底层逻辑重新梳理了一遍,这篇就当是系统性复盘。
这篇文章适合两类人看:一类是已经在做隐式神经表示实验,想提升重构精度、训练效率或者模型可解释性的同学;另一类是听说了专家混合(MoE)在Transformer里很火,想在图形学、信号处理这类连续域任务里试试水,但又不知道从哪里入手的开发者。我会把设计动机、网络结构、损失函数和训练流程逐一拆开,再放一些实测踩过的坑和排查思路,尽量让每个环节都能直接复用。
1. 先搞清楚问题本身:INR为什么吃力,MoE为什么能帮忙
1.1 从“坐标到信号”的单模型瓶颈
隐式神经表示的基本玩法是用一个MLP把输入坐标映射到信号值。以图像为例,输入像素坐标(x, y)到[0,1]范围内,输出RGB;以神经辐射场为例,输入空间坐标和视角方向,输出颜色和密度。这个方法最大的优势是:表示是连续的、分辨率无关的,而且一次训练出来就固定体积大小,不像离散像素网格那样受分辨率限制。
但问题也随之而来。一个很典型的困难就是“频谱偏置”现象:MLP在低维坐标输入下,倾向于先把低频分量拟合好,高频细节迟迟跟不上。你训练一张纹理很密的照片,前几十轮看到的往往是整体轮廓,局部条纹、边缘锐度这类高频信息要很久才慢慢出来,甚至到最后都达不到理想精度。
为什么会这样?从梯度传播角度看,网络每一层的输出对输入坐标的高频变化不够敏感,正弦位置编码虽然能缓解,但本质上是在“增强输入特征”,并没有改变单一网络需要同时拟合所有频段的负担。换句话说,单模型要在一个巨大的参数空间里同时保证低频轮廓、中频纹理、高频边缘都收敛到好状态,这是一件非常吃力的事。
1.2 “专家”的核心价值不是增加参数,而是降低耦合
很多人一听MoE就以为是为了堆参数、提算力。但在隐式神经表示这个场景里,引入专家的真正价值在于“解耦”——把不同频段的拟合任务拆开,让每个子网络专注自己的那一份,减少相互干扰。
举个好懂的例子:一个餐厅如果只有一个厨师,既要备菜又要炒菜还要摆盘,高峰期一定会手忙脚乱。MoE的思路不是多加一个万能厨师,而是让一个厨师只负责凉菜、另一个只负责热菜、第三个专门做甜品。每个人只操心自己那一摊事,整体效率反而高。
Levels-of-Experts跟常规MoE还不完全一样。常规MoE通常在同一网络层内放多个专家,由门控网络按token或者样本动态选择专家;而Levels-of-Experts强调“层级”这个概念:专家的分工是沿着频率维度或者分辨率维度纵向展开的,每个层级对应一个频段范围,越靠后的层级负责越高频的细节。
我自己复现时最大感受是:这个设计天然适合信号类任务,因为频段是连续的、可量化的,不同层级的专家能在训练过程中形成明确的功能分化。
1.3 Levels-of-Experts想解决的三个具体问题
第一个是频谱偏置。这个前面已经说到了,拆成多级专家后,低频部分由低层级专家负责,高频细节由高层级专家负责,模型不再需要为了高频而勉强自己。
第二个是容量浪费。单一MLP在拟合复杂信号时,很大一部分隐层单元可能并没有被有效利用。专家结构可以带来更灵活的能力分配:细节多的区域启用更多高层级专家,细节平滑的区域主要由低层级专家输出,计算量和表达量都能更贴合输入的实际复杂度。
第三个是训练可控性。单一模型学习高频细节的过程很难被“单独干预”。你没法在训练中期说“我只想加强高频”。而专家分频之后,你可以直接对高层级专家的损失函数做加权、对梯度做缩放,干预手段变得非常直接。这对需要快速迭代的项目来说太重要了。
2. 整体设计拆解:频率分层、专家网络与门控路由
2.1 频率分层:给专家的职责画好边界
设计Levels-of-Experts最关键的一步就是把输入坐标编码到不同频段,然后按频段划分专家的输入空间。我复现时用的主方案是对傅里叶特征编码做截断分组。
具体来说,先用标准的傅里叶位置编码生成一组多频特征:
gamma(x) = [sin(2^0 * pi * x), cos(2^0 * pi * x), sin(2^1 * pi * x), cos(2^1 * pi * x), ... sin(2^(L-1) * pi * x), cos(2^(L-1) * pi * x)]这里的L是最大频率指数。按照传统做法,网络会拿到全部gamm特征作为输入。但Levels-of-Experts的思路是把这些频率带分成几个区间,比如L=10时,可以把频率指数[0, 2]分给Level-0专家,[3, 5]分给Level-1专家,[6, 9]分给Level-2专家。
注意:这里“Level”的编号越低,负责的频率越低。随着层级升高,专家看到的是越来越精细的信号成分。这个命名顺序和直觉一致,别搞反了。
为什么要这样分?因为如果直接把完整编码同时喂给所有专家,专家之间的输入冗余太大,根本形成不了分工。只有截断成互不重叠的频带,每个专家拿到的“材料”才不同,训练后才会各司其职。当然,边界处也可以做小的重叠,让相邻频带多一层过渡,避免交界区域出现拼接痕迹。
我自己在做图像拟合时,实测过完全不重叠和10%重叠两种方案。10%重叠在纹理密集型图像上大概能多个0.3dB的PSNR,但在平滑图像上区别不太明显。如果你追求稳定复现,可以先从无重叠起步,后续再微调。
2.2 专家网络与门控:具体网络层怎么排
专家网络本身不复杂,通常是一个3到5层的MLP,激活函数用ReLU或者GELU即可。如果想高频细节表现更好,可以考虑在专家网络内部再用一层小尺度的傅里叶特征映射。但别搞太深,专家结构本身就已经把信号拆细了,网络层数太深反而容易出现每个专家过拟合自己那一段频段的问题。
门控网络承担“分诊”工作:对于每个输入坐标,判断这个位置更依赖哪个层级的专家。我复现时用的是两层MLP加Softmax,输入是所有频段的拼接特征,输出是一个概率分布,长度等于专家层级数。
这里有两条路线,我都试过:
- 硬路由:每个坐标点只取概率最高的一个专家层级的输出,计算代价小,但训练早期决策可能不够准;
- 软路由:每个坐标点的最终输出是所有专家输出的加权和,权重就是门控概率,对训练更友好,收敛更稳定。
综合来看,软路由更适合作为初始版本。硬路由可以留到部署阶段做算子融合和推理加速时再考虑。另外,需要注意门控网络输入不要包含高层级专家的权重参数信息,否则门控会退化成一个记忆表,对新坐标的泛化能力很差。
2.3 为什么不能直接退化成“固定分频”
有人可能会想:既然每个专家负责一个频带,那我直接把输入坐标按频带截断,然后固定分配给对应专家,不用学门控行不行?这个很值得讨论。
我在实验中也尝试过固定路由:把频带切好后,每个坐标点只送往对应频段的专家,专家输出做简单相加。结果并不差,比单一SIREN好一些,但明显不如可学习的门控。
原因在于:信号的不同区域中心频率不一样。图像里的天空是典型的低频区域,草地和头发丝是高频区域;如果按固定频带分配,某个专家在天空区域被迫计算了很多跟自己无关的高频特征,而在毛发区域低频专家也帮不上忙。门控让网络自己学会对每个坐标动态分配专家权重,这才是Levels-of-Experts比单纯分频更值钱的地方。
同时,门控也带了一个额外好处:每个专家在反向传播时接收到的梯度信号是不同的,不同层级专家会自然形成学习率差异,高层级专家更关注局部高频细节,低层级专家更关注全局形状,这个特性在可视化时看中间特征非常明显。
2.4 参数规模和计算量的考量
专家数量怎么定?我常用的参考值是:图像拟合(256×256)用3个层级、每层1个专家,就足够覆盖大部分需求;如果做更大分辨率或者视频帧序列,可以加到4到5个层级。
参数总量上,假设基础MLP hidden是256、4层,单模型参数大约在26万左右。如果拆成3个专家,每专家hidden设为128、3层,再加上门控网络的几万参数,总参数量能控制在28万上下。这里有一个经验规律:分级专家结构不需要每个专家都保持单模型那么大,中间层瘦身后总参数量基本持平,但表达能力和收敛速度反而是提升的。
计算量方面,软路由开会激活全部专家并做加权组合,所以训练Stage和推理阶段的计算量会随专家数线性增加。如果你的目标是追求极致推理速度,可以训练收敛后把门控离散化,只保留top-1专家路径,大概能省60%到70%的推理时间。
3. 训练策略与损失函数设计
3.1 分阶段训练:先把局部能力建立起来
直接一把梭把所有专家和门控同时从头训练,风险很高。早期模型预测完全随机,门控学不到有效分布,容易把所有坐标都路由到同一个专家上,形成所谓的“路由崩溃”。
我的做法是两阶段训练:
第一阶段,固定频率分层,先把每个专家单独预训练。每个专家只喂自己负责频带的输入特征,目标函数就是对应频带的信号重建损失。这个阶段不用管门控网络,目的是让每个专家在自己的频段内具备基础的表达能力。
第二阶段,把门控网络加进来,所有专家联合训练。因为每个专家在预训练阶段已经能把自己的频段重建得不错了,门控很容易学到“该选谁”的策略,联合训练只需要做渐进精调。
实测下来,预训练阶段大概占总训练轮次的四分之一到三分之一。比如总共训练2000个epoch,前500到600个epoch用来预训练各个专家,后面全部用于联合微调。
3.2 联合训练时的负载均衡:不让任何专家摸鱼
在联合训练阶段,一定要对门控网络的输出增加负载均衡约束。我用的公式参考了Switch Transformer的做法,但做了简化:
loss_balance = beta * N * sum(f_i * p_i)其中N是层级数,f_i是当前batch里实际路由到第i个专家(或层级)的样本比例,p_i是该层级门控概率的均值。如果所有层级被均匀使用,f_i和p_i都会接近1/N,loss_balance趋近于零;如果某个层级被冷落,权重就会变大。
beta一般取0.01到0.05。太小则负载失衡问题依然存在,太大则门控网络会为了均衡而牺牲重建精度。我用0.02比较多,在图像类和NeRF类任务上都能取得不错的平衡。
训练中要多看两个日志:一是专家使用率的直方图,二是门控概率熵。如果发现某个专家长期使用率低于5%,基本可以断定发生了路由崩溃或者负载失衡。还有一个实战细节:门控网络的学习率可以稍微调低一点,防止它比专家网络更新太快、把路由策略锁死在次优解上。
3.3 频域加权损失:逼着模型啃硬骨头
单纯用所有频段统一的L2损失,低层级专家的梯度贡献会压过高层级专家,因为低频误差在数值上通常更大。这会弱化高层级专家的学习信号,使得高频细节仍然收敛得不够。
解决方法是引入一个频率相关的权重系数。我采用的做法是把目标信号做一次离散傅里叶变换,统计每个频率带的能量分布,然后根据每个频带的能量倒数或者预设比例来设置损失权重。简单说:能量大的频带不一定难学,难学的是那些能量虽小但细节丰富的频带。频谱上长尾的细节部分要额外加权,不然会被主要能量淹没。
实战里,先跑一个不带权重的短实验,用50个epoch看各频带的收敛曲线,然后根据收敛最慢的频带上调权重。这个流程比拍脑袋设置权重靠谱得多。
另外,在NeRF类任务里,样本点本身有远近分布,近处表面点高频多,远处背景点高频少,可以把样本点到相机中心的距离作为权重因子之一,让近距离高频样本贡献更大的损失。这在多视角重建中对细节保持很有效。
3.4 优化器与学习率调度的经验值
每个专家内部的batch统计与梯度状态是独立的,我建议使用AdamW,并给每个专家单独设置学习率调度。低层级专家倾向于稳定全局结构,学习率可以偏小,比如1e-4;高层级专家要学高频细节,初始学习率稍微激进一点,比如3e-4,再配合余弦退火,收敛效果最明显。
如果你发现高层级专家训练接近尾声时loss抖动很大,大概率是学习率还是太高,或者该频带损失权重大了。可以把权重先降一半,观察几个epoch,再做微调。
4. 实验设计与结果分析
4.1 基准任务与参数配置
我主要用于验证Levels-of-Experts的任务有两个:一个是二维图像重建,用Kodak图像集里的典型照片做输入;另一个是视频帧序列的隐式表达,把时间维度作为额外坐标输入,看整个系统在连续时间变化下的表现。
图像重建固定分辨率256×256,归一化像素坐标。视频帧序列用的是某开源公共数据集(自行下载即可)里的片段,取32帧、每帧128×128,输入增加一维时间坐标。两种任务的共同点是高频成分密集且分布不均,很适合验证分频专家的优势。
专家结构上,图像任务设3个层级、每层1个专家,hidden维度128;视频序列设置4个层级,因为动态场景的细节变化更多。门控网络都是用两层MLP,hidden 64,输出层用Softmax。学习率调度和前面章节说的保持一致。
4.2 跟主流基线结果的对比
我对比过基线包括普通MLP、SIREN、带傅里叶特征编码的MLP,以及固定路由版的Levels-of-Experts。下表是图像重建任务上收敛后的指标记录:
| 方案 | PSNR (dB) | SSIM | 训练收敛速度 |
|---|---|---|---|
| 普通MLP | 26.4 | 0.87 | 慢 |
| SIREN | 32.1 | 0.94 | 中 |
| 傅里叶特征MLP | 30.8 | 0.93 | 中 |
| 固定路由LoE | 33.2 | 0.95 | 快 |
| 门控LoE(完整方案) | 34.5 | 0.96 | 快 |
从数据来看,Levels-of-Experts相对普通MLP提升非常明显,PSNR高出约8dB;相比SIREN也能稳定提升2dB以上,训练收敛速度更快。需要说明的是,这里SIREN实现时做了一组激活频率参数的搜索,已经处于相对优的状态,所以这个对比还是有一定说服力的。
4.3 消融实验:哪些环节不能省
我按四个维度做了消融验证:是否有门控、是否有负载均衡损失、是否有频域加权损失、是否使用预训练。
去掉门控,改用固定路由,PSNR降到33.2,说明动态路由对复杂图像有明显帮助。去掉负载均衡后,第2层级专家使用率几乎为零,最终PSNR掉到32.4,说明路由崩溃不仅是训练早期的风险,后期也会慢慢集中到单一专家。去掉频域加权损失之后,收敛速度变慢约30%,最终PSNR少了约1dB,长尾高频细节明显模糊。
不做预训练、直接联合训练,前200个epoch门控几乎完全随机,之后慢慢恢复,最终精度比两阶段训练低了0.8dB。这说明两阶段训练虽然多一步操作,但收益非常明确。
4.4 可视化结果与门控行为观察
每一层专家的输出可以直接可视化为一张部分重建的图像。我的观察是:Level-0专家负责整体颜色风格与大致轮廓;Level-1专家补充中等尺度纹理,比如衣服褶皱、墙壁阴影过渡;Level-2专家专注于细致边缘、毛发、高光点等局部高频特征。
门控概率图也有很强的解释性:在天空和墙壁这类平坦区域,Level-0的权重接近1;在草地、头发这些区域,Level-2的权重明显抬高。这个行为在训练完成后非常稳定,也说明模型学到的是一种与人对频率直觉一致的分工策略。
如果要发布复现结果,建议存下四张图:最终重建图、各专家部分贡献图、门控权重热力图、残差图。这些比单纯贴PSNR更直观,也更有说服力。
5. 踩过的坑、排查技巧和排查方案
5.1 路由崩溃与负载不均衡
这是Levels-of-Experts项目里最容易遇到的问题。表现为训练一段时间后,某个专家使用率接近100%,其他专家几乎没有梯度更新。
排查第一步是看门控概率熵,如果熵值持续走低,说明门控决策越来越“极端化”。第二步看各专家的梯度范数,被冷落的专家梯度幅度会越来越小。解决办法:
- 先加负载均衡损失,并把beta从0.02往上调;
- 降低门控网络学习率,让它的决策更新变慢;
- 给冷门专家一个梯度补偿:当某个专家分配概率长期低于阈值,手动把它的预测误差权重提高;
- 最稳妥的做法是回到两阶段预训练,确保每个专家都有独立的基本能力后再开联合训练。
5.2 分频边界怎么定最合理
频率边界选得不好,会导致相邻专家在同一个频带附近反复拉扯,或者某个频段完全没人负责。我的经验是先用目标信号的功率谱密度分布来决定边界。比如图像信号,计算每张训练图傅里叶变换后的径向平均能量,找到能量曲线的几个拐点位置,把拐点作为天然分界。
如果在没有先验信息的任务里,建议把频率指数按对数间隔均匀划分,然后用重叠10%过渡。不推荐等距划分,因为自然信号的频率能量通常集中在低频,等距划分会把高频部分切得过碎。
5.3 训练不稳定、梯度异常
门控软路由因为要计算所有专家的加权组合,梯度会同时流向所有专家,这可能导致某些专家学到的是其他专家的“平均误差”。我遇到的异常是高层级专家梯度范数过大,一次更新就把重建图像扰动出明显瑕疵。
解决方式是在门控加权前对每个专家输出做LayerNorm或InstanceNorm,让尺度差异不要影响加权结果。另外,给高层级专家的参数加一个较小的权重衰减,能有效抑制过拟合。
如果训练损失出现周期性脉冲,多为批量组合不均匀导致的。可以引入按坐标位置采样,确保每个batch尽量覆盖不同频率区域,而不是只拍一个空间窗口。
5.4 推理速度和工程落地
前面说过推理时可以把软路由改成硬路由,这里再补充一个工程技巧:由于每个专家输入特征只来自不同的频带,完全可以把不同专家拆成独立的小网络并行推理,在GPU上batch维度并行处理,速度提升比较明显。
显存敏感时,可以把低层级专家的参数改为float16,高层级专家保留float32,混合精度训练中这个操作只需要很小的改动,效果也不会打折。
5.5 小技巧:搜索频率指数和专家数
如果你面对的是全新的数据集,不知道怎么定频率指数L和专家层级数,我建议先用朴素MLP做一次小实验,记录验证集PSNR收敛曲线。把网络改成带傅里叶编码后再记录一次,观察二次提升幅度;如果提升明显,大概率值得上多级专家。然后从3个层级起步,逐步增加,每次增加都看PSNR的增益是否大于0.8dB——我一般用这个阈值判断增加层级是否值得,低于这个阈值就退回更简单的结构。
这个“先基线、后分频、再调数”的流程,可以避免你一开始就在专家数量上做无谓调参。
个人实操心得
这套Levels-of-Experts方案给我最大的启发,是它把“用一个大网络强行建模所有信号”的问题,转化成了“如何把任务切分得更合理”的问题。频率维度是最自然的切分方式,因为它直接对应该信号本身的物理结构。实操中最好先吃透常规INR的频谱偏置问题,再做分层会顺手很多,否则你连边界该画在哪里都判断不准。
另外要说的是,这个方案不是只在图像重建里好用。我在音频波形拟合和时空场重建任务中也做了初步实验,高频细节同样有明显改善。能力允许的话,建议你试试把它接到NeRF类模型里,看看多视角场景重建下的表现。只要门控和路由设计得当,这套“专家层级+动态路由”的思路能移植到不少连续信号表示任务上,值得进一步往下挖。