Virtual Embryo Challenge更新于 10-03 20:28(北京时间) / 每 5 分钟更新

总览 · ← 返回运行 20261003-004922-search-t2-heart-interp-g24-D

节点 n17 在终选来历上

型内kNN坐标平滑位移上限0.2→0.45×型内SD强化局部致密化;PLAN的RMS恢复与各向异性缩放在代理上证伪(把尺度推离参考),按止损关闭,另加自适应k提升final稳健性。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-004922-search-t2-heart-interp-g24-D
父节点n15
子节点n19、n21
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 61.41(+0.4) · proxy 61.41(+0.4) · 3 次复测均分 61.33
审查通过 1 越界读取:未发现问题——run.py 只经 view_io 的 load_manifest/panel_genes/read_stage 读 --data 视图目录并写 --out(run.py:214-227,258),无绝对路径、'..'、/mnt、/home、data/raw、打分器路径,无联网代码(grep 无 http/urllib/socket 等命中)。; 2 硬编码目标统计量:未发现问题——代码常量仅为调参超参 K=20、STRENGTH=1.5、MAX_FRAC=0.45(run.py:60-68),无细胞类型比例表、基因列表或大段数字常量(run.py 无三位以上数字…
用时?从运行开始到结束(或到现在)的挂钟时间。21 分
程序版本5091e4a1feb103787e8936555fbfe1da7723028b (programs.git)

方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。

来自 programs.git 5091e4a1fe:solution/METHOD.md

型内kNN坐标平滑位移上限0.2→0.45×型内SD强化局部致密化;PLAN的RMS恢复与各向异性缩放在代理上证伪(把尺度推离参考),按止损关闭,另加自适应k提升final稳健性。

方法族 / 实现

family_id = T2HI-05(kNN 平滑后 RMS 恢复 + 各向异性轴缩放,按 PLAN 实现并检验)。基线 = 父节点15:mix(align=procrustes, scale_damp=1)+ 型内 kNN 坐标平滑(k=20, strength=1.5, 位移≤max_frac×型内SD)。表达、细胞数、类型组成全程逐位不动,只改 obsm["spatial_3D"]。

按 PLAN 实现了两个新机制(--rescale-damp、--aniso/--aniso-damp)和自适应 k(--k-adaptive):

  1. 均匀 RMS 恢复:平滑后 RMS_post 对 mix 已算好的 log 线性 target_rms(info["target_rms"])做 factor=1+damp·(target/RMS_post−1) 的绕质心缩放。
  2. 各向异性轴缩放:两输入阶段 align 后缩放到 target_rms,逐轴 SD 做 log 线性插值得 target_SD_d,对平滑后坐标逐轴 factor_d=1+damp·(target_SD_d/SD_d−1)。
  3. 自适应 k:k_eff=min(k, max(3, m−1)),细胞数 <21 的小类型不再被跳过(proxy 上 5 型全部 ≥21,为 no-op;final 31 个共有型时保证稀有型也被平滑)。

对照结果(mechanism_off_control)

--rescale-damp 0 --aniso off --max-frac 0.2(=父参数)的输出与父节点15输出 X 与 spatial_3D 均 np.array_equal = True(逐位一致),确认新代码在关闭态不泄漏。

机制检验:PLAN 的两个机制在 proxy 上被证伪(A半,seed 0)

配置榜分shape_scalelocal_spatialscale_log_ratiooccupancy_dice
父节点15(mf0.2, 无缩放)60.7753.5259.81~0.4510.838
+均匀RMS恢复 damp=1.060.6953.2259.810.4670.838
+RMS恢复+aniso damp=1.060.6553.0659.800.4600.834

证据数字:平滑确实系统性收缩 RMS(RMS_post/target = 0.9832,收缩 1.7%,方向与 PLAN 预期一致);恢复后 RMS/target = 1.0000。但 shape_scale 反而下降:scale_log_ratio 0.451→0.467 恶化——说明参考阶段的尺度低于 mix 的 log 线性 target_rms(与方法卡"心脏尺度非单调,log 线性 346 够不到真值 217"一致),把 RMS 推回 target 是推离参考。aniso 的各轴 ratio_d 均 <2%(0.980/0.997/1.001),且 occupancy_dice 0.838→0.834 下降。命中 PLAN 风险①③,按止损条款以 rescale_damp=0、aniso off 提交。进一步用输入数据之外的方式"猜"目标尺度(更强的整体收缩)无法从两输入阶段合法导出(两端 RMS 354/335,log 线性对 damp 不敏感),针对 proxy 参考调尺度=向真值泄漏,不做。

实际提交的改进:平滑位移上限 max_frac 0.2→0.45(父节点 ANALYSIS 建议方向)

父节点 next_suggestions 明确建议"试 max_frac 0.3–0.4 看 shape/局部是否随更强收缩改善"。网格(k=20, strength=1.5, A半 seed 0):

max_frac榜分local_spatialshape_scaleneighborhood_mmdmean_disp/SD
0.20(父)60.7759.8153.520.06450.104
0.3060.8961.1152.710.0611—
0.3561.0161.4152.860.06040.153
0.45(提交)61.0361.7052.680.05970.176
0.6061.0862.0052.590.0589—
0.8061.0762.1852.360.0585—
0.35+s2.560.8160.5752.930.06250.180

mf∈[0.45, 0.8] 是平台(61.03–61.08,差在噪声内);取 0.45(平台中部、shape 侵蚀最小,迁移到 B半/final 更安全)。跨种子一致性:seed 1 下 mf0.45 = 61.27 vs 父配置 seed 1 = 61.02(+0.24,与 seed 0 的 +0.26 同向;local_spatial 60.2→62.0,+1.8 超噪声,shape −0.8 部分抵消)。净增益 ~+0.25 小于 T2 噪声 ~1 分,属"方向一致的小幅改进",不是大幅突破——如实记录。

机制生效证据(提交默认,proxy seed 0)

  • 平滑覆盖率 100%(17616/17616,跳过类型 0);mean_disp/型内SD = 0.176(≤0.45 上限);max|delta| = 147.4。
  • neighborhood_mmd 0.0645→0.0597(单调改善),local_spatial 59.81→61.70。
  • 表达矩阵、细胞数(17616 ∈ [1000, 17616])、类型组成与父逐位一致(X array_equal True);只有坐标变。
  • 关闭对照(mf=0.2)与父输出逐位一致(见上)。

验证过

  • 默认参数(无 flag)输出与网格 mf045_s15 文件逐位一致;seed 0 重跑逐位确定;seed 1 输出不同(无 seed 分支)。
  • vec-check ok;坐标全部有限。
  • 视图无关:构造 +1 天平移、manifest 键序打乱、external 阶段同步平移的伪装视图,seed 0 输出的 X 与 spatial_3D 与真实视图逐位相同;程序只用相对时间 t、坐标、标签,不读绝对时间/路径/board 字段。
  • 纯 CPU(numpy+scipy cKDTree),runtime ~2.1s,峰值内存与父相当(~0.5GB);EXECUTION.json {"gpu": false}。
  • 查分用量:10/20(control 未查分,用逐位对照代替)。

未验证 / 风险

  • final 括号(31 共有型)未测;k_adaptive 使小类型(≥4 细胞)也被平滑,覆盖率应高于父节点的"跳过 <21 型",但小类型上 k_eff=3–19 的平滑幅度更依赖其自身 SD(自适应封顶),预期稳健、未实测。
  • 净 +0.25(A半)在噪声边缘;依据是 local_spatial +1.8 在两个 seed 上同向、平台宽(mf 0.45–0.8),非单点尖峰。
  • shape_scale 的 scale 分量短板仍在(scale_log_ratio≈0.44):合法可用的输入信息推不出参考尺度(非单调 354→217→335),任何"整体缩到某个魔数"的做法都是对 proxy 真值的拟合,不可迁移。

知识来源

仅通用几何/统计操作(kNN 收缩、逐维 SD 裁剪、log 线性插值、Kabsch 对齐,均沿自父节点与 src.task2_spatial)。未使用保留阶段(E8.5/E10.5/E12.5、禁窗 (8.25,8.75)、9.5<E≤13.5)或保留基因型的任何测量信息;对目标尺度未注入任何外部数值。

调研员的计划

名称kNN平滑后RMS恢复+各向异性轴缩放修正shape_scale
动机父节点15的shape_scale=53.08是四组最短板,ANALYSIS指出scale_log_ratio≈0.45。kNN向邻域质心收缩是局部操作,但对非均匀点云会系统性压缩全局二阶矩(外围细胞邻居偏向内侧),导致平滑后RMS低于mix基线已计算的log线性目标RMS。此外,各轴缩放比可能因心脏形态变化(沿轴非等比生长)而不一致。节点13曾在不同基线(node 6 comp重抽)上试坐标缩放未成功,但本节点基线不同(mix+平滑,无comp重抽),且此处缩放是对已知收缩伪影的校正而非主机制。
做法在节点15代码基础上,_knn_smooth返回后、写入前,增加两步坐标后处理:

1)均匀RMS恢复:计算平滑后点云RMS_post=mean(||coords−centroid||),从mix基线已有的log线性插值获取target_RMS(代码中已有该值),令scale_uniform=target_RMS/RMS_post,coords←centroid+scale_uniform×(coords−centroid)。加阻尼参数rescale_damp∈{0.5,0.75,1.0},实际缩放因子=1+rescale_damp×(scale_uniform−1)。

2)各向异性轴缩放(可选开关--aniso on/off):对每轴d计算输入两阶段的SD_d,log线性插值得target_SD_d;计算smoothed_SD_d;ratio_d=target_SD_d/smoothed_SD_d;应用阻尼coords[:,d]←centroid_d+aniso_damp×(ratio_d−1)×(coords[:,d]−centroid_d)+coords[:,d]−centroid_d,即coords[:,d]=centroid_d+(1+aniso_damp×(ratio_d−1))×(coords[:,d]−centroid_d)。aniso_damp∈{0.5,1.0}。

3)自适应k(次要):k_eff=min(k, max(3, m−1)),使小类型不被跳过(对final 31型稳健)。

网格:先跑control(rescale_damp=0, aniso off)确认与父节点逐位一致;再跑rescale_damp=1.0+aniso off;再跑rescale_damp=1.0+aniso on damp=1.0;最后微调。每档一次vec-score(≤8次查分)。单输入阶段退路:无括号时沿用父回退(take抽样),不做平滑也不做缩放。

关键参数初值:rescale_damp=1.0, aniso_damp=1.0, k_adaptive=True。
风险1)shape_scale的scale分量可能不是RMS而是其他度量(如bounding box),均匀缩放无效——Engineer第一次查分若shape_scale不变即可发现,止损回退到父节点输出。2)各向异性校正过强可能轻微扭曲局部邻域,使local_spatial下降0.5-1分——若local_spatial降幅>1.5则关闭aniso只保留均匀缩放。3)RMS_post与target_RMS差距极小(<2%)时改善在噪声内——此时以rescale_damp=0提交(等同父节点)。

代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。

对比:父节点版本 10e89cbf5d。改动的文件:solution/METHOD.md +42 −47、solution/run.py +84 −10

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex aaffead..6d31c33 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,71 +1,66 @@-在 mix 基线上仅做型内 kNN 坐标平滑(k=20, strength=1.5, 位移≤0.2×型内SD),只改坐标,表达/细胞数/类型组成逐位不变。+型内kNN坐标平滑位移上限0.2→0.45×型内SD强化局部致密化;PLAN的RMS恢复与各向异性缩放在代理上证伪(把尺度推离参考),按止损关闭,另加自适应k提升final稳健性。  ## 方法族 / 实现 -family_id = **T2HI-04**(型内 kNN 坐标平滑)。基线 = 父节点(节点12 = 节点2 的 `mix`,align=procrustes, scale_damp=1):取目标前后最近两输入括号,两朵云对齐并缩放到 log 线性 RMS,按 (1−t, t) 分层抽真实细胞,表达与坐标一起走。+family_id = **T2HI-05**(kNN 平滑后 RMS 恢复 + 各向异性轴缩放,按 PLAN 实现并检验)。基线 = 父节点15:mix(align=procrustes, scale_damp=1)+ 型内 kNN 坐标平滑(k=20, strength=1.5, 位移≤max_frac×型内SD)。表达、细胞数、类型组成全程逐位不动,只改 `obsm["spatial_3D"]`。 -在此之上**只修改坐标**,实现 PLAN 指定的机制:+按 PLAN 实现了两个新机制(`--rescale-damp`、`--aniso`/`--aniso-damp`)和自适应 k(`--k-adaptive`): -1. 复原输出细胞的来源型标签:用与 `interpolate` 相同的 `default_rng(seed)` 重放 `mix_indices`(它是 interpolate 内第一个 rng 消费者),断言 `len(ia)==info["n_from_a"]`,保证标签与坐标行一一对应。-2. 逐细胞型在其坐标上建欧氏 kNN(`scipy.spatial.cKDTree`),`kk=min(k+1, m)`,去掉自身后取 k 个最近同型邻居的坐标均值 `c_i`。-3. 位移 `delta_i = strength·(c_i − coords_i)`(向邻居质心收缩)。-4. 约束:逐维位移 `|delta_d| ≤ max_frac·SD_type_d`(`max_frac=0.2`,SD 为该型逐维坐标标准差);任一维超限则整体等比缩小 `delta`(保方向,proportional truncation)。-5. 细胞数 < k+1 的型跳过不平滑;**表达、细胞数、分层抽样、类型组成完全不动**。-6. 单输入(无括号):沿用父回退(`take` 抽样原样输出),不平滑。+1. **均匀 RMS 恢复**:平滑后 RMS_post 对 mix 已算好的 log 线性 target_rms(`info["target_rms"]`)做 `factor=1+damp·(target/RMS_post−1)` 的绕质心缩放。+2. **各向异性轴缩放**:两输入阶段 align 后缩放到 target_rms,逐轴 SD 做 log 线性插值得 target_SD_d,对平滑后坐标逐轴 `factor_d=1+damp·(target_SD_d/SD_d−1)`。+3. **自适应 k**:`k_eff=min(k, max(3, m−1))`,细胞数 <21 的小类型不再被跳过(proxy 上 5 型全部 ≥21,为 no-op;final 31 个共有型时保证稀有型也被平滑)。 -关键参数(网格选出):**k=20, strength=1.5, max_frac=0.2**(`--k/--strength/--max-frac` 可覆盖)。可选 `--pca-norm`(k026 坐标规范化)默认 **off**——见下。+## 对照结果(mechanism_off_control) -## 机制生效证据(proxy, seed 0, k=20 strength=1.5)+`--rescale-damp 0 --aniso off --max-frac 0.2`(=父参数)的输出与父节点15输出 **X 与 spatial_3D 均 `np.array_equal` = True**(逐位一致),确认新代码在关闭态不泄漏。 -- (1) 被平滑细胞占比 = **100%**(n_smoothed 17616/17616,skipped types 0;proxy 只有 5 个共有型但每型细胞都 ≥ k+1)。-- (2) 平均位移/型内SD = **0.104**(≤ 0.2 上限);max|delta| = 65.5 坐标单位(RMS≈346)。-- (3) 表达矩阵与父节点输出 **`np.array_equal` = True**(逐位不变,机制只落在 `obsm["spatial_3D"]`)。-- (4) 细胞数 17616 不变;类型组成不变(抽样未动)。-- (5) `local_spatial` **53.46 → 59.81(+6.35)**,远超 PLAN 目标 +1.5;`neighborhood_mmd` 0.0834 → 0.0645(越低越好,单调下降)。-- (6) `shape_scale` 53.07 → 53.52(**+0.45**,未降;occupancy_dice 0.834→0.838)。+## 机制检验:PLAN 的两个机制在 proxy 上被证伪(A半,seed 0) -四组分(A半,control→best):expression_change 63.83→63.83(不变,符合"不动表达");cell_state 65.93→65.93(不变);local_spatial 53.46→59.81(**主要收益**);shape_scale 53.07→53.52(略升)。**机制只推动 local_spatial,其余三组逐位不变或微升,与设计一致。**+| 配置 | 榜分 | shape_scale | local_spatial | scale_log_ratio | occupancy_dice |+|---|---:|---:|---:|---:|---:|+| 父节点15(mf0.2, 无缩放) | 60.77 | 53.52 | 59.81 | ~0.451 | 0.838 |+| +均匀RMS恢复 damp=1.0 | 60.69 | 53.22 | 59.81 | 0.467 | 0.838 |+| +RMS恢复+aniso damp=1.0 | 60.65 | 53.06 | 59.80 | 0.460 | 0.834 | -## 对照结果(mechanism_off_control)+证据数字:平滑确实系统性收缩 RMS(RMS_post/target = **0.9832**,收缩 1.7%,方向与 PLAN 预期一致);恢复后 RMS/target = 1.0000。但 **shape_scale 反而下降**:scale_log_ratio 0.451→0.467 恶化——说明参考阶段的尺度**低于** mix 的 log 线性 target_rms(与方法卡"心脏尺度非单调,log 线性 346 够不到真值 217"一致),把 RMS 推回 target 是推离参考。aniso 的各轴 ratio_d 均 <2%(0.980/0.997/1.001),且 occupancy_dice 0.838→0.834 下降。命中 PLAN 风险①③,按止损条款以 **rescale_damp=0、aniso off** 提交。进一步用输入数据之外的方式"猜"目标尺度(更强的整体收缩)无法从两输入阶段合法导出(两端 RMS 354/335,log 线性对 damp 不敏感),针对 proxy 参考调尺度=向真值泄漏,不做。++## 实际提交的改进:平滑位移上限 max_frac 0.2→0.45(父节点 ANALYSIS 建议方向) -`--strength 0 --pca-norm off` 的输出与父节点(本地重跑节点2/12 的 `mix`)**逐位相同**(X 与 spatial_3D 均 `np.array_equal` True),确认平滑逻辑不泄漏到抽样或坐标管线。该对照 A半 = **59.07**(注:父节点榜单 59.50 是 B半;A/B 半差约 0.4,属评分器 10% 抽样噪声)。所有 A半对比均以此 59.07 为基线,避免 A/B 混淆。+父节点 next_suggestions 明确建议"试 max_frac 0.3–0.4 看 shape/局部是否随更强收缩改善"。网格(k=20, strength=1.5, A半 seed 0): -`--pca-norm on`(k026 规范化)单测 A半 59.07,与规范化前逐位同分(对 shape/scale 无净收益,且引入额外 SVD 开销与潜在符号不确定性),故**默认 off**,规避 PLAN 风险④。+| max_frac | 榜分 | local_spatial | shape_scale | neighborhood_mmd | mean_disp/SD |+|---:|---:|---:|---:|---:|---:|+| 0.20(父) | 60.77 | 59.81 | 53.52 | 0.0645 | 0.104 |+| 0.30 | 60.89 | 61.11 | 52.71 | 0.0611 | — |+| 0.35 | 61.01 | 61.41 | 52.86 | 0.0604 | 0.153 |+| **0.45(提交)** | **61.03** | **61.70** | **52.68** | **0.0597** | **0.176** |+| 0.60 | 61.08 | 62.00 | 52.59 | 0.0589 | — |+| 0.80 | 61.07 | 62.18 | 52.36 | 0.0585 | — |+| 0.35+s2.5 | 60.81 | 60.57 | 52.93 | 0.0625 | 0.180 | -## vec-score 网格(A半;每档只改 strength/k,表达恒等)+mf∈[0.45, 0.8] 是平台(61.03–61.08,差在噪声内);取 **0.45**(平台中部、shape 侵蚀最小,迁移到 B半/final 更安全)。**跨种子一致性**:seed 1 下 mf0.45 = 61.27 vs 父配置 seed 1 = 61.02(+0.24,与 seed 0 的 +0.26 同向;local_spatial 60.2→62.0,+1.8 超噪声,shape −0.8 部分抵消)。净增益 ~+0.25 小于 T2 噪声 ~1 分,属"方向一致的小幅改进",不是大幅突破——如实记录。 -| 配置 | 榜分 | local_spatial | shape_scale | neighborhood_mmd |-|---|---:|---:|---:|---:|-| control (s0) | 59.07 | 53.46 | 53.07 | 0.08343 |-| k10 s0.05 | 59.14 | 53.72 | 53.09 | 0.08255 |-| k10 s0.10 | 59.25 | 54.16 | 53.07 | 0.08112 |-| k10 s0.20 | 59.42 | 54.76 | 53.15 | 0.07919 |-| k10 s0.40 | 59.72 | 55.80 | 53.31 | 0.07595 |-| k10 s0.60 | 60.06 | 56.97 | 53.54 | 0.07246 |-| k10 s1.00 | 60.36 | 58.58 | 53.09 | 0.06785 |-| k10 s1.50 | 60.55 | 59.22 | 53.22 | 0.06611 |-| **k20 s1.50(提交)** | **60.77** | **59.81** | **53.52** | **0.06452** |-| k20 s2.50 | 60.74 | 59.62 | 53.60 | 0.06504 |-| k30 s1.50 | 60.62 | 59.53 | 53.18 | 0.06526 |-| k5 s1.50 | 60.27 | 57.70 | 53.61 | 0.07033 |-| k10 s4.00 | 60.30 | 58.49 | 52.94 | 0.06811 |-| k10 s8.00 | 60.14 | 58.04 | 52.76 | 0.06938 |+## 机制生效证据(提交默认,proxy seed 0) -榜分与 local_spatial 随 strength 单调升到 s≈1.5、k=20 达峰(60.77),过度平滑(s≥4 或 k=30)后 neighborhood_mmd 回升、shape 下降,出现拐点。k=20 优于 k=5/10/30,说明中等邻域最能修复 mix 叠加两阶段细胞造成的局部邻域增稠。+- 平滑覆盖率 100%(17616/17616,跳过类型 0);mean_disp/型内SD = 0.176(≤0.45 上限);max|delta| = 147.4。+- neighborhood_mmd 0.0645→0.0597(单调改善),local_spatial 59.81→61.70。+- 表达矩阵、细胞数(17616 ∈ [1000, 17616])、类型组成与父逐位一致(X `array_equal` True);只有坐标变。+- 关闭对照(mf=0.2)与父输出逐位一致(见上)。  ## 验证过 -- 提交默认(无显式 flag)== k20 s1.5 逐位一致;seed 0 重跑逐位确定;seed 1 结果不同(未对特定 seed 写分支)。-- 表达逐位等于父节点;坐标改变、全部有限;n=17616 ∈ [min 1000, max 17616];`vec-check` 通过。-- **视图无关**:构造 +1 天平移、manifest 键序打乱的伪装视图,t 仍 0.4,输出 X 与 spatial_3D 逐位与真实视图相同(程序只用相对时间 t 与坐标/标签,不含绝对时间、不读视图路径/文件名)。-- 纯 CPU(numpy + scipy cKDTree),peak mem 与父相当,runtime ~2s;已声明 `EXECUTION.json {"gpu": false}`。+- 默认参数(无 flag)输出与网格 mf045_s15 文件逐位一致;seed 0 重跑逐位确定;seed 1 输出不同(无 seed 分支)。+- `vec-check` ok;坐标全部有限。+- **视图无关**:构造 +1 天平移、manifest 键序打乱、external 阶段同步平移的伪装视图,seed 0 输出的 X 与 spatial_3D 与真实视图**逐位相同**;程序只用相对时间 t、坐标、标签,不读绝对时间/路径/board 字段。+- 纯 CPU(numpy+scipy cKDTree),runtime ~2.1s,峰值内存与父相当(~0.5GB);`EXECUTION.json {"gpu": false}`。+- 查分用量:10/20(control 未查分,用逐位对照代替)。  ## 未验证 / 风险 -- **final 括号未测**:final 心脏插值有 31 个共有型(proxy 仅 5)。k=20 需每型 ≥21 细胞才平滑;final 总细胞按类型均分后多数型 ≫21,但稀有型可能 <21 被跳过,覆盖率或略低于 proxy 的 100%(仍应 ≫70%)。机制按型内 SD 自适应、k 由型大小封顶,对更细的类型划分稳健。-- strength=1.5 远超 PLAN 初值网格(0.05–0.20):因该网格上限位移太小(s0.20 时 mean_disp/SD 仅 0.015),未触及拐点;实测最优点 mean_disp/SD=0.104 仍受 0.2 上限约束,未违反 PLAN 的位移幅度约束。-- 提交分数用 B半,A半 60.77 与 B半可能差 ~0.4;但相对父的 +1.70(A半同尺)主要来自 local_spatial +6.35,远超噪声,方向应成立。+- final 括号(31 共有型)未测;k_adaptive 使小类型(≥4 细胞)也被平滑,覆盖率应高于父节点的"跳过 <21 型",但小类型上 k_eff=3–19 的平滑幅度更依赖其自身 SD(自适应封顶),预期稳健、未实测。+- 净 +0.25(A半)在噪声边缘;依据是 local_spatial +1.8 在两个 seed 上同向、平台宽(mf 0.45–0.8),非单点尖峰。+- shape_scale 的 scale 分量短板仍在(scale_log_ratio≈0.44):合法可用的输入信息推不出参考尺度(非单调 354→217→335),任何"整体缩到某个魔数"的做法都是对 proxy 真值的拟合,不可迁移。  ## 知识来源 -仅通用机制知识与几何操作:mix 叠加两阶段真实细胞会使同一空间位置附近混入不同发育时刻的同型细胞,局部邻域比真实中间阶段更"稀/杂";向同型近邻质心轻微收缩可重新致密化局部结构而不改动全局形状或表达。kNN、逐维 SD 裁剪、PCA 定向均为标准几何/统计操作。未使用任何保留阶段(E8.5/E10.5/E12.5 及禁窗)或保留基因型的测量信息;程序只读 manifest 的相对时间与视图内表达/坐标/标签,对时间平移不变。+仅通用几何/统计操作(kNN 收缩、逐维 SD 裁剪、log 线性插值、Kabsch 对齐,均沿自父节点与 `src.task2_spatial`)。未使用保留阶段(E8.5/E10.5/E12.5、禁窗 (8.25,8.75)、9.5<E≤13.5)或保留基因型的任何测量信息;对目标尺度未注入任何外部数值。diff --git a/solution/run.py b/solution/run.pyindex 34031aa..bdfa47a 100644--- a/solution/run.py+++ b/solution/run.py@@ -16,15 +16,24 @@ type composition are untouched):        delta_i = strength * (c_i - coords_i) -  Each cell's displacement is capped at ``max_frac`` (0.2) times the type's+  Each cell's displacement is capped at ``max_frac`` (0.45) times the type's   per-dimension coordinate SD; if any dimension exceeds its cap the whole   delta is scaled down proportionally (direction preserved). -  Types with < k+1 cells are skipped (left untouched).+  With --k-adaptive on, k_eff = min(k, max(3, m-1)) so small types are smoothed+  with a smaller neighbourhood instead of being skipped (no-op when m >= k+1).++Optional post-smoothing coordinate rescaling (family T2HI-05, tested and+FALSIFIED on the proxy A-half, therefore OFF by default):+``--rescale-damp`` restores the log-linear target RMS (uniform scale about the+centroid); ``--aniso on`` matches per-axis SDs to the log-interpolated aligned+input SDs. Both moved scale_log_ratio away from the reference (shape_scale+53.52 -> 53.22 / 53.06); see METHOD.md. Defaults reproduce the grid-selected+configuration (max_frac 0.45); ``--max-frac 0.2 --rescale-damp 0 --aniso off``+reproduces the parent (node 15) output bit-for-bit.  ``--strength 0`` disables the smoothing entirely (delta = 0, coordinates-untouched) and, with ``--pca-norm off``, reproduces the parent output-bit-for-bit.  Single input (no bracket): parent fallback, no smoothing.+untouched).  Single input (no bracket): parent fallback, no smoothing.  Optional ``--pca-norm on`` applies a deterministic PCA canonicalisation of the output frame (subtract centroid -> rotate onto PCA axes -> force det=+1 ->@@ -43,6 +52,7 @@ import sys import numpy as np from scipy.spatial import cKDTree +from src.task2_spatial.frame import align_pair, log_interp, rms_radius, scale_to_rms from src.task2_spatial.methods import interpolate from src.task2_spatial.sample import mix_indices, take from src.task2_spatial.view_io import board_params, interp_bracket, load_manifest, panel_genes, read_stage, write_t2@@ -50,11 +60,15 @@ from src.task2_spatial.view_io import board_params, interp_bracket, load_manifes PARAMS = {"align": "procrustes", "scale_damp": 1.0} K = 20 STRENGTH = 1.5  # grid-searched on the proxy A-half; 0 = parent behaviour (control)-MAX_FRAC = 0.2+MAX_FRAC = 0.45  # displacement cap x type coord SD; grid: 0.2(parent)..0.8 plateau 61.0-61.1, 0.45 mid-plateau PCA_NORM = False+RESCALE_DAMP = 0.0  # uniform RMS restore FALSIFIED on proxy (moves RMS away from ref scale); 0 = off+ANISO = False  # per-axis SD correction: also falsified (occupancy_dice drop); off+ANISO_DAMP = 1.0+K_ADAPTIVE = True  # k_eff = min(k, max(3, m-1)): smooth small types instead of skipping (robustness for finer type vocabularies; no-op when all types >= k+1)  -def _knn_smooth(coords: np.ndarray, labels: np.ndarray, k: int, strength: float, max_frac: float):+def _knn_smooth(coords: np.ndarray, labels: np.ndarray, k: int, strength: float, max_frac: float, adaptive: bool = False):     """Per-type kNN contraction toward neighbour centroid, capped by type coord SD.      Returns (new_coords, evidence dict). Coordinates are modified in place-safe@@ -71,7 +85,8 @@ def _knn_smooth(coords: np.ndarray, labels: np.ndarray, k: int, strength: float,     for lab in np.unique(labels):         idx = np.flatnonzero(labels == lab)         m = idx.size-        if m < k + 1:+        k_eff = min(k, max(3, m - 1)) if adaptive else k+        if m < k_eff + 1:             n_skipped_types += 1             n_skipped_cells += m             continue@@ -79,7 +94,7 @@ def _knn_smooth(coords: np.ndarray, labels: np.ndarray, k: int, strength: float,         sd = pts.std(axis=0)  # per-dimension SD of this type         cap = max_frac * sd  # per-dimension displacement cap         tree = cKDTree(pts)-        kk = min(k + 1, m)+        kk = min(k_eff + 1, m)         _, nb = tree.query(pts, k=kk)  # includes self as nearest         if nb.ndim == 1:             nb = nb[:, None]@@ -134,6 +149,53 @@ def _pca_normalize(coords: np.ndarray) -> np.ndarray:     return P.astype(np.float32)  +def _rms_restore(coords: np.ndarray, target_rms: float, rescale_damp: float,+                 aniso: bool, aniso_damp: float, stage_a, stage_b, t: float, align: str):+    """Undo the systematic kNN-contraction shrinkage of the global second moment.++    1) uniform: scale about the centroid so RMS -> target_rms (damped).+    2) aniso (optional): per-axis SD scaled toward the log-linear interpolation+       of the two aligned+scaled input clouds' per-axis SDs (damped).++    Expression, cell count and composition are untouched; only coordinates move.+    Returns (new_coords float32, evidence dict).+    """+    x = np.asarray(coords, dtype=np.float64)+    ev: dict = {}+    centroid = x.mean(axis=0)+    rms_post = rms_radius(x)+    ev["rms_post_smooth"] = rms_post+    ev["rms_target"] = target_rms+    ev["rms_ratio_post_over_target"] = rms_post / max(target_rms, 1e-12)+    if rescale_damp != 0.0 and rms_post > 1e-8 and target_rms > 0:+        s_uniform = target_rms / rms_post+        factor = 1.0 + rescale_damp * (s_uniform - 1.0)+        x = centroid + factor * (x - centroid)+        ev["uniform_factor"] = factor+        ev["rms_after_uniform"] = rms_radius(x)+    if aniso:+        al_a, al_b, _ = align_pair(stage_a.coords, stage_b.coords, stage_a.labels, stage_b.labels, align)+        ca = scale_to_rms(al_a, target_rms)+        cb = scale_to_rms(al_b, target_rms)+        sd_a = ca.std(axis=0)+        sd_b = cb.std(axis=0)+        centroid = x.mean(axis=0)+        sd_cur = x.std(axis=0)+        factors = np.ones(x.shape[1])+        tsds = np.zeros(x.shape[1])+        for d in range(x.shape[1]):+            tsd = log_interp(sd_a[d], sd_b[d], t, 1.0)+            tsds[d] = tsd+            r = tsd / max(sd_cur[d], 1e-12)+            factors[d] = 1.0 + aniso_damp * (r - 1.0)+            x[:, d] = centroid[d] + factors[d] * (x[:, d] - centroid[d])+        ev["target_sd"] = tsds.tolist()+        ev["sd_post_smooth"] = sd_cur.tolist()+        ev["aniso_factors"] = factors.tolist()+        ev["rms_after_aniso"] = rms_radius(x)+    return x.astype(np.float32), ev++ def main() -> None:     parser = argparse.ArgumentParser()     parser.add_argument("--data", required=True)@@ -143,6 +205,10 @@ def main() -> None:     parser.add_argument("--strength", type=float, default=STRENGTH)     parser.add_argument("--max-frac", type=float, default=MAX_FRAC)     parser.add_argument("--pca-norm", choices=("on", "off"), default=("on" if PCA_NORM else "off"))+    parser.add_argument("--rescale-damp", type=float, default=RESCALE_DAMP)+    parser.add_argument("--aniso", choices=("on", "off"), default=("on" if ANISO else "off"))+    parser.add_argument("--aniso-damp", type=float, default=ANISO_DAMP)+    parser.add_argument("--k-adaptive", choices=("on", "off"), default=("on" if K_ADAPTIVE else "off"))     args = parser.parse_args()      manifest = load_manifest(args.data)@@ -174,13 +240,21 @@ def main() -> None:         labs_a = np.asarray(stage_a.labels).astype(str)[ia]         labs_b = np.asarray(stage_b.labels).astype(str)[ib]         labels = np.concatenate([labs_a, labs_b])-        coords, ev = _knn_smooth(coords, labels, args.k, args.strength, args.max_frac)+        coords, ev = _knn_smooth(coords, labels, args.k, args.strength, args.max_frac,+                                 adaptive=(args.k_adaptive == "on"))+        if args.rescale_damp != 0.0 or args.aniso == "on":+            coords, ev2 = _rms_restore(coords, float(info["target_rms"]), args.rescale_damp,+                                       args.aniso == "on", args.aniso_damp, stage_a, stage_b, t,+                                       str(params.get("align", "procrustes")))+            ev.update(ev2)      if args.pca_norm == "on":         coords = _pca_normalize(coords)      keep = {k: info.get(k) for k in ("t", "n", "rms_a", "rms_b", "out_rms", "n_shared_types", "z_dot", "z_flipped", "align", "n_from_a", "n_from_b")}-    print(json.dumps({"bracket": [a["stage"], b["stage"]], **keep, "strength": args.strength, "k": args.k, "pca_norm": args.pca_norm, **ev}, default=float), file=sys.stderr)+    print(json.dumps({"bracket": [a["stage"], b["stage"]], **keep, "strength": args.strength, "k": args.k,+                      "pca_norm": args.pca_norm, "rescale_damp": args.rescale_damp, "aniso": args.aniso,+                      "aniso_damp": args.aniso_damp, "k_adaptive": args.k_adaptive, **ev}, default=float), file=sys.stderr)     write_t2(args.out, expr, coords, genes, seed=args.seed)  

调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k026Canonicalise predicted 3D coordinates before submissionnotes/pitfalls/04_scorer_invariance.md
k027Joint expression-geometry generation with relative geometrynotes/competition/03_solution_landscape.md

分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。

改了什么PLAN 的 T2HI-05 机制(平滑后均匀 RMS 恢复 + 各向异性轴缩放)已实现但在 proxy 上被 Engineer 证伪并默认关闭;实际提交的改动是父节点 T2HI-04 平滑的位移上限 max_frac 0.2→0.45(k=20, strength=1.5 不变)加 k_adaptive(proxy 上为 no-op,为 final 小类型稳健性)。只改坐标,表达/细胞数/组成逐位不变。
各组分数的变化cell_state:不变,+0.00(66.70→66.70)
expression_change:不变,+0.00(63.90→63.90,坐标-only 改动,符合预期)
local_spatial:变好,+1.94(60.40→62.34),超过 T2 噪声约 1 分,且 proxy 两 seed 同向(+6.35 内 local_spatial 59.81→61.70),是榜分 +0.39(噪声内)的主要来源
shape_scale:噪声内,-0.38(53.08→52.70);与 proxy 上 mf 增大轻微侵蚀 shape 的记录一致,PLAN 预期的 shape_scale 提升未发生
family_idT2HI-04
假设是否成立否
经验
  1. 在 mix 基线上,log 线性插值的 target_rms 高于中间参考的真实尺度(scale_log_ratio≈0.45,两端 354/335 对真值 217 非单调),因此把平滑后 RMS 恢复到 target_rms 会把尺度推离参考(0.451→0.467,shape_scale 53.52→53.22)——RMS 恢复类机制在此 board 上方向即错。
  2. 各向异性轴校正在两输入阶段 axis ratio 均 <2%(0.980/0.997/1.001)时没有信号可提取,反而使 occupancy_dice 0.838→0.834:校正量级小于度量噪声时不要开启。
  3. 型内 kNN 平滑的位移上限 max_frac 在 0.45–0.8 存在收益平台(proxy 61.03–61.08),local_spatial 随上限单调升、shape_scale 轻微降;取平台低端(0.45)可在迁移到 B 半/final 时最小化 shape 侵蚀。
  4. 仅用坐标全局/逐轴缩放无法合法修复 scale_log_ratio 短板:参考尺度非单调,任何'缩到某个魔数'都是对 proxy 真值的拟合,不可迁移。
  5. 本节点是'PLAN 机制被证伪后按止损条款回退并改走参数强化'的正面例子:关闭态与父输出逐位一致(array_equal 验证)保证了证伪结论和提交基线都可信。
mechanism_active否
下一步建议
  1. 针对 shape_scale(52.70,最短板):放弃全局坐标缩放路线;可试只影响 occupancy/形状而非 RMS 的局部操作,或检查 scale_log_ratio 是否被 mix 抽样比例(1-t,t)系统性偏置,针对 shape_scale 组调整分层抽样权重。
  2. 针对 local_spatial:mf 已在平台内,继续加大无益;试 strength 与 k 的联合微调(如 k=25, s=1.5, mf=0.45)或与节点9的分层组成混合基线组合,验证 local_spatial 增益是否叠加。
  3. 针对 expression_change(63.90)/cell_state(66.70):坐标侧机制已饱和且逐位不变这两组,应在表达侧找新机制(如按局部邻域表达轻微重加权),但需先设计关闭态逐位一致的对照。

对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。

只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。

分析员

角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。分析员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数?大模型一共回复了几轮(每轮可以调用多个工具)。3
工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。共 3 次:bash 1、read 1、write 1
用时不到 1 分
token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。输入 16,079 · 输出 1,178 · 思考 1,515
任务(第一行)分析节点 n17 的打分结果,写 ANALYSIS.json
最后的回答(摘录)
ANALYSIS.json written
原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/analyst.jsonl 10 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/analyst.stderr

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数33
工具调用共 40 次:bash 31、edit 7、read 1、write 1
用时18 分
token 数输入 71,634 · 输出 11,171 · 思考 15,310
任务(第一行)按计划修改程序:kNN平滑后RMS恢复+各向异性轴缩放修正shape_scale
最后的回答(摘录)
**做了什么**:按 PLAN(T2HI-05)在节点15上实现平滑后均匀 RMS 恢复 + 各向异性轴缩放 + 自适应 k。对照(关闭态)与父输出逐位一致。两机制在 proxy 上被证伪:RMS 恢复把 scale_log_ratio 0.451→0.467 推离参考(shape_scale 53.52→53.22),aniso 各轴 ratio <2% 且 occupancy_dice 下降——按 PLAN 风险①③止损关闭。改走父 ANALYSIS 建议方向:位移上限 max_frac 0.2→0.45(平台 0.45–0.8 取中),k_adaptive 保留(final 小类型稳健性)。

**查分**(A半,10/20 次):提交配置 seed0 = **61.03**(父 60.77),local_spatial 59.81→61.70,shape_scale −0.84;seed1 = 61.27 vs 父配置 seed1 = 61.02,两 seed 同向 +0.25。视图无关(+1天伪装视图逐位相同)、确定性、vec-check 均通过。

**下一步**:scale_log_ratio≈0.44 仍是短板,但合法输入推不出非单调的目标尺度(354→217→335),继续调全局缩放只会拟合 proxy 真值;更值得试的是把强化平滑(mf0.45)与节点9的分层组成混合基线组合,或在表达侧找 cell_state/expression_change 的新机制。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/engineer.jsonl 183 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时2 分
token 数输入 12,229 · 输出 1,088 · 思考 3,818
任务(第一行)为节点 n17(改进,父节点 n15)写改进计划 PLAN.json
最后的回答(摘录)
质心收缩是局部操作,但对非均匀点云会系统性压缩全局二阶矩(外围细胞邻居偏向内侧),导致平滑后RMS低于mix基线已计算的log线性目标RMS。此外,各轴缩放比可能因心脏形态变化(沿轴非等比生长)而不一致。节点13曾在不同基线(node 6 comp重抽)上试坐标缩放未成功,但本节点基线不同(mix+平滑,无comp重抽),且此处缩放是对已知收缩伪影的校正而非主机制。",
  "approach": "在节点15代码基础上,_knn_smooth返回后、写入前,增加两步坐标后处理:\n\n1)均匀RMS恢复:计算平滑后点云RMS_post=mean(||coords−centroid||),从mix基线已有的log线性插值获取target_RMS(代码中已有该值),令scale_uniform=target_RMS/RMS_post,coords←centroid+scale_uniform×(coords−centroid)。加阻尼参数rescale_damp∈{0.5,0.75,1.0},实际缩放因子=1+rescale_damp×(scale_uniform−1)。\n\n2)各向异性轴缩放(可选开关--aniso on/off):对每轴d计算输入两阶段的SD_d,log线性插值得target_SD_d;计算smoothed_SD_d;ratio_d=target_SD_d/smoothed_SD_d;应用阻尼coords[:,d]←centroid_d+aniso_damp×(ratio_d−1)×(coords[:,d]−centroid_d)+coords[:,d]−centroid_d,即coords[:,d]=centroid_d+(1+aniso_damp×(ratio_d−1))×(coords[:,d]−centroid_d)。aniso_damp∈{0.5,1.0}。\n\n3)自适应k(次要):k_eff=min(k, max(3, m−1)),使小类型不被跳过(对final 31型稳健)。\n\n网格:先跑control(rescale_damp=0, aniso off)确认与父节点逐位一致;再跑rescale_damp=1.0+aniso off;再跑rescale_damp=1.0+aniso on damp=1.0;最后微调。每档一次vec-score(≤8次查分)。单输入阶段退路:无括号时沿用父回退(take抽样),不做平滑也不做缩放。\n\n关键参数初值:rescale_damp=1.0, aniso_damp=1.0, k_adaptive=True。",
  "expected_groups": ["shape_scale"],
  "risks": "1)shape_scale的scale分量可能不是RMS而是其他度量(如bounding box),均匀缩放无效——Engineer第一次查分若shape_scale不变即可发现,止损回退到父节点输出。2)各向异性校正过强可能轻微扭曲局部邻域,使local_spatial下降0.5-1分——若local_spatial降幅>1.5则关闭aniso只保留均匀缩放。3)RMS_post与target_RMS差距极小(<2%)时改善在噪声内——此时以rescale_damp=0提交(等同父节点)。",
  "family_id": "T2HI-05",
  "mechanism": "kNN收缩对非均匀点云产生系统性RMS压缩(外围向内偏),平滑后按mix基线已算好的目标RMS做均匀重缩放,并可选按各轴输入阶段SD插值做各向异性校正,恢复正确尺度。",
  "vs_constant_shift": "常数位移改变表达值;本机制只乘坐标缩放因子(均匀或逐轴),不改变任何表达值、不改变细胞数或类型组成,且缩放因子由两输入阶段的几何统计量插值决定而非全局常数。",
  "mechanism_evidence": "Engineer记录:(1)RMS_post/RMS_pre比值(预期<1,证实收缩伪影);(2)缩放后RMS与target_RMS的比值(预期≈1);(3)各轴ratio_d偏离1的程度;(4)四组分各自变化——预期shape_scale提升≥1.5,local_spatial变化<±1,cell_state/expression_change逐位不变。",
  "mechanism_off_control": "--rescale-damp 0 --aniso off时缩放因子恒为1,输出与父节点15逐位相同(np.array_equal验证)。预期差别:关闭时shape_scale维持53.08,开启后预期≥54.5。"
}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/researcher.jsonl 5 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/researcher.stderr

审查员

角色审查员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数17
工具调用共 16 次:bash 8、read 7、write 1
用时2 分
token 数输入 30,324 · 输出 2,158 · 思考 5,090
任务(第一行)审查节点 n17 的程序是否越界读取、写死目标、钻评分器漏洞
最后的回答(摘录)
REVIEW.json written
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/reviewer.jsonl 109 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24-D/nodes/17/reviewer.stderr