ショウジョウバエ全脳コネクトームの公開とLLMとの違い
目次
2024年10月、成体ショウジョウバエ(Drosophila melanogaster)の全脳シナプス配線図がNatureの特集号で公開された。プリンストン大学のセバスチャン・スン教授やマラ・マーシー教授らが率いる国際共同研究体「FlyWireコンソーシアム」がまとめた。
1986年に解明された線虫(C. elegans、302ニューロン)から38年が経ち、飛翔や視覚追跡、学習といった複雑な自律行動を行う昆虫の脳配線が、シナプス単位で手に入るようになった。公開された配線図の規模や研究動向、LLMとの違い、Pythonでデータを扱う基本手順を整理した。
配線図の規模と主な研究事例
公開された配線図の主な内訳。
| 項目 | 規模 |
|---|---|
| ニューロン総数 | 139,255個 |
| シナプス総数 | 約5,450万個 |
| 神経突起の総延長 | 約150メートル(1立方ミリメートル未満の脳内に密集) |
| 分類された細胞型 | 8,453種類(うち4,500種以上が今回の研究で初同定) |
電子顕微鏡の連続断面画像(FAFBデータセット)をAIで領域分割し、世界中の研究者やボランティアがクラウドツール上でエラーを修正して完成させた。配線図の公開以降、神経科学や機械学習の領域で複数の計算モデルが発表されている。
全脳LIFシミュレーション
Shiuらの研究チーム(Nature 2024)は、13.9万ニューロンと5,450万シナプスの接続強度、および神経伝達物質(アセチルコリン、GABA、グルタミン酸など)の興奮・抑制特性を組み込んだ全脳計算モデルを構築した。
糖の味覚刺激を与えた際に口器を伸ばす反射行動や、毛づくろい行動の発現回路を計算機上で動かし、実際の生体実験の神経応答と90%以上一致することを示した。
コネクトーム制約を入れた深層学習
視覚系の配線構造を固定し、各シナプスの伝達効率や時定数だけを深層学習で最適化する手法(Deep Mechanistic Networks)が開発された。
動体追跡のタスクを実行させただけで、過去の生理学実験で報告されてきた「運動方向を選択的に検知する個別神経の応答」がモデル内部に自然と現れることが確認されている。
身体性シミュレータとの統合
EPFL(スイス連邦工科大学)が公開している仮想昆虫モデル「NeuroMechFly v2」や、Google DeepMindの「flybody」などのMuJoCo環境に、コネクトーム由来の神経回路を組み込む研究が行われている。
視覚や脚の接地感覚を受け取りながら、閉ループで歩行や障害物回避を行う仮想昆虫が動いている。
ニューロモーフィックチップへの全脳マッピング
米サンディア国立研究所の研究チームは、Intelのニューロモーフィックチップ「Loihi 2」上にFlyWireの全脳コネクトームを直接マッピングした。
非同期のイベント駆動型スパイクによって、極めて低い消費電力で全脳規模の神経発火ダイナミクスをリアルタイム実行できることが実証されている。
LLMとコネクトームの構造差
LLMとハエの全脳コネクトームの主な相違点。
| 比較項目 | 大規模言語モデル(LLM) | ショウジョウバエ全脳コネクトーム |
|---|---|---|
| 規模 | 数十億〜数千億パラメータ(密な行列) | 約13.9万ニューロン、約5,450万シナプス |
| 消費電力 | 数百キロワット〜メガワット級(データセンター) | 数ミリワット以下(生体個体) |
| 配線構造 | 均一なレイヤー構造の一方向順伝播(Transformer) | 局所的・大域的な高密度フィードバックループ |
| 計算方式 | クロック同期の密な行列積(GEMM) | 非同期イベント駆動スパイク(SNN)、疎な発火 |
| 身体性 | 身体を持たない記号空間内の自己回帰推論 | 感覚と運動が直結した閉ループ |
| 獲得方式 | 膨大なテキストデータによる事後学習 | 進化の過程で遺伝的に組み込まれた配線 |
LLMは均一な層を重ねて大量のデータから重みを最適化する。一方、ハエの脳は14万ニューロンの接続トポロジーそのものに動体検知や方位維持の回路が組み込まれており、学習を介さずに配線構造だけで物理環境に応答する。
ロボティクスやエッジ制御への応用領域
ハエの脳回路は、GPUを搭載できない軽量ロボットや低消費電力が求められるエッジ制御で研究が進んでいる。
マイクロエアビークル(MAV)や極小ロボットの自律制御では、重量数グラムの機体に重い演算器を積めない。ハエの視覚葉(ロブラプレート)の配線は、小型マイコンやSNNチップ上で壁面衝突回避やオプティックフローによる姿勢制御に利用されている。
ハエの中心複合体にあるE-PGニューロン群は、リング状に並んだアトラクター回路を構成し、外部の偏光や自身の角速度を積分して現在の方位を追跡する。地下やトンネルなど、GPS電波が届かない環境での自律推測航法に応用されている。
触角による風向・風速検知と、漂う匂い分子の感知、複眼による視覚流をミリ秒単位で統合する回路は、気流が乱れた環境下で発生源を追跡するロボット制御に応用されている。
突風で機体が傾いた際に数ミリ秒以内で翅の羽ばたき角を戻す反射回路も、遅延が許されない高機動ドローンの姿勢制御ロジックとして研究されている。
公開データの取得とPythonコード例
FlyWireのデータセットはオープンアクセスで公開されており、ブラウザ上での検索やPythonライブラリからの取得に対応している。神経データの可視化や解析には主に navis、fafbseg、brian2 が使われる。
ブラウザと3Dメッシュでの配線確認
公式プラットフォームの FlyWire Codex(https://codex.flywire.ai)では、ニューロン名や細胞型で検索し、3Dモデルや接続シナプス数を直接閲覧できる。方位角コンパスの E-PG や動体検知の T4 / T5 など、同定済みの神経群を個別に確認できる。
Python上で3Dメッシュをプロットするコードはこんな感じ。
import navis
import fafbseg.flywire as fw
# 方位角コンパス(E-PGニューロン)のRoot IDを指定
root_ids = [720575940614131064, 720575940625345758]
# 3Dメッシュを取得してPlotlyでブラウザ描画
neurons = fw.get_mesh_neuron(root_ids)
fig = navis.plot3d(neurons, backend="plotly", inline=False)
fig.show()
シナプス接続行列の取得
指定したニューロン群同士のシナプス結合数をPandasのデータフレームで取得するコードはこんな感じ。
from fafbseg import flywire
# 指定ニューロン間のシナプス接続を取得
synapses = flywire.get_synapses(root_ids, pre=True, post=True)
matrix = synapses.groupby(["pre_pt_root_id", "post_pt_root_id"]).size().unstack(fill_value=0)
print(matrix)
Brian2によるSNNシミュレーション
取得したシナプス数を結合重み(シナプス後電位の大きさ)に割り当て、SNNシミュレータ(brian2)で2ニューロン間のスパイク伝播をシミュレーションする最小スクリプト。
import matplotlib.pyplot as plt
from brian2 import *
start_scope()
# LIF(Leaky Integrate-and-Fire)モデル
tau = 10 * ms
eqs = """
dv/dt = (v_rest - v) / tau : volt (unless refractory)
v_rest : volt
"""
G = NeuronGroup(2, eqs, threshold="v > -50*mV", reset="v = -70*mV", refractory=2*ms, method="exact")
G.v = [-65, -70] * mV
G.v_rest = [-45, -70] * mV # ニューロン0に自発発火を起こす
# コネクトームのシナプスカウントを重みに反映
syn_weight = 3.5 * mV
S = Synapses(G, G, on_pre="v_post += syn_weight")
S.connect(i=0, j=1)
statemon = StateMonitor(G, "v", record=True)
run(100 * ms)
plt.figure(figsize=(9, 3.5))
plt.plot(statemon.t / ms, statemon.v[0] / mV, label="Neuron 0 (Pre)")
plt.plot(statemon.t / ms, statemon.v[1] / mV, label="Neuron 1 (Post)")
plt.axhline(-50, ls="--", color="gray", label="Threshold (-50mV)")
plt.xlabel("Time (ms)")
plt.ylabel("Voltage (mV)")
plt.legend()
plt.tight_layout()
plt.savefig("snn_test.png")