从卷积核重新定义 TreeHeap 操作
上一篇 SPR-022 把 TreeHeap 放回了已有数学背景:
rooted-tree Hopf algebra
operad
decomposition space
tree kernel
但 Houming818 指出了一个更核心的问题:
TreeHeap 的操作不应该先被理解成一堆手写函数。
TreeHeap 的核心操作应该是 kernel 在树上的卷积。
这句话把方向拉正了。
以前容易说成:
TreeHeap 有 plus、compose、decompose、conjugate。
另外,我们再给它加一个 kernel。
现在应该反过来:
TreeHeap 的 plus、search、compose、decompose、fold、conjugate,
都应该从 kernel 如何卷积整棵树并更新内存态来定义。
也就是说:
TreeHeap 不是“树结构 + 一堆函数”。
TreeHeap 是“树形高维状态场 + 一组卷积核”。
先看 CNN 的类比
在 CNN 里,一张图像是一个状态场:
image[row, col, channel]
卷积核扫过图像:
3x3 patch
↓
kernel
↓
feature score
整张图扫完以后得到:
feature map
例如一个边缘检测 kernel,不是在一个像素上做判断,而是在整张图上滑动,生成一张“哪里像边缘”的图。
TreeHeap 应该类似。
TreeHeap 的状态场不是二维图像,而是:
value × address × topology
也就是:
节点值
路径地址
父子拓扑
所以 TreeHeap kernel 不是看一个孤立节点。 它看一个局部子堆:
root
/ \
left right
然后在整棵树上滑动。
TreeHeap kernel convolution 的定义
设当前 TreeHeap 内存态是:
$$ H_t $$以路径 (a) 为中心的局部子堆是:
$$ S_a(H_t) $$一个 kernel 是:
$$ K_\theta(q, S_a, W) $$其中:
| 符号 | 含义 |
|---|---|
| (q) | query,要找或要写的目标 |
| (S_a) | 地址 (a) 处的局部子堆 |
| (W) | world model / 背景场 |
| (\theta) | kernel 参数,可以固定,也可以学习 |
卷积整棵树就是:
$$ \operatorname{Conv}_K(H_t, q) = \{K_\theta(q, S_a(H_t), W)\}_{a \in A(H_t)} $$翻译成人话:
对树上每个候选地址 a:
取局部子堆 S_a
用同一个 kernel 计算响应
最终得到一张覆盖整棵树的响应图
这张响应图可以叫:
score map
update map
route map
probability field
不同名字对应不同用途,但本质都是:
kernel 扫树以后得到的全局状态场。
plus 不再是“写到某个地址”
以前我们容易把 plus 理解成:
H plus x = 把 x 写到地址 a
但这太像普通数组写入了。
新的定义应该是:
plus kernel 扫描整棵 TreeHeap。
每个地址都产生一个 write score。
这些 score 形成一个写入概率场。
然后 H 根据这个概率场更新。
数学上:
$$ s_a = K_{\text{plus}}(x, S_a(H_t), W) $$$$ p_a = \operatorname{softmax}(s_a) $$$$ H_{t+1} = H_t + \sum_a p_a \cdot \Delta_a(x, H_t) $$其中:
s_a = 地址 a 的写入响应
p_a = 地址 a 的写入概率
Δ_a = 如果写到地址 a,会产生的局部状态更新
所以 plus 的本质不是:
直接指定地址。
而是:
kernel 卷积整棵树,形成 write field,再更新内存态。
search 也是同一个东西
search 更直观。
定义:
$$ s_a = K_{\text{search}}(q, S_a(H_t), W) $$如果只要硬搜索结果:
$$ a^* = \arg\max_a s_a $$如果要概率容器:
$$ p_a = \operatorname{softmax}(s_a) $$所以 search 不是特殊函数。
它就是:
kernel 卷积树,输出 score map。
plus 和 search 的差别只是:
search 把 score map 用来读。
plus 把 score map 用来写。
conjugate 不是额外 if-else
共轭操作也应该从 kernel 角度定义。
假设镜像变换是:
L <-> R
例如:
LRL -> RLR
记为:
$$ \sigma(a) $$那么 kernel 的共轭是:
$$ K^\sigma = \sigma^{-1} \circ K \circ \sigma $$这句话的意思是:
先把 TreeHeap 镜像过去;
在镜像空间里用 kernel 做卷积;
再把响应映射回来。
所以 conjugate 不是:
如果左边怎样,右边就怎样。
它是:
卷积核本身做了一次对称翻转。
这就像图像里一个检测左斜边缘的 kernel,可以通过翻转变成检测右斜边缘的 kernel。
TreeHeap 里对应的是:
左路径结构
↓ 镜像
右路径结构
这次 ARA 的新 claim
这次新增:
M0-SOFT-C08
Claim:
TreeHeap primitive operations can be defined as kernel convolutions over
the whole tree state:
search emits a score map,
plus/write uses that map as an update field,
and conjugate is a symmetry transform of the kernel.
中文解释:
TreeHeap 的基本操作可以统一成:
kernel 在整棵树上卷积,然后产生状态图。
search 用这张图读;
plus 用这张图写;
conjugate 是对 kernel 做镜像变换。
这不是说语言任务已经解决。 它只是先把操作语义统一起来。
Toy proof 怎么设计
我们做了一个小实验:
kernel_convolution_ops_probe.py
构造一棵 full binary TreeHeap。
在目标地址放入一个不对称子堆:
target_path = LRL
query = [root, left, right]
= [2.0, 5.0, -3.0]
局部子堆是:
patch(a) = [H[a], H[aL], H[aR]]
kernel 定义为:
$$ score(a) = -\lVert patch(a) - query\rVert^2 $$这个 kernel 很朴素。 它不是学习出来的。 它只是为了测试:
同一个卷积响应图,能不能解释 search / plus / conjugate。
实验 1:search score map
kernel 扫描所有候选子堆。
输出:
score(path)
然后取:
argmax score(path)
结果:
| 指标 | 结果 |
|---|---|
| search hit@1 | True |
| hit path | LRL |
| target probability | 1.0 |
说明:
search 可以被定义成 kernel 卷积后的 score map。
实验 2:plus write field
同一张 score map 不只可以拿来读。
也可以变成写入概率:
$$ p(a)=\operatorname{softmax}(score(a)) $$然后更新 TreeHeap:
$$ H_{t+1} = H_t + \sum_a p(a)\cdot write(a) $$结果:
| 指标 | 结果 |
|---|---|
| plus write hit@1 | True |
| write path | LRL |
| target update error | 0.000000 |
| max disjoint non-target update norm | 0.000000 |
这里有一个细节。
max_nontarget_update_norm = 0.75,看起来像有非目标节点被影响。
但原因是 TreeHeap 的子堆会重叠。 例如一个父 patch 会包含它的子节点。 目标子堆被写入以后,和它共享节点的其它 patch 也会观察到变化。
所以更干净的定位指标是:
max_disjoint_nontarget_update_norm = 0.0
意思是:
不共享节点的非目标子堆没有被写乱。
这说明 plus/write 可以被解释成:
kernel 卷积产生 write field,然后写入 TreeHeap 内存态。
实验 3:conjugate mirror
目标路径:
LRL
镜像以后:
RLR
原始 query 是不对称的:
[2.0, 5.0, -3.0]
如果直接拿原 kernel 去扫镜像树,会失败:
| 指标 | 结果 |
|---|---|
| raw mirror hit@1 | False |
| raw mirror hit path | RLLR |
但如果使用共轭 kernel:
K^sigma = sigma^-1 K sigma
结果:
| 指标 | 结果 |
|---|---|
| conjugate mirror hit@1 | True |
| conjugate hit path | RLR |
| score-map equiv max error | 0.000000e+00 |
这说明:
共轭不是树外的 if-else。
共轭是 kernel 的对称变换。
也说明 TreeHeap 的镜像能力可以从卷积核角度定义。
实验总表
| 检查项 | 结果 |
|---|---|
| pilot_pass | True |
| search hit@1 | True |
| plus write hit@1 | True |
| target update error | 0.000000 |
| max disjoint non-target update norm | 0.000000 |
| raw mirror hit@1 | False |
| conjugate mirror hit@1 | True |
| score-map equiv max error | 0.000000e+00 |
证据路径:
ara/m0-treeheap-math/src/kernel_convolution_ops_probe.py
ara/m0-treeheap-math/evidence/kernel_convolution_ops_probe/
这个 proof 证明了什么
它证明了一个很小、但很关键的东西:
search、plus/write、conjugate 可以共享同一种 kernel convolution 语义。
也就是:
kernel 扫树
↓
产生 score/update map
↓
读、写、镜像都从这张 map 或它的对称变换产生
这让 TreeHeap 操作不再是一堆散装函数。
它们开始有一个统一形式:
$$ H_{t+1} = \operatorname{Op}_K(H_t) $$其中:
$$ \operatorname{Op}_K $$来自 kernel 在树上的卷积。
这个 proof 没证明什么
它没有证明:
kernel 可以自己学出来。
这次 kernel 是固定的:
$$ score(a) = -\lVert patch(a)-query\rVert^2 $$它也没有证明:
TreeHeap 可以翻译。
TreeHeap 可以理解语言。
TreeHeap 比 Transformer 强。
这些都还不能说。
它只证明:
从操作定义上,TreeHeap 可以把 search、plus/write、conjugate
统一为 kernel convolution。
这个地基比“我们手写了几个函数”更干净。
GLM 审计后的修订
Runner / GLM 复核以后指出了一个非常重要的边界:
C08 的 conjugate proof 是 by construction 的恒等。
这句话是什么意思?
在代码里,我们定义了两个东西:
mirror_tree:
把路径 L/R 互换。
mirror_patch:
把局部子堆的 left/right 互换。
于是对于原始路径 (p),有:
$$ \operatorname{mirror\_patch} \big( \operatorname{patch}(\operatorname{mirror\_tree}(H), \sigma(p)) \big) = \operatorname{patch}(H,p) $$所以:
$$ score_{\text{conjugate}}(\sigma(p)) = score_{\text{original}}(p) $$这不是模型“自己发现了镜像规律”。
这是我们按共轭定义写出来以后,数学上必然成立。
因此,score_map_equiv_max_error = 0.0 的意义不是:
TreeHeap 学会了镜像。
而是:
如果我们把 conjugate 定义成 kernel 的对称变换,
那么 TreeHeap 的镜像 score map 可以保持一致。
这依然有价值。
但它的价值是:
操作语义统一。
不是:
学习能力证明。
所以 M0-SOFT-C08 的精确边界应该写成:
C08 支持的是 operator-semantics pilot。
它证明 search / plus / conjugate 可以被统一写成 kernel convolution。
它不证明 learned kernel,也不证明模型会自动学出共轭对称。
这个修订非常重要。
否则我们会把“定义上成立”误读成“实验上发现”。
下一步 Predict
下一步不能继续证明 fixed kernel。
fixed kernel 的作用已经完成:
说明 TreeHeap 操作可以被统一定义为 kernel convolution。
下一步要证明的是:
这个 kernel 能不能从数据中学出来?
所以我建议新增两个 predict。
P-SOFT05:learned convolution kernel
Predict:
如果 TreeHeap kernel 的核心是卷积状态变换,
那么一个非线性 learned kernel 应该能从 raw query + raw subheap 中
学会产生正确的 score map 和 write field。
注意关键词是:
raw query
raw subheap
也就是说,不能再手工喂:
diff = patch - query
abs(diff)
diff^2
root_alignment
child_alignment
这些都是答案提示。
真正的 learned kernel 应该输入:
query_root, query_left, query_right
patch_root, patch_left, patch_right
path metadata
然后自己学出:
query 和 patch 是否匹配。
P-SYNTAX01:真实句法树 micro benchmark
Predict:
如果 TreeHeap kernel 不是只在 toy 树上成立,
那么它应该能在小规模真实句法树上读到局部依存结构信号。
这不是 WMT BLEU。
这是一个桥梁实验。
目标是:
让真实语言数据第一次进入 M0/S1 的 TreeHeap kernel 证据链。
建议数据:
Universal Dependencies 小型子集
100 到 1000 句
任务:
给定一个 head token 的局部 TreeHeap 子结构,
预测或匹配它的 modifier / dependent pattern。
例如:
head -> left dependent / right dependent
verb -> subject / object / modifier
noun -> determiner / adjective / prepositional phrase
这个实验不要求翻译。
它只问:
TreeHeap kernel 在真实句法树上是否比 flat baseline 更会利用局部树结构?
下一步实验设计
下一步不是继续手写 kernel。
下一步应该问:
这个 kernel 能不能被学习出来?
也就是:
raw query + raw subheap
↓
learned kernel
↓
score map / write field / conjugate transfer
建议下一步做:
P-SOFT05: learned convolution kernel
对照:
fixed kernel
linear raw kernel
MLP raw kernel
TreeHeap convolution kernel
目标:
不用手工 diff。
让模型自己学会 query-subheap 比较。
如果 learned kernel 能做到:
search map 正确
write field 正确
mirror conjugate 可迁移
那我们才可以把 C05 往前推进。
实验 A:learned multi-pattern kernel
数据生成:
每个样本随机生成一个 query pattern。
把这个 pattern 注入 TreeHeap 的某个目标子堆。
模型必须在所有候选子堆里找出目标位置。
关键点:
不是固定 query。
必须是 multi-pattern。
因为固定 query 很容易退化成:
记住某一个模式。
多 pattern 才能测试:
kernel 是否真的学会比较 query 和 patch。
对照组:
| 模型 | 输入 | 预期 |
|---|---|---|
| fixed distance kernel | 手写 ( -\lVert patch-query\rVert^2 ) | 上限参考,不算学习 |
| linear raw kernel | raw query + raw patch | 应该失败或较弱 |
| MLP raw kernel | raw query + raw patch | 应该明显强于 linear |
| TreeHeap convolution kernel | raw query + raw patch + path/topology | 应该在 OOD 地址上最好 |
Evidence gates:
E-SOFT14:
MLP raw kernel > linear raw kernel
E-SOFT15:
TreeHeap convolution kernel 在 unseen depth / unseen address 上
优于 flat MLP baseline
E-SOFT16:
不使用 hand-coded diff / alignment 特征
Falsification:
如果 linear raw 或 flat MLP 在同样数据量下稳定匹配 TreeHeap kernel,
那么 TreeHeap kernel 没有显示额外结构收益。
实验 B:learned conjugate transfer
GLM 已经指出:
当前 conjugate proof 是 by construction。
所以真正要测的是:
learned kernel 是否能在镜像结构上迁移。
设计:
训练集:
只出现左侧结构,比如 L 开头路径。
测试集:
只出现镜像右侧结构,比如 R 开头路径。
比较:
raw learned kernel
explicit conjugate kernel
data augmentation baseline
flat MLP baseline
Evidence gates:
E-SOFT17:
explicit conjugate kernel 在 mirror OOD 上优于普通 learned kernel
E-SOFT18:
使用更少右侧样本达到同等准确率
E-SOFT19:
mirror score map 在 learned setting 下误差受控
Falsification:
如果普通 MLP 通过足够少样本就学到同等镜像迁移,
或者 explicit conjugate kernel 没有 sample efficiency 优势,
那么共轭 kernel 不构成有效归纳偏置。
实验 C:真实句法树 micro benchmark
数据:
Universal Dependencies
先取 100 到 1000 句
只做英文或中文单语
构造:
把 dependency tree 转成 TreeHeap-like 局部子结构。
每个候选 patch 包含:
head token embedding / id
left dependent
right dependent
dependency label 或无监督 slot
path/topology metadata
任务:
给定 query,找出正确 head-dependent 子结构。
或给定局部子树,预测 masked dependent / role。
对照组:
BoW / token-only baseline
flat MLP
small Transformer encoder
TreeHeap convolution kernel
Evidence gates:
E-SYNTAX01:
TreeHeap kernel > token-only baseline
E-SYNTAX02:
TreeHeap kernel 在 OOD dependency pattern 上比 flat MLP 更稳
E-SYNTAX03:
去掉 path/topology/subheap 后性能明显下降
Falsification:
如果 token-only 或 flat MLP 在真实句法树 micro benchmark 上匹配 TreeHeap kernel,
则 TreeHeap 结构对真实语言局部结构没有显示额外收益。
ARA 补项
GLM 还指出了两个 ARA 文档层面的缺口。
第一,PAPER.md 里还没有把 SPR-022、SPR-023 和 M0-SOFT-C08 注册到总 claim 树。
第二,exploration_tree.yaml 里还没有把最近三步补进去:
C07 structural proof
C08 kernel convolution proof
P-SOFT05 learned kernel pivot
这些不是实验本身的问题。
它们是 ARA 索引问题。
我建议下一次 ARA 修订补:
C5-009:
SPR-022 数学底座:
TreeHeap math foundations map to BCK Hopf algebra + operad.
C5-010:
SPR-023 kernel convolution:
TreeHeap primitive ops can be defined as kernel convolutions over tree state.
同时在 trace DAG 中补:
E-SOFT-002:
structural_c05_probe
E-SOFT-003:
kernel_convolution_ops_probe
D-SOFT-003:
operator semantics unified by kernel convolution
P-SOFT-005:
learned convolution kernel
这一步我先不直接改。 原因是:
这篇 blog 先给 Houming818 review 下一步实验方向。
等 review 后,再把 PAPER.md 和 trace DAG 一次性修正。
结论
这篇的结论是一句话:
TreeHeap 的操作本体应该是 kernel convolution。
不是:
树上有一个 kernel。
而是:
kernel 扫树,产生状态场;
状态场再解释为 search、plus、write、fold、conjugate。
这把 TreeHeap 从“树形数据结构”推进到了:
树形高维状态场上的卷积计算系统。
这才是下一阶段要训练、要证明、要和 MLP / Transformer 对照的对象。