总览 · ← 返回运行 20261003-171955-search-t2-embryo-interp-chain-12h
节点 n14
T2EI-02:mix 混抽+坐标 procrustes3d/RMS 缩放不动配对,表达用非平衡 Sinkhorn OT 重心投影做逐细胞位移(s=0.6,ε=0.01,τ=0.9,每侧 4000 子样,nnz-only、|Δ|≥0.25)。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-171955-search-t2-embryo-interp-chain-12h |
|---|---|
| 父节点 | (种子,没有父节点) |
| 子节点 | — |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 草稿 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 57.24 · proxy 57.24 |
| 审查 | 未审查 |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 31 分 |
| 程序版本 | 64adcfc76fdd82baad503da41f7473054ce6ec44 (programs.git) |
| 导入自 | 20261003-094242-search-t2-embryo-interp-g24-D-s2#14 |
| 备注 | re-scored at launch (origin 20261003-094242-search-t2-embryo-interp-g24-D-s2 node 14, score there 57.24) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 64adcfc76f:solution/METHOD.md
T2EI-02:mix 混抽+坐标 procrustes3d/RMS 缩放不动配对,表达用非平衡 Sinkhorn OT 重心投影做逐细胞位移(s=0.6,ε=0.01,τ=0.9,每侧 4000 子样,nnz-only、|Δ|≥0.25)。
方法族与实现
- family_id: T2EI-02(逐细胞 OT 表达位移,坐标原配对)。与节点 5/8/10/11 的类型级常数位移不同:靶点来自每个细胞自己的 OT 耦合重心投影,型内不同细胞位移不同(诊断输出 type_disp_std_over_mean ≈ 0.2–0.4,显著 >0;常数位移应 ≈0),且不使用类型标签对齐(分层抽样除外)。
- 管线:interp_bracket 取 (a,b,t);procrustes3d 对齐坐标 + 阻尼 log-RMS(damp=0.5);n=log 线性插值夹到 [min,max],按 (1−t,t) 分层混抽;表达侧:每侧分层抽 ≤4000 细胞,合并 PCA-30,代价=平方欧氏/median,log 域非平衡 Sinkhorn(τ=0.9,γ=τ/(τ+ε),100 迭代),重心投影得靶表达,非子样细胞按 PCA 1-NN 映射取靶;位移 x'=x+s·t·(x̂−x)(a 侧)/ s·(1−t)(b 侧),只作用 x>0 且 |x̂−x|≥0.25 的项,clip≥0。
- 单阶段退路:b 缺失时分层抽 anchor ≤max_cells 原样输出。
- 开关:环境变量 T2_OT_SHIFT=0 完全跳过 OT(机制关闭对照);T2_OT_EPS/T2_OT_TAU/T2_OT_N/T2_SCALE_DAMP 可覆盖。提交默认 s=0.6、ε=0.01、τ=0.9、n_ot=4000、damp=0.5(机制打开)。
查分结果(proxy,A 半,seed 0)
| 配置 | 榜分 | 表达 | 状态 | 形状 | 邻域 | variogram skill | mmd_u skill |
|---|---|---|---|---|---|---|---|
| s=0(对照=纯 mix) | 56.38 | 59.8 | 36.2 | 75.0 | 54.5 | 0.216 | 0.509 |
| s=0.6, ε=0.05 | 55.39 | 58.6 | 36.4 | 75.0 | 51.6 | 0.304 | 0.424 |
| s=1.0, ε=0.05 | 49.78 | 58.1 | 34.9 | 63.7 | 42.5 | 0.396 | 0.302 |
| s=0.6, ε=0.01(提交) | 56.51 | 60.0 | 38.1 | 75.0 | 53.0 | 0.301 | 0.461 |
机制生效证据与解读
- 机制确实改变细胞:3000/3000 a 侧、2000/2000 b 侧细胞被移动,436–498 个基因;有效耦合邻居数中位数 ~930/4000(多靶点加权,非 1-NN 复制),ε=0.01 时部分行下溢(pi_mass 0.72)。
- 方向性收益:variogram skill 0.216→0.30(共变结构改善,机制的靶效应),cell_state 组 36.2→38.1,expression_change 59.8→60.0。
- 代价:重心投影是收缩算子,mmd_u 变差(0.509→0.461)、neighborhood_mmd 变差(54.5→53.0,坐标未动但表达改变影响邻域均值分布)。s 越大收缩越强,s=1 时邻域跌破地板触发结构门(形状 75→63.7),总分崩到 49.8。
- 净效果:s=0.6+ε=0.01 比对照 +0.13,在 T2 噪声(~1 分)以内,不构成显著收益;但组分结构(variogram/cell_state 升、mmd_u/邻域降)指明改进方向。
- 未验证:τ 扫描、ε=0.2、s∈{0.3,4}、n_ot=1500 快扫(时间超限);s=0 与 mix 基线节点 2 的逐位一致性(管线独立实现,分数一致 56.4 vs 57.2 在噪声内)。
- 视图无关性:只用 t、时间差、细胞数与 manifest 上下限,无绝对时间/阶段名/路径依赖;随机性全部来自 default_rng(seed)。
知识来源
无外部生物学知识;全部统计量从 view 输入现场计算。方法为通用 OT/Sinkhorn(Peyré & Cuturi 教科书算法),坐标对齐复用 src.task2_spatial.frame。
下一步建议
收缩是主要伤害:把位移改为「向靶移动 + 型内/局部方差保持」(例如位移后再加回 (x−x̂) 的收缩分量的一部分),或只对 DE 显著基因位移;或把重心投影换成耦合抽样(sample_partner)避免平滑。
调研员的计划
| 名称 | T2EI-02: 非平衡Sinkhorn OT逐细胞表达位移(坐标原配对保邻域) |
|---|---|
| 动机 | draft 从零建立 T2EI-02 族。当前最佳节点 5/8/10/11(61.3–61.8)的位移全部是『每个类型一个常数向量』(Δ_type=μ_b−μ_a),依赖两侧类型名对齐,且型内所有细胞同向移动;最弱的 cell_state 组在最佳节点仍只有 49.3–50.3(variogram skill 仅 0.39,是组内主要失分项)。方法卡显示逐细胞 OT 插坐标会把邻域打到 23–31、结构门 0.46–0.61,因此本方案 OT 只作用于表达、坐标保持原配对,与节点 5 证明安全的『表达动、坐标不动』路线一致(节点 5 邻域 57.27→61.02)。 |
| 做法 | 1) 读 manifest 按时间排序取括号两端阶段 a(早)/b(晚)与目标时间,t=(T−t_a)/(t_b−t_a);禁止硬编码阶段名或绝对时间(伪装视图时间整体平移 1 天须输出不变)。单阶段退路:视图只有一个阶段时直接分层抽该阶段 ≤5000 个细胞原样输出(等价 copy_last),跳过 OT。2) 坐标:procrustes3d 把 b 对齐到 a,再按 log-RMS 以 damp=0.5 向括号插值(复刻 mix 基线做法);每细胞保留自己的坐标,不做逐细胞 OT 坐标转移——这是保邻域的关键决定。3) 表达 OT:合并 a、b 细胞,每侧最多 4000 个(超量则按细胞数分层抽样,未入选细胞用 PCA 空间 1-NN 映射到入选集取靶点);在合并集上拟合 PCA d=30,代价 C=平方欧氏距离/median(C);log 域非平衡 Sinkhorn(手写 ~30 行,勿假设 POT 可用):ε 初值 0.05·median(C),搜索 {0.01,0.05,0.2}·median;τ(KL 松弛)初值 0.9,搜索 {0.8,0.9,0.95};100 次迭代。4) 重心投影得逐细胞靶点:a 侧 x̂_b(i)=Σ_j π_ij·x_bj / Σ_j π_ij(在原表达空间做,非 PCA),b 侧对称。5) 位移:a 侧 x'=x+s·t·(x̂_b−x),b 侧 x'=x+s·(1−t)·(x̂_a−x);只作用 x>0 的项、只保留 |x̂−x|≥0.25 的基因、clip≥0(与节点 5 的安全约定一致)。s 初值 1.0,环境变量覆盖,搜索 {0.3,0.6,1,2,4}(节点 5/10 显示大强度过冲有效,但逐细胞靶点比型均值噪声大,故从小值扫起)。6) 输出:按 (1−t, t) 比例从 a、b 分层混抽 n=5000(受 manifest max_cells 约束),表达/坐标配对原样写入。7) 查分策略(≤8 次/20 次上限):先跑 s=0 对照确认 ≈ mix 基线(~57);再在 n_ot=1500 子样上扫 s∈{0.6,1,2}(ε、τ 固定初值)各查 1 次;选优后全量跑 1–2 次确认。T2 噪声 ~1 分,小于 1 分的差距不算收益。 |
| 风险 | 1) 重心投影过度平滑:逐细胞靶点是加权均值,可能比型均值位移更收缩型内方差,variogram 反而差于节点 5 的 0.01395——Engineer 应先在 n_OT=1500、s=1 跑一次看 mmd_u/variogram raw,再扫全网格。2) 耦合退化:ε 过小 → 耦合近 one-hot,靶点=1-NN 复制,机制退化为『复制 b 细胞』;每次跑打印每细胞有效邻居数(exp(行熵)),应 ≥5,否则调大 ε。3) τ 过大在出现/消失的类型上造质量,检查耦合边缘与均匀边缘的最大偏差。4) 逐细胞靶点噪声大,过冲(s>2)可能放大噪声伤 mmd_u——若 s=2,4 变差即止损在 s≤1。5) 30 分钟时限:4000×4000 float32 代价阵 64MB、100 次 Sinkhorn 迭代是秒级,风险低;先小样本后全量。6) 本 draft 的合格线是显著超过 mix 基线(57.2)并证明机制生效,不要求一次超过节点 11 的 61.8。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:这个提交的上一版(种子程序:相对空仓库)。改动的文件:solution/EXECUTION.json +1 −0、solution/METHOD.md +34 −0、solution/run.py +188 −0
diff --git a/solution/EXECUTION.json b/solution/EXECUTION.jsonnew file mode 100644index 0000000..9d5125c--- /dev/null+++ b/solution/EXECUTION.json@@ -0,0 +1 @@+{"gpu": false}diff --git a/solution/METHOD.md b/solution/METHOD.mdnew file mode 100644index 0000000..cca7e29--- /dev/null+++ b/solution/METHOD.md@@ -0,0 +1,34 @@+T2EI-02:mix 混抽+坐标 procrustes3d/RMS 缩放不动配对,表达用非平衡 Sinkhorn OT 重心投影做逐细胞位移(s=0.6,ε=0.01,τ=0.9,每侧 4000 子样,nnz-only、|Δ|≥0.25)。++## 方法族与实现++- family_id: T2EI-02(逐细胞 OT 表达位移,坐标原配对)。与节点 5/8/10/11 的类型级常数位移不同:靶点来自每个细胞自己的 OT 耦合重心投影,型内不同细胞位移不同(诊断输出 type_disp_std_over_mean ≈ 0.2–0.4,显著 >0;常数位移应 ≈0),且不使用类型标签对齐(分层抽样除外)。+- 管线:interp_bracket 取 (a,b,t);procrustes3d 对齐坐标 + 阻尼 log-RMS(damp=0.5);n=log 线性插值夹到 [min,max],按 (1−t,t) 分层混抽;表达侧:每侧分层抽 ≤4000 细胞,合并 PCA-30,代价=平方欧氏/median,log 域非平衡 Sinkhorn(τ=0.9,γ=τ/(τ+ε),100 迭代),重心投影得靶表达,非子样细胞按 PCA 1-NN 映射取靶;位移 x'=x+s·t·(x̂−x)(a 侧)/ s·(1−t)(b 侧),只作用 x>0 且 |x̂−x|≥0.25 的项,clip≥0。+- 单阶段退路:b 缺失时分层抽 anchor ≤max_cells 原样输出。+- 开关:环境变量 T2_OT_SHIFT=0 完全跳过 OT(机制关闭对照);T2_OT_EPS/T2_OT_TAU/T2_OT_N/T2_SCALE_DAMP 可覆盖。提交默认 s=0.6、ε=0.01、τ=0.9、n_ot=4000、damp=0.5(机制打开)。++## 查分结果(proxy,A 半,seed 0)++| 配置 | 榜分 | 表达 | 状态 | 形状 | 邻域 | variogram skill | mmd_u skill |+|---|---:|---:|---:|---:|---:|---:|---:|+| s=0(对照=纯 mix) | 56.38 | 59.8 | 36.2 | 75.0 | 54.5 | 0.216 | 0.509 |+| s=0.6, ε=0.05 | 55.39 | 58.6 | 36.4 | 75.0 | 51.6 | 0.304 | 0.424 |+| s=1.0, ε=0.05 | 49.78 | 58.1 | 34.9 | 63.7 | 42.5 | 0.396 | 0.302 |+| s=0.6, ε=0.01(提交) | 56.51 | 60.0 | 38.1 | 75.0 | 53.0 | 0.301 | 0.461 |++## 机制生效证据与解读++- 机制确实改变细胞:3000/3000 a 侧、2000/2000 b 侧细胞被移动,436–498 个基因;有效耦合邻居数中位数 ~930/4000(多靶点加权,非 1-NN 复制),ε=0.01 时部分行下溢(pi_mass 0.72)。+- 方向性收益:variogram skill 0.216→0.30(共变结构改善,机制的靶效应),cell_state 组 36.2→38.1,expression_change 59.8→60.0。+- 代价:重心投影是收缩算子,mmd_u 变差(0.509→0.461)、neighborhood_mmd 变差(54.5→53.0,坐标未动但表达改变影响邻域均值分布)。s 越大收缩越强,s=1 时邻域跌破地板触发结构门(形状 75→63.7),总分崩到 49.8。+- 净效果:s=0.6+ε=0.01 比对照 +0.13,在 T2 噪声(~1 分)以内,**不构成显著收益**;但组分结构(variogram/cell_state 升、mmd_u/邻域降)指明改进方向。+- 未验证:τ 扫描、ε=0.2、s∈{0.3,4}、n_ot=1500 快扫(时间超限);s=0 与 mix 基线节点 2 的逐位一致性(管线独立实现,分数一致 56.4 vs 57.2 在噪声内)。+- 视图无关性:只用 t、时间差、细胞数与 manifest 上下限,无绝对时间/阶段名/路径依赖;随机性全部来自 default_rng(seed)。++## 知识来源++无外部生物学知识;全部统计量从 view 输入现场计算。方法为通用 OT/Sinkhorn(Peyré & Cuturi 教科书算法),坐标对齐复用 src.task2_spatial.frame。++## 下一步建议++收缩是主要伤害:把位移改为「向靶移动 + 型内/局部方差保持」(例如位移后再加回 (x−x̂) 的收缩分量的一部分),或只对 DE 显著基因位移;或把重心投影换成耦合抽样(sample_partner)避免平滑。diff --git a/solution/run.py b/solution/run.pynew file mode 100644index 0000000..95e0319--- /dev/null+++ b/solution/run.py@@ -0,0 +1,188 @@+"""T2 embryo interpolation: mix baseline + per-cell unbalanced-Sinkhorn OT expression displacement.++Coordinates: procrustes3d alignment + damped log-RMS scaling, per-cell coordinate/expression+pairing preserved (protects neighborhood_mmd and the structure gate).+Expression: each output cell moves toward its own barycentric OT target on the other stage.+T2_OT_SHIFT=0 disables the mechanism exactly (pure mix pipeline).+"""++from __future__ import annotations++import argparse+import json+import os+from pathlib import Path++import numpy as np++from src.task2_spatial import view_io+from src.task2_spatial.frame import log_interp, rms_radius, scale_to_rms+from src.task2_spatial.sample import clip_n, mix_indices, take+from src.task2_spatial.transport import as_dense, stratified_choice+++def _env(name: str, default: float) -> float:+ try:+ return float(os.environ.get(name, default))+ except ValueError:+ return default+++def sinkhorn_log(C: np.ndarray, eps: float, tau: float, n_iter: int = 100):+ """Unbalanced Sinkhorn in log domain; returns coupling pi (float32)."""+ n, m = C.shape+ log_mu = np.full(n, -np.log(n))+ log_nu = np.full(m, -np.log(m))+ K = -C / eps+ f = np.zeros(n)+ g = np.zeros(m)+ gamma = tau / (tau + eps)+ for _ in range(n_iter):+ f = gamma * (log_mu - _lse_row(K + g[None, :]))+ g = gamma * (log_nu - _lse_row((K + f[:, None]).T))+ log_pi = K + f[:, None] + g[None, :]+ return np.exp(log_pi).astype(np.float32)+++def _lse_row(M: np.ndarray) -> np.ndarray:+ mx = M.max(axis=1)+ return mx + np.log(np.exp(M - mx[:, None]).sum(axis=1))+++def _sqdist(P: np.ndarray, Q: np.ndarray) -> np.ndarray:+ return (P * P).sum(1)[:, None] + (Q * Q).sum(1)[None, :] - 2.0 * (P @ Q.T)+++def ot_targets(Xa: np.ndarray, Xb: np.ndarray, n_ot: int, eps_mult: float, tau: float,+ rng: np.random.Generator, labels_a=None, labels_b=None, verbose=True):+ """Barycentric OT targets for every cell of a (toward b) and of b (toward a)."""+ na, nb = len(Xa), len(Xb)+ sa = np.arange(na) if na <= n_ot else stratified_choice(labels_a, n_ot, rng)+ sb = np.arange(nb) if nb <= n_ot else stratified_choice(labels_b, n_ot, rng)+ As, Bs = Xa[sa].astype(np.float64), Xb[sb].astype(np.float64)++ mu = np.vstack([As, Bs]).mean(axis=0)+ Y = np.vstack([As, Bs]) - mu+ Vt = np.linalg.svd(Y, full_matrices=False)[2][:30]++ def embed(X):+ return (X.astype(np.float64) - mu) @ Vt.T++ Esub_a, Esub_b = embed(As), embed(Bs)+ d2 = np.maximum(_sqdist(Esub_a, Esub_b), 0.0)+ C = d2 / (np.median(d2) + 1e-12)+ pi = sinkhorn_log(C, eps_mult, tau)++ ra = pi.sum(axis=1)+ rb = pi.sum(axis=0)+ bary_b = (pi / np.maximum(ra, 1e-12)[:, None]) @ Bs.astype(np.float32) # targets for subsample a+ bary_a = (pi.T / np.maximum(rb, 1e-12)[:, None]) @ As.astype(np.float32) # targets for subsample b++ out = []+ for Xall, Esub, bary in ((Xa, Esub_a, bary_b), (Xb, Esub_b, bary_a)):+ if len(Xall) == len(Esub):+ out.append(bary)+ else:+ Eall = embed(Xall)+ nn = _sqdist(Eall, Esub).argmin(axis=1)+ out.append(bary[nn])+ if verbose:+ p = pi / np.maximum(ra, 1e-12)[:, None]+ ent = -(p * np.log(p + 1e-300)).sum(axis=1)+ print(f"[ot] n_sub a={len(sa)} b={len(sb)} eff_neighbors median={np.exp(np.median(ent)):.1f} "+ f"pi_mass={pi.sum():.3f} marg_dev={max(abs(ra.sum()-1), abs(rb.sum()-1)):.3f}", flush=True)+ return out[0], out[1]+++def apply_shift(X: np.ndarray, bary: np.ndarray, s: float, w: float, min_delta: float = 0.25) -> np.ndarray:+ """X' = X + s*w*(bary - X) on expressed entries with |delta|>=min_delta, clipped at 0."""+ if s == 0.0:+ return X+ delta = (bary - X).astype(np.float32)+ mask = (X > 0) & (np.abs(delta) >= min_delta)+ out = X.copy()+ out[mask] = out[mask] + np.float32(s * w) * delta[mask]+ return np.clip(out, 0.0, None)+++def main():+ ap = argparse.ArgumentParser()+ ap.add_argument("--data", required=True)+ ap.add_argument("--out", required=True)+ ap.add_argument("--seed", type=int, default=0)+ args = ap.parse_args()++ view = Path(args.data)+ manifest = view_io.load_manifest(view)+ genes = view_io.panel_genes(view, manifest)+ lo = int(manifest["min_cells"])+ hi = int(manifest["max_cells"])++ s = _env("T2_OT_SHIFT", 0.6)+ n_ot = int(_env("T2_OT_N", 4000))+ eps_mult = _env("T2_OT_EPS", 0.01)+ tau = _env("T2_OT_TAU", 0.9)+ scale_damp = _env("T2_SCALE_DAMP", 0.5)++ entry_a, entry_b, t = view_io.interp_bracket(manifest)+ stage_a = view_io.read_stage(view, entry_a, genes)+ rng = np.random.default_rng(args.seed)++ if entry_b is None: # single-stage fallback: copy anchor+ idx = take(stage_a.labels, hi, rng)+ expr = as_dense(stage_a.X, idx)+ view_io.write_t2(args.out, expr, stage_a.coords[idx], genes, seed=args.seed)+ print(f"[fallback] single input, n={len(idx)}", flush=True)+ return++ stage_b = view_io.read_stage(view, entry_b, genes)+ t = float(t)++ # --- coordinates: procrustes3d + damped log-RMS (identical to mix baseline) ---+ from src.task2_spatial.frame import align_pair+ ca, cb, info = align_pair(stage_a.coords, stage_b.coords, stage_a.labels, stage_b.labels,+ method="procrustes3d")+ target_rms = log_interp(rms_radius(stage_a.coords), rms_radius(stage_b.coords), t, scale_damp)+ ca = scale_to_rms(ca, target_rms)+ cb = scale_to_rms(cb, target_rms)++ n = clip_n(log_interp(stage_a.n, stage_b.n, t), lo, hi)+ ia, ib = mix_indices(stage_a.labels, stage_b.labels, t, n, rng)+ print(f"[mix] t={t:.3f} n={n} from_a={len(ia)} from_b={len(ib)} "+ f"shared_types={info.get('n_shared_types')} z_dot={info.get('z_dot'):.3f} rms={target_rms:.1f}", flush=True)++ Xa = as_dense(stage_a.X, ia)+ Xb = as_dense(stage_b.X, ib)++ if s > 0.0:+ Xa_full = as_dense(stage_a.X)+ Xb_full = as_dense(stage_b.X)+ bary_b_for_a, bary_a_for_b = ot_targets(Xa_full, Xb_full, n_ot, eps_mult, tau, rng,+ stage_a.labels, stage_b.labels)+ Xa = apply_shift(Xa, bary_b_for_a[ia], s, t)+ Xb = apply_shift(Xb, bary_a_for_b[ib], s, 1.0 - t)+ # mechanism diagnostics+ for nm, X0, X1, labs in (("a", as_dense(stage_a.X, ia), Xa, stage_a.labels[ia]),+ ("b", as_dense(stage_b.X, ib), Xb, stage_b.labels[ib])):+ d = (X1 - X0)+ nz = np.abs(d).sum(axis=0) > 0+ moved = (np.abs(d) > 0).sum(axis=1)+ ratios = []+ for lab in np.unique(labs):+ m = labs == lab+ if m.sum() >= 10:+ dm = d[m].sum(axis=1)+ if abs(dm.mean()) > 1e-6:+ ratios.append(dm.std() / abs(dm.mean()))+ print(f"[mech {nm}] cells_moved={int((moved>0).sum())}/{len(d)} "+ f"genes_moved={int(nz.sum())} mean|d|={abs(d).mean():.4f} std(d)={d.std():.4f} "+ f"type_disp_std_over_mean_median={np.median(ratios):.2f}", flush=True)++ coords = np.vstack([ca[ia], cb[ib]])+ expr = np.vstack([Xa, Xb]) if len(Xa) else Xb+ view_io.write_t2(args.out, expr, coords, genes, seed=args.seed)+ print(f"[done] n={expr.shape[0]}", flush=True)+++if __name__ == "__main__":+ main()
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k003 | Fused Gromov-Wasserstein mapping for spatial snapshots | 10.1038/s41586-024-08453-2 |
| k007 | Interval staging and held-out-window filtering of external data | notes/official/来件/virtualembryo.ai/rules.md |
| k028 | LLM-driven code evolution for analysis algorithms | 10.64898/2026.02.26.707870 |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 从零实现 T2EI-02:mix 管线(procrustes3d+阻尼 log-RMS 坐标、分层混抽、表达/坐标原配对)之上加非平衡 Sinkhorn OT(PCA-30、每侧 4000 子样、tau=0.9)重心投影的逐细胞表达位移,提交配置 s=0.6、eps=0.01、nnz-only、|delta|>=0.25;带 T2_OT_SHIFT=0 关闭开关。耗时 2.8s→37.9s,内存 0.31→2.72GB。 |
|---|---|
| 各组分数的变化 | cell_state:噪声内但结构清晰:组分 37.49→39.41(榜分贡献仅 +0.48);组内两项反向——variogram raw 0.02952→0.01884,skill 0.228→0.319,得分 +1.13;mmd_u raw 0.01657→0.02037 变差,skill 0.521→0.470,得分 -0.65 expression_change:噪声内:组分 59.72→60.00(榜分贡献 +0.14;de_score raw 0.2069→0.2414,得分 +0.15;de_direction raw 0.3757→0.3612,得分 -0.08,两项互相抵消) local_spatial:变坏、接近噪声边缘:组分 57.27→55.30(榜分贡献 -0.49;neighborhood_mmd raw 0.05791→0.06269,skill 0.573→0.553),坐标未动,纯由表达位移改变 15 近邻平均表达所致 shape_scale:噪声内:组分 74.43→74.24(d2_shape/occupancy_dice 逐位不变,坐标管线与对照一致;scale_log_ratio raw 0.0099→0.0111,得分 -0.05) |
| family_id | T2EI-02 |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 4 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 3 次:— |
| 用时 | 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 16,075 · 输出 2,709 · 思考 1,321 |
| 任务(第一行) | 分析节点 n14 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/14/analyst.jsonl (文件不在) |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 35 |
| 工具调用 | 共 37 次:— |
| 用时 | 26 分 |
| token 数 | 输入 85,107 · 输出 12,929 · 思考 11,330 |
| 任务(第一行) | 按计划修改程序:T2EI-02: 非平衡Sinkhorn OT逐细胞表达位移(坐标原配对保邻域) |
| 最后的回答(摘录) | 完成。节点 14(draft,T2EI-02 逐细胞 OT 表达位移): **做了什么**:从零实现 mix 管线(procrustes3d + 阻尼 log-RMS 坐标、分层混抽、表达/坐标原配对)+ 非平衡 Sinkhorn OT 重心投影的逐细胞表达位移(每侧 4000 子样、PCA-30、nnz-only、|Δ|≥0.25),带 `T2_OT_SHIFT=0` 机制关闭开关和单阶段退路。 **查分**(5/20 次):s=0 对照 56.38;s=0.6/ε=0.05 → 55.39;s=1.0/ε=0.05 → 49.78(邻域跌破地板触发结构门);**s=0.6/ε=0.01 → 56.51(提交默认)**。机制生效证据:全部输出细胞被移动、型内位移 std/mean≈0.2–0.4、有效耦合邻居 ~930;variogram skill 0.216→0.30、cell_state 36.2→38.1,但重心投影的收缩性伤 mmd_u(0.509→0.461)和邻域(54.5→53.0),净收益 +0.13 在噪声内,不算显著超过 mix 基线,远低于最佳节点 61.8。 **下一步最值得试**:消除收缩伤害——位移后加回被重心投影抹掉的型内/局部方差分量(或只对 DE 显著基因位移、用耦合抽样代替重心投影),保留 variogram 收益的同时守住 mmd_u 和邻域;该家族的收益上限取决于能否做到"共变改善、方差不塌"。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/14/engineer.jsonl (文件不在) |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 3 分 |
| token 数 | 输入 10,901 · 输出 1,701 · 思考 5,377 |
| 任务(第一行) | 为节点 n14(草稿,父节点 nNone)写改进计划 PLAN.json,思路 T2EI-02 |
| 最后的回答(摘录) | 按细胞数分层抽样,未入选细胞用 PCA 空间 1-NN 映射到入选集取靶点);在合并集上拟合 PCA d=30,代价 C=平方欧氏距离/median(C);log 域非平衡 Sinkhorn(手写 ~30 行,勿假设 POT 可用):ε 初值 0.05·median(C),搜索 {0.01,0.05,0.2}·median;τ(KL 松弛)初值 0.9,搜索 {0.8,0.9,0.95};100 次迭代。4) 重心投影得逐细胞靶点:a 侧 x̂_b(i)=Σ_j π_ij·x_bj / Σ_j π_ij(在原表达空间做,非 PCA),b 侧对称。5) 位移:a 侧 x'=x+s·t·(x̂_b−x),b 侧 x'=x+s·(1−t)·(x̂_a−x);只作用 x>0 的项、只保留 |x̂−x|≥0.25 的基因、clip≥0(与节点 5 的安全约定一致)。s 初值 1.0,环境变量覆盖,搜索 {0.3,0.6,1,2,4}(节点 5/10 显示大强度过冲有效,但逐细胞靶点比型均值噪声大,故从小值扫起)。6) 输出:按 (1−t, t) 比例从 a、b 分层混抽 n=5000(受 manifest max_cells 约束),表达/坐标配对原样写入。7) 查分策略(≤8 次/20 次上限):先跑 s=0 对照确认 ≈ mix 基线(~57);再在 n_ot=1500 子样上扫 s∈{0.6,1,2}(ε、τ 固定初值)各查 1 次;选优后全量跑 1–2 次确认。T2 噪声 ~1 分,小于 1 分的差距不算收益。",
"expected_groups": ["cell_state", "expression_change"],
"risks": "1) 重心投影过度平滑:逐细胞靶点是加权均值,可能比型均值位移更收缩型内方差,variogram 反而差于节点 5 的 0.01395——Engineer 应先在 n_OT=1500、s=1 跑一次看 mmd_u/variogram raw,再扫全网格。2) 耦合退化:ε 过小 → 耦合近 one-hot,靶点=1-NN 复制,机制退化为『复制 b 细胞』;每次跑打印每细胞有效邻居数(exp(行熵)),应 ≥5,否则调大 ε。3) τ 过大在出现/消失的类型上造质量,检查耦合边缘与均匀边缘的最大偏差。4) 逐细胞靶点噪声大,过冲(s>2)可能放大噪声伤 mmd_u——若 s=2,4 变差即止损在 s≤1。5) 30 分钟时限:4000×4000 float32 代价阵 64MB、100 次 Sinkhorn 迭代是秒级,风险低;先小样本后全量。6) 本 draft 的合格线是显著超过 mix 基线(57.2)并证明机制生效,不要求一次超过节点 11 的 61.8。",
"family_id": "T2EI-02",
"mechanism": "在表达 PCA 空间用非平衡 Sinkhorn 求两括号阶段的细胞间传输耦合,重心投影给每个细胞一个个性化的靶表达,a/b 两侧细胞各向自己的靶移动强度受 t 调制的比例 s;坐标只做全局 procrustes+RMS 缩放、保持原表达-坐标配对,从而保住邻域组与结构门。",
"vs_constant_shift": "节点 5/10 的位移是每个类型标签一个常数向量,型内所有细胞同向同幅、且必须有两侧类型名对齐;本方案的靶点来自每个细胞自己的 OT 耦合,型内不同细胞获得不同方向/幅度(把型内质量重新分布到中间几何,而非整块平移),完全不使用类型标签,两侧类型词汇不一致时仍可运行。与纯组成重加权(mix)相比,它改变的是细胞在表达空间的位置而不只是抽样比例。",
"mechanism_evidence": "1) 打印逐细胞位移向量在每个类型内的标准差/均值比,应显著 >0(常数位移该比值≈0);2) 位移方向与所在类型 Δ_type 的余弦中位数应高(0.6–0.95)但非全 1,证明型内有个性化分量;3) 有效邻居数(耦合行熵)≥5,证明是多靶点加权而非 1-NN 复制;4) s=0 与 s>0 的四组 raw 对比:预期 mmd_u、variogram 改善,neighborhood_mmd 不降(坐标未动),形状三项逐位不变。",
"mechanism_off_control": "环境变量 T2_OT_SHIFT=0(等价 s=0)时完全跳过 OT 与位移步,管线退化为纯 mix(procrustes+RMS+分层混抽);Engineer 用 array_equal 验证 s=0 输出与 mix-only 运行逐位相同,且 vec-score 回到 ~57 的 mix 基线水平,与 s>0 的分差即为机制贡献。"}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/14/researcher.jsonl (文件不在) |