☰
去噪粒子滤波:以单步目标重构状态估计的学习范式
2026/10/23 6:54:41 网站建设 项目流程

这篇笔记继续写 Denoising Particle Filters 的第二部分。论文标题里的 Single-Step Objectives,指的是用一种类似扩散模型的单步去噪目标来学习状态估计,而不是把整个粒子滤波轨迹展开成可微计算图去反向传播。上一篇把动机和相关工作讲完了,这篇重点拆方法、实验和几个容易理解错的地方。如果你在做机器人定位、时序状态估计,或者想把生成模型塞进贝叶斯滤波框架,这篇文章值得认真读完。

1. 为什么要在粒子滤波里谈"去噪"

粒子滤波本身是一个递归的蒙特卡洛估计器:t 时刻我们手里有一组加权粒子{z_t^i, w_t^i},对应状态后验 p(z_t | x_{1:t}) 的近似。它的每次迭代只有三个操作:从转移模型里采样新粒子、用观测似然更新权重、按权重重采样。这个流程看起来简单,但对两个模型的要求非常高——转移模型 g(z_t | z_{t-1})决定粒子往哪里散,观测似然 ℓ(x_t | z_t)决定哪些粒子值得保留。很多学习类方法都把注意力放在转移模型上,但实际做粒子滤波的人都有体会:观测似然一旦给错,粒子多样性会迅速崩塌,估计结果比转移模型偏差更致命。

问题在于这两个模型在真实场景里往往不是现成的,需要从数据里学。传统做法是端到端地训练一个"可微粒子滤波器",把时序上的滤波损失展开成计算图。也就是说,给定一段观测序列,你让滤波器跑一步、两步、三步……然后在最终估计上计算 MSE 或者负对数似然,再让梯度穿透整个轨迹回到网络参数。这种做法思路很直接,但工程上非常痛苦:序列一长,梯度要么消失要么爆炸,粒子的离散重采样又不可微,梯度方差大得离谱。

论文里提到一个阶段性改进叫"双步目标"(two-step objective),也就是不展开整条轨迹,只展开两个时间步,用两帧之间的预测误差作为学习信号。双步目标确实让展开长度从 T 降到了 2,但它本质上还是时间展开,误差会在两帧之间叠加,梯度还是会被重采样污染。作者想做的更彻底:最好根本不用跨时间展开。这就引出了"去噪"的视角。

1.1 粒子滤波的两难:模型好不如"似然好"

我做了几年的状态估计,一个很深的感受是:粒子滤波的性能瓶颈经常不在"粒子放得准不准",而在"权重给得对不对"。转移模型差一点,最多是粒子分布宽一些,重采样后还能靠观测拉回来;但似然函数如果给错了形状,权重分布会极端化,一会儿所有粒子权重都趋近于零,一会儿某一个粒子吃掉全部权重,有效样本数崩得极快。

学习似然函数最麻烦的地方是监督信号不明确。给定一个粒子 z_t^i,我们只有观测 x_t,并没有"这个粒子离真实状态有多远"的标签。回归目标不知道该往哪里打。端到端方法试图用未来观测的似然来间接监督,但这是间接信号,梯度的路径绕了一大圈。

去噪视角给了一个很漂亮的替代方案:把观测 x_t 看作真实状态 z_t 经过观测函数后再加噪声的结果。那么"给定 x_t 判断 z_t 的概率"就变成了"从带噪观测中还原干净信号"的条件去噪问题。扩散模型已经反复证明了这种任务不需要显式标签,只要构造含噪样本对,学一个噪声预测器就行。论文把同样的逻辑移植到粒子滤波的更新算子上,单步目标由此而来。

1.2 双步目标的病态来自哪里

双步目标表面上多了一步"前瞻",似乎能学到短期的动态变化,但它的病态来自两个层面。

第一个层面是模型层面的误差累积。双步目标需要把两个时刻的状态转移、观测生成和权重更新全部串起来,前一步的转移误差会直接污染后一步的权重监督信号。换句话说,梯度计算时你在对一个积分过程求导,可每一步的模型都在变,反向传播出来的梯度其实混合了不同时刻的误差,很难说清是哪个模块的问题。

第二个层面是算法层面的不可微性。粒子滤波每步都可能有重采样操作,重采样是一个离散的采样过程,不存在解析梯度。常见做法是给重采样加一个软化的近似,比如用核函数把权重平滑化,或者直接做重参数化采样。这些"软重采样"都会引入额外的近似超参数,而这些超参数又不是训练目标的一部分,结果就是训练时一个精度的样子,推理时另一个精度的样子。

单步目标之所以能绕开这个问题,是因为训练时根本不渲染滤波轨迹。它只需要同一时刻的状态-观测配对,加噪声、预测噪声、算L2损失,整个训练过程跟时间方向完全解耦。

1.3 去噪目标的第一个直觉:把状态估计当条件生成

如果你熟悉扩散模型,可能马上会发现这里的相似性。扩散模型把一张干净图像逐步加噪,直到变成纯高斯噪声,然后用一个网络学"从噪声中预测加入的噪声"这个逆过程。粒子滤波里的观测模型其实也在做类似的事:真实状态是"干净图像",观测是"加了噪声的图像",粒子滤波要做的是从带噪观测中还原状态的分布。

这个类比一开始可能觉得只是形式上的巧合,但它带来了非常实际的收益。扩散模型已经证明,用多尺度噪声训练出来的网络,对不同程度的退化都有鲁棒性。粒子滤波里的粒子离真实状态的距离也是变化的——在预测阶段粒子比较发散,在观测更新后粒子比较集中——如果我们训练一个只能在固定噪声水平下工作的网络,效果就会很脆。多噪声水平的去噪训练,相当于给状态估计做了一套覆盖各种偏差尺度的数据增强。

2. 方法框架:从预测-更新到去噪-精化

这一节进入论文的核心方法。为了说清楚,先把记号固定下来:隐状态 z_t ∈ R^d,观测 x_t ∈ R^m。我们关心的递归贝叶斯估计要交替完成两步:预测p(z_t | x_{1:t-1}) = ∫ p(z_t | z_{t-1}) p(z_{t-1} | x_{1:t-1}) dz_{t-1},更新p(z_t | x_{1:t}) ∝ p(x_t | z_t) p(z_t | x_{1:t-1})。

传统可微粒子滤波把 p(z_t | z_{t-1}) 和 p(x_t | z_t) 都参数化成神经网络,然后端到端训练。DPF 的差别在于:这两个条件分布都不直接回归,而是被"去噪网络"隐式表达。

2.1 记号和问题重述

假设我们有一条训练轨迹,最理想的情况下有真实状态序列 z_{1:T} 和观测序列 x_{1:T}。但请注意,论文设计的目标函数并不强制要求真实状态存在,这一点后面讲数据构造时会展开。我们需要学习两个模块:

  • 转移模块 T_θ:给定上一时刻状态 z_{t-1} 和当前观测 x_t,估计当前状态 z_t 的分布;
  • 更新模块 L_θ:给定当前观测 x_t 和粒子 z_t,计算粒子的权重 w_t^i。

在标准粒子滤波里,转移模块采样的粒子其实可以依赖当前观测,这叫引导滤波器(proposal distribution),论文并没有回避这一点。T_θ和L_θ的划分不是严格的时序划分,而是功能划分:一个是"生成候选状态",一个是"评估候选状态"。

DPF 的核心是:T_θ 和 L_θ 都不直接输出概率密度,而是通过一个共享的去噪网络去近似对应的条件分布。共享的好处是,转移和更新在同一个特征空间里彼此约束,训练时不会出现两个模块各学各的、对不上信号的情况。

2.2 预测算子的去噪化

先看转移模型。标准的参数化方式是把 z_t 建模成 z_t = f_θ(z_{t-1}) + σ_process ε,其中 ε 是过程噪声。这里 f_θ 可以是一个神经网络。但问题在于,f_θ 的训练信号来自哪里?如果只有观测序列,没有真实状态,这个回归目标本身就缺了标签。

DPF 的做法是把"给定 z_{t-1} 预测 z_t"改成"给定 z_{t-1} 和含噪观测预测观测噪声"。直觉上,z_t 隐式地藏在 x_t 里,我们不需要直接还原 z_t,只需要让网络学会识别"哪些信息是观测里还没被噪声掩盖的"。具体实现中,网络输入是上一时刻状态特征和当前含噪观测特征,输出是加入观测的噪声估计。这个预测任务对每个时间步独立成立,因此训练时不需要把 z_{t-1} 和 z_t 的预测误差在时间上展开。

有人可能会问:这样训练出来的转移模型,还能不能叫"转移模型"?它的确不再是一个显式的 p(z_t | z_{t-1}),但它仍然在完成"基于上一时刻信息生成当前状态候选"的职责。推理时,我们用去噪网络给出的特征来构造粒子的 proposal,而不是直接拿网络输出当状态值。

2.3 更新算子的去噪化

更新算子是最关键的部分,也是和普通扩散模型差异最大的地方。粒子滤波里,权重必须正比于观测似然 p(x_t | z_t^i)。怎么从去噪网络里得到这个似然?

论文的思路是训练一个条件观测生成模型:给定状态 z_t,观测 x_t 的分布满足 x_t = h_φ(z_t) + σ_obs ε。这里 h_φ 不是显式学出来的观测函数,而是用去噪网络在"状态条件下"预测观测噪声来代替。于是:

p(x_t | z_t^i) ∝ exp( -|| ε - ε_θ(z_t^i, x_t, σ) ||^2 / (2σ^2) )

也就是说,网络残留误差越小,说明这个粒子越能解释当前观测,权重就该越高。这是一个从条件生成模型推导似然的通用技巧,扩散模型领域叫做"从去噪评分近似条件密度"。

需要注意,这里不是简单地把网络输出当分数,而是有一个高斯密度假设在背后。观测模型被建模成"干净观测 = 状态的确定性函数 + 高斯噪声",所以似然的形式才是高斯的。如果实际系统噪声不是高斯,理论上可以换更复杂的密度形式,但训练目标就要相应调整。

2.4 单步目标函数的具体形态

把上面两块合起来,整个训练目标其实就是一个带条件的去噪损失。示意如下:

L(θ) = E_{t, (z_t, x_t), ε, σ} [ λ(σ) · || ε - ε_θ( z_t, x_t + σ·ε, σ ) ||² ]

其中 ε_θ 是去噪网络,它的输入包括粒子状态 z_t(条件信息)、含噪观测 x_t + σε(待去噪信号)以及噪声水平 σ。真实噪声 ε 是采样出来的,网络要做的事就是把 ε 预测出来,损失就是两者之间的平方误差。

这个公式和标准扩散模型的训练目标几乎一样,唯一显著的区别是多了条件 z_t。但千万别因此小看它——正是这个条件,让网络学会的不是"从纯噪声里还原观测",而是"在已知状态假设下评估观测的合理性"。训练时每个样本只涉及单个时间步的状态-观测对,没有任何时间方向的展开,这让它的梯度方差远小于时序目标。

λ(σ) 是噪声水平的加权项。不同 σ 下,损失的绝对量级差别很大,如果不做加权,网络会偏向学习大噪声样本,小噪声下的精细去噪能力会退化。论文使用的加权方式本质上是在平衡各噪声尺度的梯度贡献,这一点在消融实验中单独做了验证。

3. 训练细节:为什么"单步"能绕开时序病态

方法框架清楚了,还得看训练管道是怎么搭的。这里有很多容易踩坑的细节,读论文时如果不仔细容易忽略。

3.1 训练数据怎么构造

训练 DPF 需要的不是一堆标注好的真实状态,而是"状态-观测"在同一时刻的配对。最理想的数据来源是仿真器,因为仿真器可以随时输出真实状态。但论文强调,单步目标并不强依赖状态标签——如果没有真实状态,可以用滤波器自身的估计结果或者某种初始化先验来代替 z_t。

我在复现时发现这个设计的实际含义是:训练数据可以和应用场景解耦。比如要部署在某个复杂的机器人平台上,你不需要费劲标注真值,只需要一条连续的观测序列,自己用某个粗糙的滤波器跑一遍,把中间粒子和观测配对存下来就能训练。当然,没有真值时训练的收敛更慢、噪声更大,但至少是可用的。

更实际的数据构造方式是数据增强:同一对 (z_t, x_t) 可以在多个噪声水平 σ 下重复采样。论文的默认做法是每个 batch 内混合多种 σ,让网络在每个 batch 里都接触到从精细到粗糙的不同尺度。这样训练出的网络在推理时,无论粒子偏离真实状态多少,都有对应的去噪能力。

3.2 噪声调度和时间嵌入

扩散模型的噪声调度设计非常讲究,DPF 直接沿用了这一套。噪声水平 σ 从小到大覆盖一个区间,比如从 0.01 到 5.0(具体取值取决于观测的量级)。推理时,粒子与真实状态的误差既可能小于观测噪声,也可能大于观测噪声,所以调度区间要略宽于先验估计的偏差范围。

为了让网络知道当前用的是哪个 σ,输入里要加入噪声水平的嵌入向量。这个嵌入通常经过一个小型 MLP 或者正弦位置编码,再和观测特征相加。很多人复现时容易忽略这个条件,直接把 σ 丢掉,结果网络只能记住一个平均噪声水平下的行为,测试时一换噪声就垮掉。

另外,论文里提到一个细节:训练时 σ 是从调度区间里随机采样,而不是固定一组值。这保证了网络不是只在几个离散尺度上工作,而是学会在连续尺度上插值。这个随机采样策略几乎是零成本地提升了模型对不同噪声的鲁棒性。

3.3 损失函数的平衡项

刚才公式里的 λ(σ) 值得单独说。如果不加这个权重,直接对不同 σ 的损失求平均,大噪声样本的 MSE 数值天然会更大,梯度也会被它们主导。但真实应用中,小噪声情况(粒子已经比较准)才是滤波器稳定性的关键,因为这些样本决定了权重更新的锐度。

常见的加权方式有 λ(σ) = 1/σ²,这样做的效果是让各噪声水平下的有效信噪比接近。也可以采用基于梯度方差的启发式加权,但论文使用的还是更经典的 SNR 加权。我在自己的实验里试过不做加权、线性加权和 1/σ² 加权,差距非常明显:不加权时粒子滤波的估计在低噪声传感器下明显偏钝,换 1/σ² 之后低噪声表现立刻恢复。

3.4 与双步目标在收敛行为上的区别

如果有条件的话,可以自己在代码里对比两种目标。双步目标训练时,loss 曲线会呈现明显的周期性波动——因为每个 batch 里的两帧样本组合不同,梯度方向变化剧烈,而且时不时会出现一个特别大的梯度尖峰,基本都对应着重采样附近的样本。

单步目标下,loss 曲线会平滑很多。每一个样本对是独立同分布的,梯度方差几乎完全取决于 batch 内的噪声尺度混合程度,和时间无关。这相当于把原来"轨迹展开的风险"换成了"条件分布建模的风险",前者很难控制,后者可以通过增大 batch、调整噪声调度来控制。我认为这是论文最务实的一个贡献:它把训练难度从一个工程上难以稳定的问题,变成了一个已经有成熟工具的生成模型问题。

4. 实验解读:哪些结论值得记

论文的实验设置横跨合成系统和真实数据两类场景。我不打算复述每个表格,只讲几个实验设计上的亮点和值得记住的结论。

4.1 合成非线性系统上的精度变化

合成场景通常是一个一维或二维的非线性状态空间模型,比如带强烈非线性的振荡系统。这类系统的特点是状态转移和观测模型都存在明显的非线性耦合,传统粒子滤波如果模型不准,精度会迅速下降。

论文的对比结果显示,DPF 在中等噪声水平下的滤波精度明显优于几个基线。更有意思的是,它的优势在观测似然不对称时最明显。所谓不对称,是指同一个观测误差在不同方向上对应的状态偏差不一样,例如传感器在某个方向上的分辨率特别差。标准粒子滤波用固定协方差的似然函数时,很难表达这种不对称;而去噪网络学到的条件分布天然可以适应这种数据驱动的形状。

4.2 粒子数、噪声水平与性能的交互

我印象最深的是粒子数量的实验。直觉上,粒子数越多越好,但论文展示了另一个结论:DPF 用较少的粒子就能达到传统方法很多粒子才能达到的精度。原因是粒子的分布合理性不同。传统方法如果似然函数给得粗糙,大量粒子都落在低权重区域,有效粒子数很低;DPF 的去噪网络给出了更平滑、更准确的权重面,粒子落在有效区域的概率大大提高。

不过这里有个边界:粒子数非常少时,DPF 的优势也会被重采样离散误差抵消。粒子数从 10 涨到 100 时收益最明显,从 100 涨到 1000 时基本饱和。这和我在实际部署里的经验一致——粒子滤波的收益曲线是凹的,堆粒子数是最不经济的优化手段。

4.3 真实数据的迁移表现

真实数据实验上,论文考虑的是训练时用一种噪声水平,测试时换成另一种噪声水平的场景。传统方法面对这种 shift 通常很脆,因为模型只见过训练时那一种噪声尺度。DPF 因为训练时覆盖多种噪声水平,天然具备对噪声尺度变化的鲁棒性。

严格说,这种鲁棒性不是白来的。多噪声训练相当于一种隐式的数据增强,代价是网络在"非常干净的观测"上可能不如专门训练的模型锐利。但真实部署中传感器噪声总是波动的,这种泛化比极致的锐度更有价值。

4.4 消融实验的关键发现

消融实验做了三组:去掉条件输入、固定噪声水平、把单步目标换成双步目标。

  • 去掉条件输入之后,网络退化成一个单纯的观测自编码器,粒子滤波的权重更新完全失去状态判别性,性能急剧下降。这说明 z_t 这个条件不是锦上添花,而是整个方法的核心。
  • 固定噪声水平之后,训练更稳定,但推理时一旦粒子偏差超过固定尺度,权重面就会出现大片平坦区域,粒子无法区分。
  • 换成双步目标之后,短序列上性能接近,但序列一长就出现梯度波动,最终收敛精度明显差于单步目标。

5. 我理解的边界与易错点

读这篇论文时,有几个地方如果不结合粒子滤波的背景去理解,很容易产生误判。这里单独列出来说。

5.1 别把去噪网络当成观测似然

这是一个关键误区。去噪网络本身输出的是一堆特征或者噪声预测,并不直接是一个概率值。要让网络输出变成粒子权重,你必须经过一次"从噪声预测到密度估计"的转换。论文里用的是高斯密度假设,把网络残差代入高斯核计算权重。这意味着网络只学到了一个条件评分函数,真正算权重时仍然需要你选择密度形式。

实际复现时,这个转换的系数(也就是那个 σ² 的分母)很重要。设得太小会过度惩罚偏差大的粒子,导致权重悬殊、粒子退化;设得太大又会让所有粒子权重趋同,更新失效。论文里的设置通常和训练时使用的噪声尺度挂钩,但真实数据上可能需要额外调。

5.2 单步目标不等于"只看一步"

单步目标针对的是训练时的梯度路径,推理时仍然在递归地做多步滤波。也就是说,模型每个时刻的网络调用是独立的,但粒子状态会跨时间累积。这和"只看一步"的贪心算法有本质区别:训练目标是单步的,不代表模型不利用历史信息,因为当前粒子状态本身已经携带了历史信息。

这个区别很重要,不然你会误以为 DPF 无法应对长期遮挡或观测缺失的场合。实际上,观测缺失时粒子滤波照样靠转移模型往前推,只是这时候去噪网络没有观测可条件,权重更新会被跳过或弱化。单步目标只是让学习更容易,不是让模型失去记忆能力。

5.3 重采样策略仍然关键

论文的重心在训练目标,但推理时的重采样策略依然决定最终效果。我试过在不同任务上换用多项式重采样、残差重采样和系统重采样,差异非常明显。系统重采样通常会带来更低的方差,但计算量稍高;多项式重采样简单但容易引入额外噪声。

如果你的部署环境对响应时间敏感,建议在推理时加入有效样本量(ESS)阈值判断:ESS 低于某个阈值才触发重采样,否则继续递推。这个小技巧和论文方法完全正交,但组合使用效果很好,能省掉大量无意义的重采样开销。

6. 结合我自己的复现经验:如果要从零实现

最后分享一下我从零复现这个方法的实际流程。如果你打算在项目里试用,可以按下面的顺序推进,能少走不少弯路。

6.1 最小可复现流程

首先你需要一个能产出"状态-观测对"的数据源。最省事的是随便选一个非线性运动模型,自己写个仿真器,同时记录真值和观测。然后:

  1. 定义去噪网络。状态维度不高时,一个带条件输入的 MLP 就够了;高维状态加图像观测,则建议用类似扩散模型的 U-Net 结构。输入是观测和噪声水平的嵌入,条件特征是状态向量,输出是和观测相同维度的噪声预测。
  2. 训练数据构造。对每个时刻的状态-观测对,随机采样 σ 和噪声 ε,构造含噪观测 x_t + σε,把 (z_t, 含噪观测, σ, ε) 存成一个样本。
  3. 训练损失。直接用预测噪声和真实噪声的 MSE 乘上 λ(σ),优化器建议用 AdamW,学习率 3e-4 起步。
  4. 推理。先跑一个标准的 bootstrap 粒子滤波骨架,把似然函数换成基于去噪网络残差的高斯核,其他流程完全保留。

一个容易犯错的点:训练时状态 z_t 和观测 x_t 必须是同一时刻的配对。如果你不小心用了上一时刻的状态配对当前观测,网络会学到错误的时序关联,推理时权重更新会失真。

6.2 稳定训练的几个技巧

第一,输入归一化一定要做。状态和观测的量级如果差太多,去噪网络的损失会被大尺度变量主导。我习惯先把观测标准化到零均值单位方差,再乘上噪声水平,这样 σ 的物理含义更清晰。

第二,每个 batch 内混合多种噪声尺度。不要一个 batch 全是大噪声,下一个 batch 全是小噪声,这样梯度方向会来回震荡。固定一个噪声水平列表,比如 0.01 到 2.0 之间均匀取 10 档,每个 batch 内按档位均衡采样。

第三,梯度裁剪是必需品。虽然单步目标比双步目标稳定,但极端噪声样本仍然可能产生大梯度。梯度范数裁剪到 1.0 左右,训练几乎不会出现 NaN。

第四,如果在真实数据上训练且没有真值状态,建议先用一个粗糙的扩展卡尔曼滤波器生成伪状态标签,再送入去噪网络训练。伪标签的噪声会让训练目标变成一种"噪声之上的噪声",但实践中仍然能学到有效的权重区分度,比完全冷启动好得多。

6.3 可以继续扩展的方向

DPF 的框架本身没有绑定具体网络结构,所以扩展空间很大。我在自己的项目里试过把去噪网络换成分层结构,一个模块做观测去噪,一个模块做状态之间的转移校正,效果比单网络好但训练复杂度也上去了。另外,多模态观测的融合也值得试:不同传感器可以各自加噪、各自去噪,最后在权重更新时做乘积融合,这和粒子滤波的多传感器更新天然吻合。

还有一个方向是把它和在线学习结合。单步目标的样本独立性非常友好,新数据来了可以直接做增量训练,不需要缓存整条轨迹。这在机器人持续部署的场景里很有吸引力。

我自己读完这篇论文最大的感受是:状态估计问题里很多"难"其实是被训练目标的选择放大了。粒子滤波本身不复杂,复杂的是把一个递归过程变成可优化的计算图。从去噪扩散模型里借一个单步目标,看起来只是换个损失函数,实际上是把问题从时序层面的病态求解,转成了空间层面的条件生成建模。这个视角对做在线估计的人来说,价值不亚于再刷几个百分点精度。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询