总览 · ← 返回运行 20261003-004922-search-t2-heart-interp-g24
节点 n13
型内NN空间融合后同步表达β混合(T2HI-01):被融合b细胞表达向其a侧同型最近邻做(1−β)X_b+βX_a线性混合;proxy全β网格净分不高于β=0对照(expr_change/local_spatial升被cell_state等量降抵消),提交默认β=0(输出与父节点12逐位一致),阴性结果完整记录。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-004922-search-t2-heart-interp-g24 |
|---|---|
| 父节点 | n12 |
| 子节点 | n15 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 60.66(+0.0) · proxy 60.66(+0.0) |
| 审查 | 通过 1 越界读取:未发现问题。数据读取全部经 run.py:59-69 的 load_manifest/read_stage/panel_genes(manifest 驱动,--data 指向视图目录);无绝对路径、..、/mnt、/home、external、prior、打分器或 src/common/evaluation 的读取,无网络访问(全部源码 grep 无 requests/urllib/http)。README.md 提到的 data/processed 对比文件仅是开发期离线验证记录,程序不读取。; 2 硬编码目标统计量:未发现问题。代码中的常量均为算法超参(nn_fuse.py… |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 11 分 |
| 程序版本 | e006a839b934dbb97d8eb349a289268add740765 (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git e006a839b9:solution/METHOD.md
型内NN空间融合后同步表达β混合(T2HI-01):被融合b细胞表达向其a侧同型最近邻做(1−β)X_b+βX_a线性混合;proxy全β网格净分不高于β=0对照(expr_change/local_spatial升被cell_state等量降抵消),提交默认β=0(输出与父节点12逐位一致),阴性结果完整记录。
方法(PLAN T2HI-01 的实现)
父节点 12 pipeline(mix + 空间分层抽样 + procrustes 对齐 + 型内 NN 坐标融合 α=1.0)不动。在 nn_fuse.py 的 fuse_nn 内,cKDTree query 返回的最近邻索引被复用于表达混合:对每个被空间融合的 b 侧输出细胞,X_b ← (1−β)·X_b + β·X_a_nn(同一邻居,逐细胞、位置依赖、型内),另加可选 EXPR_BLEND_VARFIX=1:混合后把融合子集内每基因 std 恢复到混合前(保留均值位移,clip≥0)。非共有型、a 侧细胞、坐标均不动。单输入阶段(b is None)退路与父节点相同。
- 开关:
EXPR_BLEND_BETA(提交默认 0.0 = 关闭)、EXPR_BLEND_VARFIX(默认 0)。 - β=0 时融合/混合代码全被 guard 跳过,输出 X 与坐标和父节点 12 逐位一致(
X/data非零值 array_equal、spatial_3Darray_equal,已验证);vec-check ok。
β 网格(proxy,seed0,A 半,共 7 次查分)
| 配置 | 榜分 | expr_change | cell_state | local_spatial | shape_scale |
|---|---|---|---|---|---|
| β=0(对照=父12) | 60.07 | 64.07 | 66.17 | 56.26 | 53.78 |
| β=0.1 | 60.02 | 64.47 | 65.63 | 56.21 | 53.78 |
| β=0.2 | 59.95 | 64.50 | 65.27 | 56.26 | 53.78 |
| β=0.3 | 59.93 | 64.53 | 64.99 | 56.40 | 53.78 |
| β=0.5 | 59.97 | 64.55 | 64.68 | 56.88 | 53.78 |
| β=0.3+varfix | 60.02 | 64.52 | 65.17 | 56.59 | 53.78 |
| β=0.5+varfix | 60.10 | 64.80 | 64.67 | 57.14 | 53.78 |
机制生效证据(PLAN 要求的 4 项)
- cosine 相似度:被融合 b 细胞与其 a 侧邻居的表达 cos 从 0.379 升到 0.593(β=0.2,stderr 诊断
cos_before/cos_after)——混合确实按位置逐细胞改变了表达。 - 型内方差:不加 varfix 时融合子集每基因 std 按 ~(1−β)+β·ρ 收缩;varfix 变体把它恢复到混合前(mmd_u 0.0349→0.0341 @β=0.5),但 cell_state 只回收约 1/3,说明 cell_state 损失来自分布形状(mmd)而非逐基因方差。
- 四组分:expression_change 单调升(64.07→64.80,de_score 0.337→0.370);local_spatial 升(56.26→57.14,neighborhood_mmd 0.0746→0.0720,表达-空间对应一致化确实改善局部邻域);cell_state 近似线性降(66.17→64.67);shape_scale 恒等(坐标未动,符合设计)。
- 响应曲线:expression_change 对 β 单调(非 PLAN 预期的非单调),但在 β≥0.1 后饱和;净榜分对 β 平坦且全部 ≤ 对照 + 0.03(噪声 ~1 分内)。
对照结果(mechanism_off_control)
β=0(默认)输出与父节点 12 逐位一致(X 非零值与坐标 array_equal,preds/default.h5ad vs preds/b0.h5ad 验证);β>0 时仅表达变化、坐标逐位不变(b0 vs b02 coords array_equal 验证)。结论:假设被证伪——表达向空间邻居混合的 expr_change(+0.4~0.7) 与 local_spatial(+0.6~0.9) 增益,被 cell_state(−0.5~−1.5) 等量抵消,7 个配置无一在噪声外超过 β=0。PLAN 风险 1、2 同时兑现。按 PLAN 的停止规则(cell_state 降 >1 即停、β=0.1 净降即放弃),提交保持 β=0。
验证过 / 未验证
- 验证过:β=0 逐位一致 + vec-check ok;β∈{0.1,0.2,0.3,0.5}×{plain,varfix} 网格(seed0,A 半,7 次查分);运行 ~2-5s、内存不变。
- 未验证:β>0 的多种子(无配置超噪声,不值得花额度);final 视图(31 共有型、融合覆盖率更高,β 混合的作用细胞更多,cell_state 损失可能同比放大,方向结论预期不变);k>1 邻居均值混合(同属均值压缩,预期同样伤 cell_state)。
- 生物学知识来源:无新增外部知识;仅用 view 内输入数据。external/mosta 未使用。
对树的意义
表达侧"向空间邻居混合"与坐标侧 NN 融合不同:坐标融合恢复局部连续性是纯增益(节点 10/12 各 +2.6/+2.9),表达混合在 E8.75 参考分布下是零和(评分器的 cell_state/mmd 对"不在真实流形上的中间表达谱"惩罚与 DE 方向增益等量)。下一步最值得试的是 external/mosta_e95_v0 引导的表达侧改动(节点 12 next_suggestions),或在 final 括号上直接复用当前 α=1.0 底座(31 共有型 vs proxy 5 个,融合覆盖率 12.9%→更高,local_spatial 增益可能放大)。
调研员的计划
| 名称 | 型内NN空间融合后同步表达混合(b细胞向a侧最近邻表达β混合) |
|---|---|
| 动机 | 父节点12的local_spatial已达56.83(+2.86),但expression_change停在64.37、cell_state 66.95自mix基线以来未动(X逐位未改)。shape_scale 54.49最弱但坐标侧三假设已耗尽(ANALYSIS明确不建议再投坐标形变)。k027指出表达与几何不应独立生成——当前管线坐标做了型内NN融合,表达却完全不动,表达-空间对应断裂。expression_change 64.37是唯一有明确杠杆且未试过的方向。 |
| 做法 | 在nn_fuse.py的空间融合步骤中,已为每个b细胞找到a侧同型最近邻索引(cKDTree query返回)。新增表达混合:对被融合的b细胞,X_b_new = (1−β)·X_b + β·X_a_neighbor,β∈{0, 0.1, 0.2, 0.3, 0.5}网格,用vec-score在proxy上快筛。β=0为关闭对照(输出与父节点逐位一致)。仅作用于共有型中被空间融合的b细胞(同n_fused集合),非共有型和a侧细胞X不动。基因维度不变、稀疏性可能略降(β混合后原零位可能变非零),若写盘格式要求稀疏则对|X|<1e-6截断为0。单输入阶段退路:b is None时不融合、不混合,与父节点相同。实现约15行改动(在interpolate_fuse内,query返回的邻居索引直接用于X混合)。30分钟内可完成网格+3种子确认。 |
| 风险 | 1) β混合可能降低细胞间表达离散度,反而伤害cell_state(型内变异被压缩)——Engineer应同时监控cell_state,若降>1分则停止;2) 表达混合可能让expression_change也降(如果评分器期望保留完整的两阶段表达差异而非中间态)——β=0.1先试,若降则放弃;3) 稀疏→稠密转换的内存/格式问题——先检查write_t2是否接受稠密矩阵。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 af89ea07a6。改动的文件:solution/METHOD.md +26 −44、solution/nn_fuse.py +59 −7、solution/run.py +5 −2
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 7f3f9f0..ee4f24f 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,59 +1,41 @@-# mix+空间分层上移植型内近邻坐标融合(T2HI-04):关闭已证无效的形状插值;Procrustes 对齐后,每个共有型的 b 侧细胞用 cKDTree 向其 a 侧同型最近邻做 3D 位移(α=1.0),恢复型内局部空间连续性,表达矩阵不动。+# 型内NN空间融合后同步表达β混合(T2HI-01):被融合b细胞表达向其a侧同型最近邻做(1−β)X_b+βX_a线性混合;proxy全β网格净分不高于β=0对照(expr_change/local_spatial升被cell_state等量降抵消),提交默认β=0(输出与父节点12逐位一致),阴性结果完整记录。 -## 方法+## 方法(PLAN T2HI-01 的实现) -父节点 9 pipeline,SHAPE_INTERP 置 0(父节点已证类型级 xy 形状插值无效),保留 SPATIAL_STRATIFY=1(每共有型 xy k-means 分 bin、bin 内按 (1−t,t) 抽两阶段真实细胞,表达和坐标一起走,align=procrustes,scale_damp=1)。新增 `solution/nn_fuse.py`:选完细胞、放到位之后、jitter/缩放之前,对每个两阶段共有型(各 ≥ NN_MIN_TYPE_CELLS=5 细胞),用 `scipy.spatial.cKDTree` 在该型 a 侧全部对齐+缩放坐标上建树,把每个被选中的 b 侧同型细胞位移 α·(最近 a 侧同型邻居 − 自身位置),**3D 含 z**。非共有型细胞不动,表达矩阵不动(X 与对照逐位一致)。之后照常走父节点的 _jitter + scale_to_rms。+父节点 12 pipeline(mix + 空间分层抽样 + procrustes 对齐 + 型内 NN 坐标融合 α=1.0)不动。在 `nn_fuse.py` 的 `fuse_nn` 内,cKDTree query 返回的最近邻索引被复用于表达混合:对每个被空间融合的 b 侧输出细胞,`X_b ← (1−β)·X_b + β·X_a_nn`(同一邻居,逐细胞、位置依赖、型内),另加可选 `EXPR_BLEND_VARFIX=1`:混合后把融合子集内每基因 std 恢复到混合前(保留均值位移,clip≥0)。非共有型、a 侧细胞、坐标均不动。单输入阶段(b is None)退路与父节点相同。 -- 开关:`NN_FUSE=0` 或 `NN_FUSE_ALPHA=0` 为关闭对照(已验证与 SHAPE_INTERP=0 的父节点输出**逐位一致**,X 和坐标均相同)。-- 参数:`NN_FUSE_ALPHA`(默认 1.0)、`NN_FUSE_NDIM`(默认 3;2=仅 xy,z 不动)。-- 单输入阶段(b is None)退路与父节点相同(分层抽最后输入,无融合)。-- 位移是逐细胞、位置依赖的:同型不同细胞获得不同方向/幅度的位移(型内每轴位移 std 62–102),不是常数平移,也不是刚体变换。+- 开关:`EXPR_BLEND_BETA`(**提交默认 0.0 = 关闭**)、`EXPR_BLEND_VARFIX`(默认 0)。+- β=0 时融合/混合代码全被 guard 跳过,输出 X 与坐标和父节点 12 **逐位一致**(`X/data` 非零值 array_equal、`spatial_3D` array_equal,已验证);vec-check ok。 -## α 网格(proxy,seed0,A 半)+## β 网格(proxy,seed0,A 半,共 7 次查分) -| α | 榜分 | local_spatial | shape_scale |-|---|---:|---:|---:|-| 0(=父,SHAPE_INTERP=0) | 59.80 | 54.13* | 53.76* |-| 0.5 | 59.49 | 54.06 | 53.65 |-| 0.75 | 59.85 | 55.37 | 53.78 |-| **1.0(提交)** | **60.07** | **56.26** | **53.78** |-| 1.25 | 60.04 | 56.01 | 53.91 |-| 1.5 | 59.82 | 54.79 | 54.23 |-| 1.0,仅 xy(NDIM=2) | 59.73 | 54.91 | 53.75 |+| 配置 | 榜分 | expr_change | cell_state | local_spatial | shape_scale |+|---|---:|---:|---:|---:|---:|+| β=0(对照=父12) | **60.07** | 64.07 | **66.17** | 56.26 | 53.78 |+| β=0.1 | 60.02 | 64.47 | 65.63 | 56.21 | 53.78 |+| β=0.2 | 59.95 | 64.50 | 65.27 | 56.26 | 53.78 |+| β=0.3 | 59.93 | 64.53 | 64.99 | 56.40 | 53.78 |+| β=0.5 | 59.97 | 64.55 | 64.68 | 56.88 | 53.78 |+| β=0.3+varfix | 60.02 | 64.52 | 65.17 | 56.59 | 53.78 |+| β=0.5+varfix | 60.10 | 64.80 | 64.67 | 57.14 | 53.78 | -*父节点 9 表中数字;本节点 α=0 对照与其逐位一致。cell_state/expression_change 全部配置相同(66.17/64.07,X 未动)。α=1.0 与节点 10 在另一分支验证的值一致;3D 融合优于仅 xy(z 也参与配对恢复局部连续性)。+## 机制生效证据(PLAN 要求的 4 项) -## 3 种子确认(α=1.0,A 半)--| seed | 榜分 | local_spatial | shape_scale |-|---|---:|---:|---:|-| 0 | 60.07 | 56.26 | 53.78 |-| 1 | 59.75 | 56.07 | 53.20 |-| 2 | 59.74 | 55.76 | 53.44 |-| 均值 | **59.85** | **56.03** | **53.47** |--vs 父节点 9 rank3 = 59.17(local_spatial 53.97):+0.68,local_spatial +2.06(远超 T2 噪声 ~1 分,3 种子一致);shape_scale −0.43(噪声内)。与节点 10(非分层底座 + 同机制,rank3 60.13)方向一致。--## 机制生效证据(proxy E8.25_late+E9.5→E8.75,t=0.4,seed0,α=1.0)--- 融合细胞数 2273 / 17616 = **12.9% 输出细胞**(占被选 b 侧细胞 7046 的 32.3%;略低于 PLAN 的 15% 门槛,因为 proxy 共有型仅 5 个,非共有型的 b 细胞按设计不动)。-- 5 个共有型全部通过 ≥5 阈值:NCC 341、Peri 621、V-CM 814、aPHM 239、pPHM 258 个 b 细胞被融合。-- 融合前 b→a 同型最近邻平均距离 200.1(各型 102–405);融合后全局平均最近邻距离从 14.25(对照)降到 12.86(−9.8%),型内局部空间连续性恢复。-- 位移向量型内每轴 std 62.5–101.9 > 0:逐细胞位置依赖位移,非常数位移。-- 四组分响应:local_spatial 54.1→56.3(机制目标组,+2.1~2.3);shape_scale 53.8→53.8(持平);cell_state / expression_change 与对照逐位一致(X 未动)。-- occupancy 变化可见未崩塌(occupancy_dice 0.837 记录于查分 metrics;输出 RMS 346.3 与对照相同,缩放步骤在融合后统一执行)。+1. **cosine 相似度**:被融合 b 细胞与其 a 侧邻居的表达 cos 从 0.379 升到 0.593(β=0.2,stderr 诊断 `cos_before/cos_after`)——混合确实按位置逐细胞改变了表达。+2. **型内方差**:不加 varfix 时融合子集每基因 std 按 ~(1−β)+β·ρ 收缩;varfix 变体把它恢复到混合前(mmd_u 0.0349→0.0341 @β=0.5),但 cell_state 只回收约 1/3,说明 cell_state 损失来自分布形状(mmd)而非逐基因方差。+3. **四组分**:expression_change 单调升(64.07→64.80,de_score 0.337→0.370);local_spatial 升(56.26→57.14,neighborhood_mmd 0.0746→0.0720,表达-空间对应一致化确实改善局部邻域);cell_state 近似线性降(66.17→64.67);shape_scale 恒等(坐标未动,符合设计)。+4. **响应曲线**:expression_change 对 β 单调(非 PLAN 预期的非单调),但在 β≥0.1 后饱和;净榜分对 β 平坦且全部 ≤ 对照 + 0.03(噪声 ~1 分内)。 ## 对照结果(mechanism_off_control) -NN_FUSE_ALPHA=0 输出与 NN_FUSE=0(=SHAPE_INTERP=0 父节点路径)逐位一致(X 稀疏非零差 0、坐标 array_equal),已在代码改动前后各验证一次。α=1.0 比 α=0 对照(seed0 59.80)高 0.27 分、local_spatial 高 2.13 分——机制在 local_spatial 上生效超过噪声,榜分增益小于组增益因 shape_scale 微降抵消一部分。+β=0(默认)输出与父节点 12 逐位一致(X 非零值与坐标 array_equal,preds/default.h5ad vs preds/b0.h5ad 验证);β>0 时仅表达变化、坐标逐位不变(b0 vs b02 coords array_equal 验证)。结论:**假设被证伪**——表达向空间邻居混合的 expr_change(+0.4~0.7) 与 local_spatial(+0.6~0.9) 增益,被 cell_state(−0.5~−1.5) 等量抵消,7 个配置无一在噪声外超过 β=0。PLAN 风险 1、2 同时兑现。按 PLAN 的停止规则(cell_state 降 >1 即停、β=0.1 净降即放弃),提交保持 β=0。 ## 验证过 / 未验证 -- 验证过:proxy 上 α∈{0,0.5,0.75,1.0,1.25,1.5}、3D vs xy、3 种子;off 对照逐位一致;vec-check 通过;seed 确定性(同 seed 重跑输出相同,rng 均来自 `np.random.default_rng(seed)`,cKDTree 查询确定)。-- 未验证:final 括号(E8.25+E8.75→E8.5,31 个共有型、覆盖率高得多,融合细胞占比会远高于 12.9%,效果预期更大但本节点无法测);α 在 final 上的最优值可能不同(proxy 峰值 1.0 与节点 10 独立分支一致,取 1.0 不另调)。-- 生物学知识来源:仅方法卡/父节点的坐标系约定(z 为离散切片轴、procrustes 保 z、各阶段自己的帧),未引入新的外部先验。+- 验证过:β=0 逐位一致 + vec-check ok;β∈{0.1,0.2,0.3,0.5}×{plain,varfix} 网格(seed0,A 半,7 次查分);运行 ~2-5s、内存不变。+- 未验证:β>0 的多种子(无配置超噪声,不值得花额度);final 视图(31 共有型、融合覆盖率更高,β 混合的作用细胞更多,cell_state 损失可能同比放大,方向结论预期不变);k>1 邻居均值混合(同属均值压缩,预期同样伤 cell_state)。+- 生物学知识来源:无新增外部知识;仅用 view 内输入数据。external/mosta 未使用。 -## 下一步+## 对树的意义 -- 表达侧改进(cell_state 66.2 / expression_change 64.1 之外无杠杆;local_spatial 已 56):如 external/mosta_e95_v0 引导的密度加权或型内表达平滑。-- 节点 10(非分层底座,rank3 60.13)与本节点(分层底座,均值 59.85)可比较:分层抽样本身对 local_spatial 无增益(54.0 vs 54.1),融合才是有效部件;后续 improve 可直接在任一底座上叠表达侧机制。+表达侧"向空间邻居混合"与坐标侧 NN 融合不同:坐标融合恢复局部连续性是纯增益(节点 10/12 各 +2.6/+2.9),表达混合在 E8.75 参考分布下是零和(评分器的 cell_state/mmd 对"不在真实流形上的中间表达谱"惩罚与 DE 方向增益等量)。下一步最值得试的是 external/mosta_e95_v0 引导的表达侧改动(节点 12 next_suggestions),或在 final 括号上直接复用当前 α=1.0 底座(31 共有型 vs proxy 5 个,融合覆盖率 12.9%→更高,local_spatial 增益可能放大)。diff --git a/solution/nn_fuse.py b/solution/nn_fuse.pyindex 0d2bae1..bbe9388 100644--- a/solution/nn_fuse.py+++ b/solution/nn_fuse.py@@ -27,16 +27,29 @@ NN_MIN_TYPE_CELLS = 5 def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, labels_a: np.ndarray, labels_b: np.ndarray,- ca: np.ndarray, cb: np.ndarray, alpha: float, fuse_ndim: int = 3) -> dict:- """In-place displacement of picked b-side cells toward same-type a-side NNs."""- diag = {"types": {}, "n_fused": 0, "disp_std_mean": 0.0, "nn_dist_before_mean": 0.0}+ ca: np.ndarray, cb: np.ndarray, alpha: float, fuse_ndim: int = 3,+ expr: np.ndarray | None = None, expr_a: np.ndarray | None = None,+ ia: np.ndarray | None = None, beta: float = 0.0, varfix: bool = False) -> dict:+ """In-place displacement of picked b-side cells toward same-type a-side NNs.++ If beta > 0 and expr/expr_a/ia are given, the expression of each fused+ b-side output row is blended in place toward the expression of its+ a-side nearest neighbour (the same neighbour used for the coordinate+ displacement): X_b <- (1-beta)*X_b + beta*X_a_nn.+ """+ diag = {"types": {}, "n_fused": 0, "disp_std_mean": 0.0, "nn_dist_before_mean": 0.0,+ "cos_before": 0.0, "cos_after": 0.0} if alpha == 0.0: return diag labels_a = np.asarray(labels_a).astype(str) labels_b = np.asarray(labels_b).astype(str) counts_a = {k: int(v) for k, v in zip(*np.unique(labels_a, return_counts=True))} counts_b = {k: int(v) for k, v in zip(*np.unique(labels_b, return_counts=True))}- disp_stds, nn_dists = [], []+ blend = beta > 0.0 and expr is not None and expr_a is not None and ia is not None+ # map original a-side row index -> output row index (b-side output offset = ia.size)+ a_out_row = -np.ones(len(labels_a), dtype=np.int64)+ a_out_row[np.asarray(ia, dtype=int)] = np.arange(len(ia), dtype=np.int64)+ disp_stds, nn_dists, cos_b, cos_a = [], [], [], [] for lab in sorted(set(counts_a) & set(counts_b)): if counts_a[lab] < NN_MIN_TYPE_CELLS or counts_b[lab] < NN_MIN_TYPE_CELLS: continue@@ -44,7 +57,8 @@ def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, rows_b = rows[~from_a[rows]] if rows_b.size == 0: continue- xa = ca[labels_a == lab].astype(np.float64)+ mask_a = labels_a == lab+ xa = ca[mask_a].astype(np.float64) tree = cKDTree(xa[:, :fuse_ndim]) pos = coords[rows_b].astype(np.float64) dist, idx = tree.query(pos[:, :fuse_ndim], k=1)@@ -60,14 +74,45 @@ def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, } disp_stds.append(float(np.std(disp, axis=0).mean())) nn_dists.append(float(np.mean(dist)))+ if blend:+ orig_a_idx = np.flatnonzero(mask_a)[idx]+ nb_out = a_out_row[orig_a_idx]+ have = nb_out >= 0+ if have.any():+ # neighbour expression: prefer the picked copy (identical row+ # content), fall back to the original stage-a matrix+ Xnb = np.empty((rows_b.size, expr.shape[1]), dtype=np.float32)+ Xnb[have] = expr[nb_out[have]]+ if (~have).any():+ Xnb[~have] = expr_a[orig_a_idx[~have]]+ Xb = expr[rows_b]+ cos_b.append(_cos_mean(Xb, Xnb))+ Xnew = (1.0 - beta) * Xb + beta * Xnb+ if varfix:+ mu0, sd0 = Xb.mean(0), Xb.std(0)+ mu1, sd1 = Xnew.mean(0), Xnew.std(0)+ Xnew = mu1 + (Xnew - mu1) * (sd0 / (sd1 + 1e-9))+ np.clip(Xnew, 0.0, None, out=Xnew)+ expr[rows_b] = Xnew+ cos_a.append(_cos_mean(expr[rows_b], Xnb)) if disp_stds: diag["disp_std_mean"] = float(np.mean(disp_stds)) diag["nn_dist_before_mean"] = float(np.mean(nn_dists))+ if cos_b:+ diag["cos_before"] = float(np.mean(cos_b))+ diag["cos_after"] = float(np.mean(cos_a)) return diag +def _cos_mean(X: np.ndarray, Y: np.ndarray) -> float:+ num = (X * Y).sum(1)+ den = np.linalg.norm(X, axis=1) * np.linalg.norm(Y, axis=1) + 1e-12+ return float(np.mean(num / den))++ def interpolate_fuse(stage_a, stage_b, t: float, params: dict,- cells_per_bin: int = 100, ndim: int = 2, alpha: float = 1.0, fuse_ndim: int = 3):+ cells_per_bin: int = 100, ndim: int = 2, alpha: float = 1.0, fuse_ndim: int = 3,+ beta: float = 0.0, varfix: bool = False): t = float(t) damp = float(params.get("scale_damp", 1.0)) align = str(params.get("align", "procrustes"))@@ -98,7 +143,11 @@ def interpolate_fuse(stage_a, stage_b, t: float, params: dict, np.asarray(stage_b.labels).astype(str)[ib], ]) from_a = np.concatenate([np.ones(ia.size, bool), np.zeros(ib.size, bool)])- diag = fuse_nn(coords, labels_pick, from_a, stage_a.labels, stage_b.labels, ca, cb, float(alpha), fuse_ndim=int(fuse_ndim))+ diag = fuse_nn(coords, labels_pick, from_a, stage_a.labels, stage_b.labels, ca, cb, float(alpha),+ fuse_ndim=int(fuse_ndim),+ expr=expr if beta > 0 else None,+ expr_a=as_dense(stage_a.X) if beta > 0 else None,+ ia=ia, beta=float(beta), varfix=bool(varfix)) coords = _jitter(coords, rng) coords = scale_to_rms(coords, target_rms) info.update(@@ -113,6 +162,9 @@ def interpolate_fuse(stage_a, stage_b, t: float, params: dict, frac_fused=float(diag["n_fused"] / max(expr.shape[0], 1)), disp_std_mean=diag["disp_std_mean"], nn_dist_before_mean=diag["nn_dist_before_mean"],+ expr_blend_beta=float(beta),+ cos_before=diag["cos_before"],+ cos_after=diag["cos_after"], fuse_types=diag["types"], ) return expr, coords.astype(np.float32), infodiff --git a/solution/run.py b/solution/run.pyindex 60068a7..0218580 100644--- a/solution/run.py+++ b/solution/run.py@@ -45,6 +45,8 @@ SHAPE_SHIFT_CLAMP = float(os.environ.get("SHAPE_SHIFT_CLAMP", "0.08")) NN_FUSE = os.environ.get("NN_FUSE", "1") != "0" NN_FUSE_ALPHA = float(os.environ.get("NN_FUSE_ALPHA", "1.0")) NN_FUSE_NDIM = int(os.environ.get("NN_FUSE_NDIM", "3"))+EXPR_BLEND_BETA = float(os.environ.get("EXPR_BLEND_BETA", "0.0"))+EXPR_BLEND_VARFIX = os.environ.get("EXPR_BLEND_VARFIX", "0") != "0" def main() -> None:@@ -74,12 +76,13 @@ def main() -> None: elif NN_FUSE and SPATIAL_STRATIFY: expr, coords, info = interpolate_fuse(stage_a, stage_b, t, params, cells_per_bin=CELLS_PER_BIN, ndim=BIN_NDIM,- alpha=NN_FUSE_ALPHA, fuse_ndim=NN_FUSE_NDIM)+ alpha=NN_FUSE_ALPHA, fuse_ndim=NN_FUSE_NDIM,+ beta=EXPR_BLEND_BETA, varfix=EXPR_BLEND_VARFIX) elif SPATIAL_STRATIFY: expr, coords, info = interpolate_spatial(stage_a, stage_b, t, params, cells_per_bin=CELLS_PER_BIN, ndim=BIN_NDIM) else: expr, coords, info = interpolate(stage_a, stage_b, t, params)- 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", "n_remap", "frac_remap", "n_clamped", "nn_alpha", "n_fused", "frac_fused", "disp_std_mean", "nn_dist_before_mean")}+ 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", "n_remap", "frac_remap", "n_clamped", "nn_alpha", "n_fused", "frac_fused", "disp_std_mean", "nn_dist_before_mean", "expr_blend_beta", "cos_before", "cos_after")} print(json.dumps({"bracket": [a["stage"], b["stage"]], **keep}, default=float), file=sys.stderr) if os.environ.get("SHAPE_DIAG"): print(json.dumps(info.get("shape_types", {}), default=float), file=sys.stderr)
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k007 | Interval staging and held-out-window filtering of external data | notes/official/来件/virtualembryo.ai/rules.md |
| k026 | Canonicalise predicted 3D coordinates before submission | notes/pitfalls/04_scorer_invariance.md |
| k027 | Joint expression-geometry generation with relative geometry | notes/competition/03_solution_landscape.md |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 在 nn_fuse.py 的型内 NN 坐标融合中新增表达 β 混合(被融合 b 细胞表达向其 a 侧同型最近邻做 (1−β)X_b+βX_a,含 varfix 方差回充变体),并用 EXPR_BLEND_BETA/EXPR_BLEND_VARFIX 环境变量接线到 run.py;proxy 网格 7 次查分后无一配置超噪声,最终提交默认 β=0,输出与父节点 12 逐位一致。 |
|---|---|
| 各组分数的变化 | cell_state:噪声内(+0.00,66.95 不变;β>0 时会降到 64.67~65.63) expression_change:噪声内(+0.00,64.37 不变,因提交 β=0;β>0 时曾升到 64.80 但被抵消) local_spatial:噪声内(+0.00,56.83 不变) shape_scale:噪声内(+0.00,54.49 不变) |
| family_id | T2HI-01 |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 2 次:bash 1、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 11,691 · 输出 952 · 思考 307 |
| 任务(第一行) | 分析节点 n13 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/analyst.jsonl 6 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 20 |
| 工具调用 | 共 27 次:bash 15、edit 11、write 1 |
| 用时 | 8 分 |
| token 数 | 输入 50,763 · 输出 9,844 · 思考 5,483 |
| 任务(第一行) | 按计划修改程序:型内NN空间融合后同步表达混合(b细胞向a侧最近邻表达β混合) |
| 最后的回答(摘录) | **做了什么**:按 PLAN(T2HI-01)在节点 12 的型内 NN 坐标融合里新增表达 β 混合——被融合的 b 细胞表达向其 a 侧同型最近邻做 (1−β)X_b+βX_a 混合(逐细胞、位置依赖),另加方差回充变体(varfix)。β=0 为关闭对照,已验证与父节点输出逐位一致。
**查分结果**(7 次,proxy seed0 A 半):β∈{0.1,0.2,0.3,0.5}×{plain,varfix} 全部 ≤ 对照+0.03(噪声内)。机制确实生效(cos 0.379→0.593;expression_change 64.07→64.80、local_spatial 56.26→57.14),但 cell_state 66.17→64.67 等量下降,净分为零和——假设被证伪。**提交默认 β=0**(保住父节点 60.66 的性能),METHOD.md 完整记录阴性结果与网格。
**下一步最值得试**:表达侧"向邻居混合"这条路已封死;建议转向 external/mosta_e95_v0 引导的表达改动(节点 12 的建议),或直接把当前 α=1.0 底座放到 final 括号(31 共有型 vs proxy 5 个,融合覆盖率高得多,local_spatial 增益可能放大)。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/engineer.jsonl 164 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 1 分 |
| token 数 | 输入 11,415 · 输出 884 · 思考 3,535 |
| 任务(第一行) | 为节点 n13(改进,父节点 n12)写改进计划 PLAN.json |
| 最后的回答(摘录) | {
"name": "型内NN空间融合后同步表达混合(b细胞向a侧最近邻表达β混合)",
"motivation": "父节点12的local_spatial已达56.83(+2.86),但expression_change停在64.37、cell_state 66.95自mix基线以来未动(X逐位未改)。shape_scale 54.49最弱但坐标侧三假设已耗尽(ANALYSIS明确不建议再投坐标形变)。k027指出表达与几何不应独立生成——当前管线坐标做了型内NN融合,表达却完全不动,表达-空间对应断裂。expression_change 64.37是唯一有明确杠杆且未试过的方向。",
"approach": "在nn_fuse.py的空间融合步骤中,已为每个b细胞找到a侧同型最近邻索引(cKDTree query返回)。新增表达混合:对被融合的b细胞,X_b_new = (1−β)·X_b + β·X_a_neighbor,β∈{0, 0.1, 0.2, 0.3, 0.5}网格,用vec-score在proxy上快筛。β=0为关闭对照(输出与父节点逐位一致)。仅作用于共有型中被空间融合的b细胞(同n_fused集合),非共有型和a侧细胞X不动。基因维度不变、稀疏性可能略降(β混合后原零位可能变非零),若写盘格式要求稀疏则对|X|<1e-6截断为0。单输入阶段退路:b is None时不融合、不混合,与父节点相同。实现约15行改动(在interpolate_fuse内,query返回的邻居索引直接用于X混合)。30分钟内可完成网格+3种子确认。",
"expected_groups": ["expression_change"],
"risks": "1) β混合可能降低细胞间表达离散度,反而伤害cell_state(型内变异被压缩)——Engineer应同时监控cell_state,若降>1分则停止;2) 表达混合可能让expression_change也降(如果评分器期望保留完整的两阶段表达差异而非中间态)——β=0.1先试,若降则放弃;3) 稀疏→稠密转换的内存/格式问题——先检查write_t2是否接受稠密矩阵。",
"family_id": "T2HI-01",
"mechanism": "被空间融合的b细胞,其表达向同一a侧同型最近邻做β比例线性混合,使表达-空间对应一致(坐标靠近a侧,表达也适度靠近),逐细胞、位置依赖、型内进行。",
"vs_constant_shift": "常数位移是每型加同一个向量t·(mean_b−mean_a),所有同型细胞获得相同表达调整。本方案中每个b细胞混合的是其空间最近邻(不同细胞→不同邻居→不同调整方向和幅度),且仅限被空间融合的b细胞子集,调整量取决于该细胞与特定邻居的表达差,不是型级统计量。",
"mechanism_evidence": "Engineer应记录:1) 混合前后被融合b细胞的表达cosine相似度变化(应升高);2) 型内表达方差变化(应略降但不崩塌);3) 四组分各自变化——预期expression_change升、cell_state持平或微降、local_spatial/shape_scale不变(坐标未动);4) 不同β下expression_change的响应曲线应非单调(存在最优β>0)。",
"mechanism_off_control": "EXPR_BLEND_BETA=0(或NN_FUSE=0)时跳过表达混合步骤,输出X与父节点逐位一致(array_equal),坐标也一致(空间融合不受影响)。预期差别:β=0时四组分与父节点完全相同;β>0时仅expression_change和可能的cell_state变化,local_spatial/shape_scale不变。"
} |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/researcher.jsonl 4 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/researcher.stderr |
审查员
| 角色 | 审查员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 9 |
| 工具调用 | 共 12 次:bash 9、read 2、write 1 |
| 用时 | 1 分 |
| token 数 | 输入 26,577 · 输出 1,420 · 思考 2,897 |
| 任务(第一行) | 审查节点 n13 的程序是否越界读取、写死目标、钻评分器漏洞 |
| 最后的回答(摘录) | REVIEW.json written |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/reviewer.jsonl 124 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/13/reviewer.stderr |