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

即時解碼流水線

一股即時的大腦電壓訊號如何在每秒鐘內多次變成可用的命令。我們沿著從原始訊號到動作的四階段流水線走一遍,看看**即時**這項要求為何改變了每一個設計抉擇,並讀一段簡短的流水線虛擬碼。

原始訊號進,命令出

解碼的核心,是一種反覆執行的轉換:一段原始電壓進去,一個離散的命令出來。把它想像成一條工廠流水線。輸送帶永不停歇——新鮮的大腦訊號不斷到來——而在末端,一件成品(一次游標移動、一個字母、一次機械手抓握)滾落下來。這條流水線的任務,就是讓輸送帶平穩運轉,每秒數十次地把雜亂的電訊號變成乾淨的決策。

輸入是你的感測器所傳來的任何東西——來自頭皮的腦電圖(EEG,electroencephalography)、來自皮層表面的皮層腦電圖(ECoG,electrocorticography),或來自皮層內電極陣列的尖峰放電。輸出則是現實世界中的一個動作。兩者之間的一切就是流水線,而從業者的功力,正體現在每一階段如何搭建、以及整體執行有多快。

四個階段

幾乎每一個解碼器,無論簡單還是花俏,都是這四個階段依序排列的某種版本。掌握它們一次,你就能讀懂遇到的任何流水線。

  1. 前處理 / 清洗。取原始訊號流的一小段視窗並加以整理:用帶通濾波器保留有用的頻率,並剔除或去除像眨眼和市電雜訊這樣的偽跡。垃圾進、垃圾出——這一階段為後續環節把關。
  2. 提取特徵。把清洗後的視窗濃縮成寥寥幾個承載意圖的數字——特徵,比如μ節律中的頻帶功率,或某個空間濾波器的輸出。你是在丟掉一切無關的東西,只留下訊號。
  3. 分類成一個選擇。把特徵餵給一個分類器——它早先在校準時已訓練好——由它將特徵映射到為數不多的幾個意圖之一(向左還是向右、點擊還是靜息、這個字母還是那個字母)。
  4. 發出命令。把那個選擇變成一個動作——移動游標、敲下字母、驅動義肢——並把它發送出去。結果回饋給使用者,從而閉合迴路。

線上與離線

執行解碼器有兩個世界。離線分析是從容的:你有一份錄製好、存在磁碟上的資料集,可以反覆回放、偷看未來、試上一百個模型、消磨整個下午。線上(即時)解碼則毫無這份從容。訊號是即時到來的,使用者在等待,迴路必須在時機溜走之前閉合。

正是這一條約束——端到端地跟上即時訊號——塑造了一切。你只能用過去、絕不能用未來,所以非因果濾波器被排除在外。從視窗到命令的整體延遲通常必須落在大約 100 毫秒以內才感覺跟手,這就限制了你的特徵和模型能有多重。而且它必須無人看管地執行,所以流水線得優雅地處理壞樣本,而不是直接崩潰。

一段流水線虛擬碼

下面就是把整條流水線寫成的一個小迴圈。先講直覺:我們抓取訊號最新的一片,把它清洗乾淨,擠出特徵,問訓練好的分類器它意味著什麼,然後發出命令——接著馬上再來一圈。請留意,前面那四個階段,在迴圈裡恰好各佔一行。

# Real-time decoding loop. Runs as long as the BCI is on.
while bci_is_running:
    window = stream.read(samples=250)      # newest 1 s @ 250 Hz (past only)
    if has_artifact(window):
        continue                           # skip bad chunk, don't crash
    clean = bandpass(window, low=8, high=30)   # keep mu/beta band (8-30 Hz)
    feats = band_power(clean)              # extract features: power per channel
    intent = classifier.predict(feats)     # classify -> e.g. 'left' / 'right'
    send_command(intent)                   # issue command; user sees feedback
    # loop repeats every step -> a fresh decision many times per second
一個最簡線上解碼迴圈:讀取一個只含過去的視窗,清洗,提取頻帶功率特徵,分類,然後發出命令——如此持續反覆。