十组跑完,准确率从高到低排下来,真果蝇大脑排第七:
shufw_s3 0.8056 ← 权重打乱的假图
shufw_s1 0.7917
fullrand_s3 0.7847 ← 完全随机接线
degpres_s3 0.7847
fullrand_s2 0.7778
shufw_s2 0.7639
connectome 0.7639 ← 真大脑,第 7 名
degpres_s2 0.7569
degpres_s1 0.7500
fullrand_s1 0.7222
真大脑跟九个假图合并起来比,差 -0.0069,p=0.85。一点优势都没有,方向还是负的。
我花了三天做这件事,本来想证明的是反面。而更难受的地方在于:这个「输了」我也不能拿去说事——我后来算了一下自己的测量精度,发现这台仪器根本分辨不出我想找的那个差距。
想直接拿判据的看第 2 章,那就是一个除法;想知道什么东西真的能动摇这个网络,看第 5 章。
1. 我想赌的那件事
先说清楚在测什么。果蝇的连接组,就是把一只果蝇的脑子切片、用电镜拍下来、把每个神经元和它的每一根连线都重建出来的那张图。公开的 FlyWire 雌性全脑版本是 13.9 万个神经元、5450 万个突触(Nature 2024)。我用的是论文配套的 630 版:12.74 万个神经元、1468.7 万条边、5279.4 万个突触,跑在自己机器上的 Brian2 里,每个神经元是个最简单的漏电积分发放模型。
有个很诱人的想法:这张图能不能当"水库计算"(reservoir computing)用?水库计算的套路是,你搞一个巨大的、乱七八糟的循环网络,完全不训练它,只把输入灌进去,然后在输出端训一个最简单的线性读出层。那个大网络的作用是把输入炸开到超高维,让原本分不开的东西变得线性可分。
关键在于:标准做法里那个大网络是随机生成的。而果蝇这张是进化调出来的。
所以问题很干净:同样的规模、同样的度分布,进化调过的连线,会不会比随机接线更适合当水库?
我还顺手量了个东西,让这个赌注看起来更值得下。真实连接组里,A→B 的同时 B→A 也存在的双向边占 26.55%。按它的连接密度(0.0905%)随便接,双向边只会有 0.09% 左右;我做的度分布匹配随机图实测是 0.56%。差 47 倍。
双向连接就是局部的回声回路,而回声正是水库存住"刚才发生过什么"的物理基础。所以这条听起来简直是实锤:进化留了一堆回声回路在里面,随机图没有,水库任务上它该赢。
搜了一圈,没找到有人公开做过这个对照。听起来早该有人做了的问题,有时候真没人做。
2. 尺子上一格有多粗:一个除法
这是全文最有用的一段,而且它只是个除法。
我第一版实验的配置是:6 个类别、每类 8 次重复 = 48 个样本,分层留出,每类留 3 个当测试点,一共 18 个测试点。
分类准确率这东西是离散的。18 个测试点,你只可能答对 0 个、1 个……18 个。所以:
准确率的最小刻度 = 1 ÷ 测试点数
18 个测试点 → 1/18 = 0.0556
而我想找的效应有多大?水库文献里这类结构优势通常在几个百分点。我事先写死的判据是 差值 > 0.02 才算赢。
0.0556 的刻度,去量 0.02 的东西。 尺子上一格比要量的东西还粗 2.8 倍。这种情况下你测出的任何"差异",都只是"多答对了一道题还是少答对了一道题",它跟连接组是不是更优毫无关系。
发现这一点的时候我差点直接加 seed 重跑。加 seed 没用——seed 加的是重复次数,不是测试点数。留出法里你测试集多大,分辨率就多粗,跟你跑多少遍无关。
正确的修法是换交叉验证的方式:改成留一法,每个样本轮流当一次测试点。6 类 × 24 次重复 = 144 个样本,就是 144 个测试点:
1/144 = 0.0069
比要量的 0.02 细 2.8 倍了。这才算有资格开测。
再往下算一层,就更没脾气了。要让一个比例差在统计上站得住,每组需要的样本量大致是:
n ≈ p(1-p) × (1.96 × √2 ÷ d)²
p 是准确率水平,d 是你想分辨的差值。代进去:p=0.76、d=0.02,每组要 3,464 个样本。我最后跑的是每组 144 个(真大脑)和每组 432 个(三个随机族各合并 3 个 seed)。
也就是说,即使连接组真的有 2 个百分点的优势,我这个规模也看不见。 单组标准误 0.0354,比效应还大。所以第 4 章那个"输了",严格说只能支持"没有大到 5 个百分点以上的优势",别的什么都推不出来。
这条判据可以直接搬走:做任何 A/B 之前,先把「你的指标最小能跳多少」算出来,跟「你想找的差多少」比一下。前者大于后者,这个实验就还没开始就死了。
3. 为什么 100% 的准确率是废数据
尺子够细了,还有第二个坑:题目得有区分度。
我设计的任务是,在 6 个不同的位置图案上分别刺激网络,然后看能不能从全脑放电模式反推出刚才刺激的是哪一个。第一轮跑出来,四组全是 1.000。满分。
满分意味着排不出名次。真大脑 100%,完全随机图也 100%,那这个实验什么都没测到。病因是我给的 6 个图案各点亮 300 个互不相交的位点——差异大到随便一个网络都能分开。
所以我做了个难度阶梯,三个旋钮一起拧:图案之间共享多少位点(overlap,越高越难分)、驱动强度(越低响应越弱越噪)、读窗多长(越短信息越少)。判据事先写死:准确率落在 (chance+0.1, 0.95) 之间才算有鉴别力,6 类的随机猜是 0.1667,所以窗口是 (0.267, 0.95)。
实测阶梯:
| overlap | 驱动 | 读窗 | 准确率 | 打乱标签 | 判定 |
|---|---|---|---|---|---|
| 0.00 | 250 | 200ms | 1.000 | 0.211 | 天花板 |
| 0.70 | 250 | 200ms | 1.000 | 0.200 | 天花板 |
| 0.90 | 250 | 200ms | 1.000 | 0.233 | 天花板 |
| 0.90 | 60 | 200ms | 1.000 | 0.189 | 天花板 |
| 0.95 | 60 | 100ms | 0.833 | 0.211 | 有鉴别力 |
| 0.98 | 60 | 50ms | 0.278 | 0.178 | 接近地板 |
六档里只有一档能用。overlap 从 0 拧到 0.9、驱动砍到四分之一,准确率纹丝不动还是满分,得拧到 0.95 才开始掉下来,再拧一档就直接砸到接近瞎猜。能用的窗口窄得吓人,而且是拧到第五档才撞上的。
那个"打乱标签"列是另一道防线:把标签随机打乱之后重跑,必须回到随机猜的水平。实测十组平均 0.159,随机猜是 0.1667,对得上。这条要是不对,说明我的分类器在偷看标签,整轮作废。
4. 十组,和那个没有的差距
难度定在 overlap=0.95、驱动 60、读窗 100ms,然后跑十组:真连接组一组,三个随机化家族各三个 seed。
三个家族分别是:shufw 把权重在边上打乱(图的形状不动,只换权重去哪)、degpres 保持每个神经元的进出度重新接线、fullrand 完全随机接线。
结果就是开头那张排名表。按家族合并做 Welch t 检验:
| 对照组 | 准确率 | n | 与连接组之差 | p |
|---|---|---|---|---|
| connectome | 0.7639 | 144 | — | — |
| shufw | 0.7870 | 432 | -0.0231 | 0.57 |
| degpres | 0.7639 | 432 | +0.0000 | 1.00 |
| fullrand | 0.7616 | 432 | +0.0023 | 0.96 |
degpres 那行是 +0.0000。精确的零。真大脑和度分布匹配的随机图,在 144 个测试点上答对了一模一样多的题。
那个 47 倍的双向边优势,在这个任务上一点都没兑现。
我得诚实说清楚这个结果是什么:它不是"连接组当水库没用",它是"在这一个任务、这一个工作点、这个样本量下,我没看见差距"。 按第 2 章算的账,能被这个实验排除的只有"5 个百分点以上的优势"。2 个百分点的优势它压根看不见。
5. 真正能撼动这个网络的东西
null result 容易给人一个错觉:这网络对什么都不敏感,所以怎么改都一样。不对。我另一组消融实验里,它敏感得很,只是敏感的点跟我预想的不一样。
拿一个确定的读出神经元(论文里那个控制伸吻的运动神经元,基线 84.6 Hz)当探针,两种扰动各做三个 seed:
翻转 20% 边的兴奋/抑制符号 → 0.6 / 2.8 / 61.6 Hz
随机砍掉 20% 的边 → 47.2 / 34.8 / 80.8 Hz
同样是动 20% 的边,翻符号能把这个神经元的输出打到基线的 1% 和 3%,砍边什么事都没有。
这里我还栽了一跤,值得单独说。我最初写的判据是"发放率 == 0 才算被打哑",按这条,翻符号 20% 的结果是 0/3 打哑——因为 0.6 和 2.8 都不是零。可 0.6 Hz 是基线的 0.7%,这个神经元在功能上已经死透了。判据定成"等于零",就把"还剩百分之一"判成了健康。 正确的阈值是小于基线的 10%。
这一格一格看还有更清楚的形状:
翻 1% → 81.8 / 78.4 / 93.0 Hz 几乎无感
翻 5% → 83.0 / 61.2 / 85.2 Hz 还行
翻 10% → 74.2 / 58.8 / 110.4 Hz 有一个比基线还高
翻 20% → 0.6 / 2.8 / 61.6 Hz 塌方
10% 是悬崖边。 10% 以下随便翻都无所谓,有一次还蹦到 110 Hz 高过基线;从 10 跨到 20,直接塌。
为什么这件事重要:连接组里的连线和突触数量是量出来的,电镜照片上数得清清楚楚。而每条边是兴奋还是抑制,是靠一个分类器预测出来的神经递质类型推的(Eckstein 等 2024)。也就是说,整张图里唯一不是测量结果的那个字段,恰好是扰动它最致命的那个字段。 大家嘴上说的"连接组是打了折的权重",那个折扣正好打在最要命的地方。
还有个配套发现,对任何想拿连接组接机器人的人都有用:翻 20% 符号时,全脑还剩 82.5% 的神经元在放电,但那个读出神经元只剩 1% 到 3%。你在全局指标上完全看不出问题,接在下行神经元上的那只手已经不动了。读出端比群体脆得多。
6. 怎么判断一个「连接组仿真」的 demo 是真是假
这半年这类 demo 挺多的——把果蝇大脑接上虚拟身体,让它走路、躲影子、理毛。有一篇 eLife 的 reviewed preprint(2026-08-17,《The digital sphinx: Can a worm brain control a fly body?》)把这事一次性拆穿了:作者拿线虫的连接组去控制果蝇的身体,中间用强化学习训了一层映射。
结果是高度逼真的果蝇步态。摘要原话:
The resulting digital sphinx produces highly realistic fly walking—yet it is biologically meaningless. ……behavioral fidelity is achievable without biological fidelity, making such models easy to overinterpret.
行为像,不代表里面那个东西对。所以看任何一个连接组 demo,只需问一句:中间那层接口,训过没有? 训过,那走得多好看都只证明接口层学会了,跟连接组没关系。
几个真实的分层(我逐个翻了它们自己的 README 和博客,没看二手转述)。有个刷屏的桌面果蝇,实际只是 668 个神经元的子图,占全脑的 0.5%,README 自己写了两条:逃跑反应时间并非活体测量值;跨个体的接口突触在数据里根本不存在,属于建模出来的。有个更严肃的全脑+身体项目,自述视觉激活"somewhat decorative,不实质影响行为输出"。
每一层自己都承认了简化,是二手转述把限制全删了。 遇到"XX 仿真了 YY"这类说法,直接翻一手 README 的 limitations 段,作者通常比转述者诚实一个数量级。
同一个形状在图论指标上也成立。我算过从 21 个输入神经元出发的图上可达集:全脑 99.4% 可达。而同一个刺激真跑仿真,实际放电的只有 0.33%。差 301 倍。
图上可达 ÷ 仿真实际放电 = 99.4% ÷ 0.33% ≈ 301
纯图分析只能证明"不可能",不能预测"会不会"。 下次看到"这个脑区跟那个脑区之间有通路",先问它是图上算的还是跑出来的。
顺带一个更具体的翻车:我一度写下"论文里的通路是 A→B→C→读出神经元",后来去查才发现,那个说法的出处是另一个项目的 README,不是论文原文,而我管它叫"论文通路"。实测两个版本的数据集里,那最后一跳都是零条直连边。真正的主驱动是一个二手描述里从来没出现过的神经元。
7. 这个实验还有哪些地方不能信
上面每个数字都是自己跑出来的,但它们各自的可信度差很多,得分开说。
排名表和 p 值的效力只够排除大效应。 前面算过,每组 144 个点只能分辨 5 个百分点以上的差距。这一整篇最硬的结论也就到"没有大优势"为止。
只在一个工作点上测过。 难度阶梯扫了 6 档,但四组对照只在选中的那一档跑。换个 overlap、换个读窗,结论有没有可能翻,我不知道。
每个随机族只有 3 个 seed。 组间准确率在 0.7222 到 0.8056 之间飘,跨度 8 个百分点,明显大于任何组间差。3 个 seed 估不准这个方差。
那个分类任务可能根本不需要记忆。 这是我最不放心的一条。水库的价值在于把过去的输入也留在当前状态里,而"认出刚才刺激的是哪个图案"可能只靠当前瞬间的响应就够了。如果是这样,那我测的是这个网络的瞬时可分性,跟"进化调出来的回声回路"半点关系都没有——第 1 章那个赌注,可能从头到尾就没被真正测过。
更早一轮的记忆容量测量整轮作废,但方向是负的。 我先测过一轮真正的记忆容量指标,真连接组是 0.000,而权重打乱的假图是 0.447 到 0.515。看着像真大脑惨败,但那一轮所有组的当前输入相关性都是 0.98 到 0.99,等于整个网络只是输入的回声——网络在饱和态,每个神经元每秒放电约 55 次,所有组的记忆都被压成零,测量无效。病根是我连着两次拿"活跃神经元比例"当工作点判据,而活跃度只数"有没有放过电",数不出"放得多疯"。这一轮不能当证据用,但它也没给连接组加分。
正则化参数的选择用了全部数据。 代码里留一法外层是干净的,但选正则化强度的内层用了全体样本。这对所有组一视同仁,不会造成组间偏差,但会让所有组的绝对准确率略微偏高。
这几处补完之前,我不会把这个结论说死。
8. 下次再做这种对照,按这个顺序来
- 先算指标的最小刻度。
1 ÷ 测试点数。它比你要找的效应粗,就别开跑了,先改实验设计。 - 再算需要的样本量。
n ≈ p(1-p)(1.96√2/d)²。算出来跑不起,就老实把要找的效应调大,或者承认这个实验只能排除大效应。 - 先只在实验组上扫难度阶梯。 准确率落进 (chance+0.1, 0.95) 才开测。满分和瞎猜都排不出名次,跑了也白跑。
- 每轮都跑打乱标签的对照。 它必须回到随机猜的水平。不回去,说明分类器在偷看,整轮作废。
- 判据里的阈值别写"等于零"。 写"小于基线的百分之几"。0.6 Hz 和 0 Hz 在统计上不同,在功能上是一回事。
- 全局指标正常不代表读出端正常。 全脑 82.5% 还在放电的时候,你真正关心的那个神经元可能只剩 1%。盯着你实际要读的那个东西。
- 引用任何"论文说"之前,去翻论文原文。 我把一个 README 里的说法叫成"论文通路",实测那条通路的最后一跳根本不存在。
- 先证明你那个工作点是有效的,再解读结果。 网络饱和的时候,所有组的记忆都是零,那不是结论,那是测量失败。
至于连接组当水库到底行不行,我现在能说的只有一句:在我这个精度下看不出来。想看出来得每组跑三千多个样本,那大概是十几个小时的事。等我先把那个"任务到底需不需要记忆"想清楚再说,不然跑三千个也只是把一个没测对的东西测得更精确。