JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

超越線性高斯,走入迴路

當線性失效時的 EKF、UKF 與粒子濾波器,以及一個閉迴路教訓(ReFIT、CLDA):離線最佳的解碼器可能在真人使用時失靈。

當線性高斯失效

有三件事會打破卡爾曼濾波器的假設:非線性調諧(放電並非狀態的線性函數)、非高斯雜訊(卜瓦松脈衝、重尾、假影),以及多峰後驗(同時有兩個合理動作)。有三個濾波器家族以遞增的計算成本鬆綁這些假設:擴展、無跡與粒子濾波器。

EKF 與 UKF

擴展卡爾曼濾波器保留高斯機制,但在當前估計點附近把非線性觀測函數 h(\cdot) 線性化,以其雅可比矩陣作為局部的 C。它便宜、且在非線性溫和時可行,但當估計遠離真值時,線性化可能發散。

\hat{x}_k = \hat{x}_k^{-} + K_k\big(y_k - h(\hat{x}_k^{-})\big), \qquad C_k = \left.\frac{\partial h}{\partial x}\right|_{\hat{x}_k^{-}}

EKF:以真實觀測函數在預測點取值的雅可比矩陣,取代線性的 C。

當神經與狀態的關係是彎曲的,普通卡爾曼濾波就失靈了。EKF 靠線性化來補救——用真實函數在當前最佳猜測處的局部斜率(雅可比)取代固定的 C

h(\cdot)
真實的非線性觀測函數。
\hat{x}_k^{-}
預測狀態,作為線性化的展開點。
C_k
雅可比——h 在預測點的局部斜率。
K_k
卡爾曼增益,現在由 C_k 構成。

這就是擴展卡爾曼濾波;當 h 在估計附近只是輕微彎曲時效果很好。

無跡卡爾曼濾波器完全避開雅可比矩陣。它挑選一小組決定性的 sigma 點,讓每一點通過真實非線性,再由變換後的點雲重建一個高斯。對於中到強的非線性,它通常在相近成本下比 EKF 更準確。

\mathcal{X}^{(i)} = \hat{x} \pm \Big(\sqrt{(n+\lambda)\,P}\Big)_i, \qquad \hat{y} = \sum_i W_i\, h\big(\mathcal{X}^{(i)}\big)

無跡變換:直接讓 sigma 點通過 h,再重新加權——不需任何導數。

UKF 不做微分,而是在估計周圍挑幾個聰明的取樣點——sigma 點——讓每個都通過真正的非線性函數,再重新平均。它不用任何導數就能捕捉曲率。

\mathcal{X}^{(i)}
圍繞當前估計擺放的 sigma 點。
\sqrt{(n+\lambda)\,P}
sigma 點的展開幅度,由不確定性 P 決定。
W_i
把變換後的點重新組合所用的權重。
h(\cdot)
每個點所通過的非線性觀測函數。

這就是無跡卡爾曼濾波;當 h 彎曲得厲害時,它通常勝過 EKF。

粒子濾波器

當後驗確實非高斯或多峰時,不以均值與共變異數表示它,而以一群加權樣本(粒子)表示。每個粒子經動力學傳播、依其解釋新量測的好壞重新加權,並週期性地對整群重新取樣。這就是粒子濾波器,第一份指南貝葉斯遞迴最一般的實現。

w_k^{(i)} \propto w_{k-1}^{(i)}\, p\big(y_k \mid x_k^{(i)}\big), \qquad \hat{x}_k = \sum_i w_k^{(i)}\, x_k^{(i)}

序列重要性加權;後驗均值是粒子的加權平均。

用一團猜測(粒子)來表示信念。每一輪,依每個猜測把新資料預測得多好來加權,再取加權平均作為你的估計。任何形狀的分布都能處理。

x_k^{(i)}
i 個粒子——一個候選狀態。
w_k^{(i)}
該粒子的重要性權重。
p(y_k \mid x_k^{(i)})
該粒子把新量測解釋得多好。
\hat{x}_k
所有粒子的加權平均估計。

這就是粒子濾波——靈活但昂貴,因為準確度隨粒子數增加。

閉迴路的轉折

這裡是本軌道最重要的實務教訓。上述每個濾波器通常都在開迴路資料上擬合——使用者被動觀看移動的目標,而你進行記錄。但一旦你閉合迴路、讓使用者操控,他們的神經活動就會改變:他們此刻會對游標誤差做出反應、修正並適應。訓練的統計不再與測試的統計相符(共變量偏移),一個離線統計最佳的解碼器,在線上可能顯得遲鈍、偏移或不穩定。

ReFIT 與閉迴路解碼器調適

解法是讓訓練資料反映使用者的意圖,而非其不完美的開迴路游標。ReFIT 背後的洞見是:校準期間使用者幾乎總是想筆直朝目標移動。於是你取觀測到的游標速度,把每一個旋轉到指向目標(保留其速率),再以這些意圖修正後的速度重新擬合卡爾曼濾波器。

v_k^{\text{intended}} = \lVert v_k \rVert \cdot \frac{p_{\text{target}} - p_k}{\lVert p_{\text{target}} - p_k \rVert}

意圖估計:保留解碼出的速率,但在重訓練前將其方向重導向已知目標。

一個重訓練技巧:假設使用者一向就是想直奔目標,於是保留解碼出的速率,但把它的方向轉向目標,再用這些修正後的意圖重新訓練。這能大幅提升準確度。

\lVert v_k \rVert
解碼出的速率,原樣保留。
p_{\text{target}}
已知的目標位置。
p_k
當前的游標位置。
v_k^{\text{intended}}
被重導向直指目標的速度。

這個意圖估計正是 ReFIT 閉環解碼器調適的核心。

# ReFIT: rotate observed velocity toward the target, keep the speed
def refit_intention(pos, vel, target):
    to_target = target - pos
    dirn  = to_target / (np.linalg.norm(to_target) + 1e-9)
    speed = np.linalg.norm(vel)
    return speed * dirn      # intended velocity used to refit C, Q of the KF
整個 ReFIT 的想法就這四行;在校準資料上運行,然後重新擬合觀測模型。
帶著閉迴路的觀點重訪游標任務:把雜訊滑桿推向更大的量測雜訊,換得的穩定性,正是意圖修正重訓練也能提供的。

把 ReFIT 一般化,閉迴路解碼器調適(CLDA)會在使用者操控的同時反覆進行這種重新校準,於數秒至數分鐘內更新解碼器,使它與使用者一同收斂,而非與之對抗。

兩個學習者,同時調適