
玩到一個很有意思的項目果蠅大腦玩 Flappy Bird這不是一個游戲 demo這是一次神經科學實驗——把真實的果蠅連接組接入游戲世界看它能不能自己學會飛行。這個項目到底解決了什么問題如果你問一個神經科學家果蠅的大腦能不能學會玩電子游戲他大概率會告訴你——這個問題本身就沒有意義。果蠅沒有玩的概念它的神經系統(tǒng)演化出來是為了在真實世界中覓食、求偶、逃避天敵不是為了在一根管道中間鉆來鉆去。但這個問題背后藏著一個真正硬核的技術挑戰(zhàn)你能不能把一個完整的、真實的、未經修改的生物大腦放進瀏覽器里讓它接收人工感覺信號然后產生自主行為這不是訓練一個神經網絡去玩游戲。那種事情我們已經見得太多了——PPO、DQN、NEAT隨便哪個強化學習算法都能在 Flappy Bird 上刷到幾百分。那些是人工智能不是生物智能。這個項目做的事情完全不同連接組是凍結的。166,700 個神經元、25,088,107 條突觸連接全部來自 MaleCNS v1.0 真實果蠅大腦掃描數(shù)據(jù)。沒有任何一條連接的權重被修改過。這不是訓練這是移植。計算在瀏覽器里完成。不是 GPU 集群不是云端推理——是你的瀏覽器里的一個 Web Worker以 50Hz 的頻率模擬整個果蠅大腦的神經活動。行為從神經活動中涌現(xiàn)。沒有if bird.y gap.y then flap()這樣的硬編碼規(guī)則。游戲畫面被編碼成果蠅能看到的神經刺激經過 16 萬個神經元的傳播和計算最終從下行神經元的活動中解碼出拍翅指令。一句話總結創(chuàng)新點這是世界上第一個在瀏覽器中運行的完整果蠅連接組行為實驗。創(chuàng)新點一把游戲畫面翻譯成果蠅能看見的東西果蠅沒有視網膜上的像素。它的復眼由大約 800 個小眼組成每個小眼感知一個方向的光強變化。所以我們不能簡單地把 Flappy Bird 的截圖喂給果蠅大腦——那就像把一本量子力學教材塞進一臺收音機。我們需要一個編碼器FlyEncoder把游戲狀態(tài)翻譯成特定視覺神經元的刺激信號。這個編碼器的設計不是拍腦袋想出來的而是基于果蠅視覺系統(tǒng)的神經科學文獻。LC4 和 LPLC2碰撞檢測器果蠅有一套精密的 looming detection系統(tǒng)。當你用手快速接近果蠅的眼睛時它會在幾毫秒內啟動逃避反應。這套反應由 LC4Lobula Columnar type 4和 LPLC2Lobula Plate Columnar type 2神經元介導。它們對快速逼近的物體特別敏感——物體在視野中越大、越近這些神經元就越活躍。在編碼器中我們把水管到果蠅的距離映射成 LC4/LPLC2 的刺激強度approachIntensity clamp(1 - distance / 300, 0, 1)當水管距離 300 像素時刺激幾乎為零——對果蠅來說那個水管還看不見。當水管距離 30 像素時刺激達到最大值 1.0——這就像水管已經懟到果蠅臉上了。水管距離LC4 刺激生物學類比 300px0.05物體在視野邊緣幾乎無感200px0.25物體進入中央視野100px0.60物體快速逼近逃避系統(tǒng)激活 30px1.00imminent collision全力逃避LC10a-L / LC10a-R方向感知僅僅知道有東西在逼近是不夠的。果蠅還需要知道洞口在上方還是下方。我們用 LC10a 神經元的左右兩個通道來編碼垂直誤差error gapCenterY - birdY if error 0: // 果蠅低于洞口 LC10a-L normalizedError // 目標在上方信號 LC10a-R 0 else: // 果蠅高于洞口 LC10a-L 0 LC10a-R normalizedError // 目標在下方信號這不是隨意選擇的映射。LC10a 在果蠅大腦中參與視覺追蹤和目標定向行為將它映射為方向誤差是有神經科學依據(jù)的。速度通道慣性感知果蠅不只需要知道在哪還需要知道往哪走。一個正在高速上升的果蠅即使位置還低于洞口也不應該再拍翅膀——否則就會沖出頂部邊界。編碼器用兩個輔助通道編碼速度信息velocityY 0 → UPWARD 通道激活 velocityY 0 → DOWNWARD 通道激活 強度 clamp(|velocityY| / 520, 0, 1)這四個通道LC4、LPLC2、LC10a-L/R、UPWARD/DOWNWARD共同構成了果蠅對游戲世界的全部感知。沒有全局視野沒有像素級輸入只有六個標量信號——就像果蠅在真實世界中依賴的有限感覺線索。創(chuàng)新點二在瀏覽器 Web Worker 里跑 16 萬個 LIF 神經元有了感覺輸入下一步是讓這些信號在果蠅大腦中傳播。這里的核心是LIFLeaky Integrate-and-Fire神經元模型——計算神經科學中最經典、最廣泛使用的簡化模型。LIF 模型簡單但不簡陋每個神經元的狀態(tài)更新方程是這樣的v[t1] decay × v[t] gain × current[t] tonic drive其中v[t]是神經元當前的膜電位0 到 1 之間decay exp(-dt/tau)是漏電衰減因子模擬細胞膜的被動放電current[t]是上游神經元傳來的突觸電流總和tonic是基礎張力電流讓神經元保持一定的自發(fā)活動drive是外部感覺刺激來自編碼器的 LC4/LPLC2/LC10a 輸入當膜電位v 1時神經元發(fā)放一個動作電位spike膜電位重置為 0。這個 spike 會通過突觸連接傳遞給下游神經元形成級聯(lián)反應。25M 條連接的稀疏表示166,700 個神經元之間的連接矩陣有 25,088,107 條有效突觸。如果用稠密矩陣表示需要 166,700 × 166,700 278 億個元素——這顯然不現(xiàn)實。項目采用了一種精心設計的壓縮稀疏列CSC格式配合自定義的 FLYW 二進制編碼colPtr每列的非零元素累積數(shù)量varint 編碼rowIdx每個非零元素的行索引varint delta 編碼code8-bit 量化權重碼通過 256 項查找表LUT映射回浮點值整個 25M 條連接的權重數(shù)據(jù)被壓縮到57.6 MB兩個 .bin 文件。權重量化的平均誤差僅為 0.023最大誤差 0.047——對于生物神經網絡的模擬來說這個精度綽綽有余。Web Worker不能讓游戲卡成幻燈片16 萬個神經元的模擬每步需要遍歷 2500 萬條連接進行電流傳播。如果在主線程上執(zhí)行游戲幀率會從 60 FPS 直接掉到個位數(shù)。解決方案是把整個神經模擬放進一個Web Worker主線程60 FPS Web Worker50 Hz ┌──────────────┐ ┌──────────────────┐ │ 游戲物理更新 │ │ 連接組加載 │ │ 游戲畫面渲染 │ ─STEP→ │ LIF 神經模擬 │ │ 神經活動可視化│ │ 感覺刺激注入 │ │ HUD 狀態(tài)更新 │ ←RESULT │ 運動神經元讀取 │ └──────────────┘ │ 讀出層推理 │ └──────────────────┘主線程每 20ms 發(fā)送一次STEP消息攜帶當前游戲狀態(tài)Worker 完成一次神經模擬后返回BRAIN_RESULT包含決策和神經活動數(shù)據(jù)。兩個時鐘完全獨立互不阻塞。如果瀏覽器支持SharedArrayBuffer需要 COOP/COEP 響應頭神經活動數(shù)組會通過共享內存直接暴露給主線程避免每步都拷貝 166,700 字節(jié)的數(shù)據(jù)。不支持時自動降級為Transferable模式——性能略有損失但功能完全不受影響。創(chuàng)新點三三種模式一個核心約束這個項目最精妙的設計在于它的核心約束連接組永遠凍結只有讀出層可以學習。這不是技術限制而是設計哲學。我們想回答的問題是“一個真實的生物大腦在只允許調整輸出接口的情況下能不能適應一個全新的任務環(huán)境”圍繞這個約束項目提供了三種實驗模式模式一PURE BRAIN純腦模式最原始的模式。不訓練任何東西直接從 DNp01一個真實的果蠅下行神經元的活動水平解碼拍翅決策DNp01 spike count in 100ms 2 → FLAP cooldown 120ms防止連續(xù)拍翅飛出天際DNp01 在果蠅大腦中參與起飛和逃避行為。在純腦模式下我們觀察的是一個未經任何訓練的真實生物神經網絡如何對人工感覺刺激做出反應。結果果蠅會動但飛得亂七八糟。它偶爾會拍翅膀有時能躲過一根管道但很快就撞墻。這完全符合預期——一個從真實果蠅大腦掃描出來的連接組本來就沒有玩 Flappy Bird的經驗。模式二ONLINE TRAIN在線訓練模式這是默認模式也是最有趣的模式。連接組依然凍結但我們在下行神經元活動和最終決策之間加了一個邏輯回歸讀出層Logistic ReadoutDN 活動向量 → 標準化 → 邏輯回歸 → FLAP 概率 → 閾值比較 → FLAP/WAIT這個讀出層在每次飛行中實時更新一個教師策略根據(jù)游戲狀態(tài)決定應該拍翅嗎收集下行神經元的活動特征12 組 DN 群體的放電率用梯度下降更新邏輯回歸權重w - lr × (pred - label) × x 正則化學習率 0.018帶 L2 正則化防止過擬合關鍵細節(jié)安全邊界永遠不可覆蓋。無論讀出層怎么學以下規(guī)則始終生效果蠅位于目標上方 → 禁止拍翅果蠅正在快速上升 → 禁止二次拍翅這些安全約束確保了即使讀出層還沒學好果蠅也不會一上來就沖出頂部。大約 1000 個樣本約 2-3 輪飛行后讀出層就會收斂到一個合理的決策閾值果蠅的飛行能力顯著提升。模式三FAST TRAIN快速訓練模式點擊? FAST TRAIN后Worker 會在后臺快速模擬 1200 幀游戲生成訓練樣本然后進行完整的邏輯回歸訓練120 個 epoch帶驗證集早停。訓練完成后切換到FAST MODEL模式權重凍結直接使用訓練好的模型推理。原來的在線學習進度會被保存切回ONLINE TRAIN時可以恢復。兩套模型完全獨立不會互相覆蓋。創(chuàng)新點四16 萬個神經元的實時可視化如果說神經模擬是這個項目的大腦那 WebGL 可視化就是它的臉面。左欄的神經星空效果不是預先錄制的動畫——它是 166,700 個神經元的實時活動映射。Fibonacci 螺旋映射怎么把 16 萬個神經元排列到一個圓形畫布上項目使用了一種Fibonacci 螺旋也叫黃金角分布for(leti0;i166700;i){constthetai*2.3999632297;// 黃金角弧度constrMath.sqrt((i0.5)/166700)*0.92;xMath.cos(theta)*r*0.82;yMath.sin(theta)*r;}這種排列方式讓每個神經元均勻分布在圓盤上沒有聚簇也沒有空隙視覺上非常美觀。WebGL 點精靈渲染每個神經元是一個 WebGL 點精靈Point Sprite大小和亮度由活動水平決定// 頂點著色器 gl_PointSize 1.2 activity * 3.0; // 片元著色器 float d distance(gl_PointCoord, vec2(0.5)); if (d 0.5) discard; // 圓形裁剪 color vec4(0.25 v*0.6, 0.65 v*0.35, 0.54 v*0.35, 0.17 v*0.83);靜息神經元是暗淡的小綠點發(fā)放動作電位的神經元是明亮的大光點。整個畫面看起來像一片呼吸著的星空——當水管逼近時大片神經元同時亮起就像一波神經海嘯席卷了整個大腦。渲染頻率控制在 25 FPS每 40ms 更新一次遠低于游戲的 60 FPS。這是有意為之——神經活動的變化速度本來就比游戲慢更高的渲染頻率只會浪費 GPU 性能。創(chuàng)新點五從 fly.ai 到瀏覽器——自定義二進制格式MaleCNS v1.0 連接組的原始數(shù)據(jù)格式是為 Python 科學計算生態(tài)設計的。要在瀏覽器中高效加載和解析需要一套全新的二進制格式。項目設計了兩種自定義格式FLYM神經元元數(shù)據(jù)┌────────┬────────┬───────────┬──────────┬──────────┬───────────┬──────────┐ │ Magic │Version │ N(neurons)│ JSON Len │ JSON │ typeIdx │ classIdx │ │ FLYM │ u32 │ u32 │ u32 │ (types, │ u16[N] │ u8[N] │ │ 4B │ 4B │ 4B │ 4B │ params) │ │ side │ └────────┘────────┴───────────┴──────────┴──────────┴───────────┴──────────┘JSON 部分包含types所有神經元類型名稱如 “LC4”, “DNp01”, “DNg111”superclasses superclass 分類paramsLIF 模擬參數(shù)dt, tau, gain, tonic, noise_hz, noise_amp后面的二進制數(shù)組為每個神經元存儲類型索引u16、類別索引u8、左右側別u8。FLYW稀疏連接權重┌────────┬────────┬──────┬────────┬──────────────┬──────────────┬──────────┐ │ Magic │Version │ N │ NNZ │ ln_min │ colPtr │ rowIdx │ │ FLYW │ u32 │ u32 │ u32 │ f32 │ varint[N] │ varint │ │ 4B │ 4B │ 4B │ 4B │ 4B │ │ [NNZ] │ ├────────┬────────┴──────┴────────┴──────────────┴──────────────┴──────────┤ │ LUT │ weights (u8[NNZ]) │ │ f32[256]│ │ └────────┘────────────────────────────────────────────────────────────────┘關鍵設計決策Varint 編碼列指針和行索引使用可變長度整數(shù)編碼大幅減少小數(shù)字的存儲空間Delta 編碼同一列內的行索引存儲差值而非絕對值進一步壓縮8-bit 權重量化256 項查找表將每個權重從 32-bit 浮點壓縮到 8-bit壓縮比 4:1指數(shù)量化查找表使用exp(ln_min * (1 - q/127))映射對小數(shù)值的精度更高最終57.6 MB 的權重文件在瀏覽器中只需幾秒鐘就能加載完畢配合 Cache Storage第二次打開幾乎是瞬間。創(chuàng)新點六三時鐘異步架構這個項目最容易被忽視、但技術上最精妙的設計是它的三時鐘異步架構。游戲、大腦和渲染各自運行在不同的時鐘頻率上游戲時鐘60 FPS16.67ms/幀 大腦時鐘50 Hz20ms/步 渲染時鐘25 FPS40ms/幀它們之間的關系不是簡單的 1:1:1而是一個累積器模式// 主循環(huán)while(brainClock0.02){// 每 20ms 執(zhí)行一次大腦步進brainClock-0.02;brain.step(game.capture(),mode,elapsed);}// 渲染節(jié)流if(now-renderClock40){// 每 40ms 渲染一次大腦可視化brainRenderer.render(brain.activity);renderClocknow;}這意味著一個大腦步進周期內游戲可能已經更新了 1-2 幀大腦可視化每兩幀才更新一次但肉眼完全看不出差異三個時鐘完全獨立任何一個卡頓都不會拖垮其他兩個SLOW BRAIN 模式時間放大鏡當用戶點擊SLOW BRAIN按鈕時項目并不是降低了大腦的模擬頻率——它只是把游戲時鐘的縮放因子設為 0.1constscalethis.slow?0.1:1;constdtMath.min(0.033,(now-this.last)/1000)*scale;游戲世界變慢了 10 倍但大腦依然以 50Hz 運行。這就創(chuàng)造了一個時間放大鏡效果——用戶可以清楚地觀察到水管接近 → LC4/LPLC2 亮起視覺輸入檢測信號在連接組中傳播 → 中間神經元活動擴散DNp01 激活 → 下行神經元發(fā)出運動指令決策變?yōu)?FLAP → 果蠅拍翅在正常速度下整個過程不到 100 毫秒肉眼根本來不及分辨。SLOW BRAIN 模式把這個過程拉長到 1 秒讓神經信號的傳播路徑清晰可見。實驗記錄系統(tǒng)科學從可復現(xiàn)開始每個嚴肅的科學實驗都需要可復現(xiàn)性。項目通過種子隨機數(shù)實現(xiàn)了完整的實驗可復現(xiàn)// 水管生成、神經噪聲、訓練采樣——全部使用同一個種子rng(Math.imul(rng,1664525)1013904223)0;在 URL 中添加?seed12345參數(shù)就能精確復現(xiàn)某次實驗的全部條件相同的水管位置序列、相同的神經噪聲序列、相同的訓練樣本順序。實驗歷史自動保存在瀏覽器的localStorage中記錄每次飛行的Fly ID遞增編號運行模式得分通過的管道數(shù)存活時間總 spike 數(shù)頁面右側的BEST FLIES排行榜展示本瀏覽器中成績最好的 5 只果蠅。死亡也是科學的一部分果蠅在 Flappy Bird 中有四種死法每種都對應一個有趣的死因分析碰撞位置死因描述神經學解讀撞上水管上沿“THE FLY PANICKED.”視覺刺激過強DNp01 過度激活撞上水管下沿“THE FLY DID NOT FLAP.”決策延遲該拍翅時沒拍飛出頂部“THE FLY FLAPPED TOO EARLY.”連續(xù)拍翅冷卻機制失效撞上地面“THE FLY DID NOT FLAP.”完全沒反應DN 活動不足這些死因當然是娛樂性質的——但它們確實反映了神經解碼器的不同失敗模式。技術細節(jié)Cache Storage 讓二次加載秒開166,700 個神經元的數(shù)據(jù)總量接近 60 MB。如果每次打開頁面都要從服務器下載用戶體驗會很差。項目使用瀏覽器的Cache Storage API實現(xiàn)智能緩存constCACHEfly-connectome-v1;constcacheawaitcaches.open(CACHE);consthitawaitcache.match(url);if(hit)returnhit;// 緩存命中直接使用constresponseawaitfetch(url);awaitcache.put(url,response.clone());// 緩存副本第一次加載時所有 .bin 文件從 Vite 開發(fā)服務器下載并緩存。第二次打開時直接從 Cache Storage 讀取加載頁面會顯示 “WAKING UP CACHED BRAIN…”幾乎瞬間完成。訓練模型的安全邊界一個非常巧妙的設計是安全邊界不可訓練functiontrainedFlapRequest(state,learned,threshold){constbelowTargetstate.birdYstate.gapCenterY8-adaptiveMargin;constnotClimbingFaststate.birdVelocityY-70;returnlearnedthresholdbelowTargetnotClimbingFast;}無論邏輯回歸讀出層學到什么以下規(guī)則永遠生效果蠅已經在目標上方 → 不拍翅防止飛出頂部果蠅正在快速上升 → 不二次拍翅防止慣性疊加失控這意味著訓練只能在安全走廊內微調拍翅時機不可能學出危險行為。這是一個非常實用的工程約束——它保證了即使訓練還沒收斂果蠅也不會做出荒謬的動作。模型導出與共享訓練好的讀出模型可以導出為 JSON 文件{format:fly-brain-readout-v3,exportedAt:2024-01-15T10:30:00Z,model:{features:[TARGET_DN L,TARGET_DN R,...],weights:[0.823,-0.912,...],bias:-0.156,threshold:0.38,trainingSamples:2847,trainingLoss:0.412}}其他人可以導入這個模型在自己的瀏覽器中加載——跳過訓練過程直接使用已經學會飛行的模型。這創(chuàng)造了一種有趣的模型共享生態(tài)你可以比較不同訓練條件下產生的模型看看哪些特征權重最高、哪些 DN 群體對決策貢獻最大。效果展示下面是一系列從實際運行中錄制的 GIF 動圖展示果蠅大腦玩 Flappy Bird 的完整過程。 大腦加載過程首次打開頁面時瀏覽器需要從本地服務器加載約 60MB 的連接組數(shù)據(jù)。加載過程分為多個階段神經元元數(shù)據(jù) → 稀疏權重解壓 → 神經狀態(tài)構建 → 視覺/下行神經元初始化。完成后顯示 “166,700 NEURONS ONLINE” 和 “WAKE UP FLY” 按鈕。 游戲開始果蠅起飛點擊 “WAKE UP FLY” 后果蠅開始自主飛行。注意觀察右側神經數(shù)據(jù)面板——LC4 和 LPLC2 的強度隨著水管接近而逐漸升高這是視覺 looming 系統(tǒng)在工作。? 神經活動全景左欄的 WebGL 神經活動地圖是本項目最震撼的視覺效果。166,700 個神經元以 Fibonacci 螺旋排列每個點的大小和亮度對應其活動水平。當感覺刺激注入時可以看到活動波前從一側傳播到另一側——就像真實的腦成像一樣。 成功穿越管道當果蠅成功穿過一組管道時SCORE 計數(shù)器加 1。在 ONLINE TRAIN 模式下每一次成功的飛行都在為讀出層提供訓練樣本——果蠅越飛越好。 死亡與重生果蠅死亡后畫面覆蓋實驗終止信息得分、存活時間、總 spike 數(shù)、死因分析。點擊 “REVIVE FLY” 或等待 AUTO REVIVE 自動開始下一次實驗。每次重生 Fly ID 遞增種子也隨之變化。 SLOW BRAIN 模式開啟 SLOW BRAIN 后游戲速度降到 0.1 倍但大腦仍以 50Hz 運行。這讓你可以清楚地看到神經信號從視覺輸入到運動輸出的完整傳播過程。左上角的序列指示器會顯示當前階段“VISUAL INPUT DETECTED → SIGNAL PROPAGATING…” 或 “DESCENDING NEURON ACTIVE → MOTOR COMMAND”。 PURE BRAIN 模式切換到 PURE BRAIN 模式后不再使用訓練好的讀出層而是直接從 DNp01 的 spike 計數(shù)解碼決策。果蠅的動作變得更加隨機和不可預測——因為這是未經訓練的真實大腦活動。? FAST TRAIN 訓練過程點擊 FAST TRAIN 后Worker 在后臺快速生成 1200 幀訓練樣本。進度條顯示訓練進度和當前 loss 值。訓練完成后自動切換到 FAST MODEL 模式果蠅的飛行能力顯著提升。 AUTO REVIVE 連續(xù)實驗開啟 AUTO REVIVE 后果蠅死亡 2 秒后自動開始下一次實驗。你可以把頁面放在一邊讓果蠅持續(xù)飛行和訓練。經過幾輪訓練后讀出層收斂果蠅的平均得分穩(wěn)步提升。 神經數(shù)據(jù)實時變化右欄的神經數(shù)據(jù)面板是理解果蠅想法的窗口。LC4/LPLC2 反映視覺威脅強度LC10a-L/R 反映目標方向DNp01 反映運動意圖。DECISION 指示器在 FLAP 和 WAIT 之間切換FLAP PROBABILITY 顯示讀出層的置信度。項目基于 fly.ai 的 MaleCNS v1.0 果蠅連接組數(shù)據(jù)。連接組數(shù)據(jù)采用 CC BY 4.0 許可。本項目的感覺編碼和運動解碼是人工設計的實驗接口不代表真實果蠅能夠理解 Flappy Bird。