总览 · ← 返回运行 20261003-171955-search-t2-embryo-interp-chain-12h
节点 n23
T2EI-04 块抽样:以空间 k-NN 块(种子+14 近邻,k=15)为抽样单元、按块主类型分层以 (1−t):t 从两端阶段混抽,表达与坐标原样保留;jitter 关闭。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-171955-search-t2-embryo-interp-chain-12h |
|---|---|
| 父节点 | (种子,没有父节点) |
| 子节点 | n26 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 草稿 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 58.40 · proxy 58.40 |
| 审查 | 未审查 |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 27 分 |
| 程序版本 | 32a898b8f62e04162656aea52677b98e56eb544b (programs.git) |
| 导入自 | 20261003-094242-search-t2-embryo-interp-g24-D-s2#23 |
| 备注 | re-scored at launch (origin 20261003-094242-search-t2-embryo-interp-g24-D-s2 node 23, score there 58.40) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 32a898b8f6:solution/METHOD.md
T2EI-04 块抽样:以空间 k-NN 块(种子+14 近邻,k=15)为抽样单元、按块主类型分层以 (1−t):t 从两端阶段混抽,表达与坐标原样保留;jitter 关闭。
方法(family T2EI-04,最小版本)
插值榜:interp_bracket 取目标两侧输入 (a, b, t)。
align_pair(procrustes3d)把两朵坐标云放进同一帧,再各自均匀缩放到目标 RMS = log 插值(scale_damp=0.5)。- 每侧建块:随机顺序遍历细胞,未覆盖者当种子,块 = 种子 + 其 kNN 中尚未覆盖的至多 k−1 个近邻(k=15,与评分器 15-近邻含自身的定义一致;kNN 在对齐后坐标上用 cKDTree 算一次)。整侧形成互不重叠的块池(覆盖全部细胞)。
- 抽块:按块的主类型(块内众数)做类型分层——各类型配额 ∝ 该侧池内该类型细胞数 × n_side,块在类型内随机排列依次整块取出,超额的最后一块截断(保留离种子最近的细胞)。n_side 按 (1−t):t 分配(n_b = round(t·n)),总细胞数 n = log 插值夹到 [min_cells, max_cells]。
- 组装:块内表达(源细胞 CSR 行原样)与坐标原样拼入输出;可选整块刚性平移 jitter(幅度 α×平均最近邻距离),默认 α=0(关闭)。
- 输出云整体均匀缩放到目标 RMS,
write_t2写出。表达数值全程不修改。 - 单输入退路:目标不被括号时全部块取自 anchor 阶段,RMS 不变。
关键参数(默认,均可用环境变量覆盖,提交保持默认)
T2EI04_K=15(块大小);T2EI04_ALPHA=0.0(jitter,关闭);T2EI04_SCALE_DAMP=0.5;T2EI04_ALIGN=procrustes3d。- 随机性全部来自
np.random.default_rng(seed):种子顺序、块抽取、jitter;同 seed 逐位确定(已验证与显式 α=0 运行 X、坐标逐位相同)。
机制对照(mechanism_off_control:T2EI04_K=1,其余流程完全相同)
| 配置 | 榜分 | local_spatial | nbhd raw | shape_scale |
|---|---|---|---|---|
| k=15(机制开,seed 0) | 57.80 | 56.16 | 0.0597 | 78.68 |
| k=15(机制开,seed 1) | 57.53 | 57.72 | 0.0561 | 75.57 |
| k=1(机制关,seed 0) | 57.13 | 54.59 | 0.0635 | 76.37 |
- 机制生效证据 (b):输出中每个细胞 15 近邻的同侧(同来源阶段)占比 k=15 为 0.906,k=1 为 0.813——块确实把同阶段细胞聚在一起。
- 机制生效证据 (a):neighborhood_mmd raw 0.0597/0.0561(开)vs 0.0635(关),local_spatial 组 +1.6~+3.1,两个 seed 一致;k=10(56.60)、k=25(56.69)同样高于 k=1,说明是块机制而非单个 k 值的巧合。
- (c)(d):mmd_u、组成未受分层块抽取损害(cell_state 组 36.2/36.7 vs 关 37.3,差异在噪声内);d2_shape/occupancy_dice 未因块间空隙劣化(shape 组两次运行 75.6–78.7,与关对照同区间)。
- 总分差 +0.4~+0.7 小于噪声(~1 分),但机制的目标组 local_spatial 提升一致且方向明确。k=1 对照 57.13 与全树 mix 基线(节点 2 = 57.23)复现一致,说明对照确实退化为标准 mix。
验证过 / 没验证
- 验证过(proxy 视图,A 半,共用 9 次查分):k∈{1,10,15,25}、jitter α∈{0,0.3}、块池 {FPS 顺序取块, FPS 池随机抽, 全池随机抽+类型分层}。教训:FPS 早停块池偏向外周(nbhd 0.072–0.080,明显差),改为全阶段块池后恢复并超过 mix 水平;jitter α=0.3 轻微劣化 local_spatial(55.99 vs 56.16),故默认关闭。seed 0/1 均跑通且分数稳定(57.8/57.5)。单输入退路在合成视图上跑通并通过 vec-check。运行 <5 s、内存远低于上限,
EXECUTION.json声明纯 CPU。 - 没验证:真实括号(E7.25+E8.0,t=1/3)上的表现(无真值);k 在 15–25 间更细的扫描;块抽样与节点 5/8/11/13 的类型级表达位移叠加的效果(PLAN 明确要求本 draft 不混入表达修改,留给 improve)。
- 与全树比较:本 draft 高于 mix 基线(节点 2,57.23),低于表达位移家族(节点 13,62.52);预期 improve 节点在本块抽样管线上叠加节点 11/13 的表达管线可同时拿到 62 级表达分与更高的 local_spatial。
知识来源
- 未使用任何生物学先验数据或文献知识;k=15 的选择仅来自任务书公开的评分简报中 neighborhood_mmd 的“15 个最近邻(含自身)”定义,procrustes3d/log-RMS/scale_damp=0.5 来自任务书方法卡的推荐配置。未使用保留阶段/基因型的任何信息。
调研员的计划
| 名称 | T2EI-04 保邻域块抽样:以空间近邻块为单位混抽两端阶段 |
|---|---|
| 动机 | 当前最佳节点13的local_spatial=60.34(neighborhood_mmd raw 0.05112),而mix基线(节点2)仅57.27。评分简报明确指出:保留真实细胞表达-坐标配对时邻域组稳定52-55,OT插值新点则掉到23-41。节点5/8/10/11/13的表达管线已把expression_change推到62.11,但邻域项始终是短板。结构门=shape_skill×min(nbhd_skill/0.5,1),邻域skill若从~0.55提到>0.6,形状组额外获益。T2EI-04的核心假设:独立混抽破坏局部空间一致性(来自不同阶段的细胞互为近邻),以空间块为单位抽样可保持块内表达-坐标配对,直接改善neighborhood_mmd。 |
| 做法 | 1) 读取两端输入阶段(a,b)的表达矩阵与spatial_3D坐标。 2) Procrustes 3D对齐:把b侧坐标刚性对齐到a侧(旋转+平移,不缩放),使两端坐标在同一参考系。 3) 构建块:对每侧分别计算3D坐标的k-NN(k=15,与评分器的15-近邻一致)。用贪心最远点采样(FPS)选出N_seed个种子细胞,每个种子与其k个近邻构成一个块(去重:已被其他块包含的细胞不再当种子)。初始N_seed按目标细胞数/(k+1)估算,实际用覆盖-去重循环调到目标数。 4) 按(1−t):t比例从a/b侧抽取块:t=0.5时各半。用分层策略保证每侧的空间均匀性(FPS已保证)。 5) 组装输出:把选中块的表达和坐标原样拼入输出。块内坐标保持相对位移不变。 6) 块间jitter:对每个块整体加一个随机平移向量,幅度=α×块内平均最近邻距离(初始α=0.3,搜索[0.1,1.0]),防止块间精确重叠。 7) 全局RMS缩放:把输出云均匀缩放到目标RMS(取a侧RMS的(1−t)+b侧RMS的t的log插值),保持坐标单位一致。 8) 表达完全不动(原样保留源细胞的表达值),不施加任何位移或缩放。 9) 单输入阶段退路:若只有一个阶段,全部块从该阶段抽取,无混合,jitter和RMS缩放仍执行。 10) vec-score快速筛选:先在子样(每侧1500细胞、k=15)上跑3组参数(α=0.1/0.3/1.0),确认neighborhood_mmd优于独立混抽后再全量。查分上限20次,前6次用于参数扫描(k∈{10,15,25}×α∈{0.3,1.0}),保留余量给最优配置的多seed确认。 |
| 风险 | 1) 块间边界不自然:不同阶段的块拼接处可能出现表达-坐标不连续,反而拉高neighborhood_mmd。Engineer应在小样上先比较块抽样与独立混抽的neighborhood_mmd raw,若块抽样反而更差则立即停止。2) FPS种子选取可能偏向高密度区域,导致低密度区域细胞缺失、组成偏移,损害mmd_u。对策:FPS后检查输出细胞数是否达标,不足时降低k或增加种子数。3) 表达组可能略低于节点13(62.11),因为本方案不施加类型级表达位移,预期接近mix水平(~59-60)。若表达组降幅>2分,应在后续improve节点叠加表达位移而非在本draft中混入。4) 块太大(k过大)会让输出变成若干孤立团,破坏整体形状(d2_shape、occupancy_dice劣化);k=15是与评分器对齐的初始值,不应超过30。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:这个提交的上一版(种子程序:相对空仓库)。改动的文件:solution/EXECUTION.json +1 −0、solution/METHOD.md +40 −0、solution/run.py +220 −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..e5a4f1d--- /dev/null+++ b/solution/METHOD.md@@ -0,0 +1,40 @@+T2EI-04 块抽样:以空间 k-NN 块(种子+14 近邻,k=15)为抽样单元、按块主类型分层以 (1−t):t 从两端阶段混抽,表达与坐标原样保留;jitter 关闭。++# 方法(family T2EI-04,最小版本)++插值榜:`interp_bracket` 取目标两侧输入 (a, b, t)。++1. `align_pair(procrustes3d)` 把两朵坐标云放进同一帧,再各自均匀缩放到目标 RMS = log 插值(scale_damp=0.5)。+2. 每侧建块:随机顺序遍历细胞,未覆盖者当种子,块 = 种子 + 其 kNN 中尚未覆盖的至多 k−1 个近邻(k=15,与评分器 15-近邻含自身的定义一致;kNN 在对齐后坐标上用 cKDTree 算一次)。整侧形成互不重叠的块池(覆盖全部细胞)。+3. 抽块:按块的**主类型**(块内众数)做类型分层——各类型配额 ∝ 该侧池内该类型细胞数 × n_side,块在类型内随机排列依次整块取出,超额的最后一块截断(保留离种子最近的细胞)。n_side 按 (1−t):t 分配(n_b = round(t·n)),总细胞数 n = log 插值夹到 [min_cells, max_cells]。+4. 组装:块内表达(源细胞 CSR 行原样)与坐标原样拼入输出;可选整块刚性平移 jitter(幅度 α×平均最近邻距离),**默认 α=0(关闭)**。+5. 输出云整体均匀缩放到目标 RMS,`write_t2` 写出。表达数值全程不修改。+6. 单输入退路:目标不被括号时全部块取自 anchor 阶段,RMS 不变。++## 关键参数(默认,均可用环境变量覆盖,提交保持默认)++- `T2EI04_K=15`(块大小);`T2EI04_ALPHA=0.0`(jitter,关闭);`T2EI04_SCALE_DAMP=0.5`;`T2EI04_ALIGN=procrustes3d`。+- 随机性全部来自 `np.random.default_rng(seed)`:种子顺序、块抽取、jitter;同 seed 逐位确定(已验证与显式 α=0 运行 X、坐标逐位相同)。++## 机制对照(mechanism_off_control:T2EI04_K=1,其余流程完全相同)++| 配置 | 榜分 | local_spatial | nbhd raw | shape_scale |+|---|---:|---:|---:|---:|+| k=15(机制开,seed 0) | **57.80** | 56.16 | 0.0597 | 78.68 |+| k=15(机制开,seed 1) | 57.53 | 57.72 | 0.0561 | 75.57 |+| k=1(机制关,seed 0) | 57.13 | 54.59 | 0.0635 | 76.37 |++- 机制生效证据 (b):输出中每个细胞 15 近邻的**同侧(同来源阶段)占比** k=15 为 0.906,k=1 为 0.813——块确实把同阶段细胞聚在一起。+- 机制生效证据 (a):neighborhood_mmd raw 0.0597/0.0561(开)vs 0.0635(关),local_spatial 组 +1.6~+3.1,两个 seed 一致;k=10(56.60)、k=25(56.69)同样高于 k=1,说明是块机制而非单个 k 值的巧合。+- (c)(d):mmd_u、组成未受分层块抽取损害(cell_state 组 36.2/36.7 vs 关 37.3,差异在噪声内);d2_shape/occupancy_dice 未因块间空隙劣化(shape 组两次运行 75.6–78.7,与关对照同区间)。+- 总分差 +0.4~+0.7 小于噪声(~1 分),但机制的目标组 local_spatial 提升一致且方向明确。k=1 对照 57.13 与全树 mix 基线(节点 2 = 57.23)复现一致,说明对照确实退化为标准 mix。++## 验证过 / 没验证++- 验证过(proxy 视图,A 半,共用 9 次查分):k∈{1,10,15,25}、jitter α∈{0,0.3}、块池 {FPS 顺序取块, FPS 池随机抽, 全池随机抽+类型分层}。教训:FPS 早停块池偏向外周(nbhd 0.072–0.080,明显差),改为全阶段块池后恢复并超过 mix 水平;jitter α=0.3 轻微劣化 local_spatial(55.99 vs 56.16),故默认关闭。seed 0/1 均跑通且分数稳定(57.8/57.5)。单输入退路在合成视图上跑通并通过 vec-check。运行 <5 s、内存远低于上限,`EXECUTION.json` 声明纯 CPU。+- 没验证:真实括号(E7.25+E8.0,t=1/3)上的表现(无真值);k 在 15–25 间更细的扫描;块抽样与节点 5/8/11/13 的类型级表达位移叠加的效果(PLAN 明确要求本 draft 不混入表达修改,留给 improve)。+- 与全树比较:本 draft 高于 mix 基线(节点 2,57.23),低于表达位移家族(节点 13,62.52);预期 improve 节点在本块抽样管线上叠加节点 11/13 的表达管线可同时拿到 62 级表达分与更高的 local_spatial。++## 知识来源++- 未使用任何生物学先验数据或文献知识;k=15 的选择仅来自任务书公开的评分简报中 neighborhood_mmd 的“15 个最近邻(含自身)”定义,procrustes3d/log-RMS/scale_damp=0.5 来自任务书方法卡的推荐配置。未使用保留阶段/基因型的任何信息。diff --git a/solution/run.py b/solution/run.pynew file mode 100644index 0000000..922b6c8--- /dev/null+++ b/solution/run.py@@ -0,0 +1,220 @@+#!/usr/bin/env python+"""T2EI-04: neighbourhood-preserving spatial block sampling for stage interpolation.++Sampling unit = a spatial block (random uncovered seed + its k-1 nearest+uncovered neighbours, k=15 by default, matching the scorer's 15-nearest-neighbour+definition). Blocks are drawn from each bracket stage in a (1-t):t cell ratio,+type-stratified by each block's dominant cell type; expression and coordinates+are carried over verbatim so the local expression-position pairing inside each+block is never broken. An optional per-block rigid jitter (alpha x mean+nearest-neighbour distance, default 0 = off) can de-overlap blocks; the assembled+cloud is uniformly rescaled to a damped log-interpolated target RMS. Expression+values are never modified.++Mechanism-off control: set T2EI04_K=1 (each block is the seed alone) which+degenerates the pipeline to independent type-stratified cell mixing (standard mix).+"""++from __future__ import annotations++import argparse+import json+import os+from pathlib import Path++import numpy as np+from scipy.spatial import cKDTree++from src.task2_spatial import view_io+from src.task2_spatial.frame import align_pair, log_interp, rms_radius, scale_to_rms+from src.task2_spatial.sample import clip_n, interp_count+++def _env(name, default, cast):+ raw = os.environ.get(name)+ if raw is None or raw == "":+ return default+ return cast(raw)+++def fps_seeds(coords: np.ndarray, rng: np.random.Generator, max_seeds: int):+ """Lazy farthest-point-sampling seed order (deterministic given rng)."""+ n = len(coords)+ min_d = np.full(n, np.inf)+ cur = int(rng.integers(n))+ for _ in range(min(int(max_seeds), n)):+ yield cur+ d = ((coords - coords[cur]) ** 2).sum(axis=1)+ np.minimum(min_d, d, out=min_d)+ cur = int(np.argmax(min_d))+++def seed_order(coords: np.ndarray, rng: np.random.Generator, mode: str):+ if mode == "fps":+ return fps_seeds(coords, rng, len(coords))+ return (int(i) for i in rng.permutation(len(coords)))+++def build_blocks(coords: np.ndarray, k: int, rng: np.random.Generator, cover: int,+ seeds: str = "random"):+ """FPS block partition: each uncovered seed claims its uncovered (k-1) nearest neighbours.++ Stops once `cover` cells are blocked (FPS seeds are space-filling, so early+ blocks spread over the whole stage; blocks are drawn at random downstream).+ """+ n = len(coords)+ k = int(max(1, min(k, n)))+ cover = int(min(max(cover, 1), n))+ tree = cKDTree(coords)+ nbrs = tree.query(coords, k=k)[1]+ if nbrs.ndim == 1:+ nbrs = nbrs[:, None]+ if n > 1:+ nn = tree.query(coords, k=2)[1]+ d_nn = float(np.sqrt(((coords[nn[:, 0]] - coords[nn[:, 1]]) ** 2).sum(axis=1)).mean())+ else:+ d_nn = 0.0+ covered = np.zeros(n, dtype=bool)+ blocks: list[np.ndarray] = []+ total = 0+ for s in seed_order(coords, rng, seeds):+ if total >= cover:+ break+ if covered[s]:+ continue+ mem = nbrs[s][~covered[nbrs[s]]]+ if mem.size == 0:+ continue+ covered[mem] = True+ blocks.append(mem)+ total += int(mem.size)+ if total < cover:+ rest = np.flatnonzero(~covered)+ if rest.size:+ blocks.append(rest)+ return blocks, d_nn+++def draw_blocks(blocks, need: int, rng: np.random.Generator, labels: np.ndarray | None = None):+ """Random draw of whole blocks until `need` cells; last block trimmed (closest to seed).++ With `labels`, blocks are drawn type-stratified: each block is charged to its+ dominant cell type and per-type quotas follow the stage's own type fractions,+ so the output composition mirrors a stratified cell-level draw.+ """+ if labels is None:+ order = list(rng.permutation(len(blocks)))+ else:+ dom = []+ by_type: dict[str, list[int]] = {}+ for bi, m in enumerate(blocks):+ labs, cnt = np.unique(np.asarray(labels)[m], return_counts=True)+ d = str(labs[int(np.argmax(cnt))])+ dom.append(d)+ by_type.setdefault(d, []).append(bi)+ types = sorted(by_type)+ fracs = np.array([len(by_type[t_]) for t_ in types], dtype=np.float64)+ # quota over blocks weighted by block sizes: allocate cells per type+ cell_counts = np.array([sum(int(blocks[bi].size) for bi in by_type[t_]) for t_ in types],+ dtype=np.float64)+ quota = np.floor(cell_counts / max(cell_counts.sum(), 1.0) * need).astype(int)+ quota[-1] += need - quota.sum()+ order = []+ for qi, t_ in enumerate(types):+ cand = list(rng.permutation(len(by_type[t_])))+ filled = 0+ for ci in cand:+ if filled >= quota[qi]:+ break+ order.append(by_type[t_][ci])+ filled += int(blocks[by_type[t_][ci]].size)+ # top up with any unused blocks (random order) to guarantee reaching `need`+ used = set(order)+ spare = [bi for bi in range(len(blocks)) if bi not in used]+ rng.shuffle(spare)+ order.extend(spare)+ picked, tot = [], 0+ for bi in order:+ if tot >= need:+ break+ m = blocks[bi]+ if tot + m.size > need:+ m = m[: need - tot]+ picked.append(m)+ tot += int(m.size)+ return picked+++def assemble(coords: np.ndarray, picked, alpha: float, d_nn: float, rng: np.random.Generator):+ """Concatenate picked blocks with per-block rigid jitter; return (idx, coords)."""+ idx_list, coord_parts = [], []+ for m in picked:+ idx_list.append(m)+ c = coords[m]+ if alpha > 0.0 and d_nn > 0.0:+ c = c + rng.normal(0.0, alpha * d_nn, size=3)+ coord_parts.append(c)+ idx = np.concatenate(idx_list).astype(np.int64)+ C = np.vstack(coord_parts)+ return idx, C+++def main() -> None:+ 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()++ k = _env("T2EI04_K", 15, int)+ alpha = _env("T2EI04_ALPHA", 0.0, float)+ damp = _env("T2EI04_SCALE_DAMP", 0.5, float)+ align = _env("T2EI04_ALIGN", "procrustes3d", str)++ view = args.data+ manifest = json.loads((Path(view) / "manifest.json").read_text(encoding="utf-8"))+ genes = view_io.panel_genes(view, manifest)+ lo, hi = int(manifest["min_cells"]), int(manifest["max_cells"])+ rng = np.random.default_rng(int(args.seed))++ a_entry, b_entry, t = view_io.interp_bracket(manifest)+ stage_a = view_io.read_stage(view, a_entry, genes)++ if b_entry is None:+ n = clip_n(stage_a.n, lo, hi)+ blocks_a, dn_a = build_blocks(stage_a.coords, k, rng, stage_a.n)+ ia, ca = assemble(stage_a.coords, draw_blocks(blocks_a, n, rng), alpha, dn_a, rng)+ X = np.asarray(stage_a.X[ia].todense(), dtype=np.float32)+ coords = scale_to_rms(ca, rms_radius(stage_a.coords))+ else:+ stage_b = view_io.read_stage(view, b_entry, genes)+ t = float(t)+ aa, ab, _info = align_pair(stage_a.coords, stage_b.coords, stage_a.labels,+ stage_b.labels, align)+ rms_a = rms_radius(stage_a.coords)+ rms_b = rms_radius(stage_b.coords)+ target_rms = log_interp(rms_a, rms_b, t, damp)+ ca = scale_to_rms(aa, target_rms)+ cb = scale_to_rms(ab, target_rms)+ n = interp_count(stage_a.n, stage_b.n, t, lo, hi)+ n_b = int(np.clip(round(t * n), 0, min(n, stage_b.n)))+ n_a = min(n - n_b, stage_a.n)+ n_b = min(n - n_a, stage_b.n)++ blocks_a, dn_a = build_blocks(ca, k, rng, stage_a.n)+ blocks_b, dn_b = build_blocks(cb, k, rng, stage_b.n)+ ia, CA = assemble(ca, draw_blocks(blocks_a, n_a, rng, stage_a.labels), alpha, dn_a, rng)+ ib, CB = assemble(cb, draw_blocks(blocks_b, n_b, rng, stage_b.labels), alpha, dn_b, rng)++ X = np.clip(+ np.vstack([+ np.asarray(stage_a.X[ia].todense(), dtype=np.float32),+ np.asarray(stage_b.X[ib].todense(), dtype=np.float32),+ ]), 0.0, None)+ coords = scale_to_rms(np.vstack([CA, CB]), target_rms)++ view_io.write_t2(args.out, X, coords.astype(np.float32), genes, seed=int(args.seed))+++if __name__ == "__main__":+ main()
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k023 | Time-split validation with a held-out intermediate or next time point | notes/handover/02_知识学习路线.md |
| k024 | World-model evaluation dimensions for state-transition predictors | notes/competition/07_biomedical_world_models.md |
| k016 | Degenerate-solution checks for population predictions | notes/handover/02_知识学习路线.md |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 从零实现 T2EI-04 空间 k-NN 块抽样插值:procrustes3d 对齐 + 阻尼 log-RMS 缩放后,每侧以随机种子+未覆盖近邻成块(k=15),按块主类型分层以 (1−t):t 整块抽取,表达/坐标原样拼接,jitter 默认关闭(α=0)。 |
|---|---|
| 各组分数的变化 | cell_state:噪声内:mmd_u 0.01657→0.01687(-0.06 分),variogram 0.02952→0.02906(+0.04 分),组 -0.08;类型分层块抽取未损害组成。 expression_change:噪声内:de_score 0.2069→0.2414(+0.15 分),de_direction 0.3757→0.3607(-0.08 分),组 +0.27,符合预期(本方案不改表达数值)。 local_spatial:变好但幅度接近噪声:neighborhood_mmd 0.05791→0.054(skill 0.573→0.590,+0.43 分),组 +1.73;方向与 k=1 对照(raw 0.0635)一致,是机制的目标收益。 shape_scale:变好:d2_shape 0.00841→0.00514(skill 0.934→0.989,+0.46 分),occupancy_dice 0.7735→0.7919(+0.23 分),scale_log_ratio 不变,组 +2.76;块抽样+统一 RMS 缩放让整体形态更贴近真值。 |
| family_id | T2EI-04 |
| 假设是否成立 | 是 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 3 次:— |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 16,562 · 输出 1,351 · 思考 606 |
| 任务(第一行) | 分析节点 n23 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/23/analyst.jsonl (文件不在) |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 38 |
| 工具调用 | 共 43 次:— |
| 用时 | 24 分 |
| token 数 | 输入 86,960 · 输出 17,620 · 思考 19,626 |
| 任务(第一行) | 按计划修改程序:T2EI-04 保邻域块抽样:以空间近邻块为单位混抽两端阶段 |
| 最后的回答(摘录) | **完成。** draft 节点 23(T2EI-04 保邻域块抽样)已提交在 `solution/`。 - **做了什么**:从零实现空间 k-NN 块抽样插值——随机种子 + 未覆盖近邻成块(k=15),全阶段块池、按块主类型分层以 (1−t):t 整块抽取,表达/坐标原样,procrustes3d 对齐 + 阻尼 log-RMS 缩放,jitter 默认关闭;单输入退路已测。 - **查分**(9/20 次):机制开 k=15 → **57.80**(seed 1: 57.53,local_spatial 56.2/57.7,nbhd raw 0.0597/0.0561);机制关对照 k=1 → 57.13(local 54.6,nbhd 0.0635,复现 mix 基线 57.23);同侧近邻占比 0.906 vs 0.813,机制生效。k=10/25 同向。FPS 早停池偏外周(nbhd 0.072–0.080)已修复;α=0.3 jitter 轻微劣化,关闭。 - **下一步最值得试**:在本块抽样管线上叠加节点 11/13 的类型级表达位移 + 各向异性坐标整形,有望把 expression 62 级与 local_spatial 56+ 合并,冲击 63+。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/23/engineer.jsonl (文件不在) |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 1 分 |
| token 数 | 输入 11,348 · 输出 1,446 · 思考 2,681 |
| 任务(第一行) | 为节点 n23(草稿,父节点 nNone)写改进计划 PLAN.json,思路 T2EI-04 |
| 最后的回答(摘录) | 标配对,直接改善neighborhood_mmd。",
"approach": "1) 读取两端输入阶段(a,b)的表达矩阵与spatial_3D坐标。\n2) Procrustes 3D对齐:把b侧坐标刚性对齐到a侧(旋转+平移,不缩放),使两端坐标在同一参考系。\n3) 构建块:对每侧分别计算3D坐标的k-NN(k=15,与评分器的15-近邻一致)。用贪心最远点采样(FPS)选出N_seed个种子细胞,每个种子与其k个近邻构成一个块(去重:已被其他块包含的细胞不再当种子)。初始N_seed按目标细胞数/(k+1)估算,实际用覆盖-去重循环调到目标数。\n4) 按(1−t):t比例从a/b侧抽取块:t=0.5时各半。用分层策略保证每侧的空间均匀性(FPS已保证)。\n5) 组装输出:把选中块的表达和坐标原样拼入输出。块内坐标保持相对位移不变。\n6) 块间jitter:对每个块整体加一个随机平移向量,幅度=α×块内平均最近邻距离(初始α=0.3,搜索[0.1,1.0]),防止块间精确重叠。\n7) 全局RMS缩放:把输出云均匀缩放到目标RMS(取a侧RMS的(1−t)+b侧RMS的t的log插值),保持坐标单位一致。\n8) 表达完全不动(原样保留源细胞的表达值),不施加任何位移或缩放。\n9) 单输入阶段退路:若只有一个阶段,全部块从该阶段抽取,无混合,jitter和RMS缩放仍执行。\n10) vec-score快速筛选:先在子样(每侧1500细胞、k=15)上跑3组参数(α=0.1/0.3/1.0),确认neighborhood_mmd优于独立混抽后再全量。查分上限20次,前6次用于参数扫描(k∈{10,15,25}×α∈{0.3,1.0}),保留余量给最优配置的多seed确认。",
"expected_groups": ["local_spatial", "shape_scale"],
"risks": "1) 块间边界不自然:不同阶段的块拼接处可能出现表达-坐标不连续,反而拉高neighborhood_mmd。Engineer应在小样上先比较块抽样与独立混抽的neighborhood_mmd raw,若块抽样反而更差则立即停止。2) FPS种子选取可能偏向高密度区域,导致低密度区域细胞缺失、组成偏移,损害mmd_u。对策:FPS后检查输出细胞数是否达标,不足时降低k或增加种子数。3) 表达组可能略低于节点13(62.11),因为本方案不施加类型级表达位移,预期接近mix水平(~59-60)。若表达组降幅>2分,应在后续improve节点叠加表达位移而非在本draft中混入。4) 块太大(k过大)会让输出变成若干孤立团,破坏整体形状(d2_shape、occupancy_dice劣化);k=15是与评分器对齐的初始值,不应超过30。",
"family_id": "T2EI-04",
"mechanism": "以空间k-NN块(种子+15近邻,保持相对坐标和表达配对)为抽样单元,按(1−t):t比例从两端阶段抽取完整块拼成输出,块内表达-坐标配对不被打破,从而保持评分器15-近邻平均表达分布的局部一致性。",
"vs_constant_shift": "常数位移对每个细胞(或每个类型)施加统一表达偏移,不改变空间配对关系。本方案不修改任何细胞的表达值,而是改变'哪些细胞被选中、以什么空间构型进入输出'——通过保持空间邻域完整来改善表达与位置的配对质量。机制作用在空间抽样策略上,不在表达数值上。",
"mechanism_evidence": "Engineer应对比三组输出的以下指标:(a) neighborhood_mmd raw:块抽样 vs k=1独立混抽(即off对照),预期块抽样更低;(b) 块内细胞的15-近邻是否确实来自同一块(抽样后检查:输出中每个细胞的15个最近邻中,同块占比应>70%);(c) mmd_u不应显著变差(组成未改变);(d) d2_shape和occupancy_dice不应因块间空隙而显著劣化。若(a)无改善或同块占比<50%,说明块结构在拼接后被打散,机制未生效。",
"mechanism_off_control": "将k设为1(每个'块'只含种子自身,无近邻),其余流程完全相同(FPS选种、(1−t):t比例、jitter、RMS缩放)。k=1退化为独立细胞混抽,等价于标准mix。预期差别:k=1时neighborhood_mmd raw应与节点2的mix水平(~0.055-0.060)相当;k=15时若机制有效应明显更低。若k=15与k=1的neighborhood_mmd无差异,说明块结构未起作用。",
"sources": []
} |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-171955-search-t2-embryo-interp-chain-12h/nodes/23/researcher.jsonl (文件不在) |