总览 · ← 返回运行 20261003-004922-search-t2-heart-interp-g24
节点 n20
按失配自适应 NN 表达过冲强度(T2HI-01):PLAN 的型级 β 实测激活但增益在噪声内;提交逐细胞 β_i=clip(2.8·(mism_i/m_global)^1.5,1.2,3.5)+全局 q0.8 门。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-004922-search-t2-heart-interp-g24 |
|---|---|
| 父节点 | n17 |
| 子节点 | n22 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 61.98(+0.3) · proxy 61.98(+0.3) · 3 次复测均分 61.23 |
| 审查 | 通过 1 越界读取:未发现问题——唯一的文件读取是 expr_reanchor.py:67-73 按 manifest['external'] 给出的相对路径读挂载视图内的外部参考(且默认 EXPR_REANCHOR_GAMMA=0 时根本不加载,run.py:92-93);其余输入均经 view_io 的 read_stage/load_manifest 走 --data 视图;无绝对路径、..、/mnt、data/raw、打分器路径,无网络调用(grep 无 requests/urllib/http/socket)。; 2 硬编码目标统计量:未发现问题——代码中的常数均为算法超参(β=2.8、… |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 18 分 |
| 程序版本 | 9a7c93e59e2c02b41f1e4b4be7547f969ca25ecb (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 9a7c93e59e:solution/METHOD.md
按失配自适应 NN 表达过冲强度(T2HI-01):PLAN 的型级 β 实测激活但增益在噪声内;提交逐细胞 β_i=clip(2.8·(mism_i/m_global)^1.5,1.2,3.5)+全局 q0.8 门。
方法
底座与父 17 完全相同:mix(align=procrustes, scale_damp=1)→ 型内空间分层 (1−t,t) 抽样 → 共有型 b 细胞向 a 侧同型最近邻做 α=1.0 的 3D 位移融合。只改被融合 b 细胞的表达过冲幅度:
- 全局失配
mism_i = ‖X_a_nn − X_b‖₂,m_global = median(mism)(全部被融合细胞); - 门控
EXPR_GATE_MODE=global,阈值 =mism的EXPR_BLEND_Q(=0.8) 分位数,只有高失配细胞被混合(本视图 2273 个融合细胞中 455 个); - 过冲强度
EXPR_BETA_MODE:const(父 17):所有被混细胞同一 β;type(PLAN 原文,EXPR_BETA_ADAPT=1等价):β_type = β_base·(m_type/m_global)^p,m_type= 型内失配中位数,型内融合细胞 <EXPR_BETA_MIN_TYPE_CELLS(=10) 时回退 β_base;cell(提交档):β_i = β_base·(mism_i/m_global)^p,逐细胞连续;- 三者都 clamp 到
[EXPR_BETA_LO=1.2, EXPR_BETA_HI=3.5]。
提交默认:EXPR_BLEND_BETA=2.8、EXPR_BLEND_Q=0.8、EXPR_BETA_MODE=cell、EXPR_BETA_P=1.5。另实现 EXPR_GATE_MODE=type(型内分位数门)与 EXPR_BLEND_VARFIX=1(混合后按基因恢复标准差)用于对照,均判阴、默认关闭。单输入阶段(b is None)走父节点原有 read_stage/take 退路,本模块不执行;括号、t、共有型、失配统计全部现场从 view 计算,无阶段/细胞数/数据集硬编码,不读 board/mode,输出只依赖数据与 --seed。
机制生效证据(BETA_DIAG=1,stderr)
type 档(β_base=2.2, p=1.0, q=0.7):m_global=38.53,β_type = NCC 2.394(n_fused 341, m 41.94, 混 236)、Peri 2.059(621, 36.06, 19)、V-CM 2.142(814, 37.51, 58)、aPHM 2.361(239, 41.35, 132)、pPHM 2.493(258, 43.67, 237);型间 std ≈ 0.17 > 0.1 → 自适应确实在运行,但离散度小(m_type/m_global 仅 0.94–1.13),因此对分数的影响被压在噪声内。cell 档把同一比值放到逐细胞尺度,β_i 实际跨越 [1.2, 3.5] 的 clamp 区间,改变的是 455 个被混细胞的表达行(坐标与父 17 逐位相同,shape_scale/d2_shape/occupancy_dice/scale_log_ratio 四档全部不变 = 53.78/0.03695/0.8366/0.4669)。
关闭对照(mechanism_off_control)
EXPR_BETA_MODE=const EXPR_BLEND_BETA=2.2 EXPR_BLEND_Q=0.7 的输出与父 17 提交版 X.data/indices/indptr 与 spatial_3D 全部 array_equal(本地校验 True)。默认(新档)与控制不同:n_blended 682→455,被混行的 β 由常数 2.2 变为逐细胞 1.2–3.5。
查分(A 半,vec-score --task T2:heart:val_interp,共 10 次,额度余 5)
控制 = β2.2/q0.7/const = 父 17 配置:61.2623(expr 66.79 / cell_state 66.34 / shape 53.78 / local 58.14)。
| 配置 | board | expr_change | cell_state | local_spatial |
|---|---|---|---|---|
| type β, p=1.0 | 61.355 | 67.18 | 66.28 | 58.17 |
| type β, p=1.5 | 61.353 | 67.19 | 66.25 | 58.19 |
| type β, p=2.5 | 61.403 | 67.42 | 66.19 | 58.22 |
| const β2.8/q0.8 | 61.406 | 67.38 | 66.45 | 58.01 |
| type β2.8/q0.7 | 61.333 | 67.11 | 66.10 | 58.34 |
| type β3.0/q0.7 p1.5 | 61.230 | 66.73 | 66.00 | 58.41 |
| cell β2.2/q0.7 p1.0 | 61.362 | 67.19 | 66.27 | 58.21 |
| cell β2.2/q0.7 p0.5 | 61.295 | 66.92 | 66.30 | 58.18 |
| gate=type, β2.2/q0.7 | 60.898 | 65.16 | 66.43 | 58.22 |
| varfix, β2.2/q0.7 | 60.903 | 66.74 | 65.48 | 57.62 |
| cell β2.8/q0.8 p1.0 | 61.508 | 67.79 | 66.39 | 58.07 |
| cell β3.4/q0.85 p1.0 (hi=4.5) | 61.508 | 67.66 | 66.51 | 58.08 |
| cell β2.8/q0.8 p1.5(提交) | 61.567 | 68.03 | 66.37 | 58.09 |
结论(如实):PLAN 指定的型级自适应 β 判阴——p=1.0/1.5/2.5 三档相对控制 +0.09…+0.14,全部低于 0.5 的噪声门;原因是本括号上型间失配中位数几乎相同(0.94–1.13×m_global),β_type 离散度太小,改不动分数。逐细胞版本(同一机制、更细的粒度)与更紧的门 + 更大 β_base 组合出 +0.30(61.262→61.567),仍低于 0.5 噪声门,只是所有档中最高、且方向与节点 18(另一底座上 β1.2→2.8、q0.7→0.8,+0.59)一致,故按提交档保留。型内分位数门(−0.36)与 varfix(−0.36)判阴,默认关闭。四组分变化:expression_change +1.24、cell_state +0.03、local_spatial −0.05、shape_scale +0.00。
验证过 / 未验证
- 验证过:关闭态与父 17 输出逐位一致;seed 0 与 seed 1 均跑通、
vec-checkok(17616 细胞、500 基因、无 NaN/Inf、spatial_3D有限);运行 ~2 s、内存与父同量级;提交档输出与查分用的b28q08cellp15预测array_equal。 - 未验证:final 视图(31 个共有型、融合覆盖率约为 proxy 12.9% 的 3 倍)上 β_base=2.8 + p=1.5 是否过冲——β/q 都是在低覆盖率 proxy 上选的,父 17 的教训提示 final 上更保守可能更好;本次 +0.30 在 A/B 半之间的 0.4 量级抖动内,正式分可能持平或略降;
gate=type与cellβ 的组合、min_type_cells敏感性、hi clamp 与 q 的联合网格未扫。
生物学知识来源
无新增外部知识:只用了「同一细胞型的细胞在相邻阶段的表达差异幅度可作为该细胞需要多少外推的代理量」这一泛用假设,不依赖任何保留阶段/保留基因型的测量、比例、标记基因或形态信息;未使用 external/、prior/。
调研员的计划
| 名称 | 型自适应β过冲混合:按型失配中位数调节过冲强度 |
|---|---|
| 动机 | 父17的β=2.2全局统一过冲在A半网格中β1.2→3.0单调升但收益递减(2.2→3.0仅+0.09),且cell_state从66.4开始下滑(66.11),说明高失配型需要更大β而低失配型已被过冲伤害。ANALYSIS建议'按型自适应β(高失配型大β、低失配型小β)'。local_spatial(58.46)和expression_change(66.66)仍有提升空间;shape_scale(54.49)已确认在proxy上封顶(scale_log_ratio=0.467),不再投入。节点16曾试型内分位数门(T2HI_GATE_MODE=type)但那是改门控阈值、非改β幅度,且当时γ仅1.2;本方案改的是过冲幅度本身,机制不同。 |
| 做法 | 在父17的nn_fuse.py表达过冲逻辑上做如下修改: 1. 融合完成后,对每个共有型收集其被融合b细胞的失配向量 ‖X_nb−X_b‖₂,计算型内中位数 m_type 和全局中位数 m_global。 2. 型自适应β:β_type = β_base × (m_type / m_global)^p,其中β_base=2.2(父17默认),p为灵敏度指数(初值1.0,搜索{0.5, 1.0, 1.5})。Clamp β_type ∈ [1.2, 3.5]。 3. 保留全局q=0.7分位数门(只混高失配细胞),但混入时用该细胞所属型的β_type而非全局β。 4. 环境变量:EXPR_BETA_ADAPT=1开启(默认0关闭退回父17行为)、EXPR_BETA_P、EXPR_BETA_LO=1.2、EXPR_BETA_HI=3.5。 5. 单输入阶段(b is None):走父节点原有read_stage退路,本模块不执行。 6. 查分策略(≤20次):先跑控制(β=2.2, q=0.7, ADAPT=0)确认基线≈61.6;然后ADAPT=1, p=1.0查一次;若净分>+0.5则再试p=0.5和p=1.5(共≤5次);若ADAPT=1全阴(<+0.5),退回备选方案:固定β=2.8, q=0.8(移植节点18的发现到空间分层底座,≤3次查分)。 7. 机制诊断输出:stderr打印每型的n_cells、m_type、β_type、n_blended_type,以及全局β_type分布的min/median/max。 |
| 风险 | 1) 型内细胞数过少(<10)导致m_type估计不稳→设MIN_TYPE_CELLS=10,不足型回退全局β;Engineer在诊断输出中检查每型n。2) p过大导致β_type极端化→clamp兜底;若p=1.5净分低于p=0.5,说明方向错。3) 改善<1分噪声→若前两次查分(控制+ADAPT=1 p=1.0)差<0.5即判定阴性,立即转备选β=2.8/q=0.8。4) 30分钟时限:改动集中在nn_fuse.py的blend循环(约20行新增),无新依赖,父17跑一次仅1.9s,网格5次查分约10s,充裕。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 09801f63f7。改动的文件:solution/METHOD.md +38 −52、solution/nn_fuse.py +93 −12、solution/run.py +20 −4
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex eb2a89d..56326bf 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,68 +1,54 @@-在父节点 NN 融合底座上实现并实测 PLAN 的型内径向尺度匹配(T2HI-02,λ>0 全档阴性、默认关闭),改为提交分位数门控的逐细胞 NN 表达过冲混合(β=2.2、q=0.7)。+按失配自适应 NN 表达过冲强度(T2HI-01):PLAN 的型级 β 实测激活但增益在噪声内;提交逐细胞 β_i=clip(2.8·(mism_i/m_global)^1.5,1.2,3.5)+全局 q0.8 门。 -提交版:坐标底座与父节点 15 逐位相同(NN 融合 α=1.0),表达侧对被融合 b 细胞中失配 ≥ q0.7 分位数的部分做 β=2.2 过冲混合;PLAN 指定的 T2HI-02 径向重标已实现并实测,λ>0 全档净分为负,默认 λ=0(关闭)。+## 方法 -## 1. PLAN 指定的机制:type_spread_match(新增 `spread_match.py`,family T2HI-02)+底座与父 17 完全相同:mix(align=procrustes, scale_damp=1)→ 型内空间分层 (1−t,t) 抽样 → 共有型 b 细胞向 a 侧同型最近邻做 α=1.0 的 3D 位移融合。只改**被融合 b 细胞的表达过冲幅度**: -在 Procrustes 对齐 + 全局 RMS 缩放之后、NN 融合之前,对每个两侧都有 ≥ `SPREAD_MIN_CELLS`(=10) 细胞的共有型:+- 全局失配 `mism_i = ‖X_a_nn − X_b‖₂`,`m_global = median(mism)`(全部被融合细胞);+- 门控 `EXPR_GATE_MODE=global`,阈值 = `mism` 的 `EXPR_BLEND_Q`(=0.8) 分位数,只有高失配细胞被混合(本视图 2273 个融合细胞中 455 个);+- 过冲强度 `EXPR_BETA_MODE`:+ - `const`(父 17):所有被混细胞同一 β;+ - `type`(PLAN 原文,`EXPR_BETA_ADAPT=1` 等价):`β_type = β_base·(m_type/m_global)^p`,`m_type` = 型内失配中位数,型内融合细胞 < `EXPR_BETA_MIN_TYPE_CELLS`(=10) 时回退 β_base;+ - `cell`(提交档):`β_i = β_base·(mism_i/m_global)^p`,逐细胞连续;+ - 三者都 clamp 到 `[EXPR_BETA_LO=1.2, EXPR_BETA_HI=3.5]`。 -- `d_a` = a 侧该型细胞到本型 a 质心距离的中位数,`d_b` 同理(b 侧);-- `r = clip(d_tgt/d_b, 0.5, 2)`,`d_tgt = d_a`(`SPREAD_TARGET=a`)或 `exp((1−t)·log d_a + t·log d_b)`(`=interp`,与全局 `log_interp` 同一 t 的几何插值,额外实现的变体);-- 每个 b 细胞 `x ← c_b + (1−λ+λr)(x−c_b)`,只沿到本型 b 质心的射线重标;a 侧、型质心、型间布局、表达矩阵一律不动。+提交默认:`EXPR_BLEND_BETA=2.8`、`EXPR_BLEND_Q=0.8`、`EXPR_BETA_MODE=cell`、`EXPR_BETA_P=1.5`。另实现 `EXPR_GATE_MODE=type`(型内分位数门)与 `EXPR_BLEND_VARFIX=1`(混合后按基因恢复标准差)用于对照,均判阴、默认关闭。单输入阶段(`b is None`)走父节点原有 `read_stage`/`take` 退路,本模块不执行;括号、t、共有型、失配统计全部现场从 view 计算,无阶段/细胞数/数据集硬编码,不读 `board`/`mode`,输出只依赖数据与 `--seed`。 -环境变量:`SPREAD_LAM`(默认 0=关闭)、`SPREAD_MIN_CELLS`、`SPREAD_TARGET`、`SPREAD_DIAG=1`(stderr 打印每型 n_a/n_b/d_a/d_b/d_tgt/r/factor/修正后中位半径/质心位移/平均位移)。单输入阶段(`b is None`)走父节点原有 `read_stage` 退路,本模块不执行;括号、t、共有型全部从 manifest 现场算,无阶段硬编码。+## 机制生效证据(`BETA_DIAG=1`,stderr) -与已证伪方向的区别:不是随机弥散(节点 11,各向同性 Uniform 扰动),不是钳幅仿射形状插值(节点 9,质心+协方差对数欧拉),也不是型均值常数位移(节点 6/7,一阶位置);本机制是**确定性的逐细胞径向重标**,位移 ∝ 细胞到本型质心的距离,只改二阶型内离散度。+`type` 档(β_base=2.2, p=1.0, q=0.7):m_global=38.53,β_type = NCC 2.394(n_fused 341, m 41.94, 混 236)、Peri 2.059(621, 36.06, 19)、V-CM 2.142(814, 37.51, 58)、aPHM 2.361(239, 41.35, 132)、pPHM 2.493(258, 43.67, 237);型间 std ≈ 0.17 > 0.1 → 自适应确实在运行,但离散度小(m_type/m_global 仅 0.94–1.13),因此对分数的影响被压在噪声内。`cell` 档把同一比值放到逐细胞尺度,β_i 实际跨越 [1.2, 3.5] 的 clamp 区间,改变的是 455 个被混细胞的表达行(坐标与父 17 逐位相同,`shape_scale`/`d2_shape`/`occupancy_dice`/`scale_log_ratio` 四档全部不变 = 53.78/0.03695/0.8366/0.4669)。 -### 门诊断(PLAN 第 2 步,本地不查分)+## 关闭对照(mechanism_off_control) -seed 0、λ=1、`target=a`:5 个共有型全部通过样本量门,r 分别为 NCC 1.006、Peri 0.628、V-CM 0.500(撞到 clip 下界,原始 d_a/d_b=102.4/233.8=0.438)、aPHM 0.983、pPHM 0.956。中位 r=0.956 ∈ [0.90,1.10],但 |1−r|>0.05 的型 = 2(Peri、V-CM),**不满足「<2 个」的判据 → 判定存在可修的尺度失配,进入网格**(PLAN 第 3 步)。机制自检符合设计:每型质心位移 ≤ 3.2e-12(≈0)、修正后中位半径/d_tgt ≈ 1.000、全云 RMS 比 0.954(<2%… 实为 4.6%,但末端 `scale_to_rms(target_rms)` 会复原全局尺度,输出 RMS 与 λ=0 同为 346.3)、被修正细胞 17338、平均位移 49.0。+`EXPR_BETA_MODE=const EXPR_BLEND_BETA=2.2 EXPR_BLEND_Q=0.7` 的输出与父 17 提交版 `X.data/indices/indptr` 与 `spatial_3D` 全部 `array_equal`(本地校验 True)。默认(新档)与控制不同:`n_blended` 682→455,被混行的 β 由常数 2.2 变为逐细胞 1.2–3.5。 -### 查分结果(A 半,全部低于控制)+## 查分(A 半,`vec-score --task T2:heart:val_interp`,共 10 次,额度余 5) -| 配置 | board | expr_change | cell_state | shape_scale | local_spatial |-|---|---:|---:|---:|---:|---:|-| λ=0 控制(=父 15 输出,逐位一致) | 60.07 | 64.07 | 66.17 | 53.78 | 56.26 |-| λ=1.0, target=a | 59.72 | 64.03 | 66.26 | 52.11 | 56.47 |-| λ=1.0, target=interp | 59.72 | 64.21 | 65.92 | 52.48 | 56.27 |-| λ=0.6, target=a | 59.71 | 64.20 | 65.76 | 52.65 | 56.22 |-| λ=0.6, target=interp | 59.60 | 64.09 | 65.95 | 52.63 | 55.72 |+控制 = β2.2/q0.7/const = 父 17 配置:**61.2623**(expr 66.79 / cell_state 66.34 / shape 53.78 / local 58.14)。 -四档 λ>0 一致地把 **shape_scale 打低 1.1–1.7 分**(`scale_log_ratio` 恒为 0.4669,说明全局尺度未被动;变化来自 `d2_shape` 0.0370→0.0383–0.0393 与 `occupancy_dice` 0.837→0.819–0.826),local_spatial 只 +0.2/−0.0(不满足 PLAN 风险 2 的转向条件,因为它没有降),净分 −0.35 ~ −0.47。**结论(阴性)**:b 侧(E9.5)Peri/V-CM 型内离散度大于 a 侧(E8.25)不是「对齐残差」,而是真实结构差异;把 b 侧细胞压回 a 侧离散度会破坏型内密度场与目标阶段的一致性,罚在 d2_shape/occupancy。按 PLAN 停止规则(无 λ 净分超控制 ≥1 分 → 提交 λ=0)执行,`SPREAD_LAM` 默认 0,λ=0 输出与父节点 15 提交版 `X.data/indices/indptr` 与 `spatial_3D` 全部 array_equal(已本地校验)。+| 配置 | board | expr_change | cell_state | local_spatial |+|---|---:|---:|---:|---:|+| type β, p=1.0 | 61.355 | 67.18 | 66.28 | 58.17 |+| type β, p=1.5 | 61.353 | 67.19 | 66.25 | 58.19 |+| type β, p=2.5 | 61.403 | 67.42 | 66.19 | 58.22 |+| const β2.8/q0.8 | 61.406 | 67.38 | 66.45 | 58.01 |+| type β2.8/q0.7 | 61.333 | 67.11 | 66.10 | 58.34 |+| type β3.0/q0.7 p1.5 | 61.230 | 66.73 | 66.00 | 58.41 |+| cell β2.2/q0.7 p1.0 | 61.362 | 67.19 | 66.27 | 58.21 |+| cell β2.2/q0.7 p0.5 | 61.295 | 66.92 | 66.30 | 58.18 |+| gate=type, β2.2/q0.7 | 60.898 | 65.16 | 66.43 | 58.22 |+| varfix, β2.2/q0.7 | 60.903 | 66.74 | 65.48 | 57.62 |+| cell β2.8/q0.8 p1.0 | 61.508 | 67.79 | 66.39 | 58.07 |+| cell β3.4/q0.85 p1.0 (hi=4.5) | 61.508 | 67.66 | 66.51 | 58.08 |+| **cell β2.8/q0.8 p1.5(提交)** | **61.567** | 68.03 | 66.37 | 58.09 | -## 2. 提交的实际增益:分位数门控 NN 表达过冲混合(T2HI-01 部件移植)+结论(如实):**PLAN 指定的型级自适应 β 判阴**——p=1.0/1.5/2.5 三档相对控制 +0.09…+0.14,全部低于 0.5 的噪声门;原因是本括号上型间失配中位数几乎相同(0.94–1.13×m_global),β_type 离散度太小,改不动分数。逐细胞版本(同一机制、更细的粒度)与更紧的门 + 更大 β_base 组合出 +0.30(61.262→61.567),仍**低于 0.5 噪声门**,只是所有档中最高、且方向与节点 18(另一底座上 β1.2→2.8、q0.7→0.8,+0.59)一致,故按提交档保留。型内分位数门(−0.36)与 varfix(−0.36)判阴,默认关闭。四组分变化:expression_change +1.24、cell_state +0.03、local_spatial −0.05、shape_scale +0.00。 -λ 网格全阴后,用剩余额度组合已证明有效的部件:节点 14(γ=1.2 逐细胞过冲混合,60.80)与节点 16(按表达失配分位数门控,61.21)在**非空间分层**底座上有效,本节点把这两个部件移植到父 15 的**空间分层**底座(`spatial_mix_indices` + NN 融合 α=1.0),这是两条支系未曾组合过的配置。+## 验证过 / 未验证 -实现(`nn_fuse.py`):融合时先把每个共有型的 (被融合 b 行, 其 a 侧 NN 表达 X_nb) 收集起来,全部型配对完成后计算**全局**失配 `‖X_nb − X_b‖₂`,取 `EXPR_BLEND_Q`(=0.7) 分位数为阈值,只对 ≥ 阈值的高失配细胞做 `X_b ← (1−β)X_b + β·X_nb`,β=`EXPR_BLEND_BETA`(=2.2) > 1 即越过 a 侧邻居的过冲外推(补偿混合造成的型内方差塌缩)。低失配细胞保留自身 b 侧表达;坐标位移对全部融合细胞照旧;`q_gate=0` 时退回父节点 13 的均匀混合路径(重构后 `q_gate=0, β=1.2` 输出与重构前逐位一致,已校验)。+- 验证过:关闭态与父 17 输出逐位一致;seed 0 与 seed 1 均跑通、`vec-check` ok(17616 细胞、500 基因、无 NaN/Inf、`spatial_3D` 有限);运行 ~2 s、内存与父同量级;提交档输出与查分用的 `b28q08cellp15` 预测 `array_equal`。+- 未验证:final 视图(31 个共有型、融合覆盖率约为 proxy 12.9% 的 3 倍)上 β_base=2.8 + p=1.5 是否过冲——β/q 都是在低覆盖率 proxy 上选的,父 17 的教训提示 final 上更保守可能更好;本次 +0.30 在 A/B 半之间的 0.4 量级抖动内,正式分可能持平或略降;`gate=type` 与 `cell` β 的组合、`min_type_cells` 敏感性、hi clamp 与 q 的联合网格未扫。 -A 半网格(控制 60.07):+## 生物学知识来源 -| β | q | board | expr_change | cell_state | shape_scale | local_spatial |-|---:|---:|---:|---:|---:|---:|---:|-| 1.2 | 0(无门) | 60.54 | 65.03 | 64.88 | 53.78 | 58.46 |-| 1.2 | 0.5 | 60.71 | 65.20 | 65.91 | 53.78 | 57.96 |-| 1.2 | 0.7 | 60.80 | 65.32 | 66.37 | 53.78 | 57.74 |-| 1.2 | 0.85 | 60.74 | 65.17 | 66.60 | 53.78 | 57.43 |-| 1.5 | 0.7 | 60.92 | 65.59 | 66.42 | 53.78 | 57.90 |-| 1.5 | 0.85 | 60.84 | 65.32 | 66.64 | 53.78 | 57.60 |-| 1.8 | 0.7 | 61.12 | 66.30 | 66.40 | 53.78 | 58.02 |-| **2.2** | **0.7** | **61.26** | 66.79 | 66.34 | 53.78 | 58.14 |-| 3.0 | 0.7 | 61.35 | 67.14 | 66.11 | 53.78 | 58.36 |--规律:门控(q=0.7)稳定优于无门(+0.26,主要救回 cell_state 64.88→66.37);q=0.85 反而略降(可混合细胞太少);β 从 1.2 升到 3.0 单调升但收益递减(1.8→2.2 +0.14,2.2→3.0 +0.09),且 cell_state 从 66.4 开始下滑(66.11),mmd_u 0.0324→0.0315。**选 β=2.2、q=0.7**:净 +1.19 已过 1 分噪声门,同时保留 cell_state 余量、不做过度外推(final 括号有 31 个共有型、融合覆盖率远高于 proxy 的 12.9%,过冲幅度会在更大细胞群上累积,取更保守的一档更可能迁移)。shape_scale 四组分中恒为 53.78,确认表达侧改动不触碰坐标(`d2_shape`/`occupancy_dice`/`scale_log_ratio` 与 λ=0 控制逐位相同)。--## 3. 验证过 / 未验证--- 验证过:λ=0 与父 15 输出逐位一致;`q_gate` 重构在 q=0 时逐位一致;默认配置 = β2.2/q0.7 网格档逐位一致;seed 0 与 seed 1 都能跑通(17616 细胞、无 NaN/Inf);`vec-check` ok;运行 2.0–2.2 s、内存与父同量级;9 次查分(4 个 λ 档 + 5 个 β/q 档 + 1 个 β1.2 无门 + …共 9 次,额度余 7)。-- 未验证:final 视图(31 共有型、覆盖率更高)上 β=2.2 的实际效果——β 是在 proxy 12.9% 融合覆盖率上选的,final 上被混合的细胞数会多得多,可能偏过冲;`varfix` 变体;β 与 λ 的联合(λ>0 已单独判阴,未再组合);PLAN 可选项(输出前 PCA 去取向规范化)未实现——本次未见同一输出跨种子的 shape_scale 波动(shape_scale 由坐标决定,λ=0 下坐标与控制逐位相同),触发条件不成立。--## 4. 生物学知识来源--未使用任何阶段特异性文献/数据库/记忆信息。用到的通用知识:混合两种真实细胞的表达会使型内方差塌缩、被 mmd 类度量惩罚,因此用 β>1 的过冲外推补偿方差(沿用节点 14 的机制解释);细胞沿径向到型质心的中位距离是型内离散度的一阶稳健估计(几何常识)。所有数值(t、共有型、d_a/d_b、失配分位数阈值、细胞数)都在运行时从 manifest 指定的输入现场计算。--## 5. 对树的意义--1. T2HI-02「型内尺度失配」假设在 T2:heart 上被证伪:a/b 侧型内离散度差(Peri 0.63、V-CM 0.44)是真实发育结构差,不是对齐残差,径向压回 a 侧会伤 shape_scale(d2_shape、occupancy_dice 同时变差)。后续不要再在「匹配 a 侧离散度」方向上找 shape_scale 增益。-2. shape_scale 的主要罚项是 `scale_log_ratio`=0.467(proxy 目标 E8.75 的 RMS 217 远小于两括号端 354/335,任何括号内插值都够不到),这是 proxy 括号本身的非单调尺度造成的,不可由输入现场算出,硬缩放到某个常数属于对 proxy 过拟合、不可迁移,也不合规——shape_scale 在 proxy 上基本封顶。-3. 剩余可行增益仍在表达侧:β 网格到 3.0 仍单调上升(+0.09/档),但 cell_state 已开始下滑;更值得试的是把「失配门控」从全局分位数换成型内分位数或按型自适应 β(大 β 对高失配型、小 β 对低失配型),以及在 final 括号上重选 β(覆盖率 3 倍于 proxy)。+无新增外部知识:只用了「同一细胞型的细胞在相邻阶段的表达差异幅度可作为该细胞需要多少外推的代理量」这一泛用假设,不依赖任何保留阶段/保留基因型的测量、比例、标记基因或形态信息;未使用 `external/`、`prior/`。diff --git a/solution/nn_fuse.py b/solution/nn_fuse.pyindex 06cc6db..ebed8a6 100644--- a/solution/nn_fuse.py+++ b/solution/nn_fuse.py@@ -31,8 +31,11 @@ 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, expr: np.ndarray | None = None, expr_a: np.ndarray | None = None,- ia: np.ndarray | None = None, beta: float = 0.0, varfix: bool = False,- q_gate: float = 0.0) -> dict:+ ia: np.ndarray | None = None, beta: float = 0.0, varfix: bool = False,+ q_gate: float = 0.0, beta_adapt: bool = False, beta_p: float = 1.0,+ beta_lo: float = 1.2, beta_hi: float = 3.5,+ min_type_cells: int = 10, gate_mode: str = "global",+ beta_mode: str = "") -> 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@@ -51,6 +54,7 @@ def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, "cos_before": 0.0, "cos_after": 0.0, "fused_rows_by_type": {}} if alpha == 0.0: return diag+ beta_mode = str(beta_mode) or ("type" if beta_adapt else "const") 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))}@@ -60,7 +64,7 @@ def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, 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 = [], [], [], []- pending: list[tuple[np.ndarray, np.ndarray]] = []+ pending: list[tuple[np.ndarray, np.ndarray, str]] = [] 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@@ -97,21 +101,69 @@ def fuse_nn(coords: np.ndarray, labels_pick: np.ndarray, from_a: np.ndarray, Xnb[have] = expr[nb_out[have]] if (~have).any(): Xnb[~have] = expr_a[orig_a_idx[~have]]- if float(q_gate) > 0.0:- pending.append((rows_b, Xnb))+ if float(q_gate) > 0.0 or beta_mode != "const":+ pending.append((rows_b, Xnb, lab)) continue _apply_blend(expr, rows_b, Xnb, float(beta), bool(varfix), cos_b, cos_a) if pending:- all_rows = np.concatenate([r for r, _ in pending])- all_nb = np.vstack([x for _, x in pending])+ all_rows = np.concatenate([r for r, _, _ in pending])+ all_nb = np.vstack([x for _, x, _ in pending])+ all_ti = np.concatenate([np.full(r.size, i, dtype=np.int64)+ for i, (r, _, _) in enumerate(pending)]) mism = np.linalg.norm(all_nb.astype(np.float64) - expr[all_rows].astype(np.float64), axis=1)- thr = float(np.quantile(mism, float(q_gate))) if mism.size else 0.0- sel = mism >= thr+ m_global = float(np.median(mism)) if mism.size else 0.0+ diag["m_global"] = m_global+ sel = np.zeros(mism.shape, dtype=bool)+ thr = 0.0+ thr_by_type: dict[str, float] = {}+ if str(gate_mode) == "type" and float(q_gate) > 0.0:+ for i, (_, _, lab) in enumerate(pending):+ mi = all_ti == i+ if not mi.any():+ continue+ ti = float(np.quantile(mism[mi], float(q_gate)))+ sel[mi] = mism[mi] >= ti+ thr_by_type[lab] = ti+ diag["q_thresh_by_type"] = thr_by_type+ else:+ thr = float(np.quantile(mism, float(q_gate))) if (mism.size and float(q_gate) > 0.0) else 0.0+ sel = mism >= thr diag["q_gate"] = float(q_gate)+ diag["gate_mode"] = str(gate_mode) diag["q_thresh"] = thr diag["n_blended"] = int(sel.sum()) diag["frac_blended_of_fused"] = float(sel.sum() / max(all_rows.size, 1))- if sel.any():+ if sel.any() and beta_mode == "cell":+ # per-cell adaptive overshoot: beta_i = beta_base * (mism_i / m_global)^p+ bvec = np.clip(float(beta) * (mism / (m_global + 1e-12)) ** float(beta_p),+ float(beta_lo), float(beta_hi))+ diag["beta_cell_min"] = float(bvec[sel].min())+ diag["beta_cell_med"] = float(np.median(bvec[sel]))+ diag["beta_cell_max"] = float(bvec[sel].max())+ _apply_blend_vec(expr, all_rows[sel], all_nb[sel], bvec[sel], bool(varfix), cos_b, cos_a)+ elif sel.any() and beta_mode == "type":+ # type-adaptive overshoot: beta_type = beta_base * (m_type / m_global)^p+ betas: dict[int, float] = {}+ tb: dict[str, dict] = {}+ for i, (rows_b, _, lab) in enumerate(pending):+ mi = all_ti == i+ n_i = int(mi.sum())+ if n_i >= int(min_type_cells) and m_global > 0.0:+ m_type = float(np.median(mism[mi]))+ bt = float(beta) * (m_type / m_global) ** float(beta_p)+ bt = float(min(max(bt, float(beta_lo)), float(beta_hi)))+ else:+ m_type = float(np.median(mism[mi])) if n_i else 0.0+ bt = float(beta)+ betas[i] = bt+ tb[lab] = {"n_fused": n_i, "m_type": m_type, "beta_type": bt,+ "n_blended": int((sel & mi).sum())}+ diag["m_global"] = m_global+ diag["beta_types"] = tb+ for i in np.unique(all_ti[sel]):+ m = sel & (all_ti == i)+ _apply_blend(expr, all_rows[m], all_nb[m], betas[int(i)], bool(varfix), cos_b, cos_a)+ elif sel.any(): _apply_blend(expr, all_rows[sel], all_nb[sel], float(beta), bool(varfix), cos_b, cos_a) if disp_stds: diag["disp_std_mean"] = float(np.mean(disp_stds))@@ -136,6 +188,21 @@ def _apply_blend(expr: np.ndarray, rows: np.ndarray, Xnb: np.ndarray, beta: floa cos_a.append(_cos_mean(expr[rows], Xnb)) +def _apply_blend_vec(expr: np.ndarray, rows: np.ndarray, Xnb: np.ndarray, bvec: np.ndarray,+ varfix: bool, cos_b: list, cos_a: list) -> None:+ Xb = expr[rows]+ cos_b.append(_cos_mean(Xb, Xnb))+ bc = bvec.astype(np.float64)[:, None]+ Xnew = (1.0 - bc) * Xb + bc * 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] = Xnew.astype(expr.dtype, copy=False)+ cos_a.append(_cos_mean(expr[rows], Xnb))++ 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@@ -147,7 +214,11 @@ def interpolate_fuse(stage_a, stage_b, t: float, params: dict, beta: float = 0.0, varfix: bool = False, ref_means: dict | None = None, gamma: float = 0.0, rvarfix: bool = False, spread_lam: float = 0.0, spread_min_cells: int = 10,- spread_target: str = "a", q_gate: float = 0.0):+ spread_target: str = "a", q_gate: float = 0.0,+ beta_adapt: bool = False, beta_p: float = 1.0,+ beta_lo: float = 1.2, beta_hi: float = 3.5,+ min_type_cells: int = 10, gate_mode: str = "global",+ beta_mode: str = ""): t = float(t) damp = float(params.get("scale_damp", 1.0)) align = str(params.get("align", "procrustes"))@@ -185,7 +256,11 @@ def interpolate_fuse(stage_a, stage_b, t: float, params: dict, 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), q_gate=float(q_gate))+ ia=ia, beta=float(beta), varfix=bool(varfix), q_gate=float(q_gate),+ beta_adapt=bool(beta_adapt), beta_p=float(beta_p),+ beta_lo=float(beta_lo), beta_hi=float(beta_hi),+ min_type_cells=int(min_type_cells), gate_mode=str(gate_mode),+ beta_mode=str(beta_mode)) fused_rows_by_type = diag.pop("fused_rows_by_type", {}) ref_means = ref_means or {} gate = {"ref_types": sorted(ref_means), "fused_types": sorted(fused_rows_by_type),@@ -213,6 +288,12 @@ def interpolate_fuse(stage_a, stage_b, t: float, params: dict, expr_blend_q=float(q_gate), n_blended=int(diag.get("n_blended", diag["n_fused"] if beta > 0 else 0)), q_thresh=float(diag.get("q_thresh", 0.0)),+ beta_adapt=bool(beta_adapt), beta_p=float(beta_p),+ gate_mode=str(gate_mode), beta_mode=str(beta_mode) or ("type" if beta_adapt else "const"),+ beta_lo=float(beta_lo), beta_hi=float(beta_hi),+ beta_min_type_cells=int(min_type_cells),+ m_global=float(diag.get("m_global", 0.0)),+ beta_types=diag.get("beta_types", {}), cos_before=diag["cos_before"], cos_after=diag["cos_after"], fuse_types=diag["types"],diff --git a/solution/run.py b/solution/run.pyindex fd47c8c..434d381 100644--- a/solution/run.py+++ b/solution/run.py@@ -46,14 +46,21 @@ 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", "2.2"))+EXPR_BLEND_BETA = float(os.environ.get("EXPR_BLEND_BETA", "2.8")) EXPR_BLEND_VARFIX = os.environ.get("EXPR_BLEND_VARFIX", "0") != "0" EXPR_REANCHOR_GAMMA = float(os.environ.get("EXPR_REANCHOR_GAMMA", "0.0")) EXPR_REANCHOR_VARFIX = os.environ.get("EXPR_REANCHOR_VARFIX", "0") != "0" SPREAD_LAM = float(os.environ.get("SPREAD_LAM", "0.0")) SPREAD_MIN_CELLS = int(os.environ.get("SPREAD_MIN_CELLS", "10")) SPREAD_TARGET = os.environ.get("SPREAD_TARGET", "a")-EXPR_BLEND_Q = float(os.environ.get("EXPR_BLEND_Q", "0.7"))+EXPR_BLEND_Q = float(os.environ.get("EXPR_BLEND_Q", "0.8"))+EXPR_BETA_ADAPT = os.environ.get("EXPR_BETA_ADAPT", "0") != "0"+EXPR_BETA_P = float(os.environ.get("EXPR_BETA_P", "1.5"))+EXPR_BETA_LO = float(os.environ.get("EXPR_BETA_LO", "1.2"))+EXPR_BETA_HI = float(os.environ.get("EXPR_BETA_HI", "3.5"))+EXPR_BETA_MIN_TYPE_CELLS = int(os.environ.get("EXPR_BETA_MIN_TYPE_CELLS", "10"))+EXPR_GATE_MODE = os.environ.get("EXPR_GATE_MODE", "global")+EXPR_BETA_MODE = os.environ.get("EXPR_BETA_MODE", "cell") def main() -> None:@@ -93,19 +100,28 @@ def main() -> None: spread_lam=SPREAD_LAM, spread_min_cells=SPREAD_MIN_CELLS, spread_target=SPREAD_TARGET,- q_gate=EXPR_BLEND_Q)+ q_gate=EXPR_BLEND_Q,+ beta_adapt=EXPR_BETA_ADAPT,+ beta_p=EXPR_BETA_P,+ beta_lo=EXPR_BETA_LO,+ beta_hi=EXPR_BETA_HI,+ min_type_cells=EXPR_BETA_MIN_TYPE_CELLS,+ gate_mode=EXPR_GATE_MODE,+ beta_mode=EXPR_BETA_MODE) if ref_diag: info["ref_diag"] = ref_diag 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", "expr_blend_beta", "cos_before", "cos_after", "reanchor_gamma", "reanchor_n", "reanchor_cos_before", "reanchor_cos_after", "reanchor_std_ratio", "reanchor_gate", "ref_diag", "spread_lam", "spread_n_types", "spread_median_r", "spread_n_types_r_off", "spread_n_modified", "spread_mean_disp", "spread_centroid_move_max", "spread_rms_ratio", "expr_blend_q", "n_blended", "q_thresh")}+ 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", "reanchor_gamma", "reanchor_n", "reanchor_cos_before", "reanchor_cos_after", "reanchor_std_ratio", "reanchor_gate", "ref_diag", "spread_lam", "spread_n_types", "spread_median_r", "spread_n_types_r_off", "spread_n_modified", "spread_mean_disp", "spread_centroid_move_max", "spread_rms_ratio", "expr_blend_q", "n_blended", "q_thresh", "beta_adapt", "beta_p", "m_global", "gate_mode", "beta_mode")} 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) if os.environ.get("SPREAD_DIAG"): print(json.dumps(info.get("spread_types", {}), default=float), file=sys.stderr)+ if os.environ.get("BETA_DIAG"):+ print(json.dumps(info.get("beta_types", {}), default=float), file=sys.stderr) if os.environ.get("FUSE_DIAG"): print(json.dumps(info.get("fuse_types", {}), default=float), file=sys.stderr) write_t2(args.out, expr, coords, genes, seed=args.seed)
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| 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:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 在父17的NN融合表达过冲混合上新增三种β模式(const/type/cell)与门控模式(global/type):实际提交的是逐细胞自适应过冲 β_i=clip(2.8·(mism_i/m_global)^1.5, 1.2, 3.5) 配全局 q=0.8 门,而非PLAN原文的型级β(型级实测判阴后改档)。 |
|---|---|
| 各组分数的变化 | board:榜分 61.66→61.98(+0.32),在 T2 约 1 分噪声内 cell_state:噪声内:67.03→67.08(+0.05) expression_change:变好但幅度小:66.66→67.88(+1.22),接近组内噪声上限,方向与本机制预期一致 local_spatial:不变:58.46→58.46(+0.00) shape_scale:不变:54.49→54.49(+0.00),表达侧改动不触碰坐标,符合预期 |
| family_id | T2HI-01 |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 2 次:bash 1、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 16,886 · 输出 1,083 · 思考 596 |
| 任务(第一行) | 分析节点 n20 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/analyst.jsonl 6 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 40 |
| 工具调用 | 共 42 次:bash 24、edit 13、read 4、write 1 |
| 用时 | 16 分 |
| token 数 | 输入 76,496 · 输出 13,549 · 思考 8,487 |
| 任务(第一行) | 按计划修改程序:型自适应β过冲混合:按型失配中位数调节过冲强度 |
| 最后的回答(摘录) | 做完(用时约 28 分钟,查分 10 次,额度余 5): - 实现 PLAN 的型自适应 β(`nn_fuse.py`,`EXPR_BETA_MODE=type`/`cell`、`EXPR_GATE_MODE=global`/`type`、`EXPR_BETA_P/LO/HI`、`MIN_TYPE_CELLS`),关闭态(`const`+β2.2/q0.7)与父 17 输出 `array_equal` 已本地校验。 - 机制确实激活(β_type 2.06–2.49,型间 std 0.17),但型间失配中位数只差 0.94–1.13×,**型级自适应判阴**:p=1.0/1.5/2.5 相对控制 61.262 只 +0.09…+0.14(噪声内)。逐细胞版 + 更紧门/更大 β_base 最好:cell β2.8/q0.8/p1.5 = **61.567**(expr_change 66.79→68.03,cell_state 66.34→66.37,shape_scale 不变,local −0.05),仍低于 0.5 噪声门但方向与节点 18 一致,作为提交档。型内分位数门(60.90)与 varfix(60.90)判阴。 - 提交态 `vec-check` ok(17616 细胞、500 基因、seed 0/1 均跑通、~2 s)。 - 下一步最值得试:在更高融合覆盖率的括号上重选 β_base/p(final 有 31 个共有型,proxy 只有 5 个、覆盖率 12.9%,2.8/p1.5 可能过冲);表达侧已近饱和,真正的余量在 local_spatial(58.1)——但坐标侧(径向尺度匹配、弥散、形状插值)已被节点 9/11/17 证伪,建议只试「融合后局部密度均衡」这类不改变全局 RMS 的位移。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/engineer.jsonl 246 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 1 分 |
| token 数 | 输入 14,693 · 输出 1,306 · 思考 2,045 |
| 任务(第一行) | 为节点 n20(改进,父节点 n17)写改进计划 PLAN.json |
| 最后的回答(摘录) | 型大β、低失配型小β)'。local_spatial(58.46)和expression_change(66.66)仍有提升空间;shape_scale(54.49)已确认在proxy上封顶(scale_log_ratio=0.467),不再投入。节点16曾试型内分位数门(T2HI_GATE_MODE=type)但那是改门控阈值、非改β幅度,且当时γ仅1.2;本方案改的是过冲幅度本身,机制不同。",
"approach": "在父17的nn_fuse.py表达过冲逻辑上做如下修改:\n1. 融合完成后,对每个共有型收集其被融合b细胞的失配向量 ‖X_nb−X_b‖₂,计算型内中位数 m_type 和全局中位数 m_global。\n2. 型自适应β:β_type = β_base × (m_type / m_global)^p,其中β_base=2.2(父17默认),p为灵敏度指数(初值1.0,搜索{0.5, 1.0, 1.5})。Clamp β_type ∈ [1.2, 3.5]。\n3. 保留全局q=0.7分位数门(只混高失配细胞),但混入时用该细胞所属型的β_type而非全局β。\n4. 环境变量:EXPR_BETA_ADAPT=1开启(默认0关闭退回父17行为)、EXPR_BETA_P、EXPR_BETA_LO=1.2、EXPR_BETA_HI=3.5。\n5. 单输入阶段(b is None):走父节点原有read_stage退路,本模块不执行。\n6. 查分策略(≤20次):先跑控制(β=2.2, q=0.7, ADAPT=0)确认基线≈61.6;然后ADAPT=1, p=1.0查一次;若净分>+0.5则再试p=0.5和p=1.5(共≤5次);若ADAPT=1全阴(<+0.5),退回备选方案:固定β=2.8, q=0.8(移植节点18的发现到空间分层底座,≤3次查分)。\n7. 机制诊断输出:stderr打印每型的n_cells、m_type、β_type、n_blended_type,以及全局β_type分布的min/median/max。",
"expected_groups": ["expression_change", "local_spatial", "cell_state"],
"risks": "1) 型内细胞数过少(<10)导致m_type估计不稳→设MIN_TYPE_CELLS=10,不足型回退全局β;Engineer在诊断输出中检查每型n。2) p过大导致β_type极端化→clamp兜底;若p=1.5净分低于p=0.5,说明方向错。3) 改善<1分噪声→若前两次查分(控制+ADAPT=1 p=1.0)差<0.5即判定阴性,立即转备选β=2.8/q=0.8。4) 30分钟时限:改动集中在nn_fuse.py的blend循环(约20行新增),无新依赖,父17跑一次仅1.9s,网格5次查分约10s,充裕。",
"family_id": "T2HI-01",
"mechanism": "被融合b细胞的表达过冲混合中,过冲系数β不再是全局常数,而是按该细胞所属型的失配中位数与全局中位数之比自适应调节:高失配型获得更大β(更强外推),低失配型获得更小β(保护已有表达),解决统一β在型间异质性下的过冲/欠冲问题。",
"vs_constant_shift": "常数位移对同型所有细胞施加相同表达向量;本机制是逐细胞、按失配门控的过冲混合(仅高失配细胞被混入),且β幅度按型的失配水平连续变化,不是离散型级偏移。关闭门控(q=0)或关闭自适应(ADAPT=0)均退回不同行为,输出连续依赖于每个细胞的失配值和其型的统计量。",
"mechanism_evidence": "Engineer应检查:(1) 诊断输出中β_type的型间离散程度(std>0.1说明自适应在运行);(2) 与控制(ADAPT=0)相比,哪些型的被混细胞数发生变化;(3) 四组分各自变化方向——预期expression_change升、cell_state不降或微升(低失配型受保护);(4) 若β_type全部等于β_base(如所有型m_type≈m_global),说明机制未激活。",
"mechanism_off_control": "EXPR_BETA_ADAPT=0时,所有型统一使用β_base=2.2,逻辑与父17提交版完全一致,输出应逐位相同(array_equal校验)。预期差别:ADAPT=0时expression_change≈66.66;ADAPT=1时若机制有效,expression_change应>+0.5且cell_state不降。",
"sources": []
}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/researcher.jsonl 5 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/researcher.stderr |
审查员
| 角色 | 审查员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 8 |
| 工具调用 | 共 13 次:bash 6、read 6、write 1 |
| 用时 | 2 分 |
| token 数 | 输入 36,715 · 输出 1,713 · 思考 2,757 |
| 任务(第一行) | 审查节点 n20 的程序是否越界读取、写死目标、钻评分器漏洞 |
| 最后的回答(摘录) | REVIEW.json written |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/reviewer.jsonl 178 KB /home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-heart-interp-g24/nodes/20/reviewer.stderr |