最近把 Implicit Neural Representations with Periodic Activation Functions 这篇论文从头到尾推了一遍就是大家常说的 SIREN中文一般翻译成“基于周期激活函数的隐式神经表示”。论文核心一句话就能讲完把全连接网络的激活函数换成 sin再配上一套专门的初始化方式网络就能光滑地表示图像、音频、3D 形状这类连续信号并且导数信息也都能派上用场。这篇拆解是给刚入门这个方向的同学写的我会尽量绕开论文里那些劝退的公式推导把“它到底做了什么、为什么有效、复现时要注意什么”讲明白。如果你正准备读这篇论文却被符号卡住或者想用隐式神经表示做点图像和形状的实验这篇文章应该能帮你省下不少时间。1. 先搞清楚 SIREN 在解决什么问题1.1 隐式神经表示到底表示的是什么要说 SIREN得先解释一个概念隐式神经表示Implicit Neural RepresentationINR。传统上我们存一张图片就是存一个像素矩阵每个格子里放一个颜色值。这本质上是离散采样分辨率在采集那一刻就固定了放大就会糊。而隐式神经表示的思路完全反过来训练一个神经网络把“坐标”映射成“数值”。对于图像这个函数就是 (x, y) → (R, G, B)对于音频是 t → 振幅对于 3D 形状是 (x, y, z) → 符号距离值。这种表示方式最大的好处是连续。网络训练好之后你随便给一个坐标它都能输出一个合理的结果不管这个坐标是不是训练时见过的。图像想放大多少倍都行音频想插值出中间任何时刻的波形也行3D 形状想求表面任意一点的法线也可以直接算。换句话说我们不再存储离散的采样点而是存储一个“连续场”的参数。这个概念早期用在计算机图形学里后来又被神经辐射场发扬光大但万变不离其宗——核心都是让神经网络去拟合一个坐标到物理量的映射。SIREN 就是这类网络的代表实现之一。1.2 ReLU 网络做拟合时的天花板那么问题来了在此之前做这类坐标映射的网络大多用 ReLU 激活函数。ReLU 是连续的但它分段线性、导数不平滑、二阶导数几乎处处为 0。用 ReLU 网络去拟合一张图像大面颜色可能都对细节却容易糊成一片尤其是纹理和边缘部分。原因是坐标空间里的高频变化需要网络拼出大量线性片段才能逼近而 ReLU 的梯度在正半轴和负半轴的差异又会让训练变得不稳定。更麻烦的是很多下游任务需要信号的导数。比如 3D 形状的 SDF 需要法向量求解偏微分方程需要拉普拉斯算子。ReLU 网络的一阶导是阶跃函数二阶导干脆是 0这就相当于你要给一个装满棱角的积木块去磨一个光滑的球面很难受。我之前拿 ReLU 坐标网络拟合过一段语音波形结果波形上明显带着“折线感”听起来有轻微的滋滋声。问题就出在 ReLU 对坐标空间的线性逼近上——不是网络容量不够而是 ReLU 这种激活函数的归纳偏置决定了它擅长分段线性逼近不擅长表达平滑的、包含高频细节的连续场。传统 MLP 处理分类任务时这个缺点不明显但放到隐式神经表示这个场景里就成了绕不开的瓶颈。1.3 SIREN 的答案把激活函数换成 sinSIREN 的做法非常直接——把隐藏层的激活函数从 ReLU、tanh 换成 sin。这个改动看起来轻描淡写实际影响很深。sin 是周期函数对输入极其敏感哪怕坐标只挪动一点点输出也会产生非线性的变化这让网络天然具备表达高频细节的能力。更关键的是sin 的一阶导数是 cos二阶导数是 −sin无论求导多少次导数都还是由 sin、cos 组合出来的有界函数不会像 sigmoid 那样梯度消失也不会像 ReLU 那样导数归零。也就是说SIREN 网络求导之后依然是“活”的梯度可以顺畅地回传。用大白话讲ReLU 网络像一个用直尺画曲线的画家必须靠很多小线段去逼近弧线SIREN 则像一支能直接画波浪线的笔天生就能描绘起伏的连续曲面。这个选择改变了网络的归纳偏置从“分段线性”变成了“处处光滑且周期重复”恰好踩中了图像、音频、3D 形状这类信号本身的频率特征。论文里大量实验也证明同样的网络容量SIREN 在表示高频细节、导数信息、解偏微分方程等方面的表现明显优于 ReLU 基准。2. 网络结构、初始化和导数三个核心细节2.1 网络结构本身并不复杂SIREN 的网络结构就是最普通的全连接 MLP。输入层接收坐标向量中间堆几层隐藏层每层若干神经元激活函数全部用 sin输出层接一个线性层把特征投影到目标维度。结构上没有任何花哨的东西不用卷积、不用批归一化、也不用残差连接。你完全可以用一个两三年前就有的全连接网络框架来搭建它。这说明一个道理SIREN 的成功不是靠堆结构而是靠“激活函数 初始化”这对组合棋高一着。隐藏层宽度和层数怎么选论文实验里常见的是 5 层左右每层 256 个神经元具体可以根据任务复杂度调整。输出层的维度就看你要表示什么图像是 RGB 三个通道输出 3 维音频是单声道振幅输出 1 维3D SDF 输出 1 维距离值视频则多一个时间轴输入输出 3 维颜色。输入坐标一般会先归一化到 [-1, 1] 或者 [0, 1]这一步看着简单但对 SIREN 来说极其重要——因为 sin 对输入范围太敏感了坐标不归一化初始化基本等于白做。2.2 初始化论文里最容易被低估的贡献SIREN 论文花了大篇幅讲初始化在我看来这是整个方法能够 work 的关键之一。为什么 sin 激活对初始化这么挑因为 sin 是非单调的周期函数。如果网络层的输入 z 恰好落在 sin 的峰值附近那一带的梯度接近 0神经元直接“死”掉如果 z 的范围太大sin 会剧烈震荡训练过程像抽风一样不收敛。论文给出的方案是让初始化后的神经元输入 z 的分布跨过多个周期使 sin(z) 的输出方差稳定在一个固定值附近论文推导的理想值是 1/2并且不随网络深度变化。这样无论网络多少层信号都能稳定地向前传播。具体到实现论文推导出了一套很漂亮的初始化公式。核心思路是让权重从均匀分布中采样并保证权重的方差与 fan_in 成反比。第一层要特殊处理因为第一层的输入是归一化后的坐标分布范围有限不像中间层的输入那样已经是多层传播后的“宽分布”。实操中有个非常流行的等价写法频率系数 ω0 统一设置为 30第一层权重用 U(-1/fan_in, 1/fan_in) 初始化后续层权重用 U(-√(6/fan_in)/ω0, √(6/fan_in)/ω0) 初始化。我做实验时的感受是初始化写对了SIREN 在图像拟合任务上几十步就能看到清晰轮廓初始化写错了Loss 要么纹丝不动要么原地起飞而且这个现象比普通 MLP 明显得多。所以复现 SIREN 千万别跳过初始化这个环节它是论文的隐形主角。2.3 导数SIREN 真正拉开差距的地方普通全连接网络也能拟合信号但它的导数不可控。SIREN 的隐藏层是 sin 激活导数链式展开之后仍然是一堆 sin、cos 的有界组合所以网络对输入的解析一阶导、二阶导都可以稳定计算出来。这意味着你可以直接对网络输出做自动微分拿到信号在任意位置的切线、法线、曲率甚至把这些导数作为监督信号一起参与训练。论文中的 3D 形状实验就用到了法向量监督偏微分方程实验用到了拉普拉斯算子都是吃到了“可导”这波红利。举个例子拟合 3D 形状的符号距离场时表面法向量就是距离场梯度的方向。ReLU 网络的梯度场是块状的算出来的法向量经常歪歪扭扭SIREN 的梯度场相对光滑法向量直接从网络输出反传一步就能拿到。这种“网络输出可微、导数可用”的特性让 SIREN 不再只是一个函数拟合器而是一个可以嵌入到物理模拟、几何处理流程里的基础模块。这一点恰恰是论文题目里 Periodic Activation Functions 之外最容易被初学者忽略的隐含价值。3. 论文实验到底验证了什么3.1 图像表示最直观的入门实验论文第一个实验是图像拟合。输入归一化坐标 (x, y)输出对应像素的 RGB 值。训练完成后你可以在任意分辨率下重新采样坐标来生成图像相当于“无限放大”。论文给出的对比结果里SIREN 在相同参数量下恢复的图像细节明显高于 ReLU 基准。我印象最深的是纹理区域的还原ReLU 网络经常把密集纹理糊成一片灰蒙蒙的色块SIREN 则能恢复出比较锐利的高频边缘。这个实验虽然简单但很适合作为上手的第一个项目。因为数据好准备、Loss 就是普通 MSE、不需要复杂的评估指标只要看 PSNR 或者直接看重建图就行。我自己的经验是图像拟合任务上 SIREN 的收敛速度非常快一个 256 宽度的 5 层网络在普通 GPU 上训练几百步就能得到肉眼可用的结果。正好可以拿这个任务来验证你自己的初始化有没有写对。3.2 音频波形一维信号的连续建模音频天然是一维连续信号t 时刻对应一个振幅值。用 SIREN 把时间 t 映射成振幅本质上也是函数拟合。论文展示了 SIREN 能生成平滑的波形并且对未见过的时刻也能给出合理的插值。音频实验还体现出 SIREN 的另一个特点训练开销小。网络规模不大分钟级别就能拟合一段不短的音频。如果之前用 ReLU 坐标网络做过类似实验对比会更强烈——ReLU 拟合出的波形经常带着锯齿状噪声回放时有“沙沙”声SIREN 的波形则圆润很多。我自己在复现音频实验时最喜欢干的一件事训练到一半去听当前模型的输出。你会发现 SIREN 的学习过程不是从“模糊”到“清晰”而是从“安静”到“有内容”再到“细节变多”整个过程听起来比较自然。ReLU 网络则更像是“哼哧哼哧”地拼凑片段偶尔还会冒出诡异的爆破声。这种主观听感差异比任何指标都更能说明问题。3.3 3D 形状与符号距离场隐式表示的主场如果说图像和音频只是热身3D 形状才是 SIREN 真正的主场。三维形状通常用符号距离场SDF表示空间中每个点输出一个距离值正负表示在物体内外零等值面就是物体表面。用 MLP 拟合 SDF 坐标网络最大的难点在于表面细节的锐利度和光滑度。SIREN 的连续导数特性让它能直接从 SDF 的梯度场中计算法向量这是 ReLU 网络很难做到的。论文里展示了 SIREN 对复杂几何体的重建结果表面光滑且细节清晰。我后来做 3D 重建相关实验时发现SIREN 对 SDF 拟合还有一个隐藏优势它对输入的微小扰动非常敏感使得表面附近的等值面变化更“锐利”而不是像 ReLU 网络那样把表面磨成一个大鼓包。配合常见的 Eikonal 约束让梯度模长接近 1来训练SIREN 能稳定学到高质量的几何场。这个领域的后续工作非常多SIREN 可以说是把“用神经网络表示几何体”这个方向往前推了一大步。3.4 视频与偏微分方程把 SIREN 当神经解算器再进一步论文把 SIREN 用在了视频表示和求解偏微分方程上。视频表示是给网络输入 (x, y, t) 坐标输出该帧像素颜色本质上把任务扩展到了时空维度。偏微分方程实验更有意思用 SIREN 去参数化一个标量场然后给网络定义物理方程的残差损失比如要求场满足拉普拉斯算子为 0从而训练网络“算出”满足方程的场。这相当于用 SIREN 替代传统数值求解器在内部边界条件约束下求一个隐式解。ReLU 网络做这件事的痛点依旧是高阶导数拉普拉斯算子要求二阶导ReLU 二阶导为 0梯度根本传不下去。SIREN 则天然具备任意阶导数并且导数之间不会互相抵消因此能真正承担起“神经偏微分方程解算器”的角色。这几个实验把一个“换个激活函数”的简单改动从一般拟合任务一路推到了科学计算场景这也是 SIREN 后续在计算机图形学、物理模拟、逆问题领域影响力巨大的原因。4. 复现 SIREN 时我踩过的坑4.1 最小可运行代码骨架先给一个最精简的 SIREN 核心模块方便你快速跑通。我用 PyTorch 风格写尽量去掉工程包装保留关键逻辑。代码里我把初始化逻辑直接写在 SineLayer 里这样不容易漏。import math import torch import torch.nn as nn class SineLayer(nn.Module): def __init__(self, in_features, out_features, biasTrue, is_firstFalse, omega_030.0): super().__init__() self.omega_0 omega_0 self.in_features in_features self.is_first is_first self.linear nn.Linear(in_features, out_features, biasbias) self._init_weights() def _init_weights(self): with torch.no_grad(): if self.is_first: # 第一层输入是归一化坐标范围比较有限 # 用 U(-1/in_f, 1/in_f) 防止 sin 在初始化后进入过高频震荡 bound 1.0 / self.in_features else: # 后续层论文推导的尺度让 sin 输入保持合适方差 bound math.sqrt(6.0 / self.in_features) / self.omega_0 self.linear.weight.uniform_(-bound, bound) if self.linear.bias is not None: self.linear.bias.uniform_(-bound, bound) def forward(self, x): return torch.sin(self.omega_0 * self.linear(x)) class SIREN(nn.Module): def __init__(self, in_dim, hidden_dim, out_dim, num_layers, omega_030.0): super().__init__() layers [] for i in range(num_layers - 1): is_first (i 0) in_f in_dim if is_first else hidden_dim layers.append(SineLayer(in_f, hidden_dim, is_firstis_first, omega_0omega_0)) # 输出层普通线性层不加激活函数 layers.append(nn.Linear(hidden_dim, out_dim)) self.net nn.Sequential(*layers) def forward(self, x): return self.net(x)训练循环也很常规每次随机采样一批坐标计算 MSE 损失Adam 优化器更新。学习率我建议从 1e-4 起步比这个高容易出现震荡。下面是一个最小训练骨架model SIREN(in_dim2, hidden_dim256, out_dim3, num_layers5, omega_030.0) optimizer torch.optim.Adam(model.parameters(), lr1e-4) loss_fn torch.nn.MSELoss() # coords: 随机采样的坐标点target: 对应真值 # loss loss_fn(model(coords), target) # optimizer.zero_grad() # loss.backward() # optimizer.step()把这个骨架放到图像拟合任务上应该很快能看到 SIREN 的高频表达能力。如果训练 Loss 下降特别慢大概率是初始化或者坐标归一化出了问题先别急着调模型宽度。4.2 最容易踩的四个坑第一个坑忘记归一化坐标。SIREN 对输入尺度极其敏感坐标范围不一样sin 的输入分布就完全变了初始化里的很多假设都会失效。图像坐标归一化到 [-1, 1]3D 坐标也要做类似缩放这是复现 SIREN 的基本功。第二个坑学习率调太高。SIREN 虽然不像某些模型那样动不动就崩但对学习率依然比较敏感。我自己测试下来Adam 配 1e-4 附近比较稳调到 1e-3 就会出现 Loss 反复震荡。遇到 SIREN 训练不收敛先降学习率而不是加网络容量。第三个坑初始化写错。尤其是第一层不按论文方式初始化网络会默认偏向低频图像细节出不来如果把频率系数乘过头又会冒出密密麻麻的高频噪点。ω0 这个参数本身就是可调超参但新手就老老实实从 30 开始等流程跑通了再试其他值。第四个坑输出层误加了 sin 激活。很多人习惯把所有层都套上激活函数但 SIREN 的输出层论文里用的是线性层不加激活。如果输出层也套 sin颜色值或距离值会被限制在 [-1, 1]而且梯度信号会进一步扭曲。检查代码时第一件事就是确认最后一层是普通 Linear。4.3 常见问题速查表问题现象可能原因解决方案Loss 完全不降权重初始化未按 SIREN 方案检查 SineLayer 的初始化逻辑确认第一层和后续层用的是不同尺度Loss 剧烈震荡学习率过高把 Adam 学习率降到 1e-4 以下输出图像模糊、缺细节ω0 太小或网络太窄尝试 ω060或增加隐藏层宽度输出布满高频噪点ω0 过大或训练数据不足降低 ω0或增加训练步数、使用早停3D 表面不光滑缺少梯度/法向量监督加入 Eikonal 约束或法向量损失音频波形有锯齿输出层误用 sin 激活把输出层改为线性层这张表是我实际排错时反复用到的基本能把 SIREN 复现中 90% 的问题定位到具体环节。5. 一些使用 SIREN 的个人体会与扩展方向我自己把 SIREN 在图像、音频、SDF 三个任务上完整跑过一遍之后最大的感受是这个模型的代码量真的小但效果上的差别几乎全部来自“激活函数选型 初始化”这个底层设计。很多人第一次复现失败不是网络结构搭错而是没有意识到 sin 激活对初始化如此敏感。所以我强烈建议想入门隐式神经表示的同学先拿图像拟合把初始化验证明白再往 3D 或音频上迁移。关于扩展方向SIREN 后来的影响力远超论文本身。无论是最早把坐标编码用到神经辐射场里的各种变体还是把隐式场用于求解逆问题、物理模拟都能看到 SIREN 的影子。理解了 SIREN 的激活-初始化联动机制再去看后面那些坐标网络的改进方案会轻松很多。最后再分享一个小技巧调 ω0 时别用默认的 30 一根筋走到黑。图像纹理特别密集的任务可以试 60平滑的形状表示可以试 10关键是观察输出的频率分布是否符合预期。这个参数比网络宽度和深度更值得花时间调因为它直接影响模型对“信号频率”的先验假设。SIREN 换了激活函数这件事本身并不神秘神秘的是它让你重新思考神经网络在表示一个连续信号时到底应该拥有怎样的归纳偏置。 SEO 优化官网定制响应式建站教育培训建站