Set Transformer 金融表征:用诱导点注意力聚合多资产
组合是集合不是序列,但 DeepSets 的「逐资产编码+对称池化」有个盲区:池化前每个资产互相看不见,成对交互(拥挤度、相似持仓共振)只能靠编码器隐式凑。Set Transformer(ICML 2019)把交互焊进结构:SAB 让集合内元素两两做注意力,PMA 用可学习种子向量做注意力池化,ISAB 用 m 个诱导点把 O(K²) 注意力砍成 O(K·m)。纯 numpy 从零实现 SAB+PMA(手写 einsum 反向传播,梯度校验 1e-9 级),在组合拥挤度聚合任务上实测:SetTransformer R²=0.843 > DeepSets-mean 0.831 ≈ 统计聚合+Ridge 0.830——成对交互任务上有真实但温和的优势;注意力矩阵与真实相似度结构吻合,置换偏移 1.4e-15;ISAB 实测 K=2048 时提速 55 倍。但诚实翻车:n=300 小样本下 SetTransformer 过拟合(train 0.92 / test 0.53),被 DeepSets(0.80)反杀——注意力参数多,先吃数据。拆穿注意力必胜/池化都一样/诱导点无损/交互自动学会/直接上实盘五类陷阱(中阶)。
先说结论:DeepSets 的对称池化解决了「置换不变」,但没解决「资产之间互相看见」——池化前每个资产是独立编码的,成对交互只能靠 φ 网络隐式凑。Set Transformer 把交互显式焊进结构:集合内两两注意力(SAB)+ 注意力池化(PMA),交互任务上确实更强,但强得有条件——数据要够,任务要真的需要成对交互。
在组合拥挤度聚合任务上(目标由资产两两相似度决定),纯 numpy 实现的 SetTransformer 测试集 R²=0.843,高于 DeepSets-mean 的 0.831 和手工统计聚合+Ridge 的 0.830;但把训练集砍到 300 条后,SetTransformer 过拟合到 train 0.92 / test 0.53,被 DeepSets 的 0.80 反杀。这一涨一跌,就是这篇文章要讲清楚的边界。

一、DeepSets 的盲区:池化前,资产互相看不见#
上一篇《置换不变集合建模》讲过 DeepSets 的万能分解:任意置换不变函数都能写成
逐资产编码 φ、对称池化 Σ、读出 ρ。这个定理在数学上是完备的——但「存在这样的 φ 和 ρ」不等于「梯度下降能在有限宽度、有限数据下学出来」。
问题出在结构上:φ(xᵢ) 只吃 xᵢ 一个资产。如果目标函数依赖资产两两之间的关系——比如:
- 组合拥挤度:持仓之间相似度高 → 同涨同跌风险大,这本质是 ;
- 对冲配对质量:组合里有没有互相对冲的两条腿;
- 风格集中度:多少资产暴露在同一隐因子上;
这些量都是成对交互(pairwise interaction),池化后才相遇的编码向量必须提前把「我可能跟谁比」的所有信息塞进固定维度——维度不够就塞不下,这就是 DeepSets 在交互任务上的结构性劣势。
Set Transformer(Lee et al., ICML 2019)的回答很直接:别等池化后再相遇,在编码阶段就让元素两两做注意力。
二、三个积木:SAB、PMA、ISAB#
2.1 SAB:集合内自注意力块#
SAB(Set Attention Block)就是把标准自注意力用在集合元素上:
每个资产 i 对所有资产 j 计算注意力权重,按权重聚合。关键性质:注意力对元素排列是等变的(equivariant)——把输入行序打乱,输出跟着同样打乱,不变性留给后面的池化步骤完成。
与序列 Transformer 的唯一区别:没有位置编码。集合无序,加位置编码反而破坏置换对称性。
2.2 PMA:用注意力做池化#
DeepSets 用 mean/sum 池化,每个元素权重相等(或恒为 1)。PMA(Pooling by Multihead Attention)引入一个可学习的种子向量 s,让它作为 query 对集合元素做注意力:
池化权重 αᵢ 由内容决定——重要的资产多贡献,无关的资产少贡献。softmax 对下标 i 求和是对称操作,所以 PMA 输出严格置换不变。
我的简化实现(单头、单种子):
def st_forward(p, X): # X: (batch, K, d)
E = np.maximum(X @ p["We"] + p["be"], 0) # 逐资产嵌入
Q, Kk, V = E @ p["Wq"], E @ p["Wk"], E @ p["Wv"]
S = np.einsum("bik,bjk->bij", Q, Kk) / np.sqrt(h)
A = softmax(S) # (b,K,K) 两两注意力
U = np.einsum("bij,bjh->bih", A, V) # SAB 输出
F = np.maximum(U @ p["W1"] + p["b1"], 0)
al = softmax(F @ p["ws"]) # PMA 池化权重
z = np.einsum("bk,bkh->bh", al, F) # 注意力池化
return z @ p["w2"] + p["b2"][0]python反向传播全部手写(einsum 的转置规则 + softmax 的 Jacobian),有限差分梯度校验最大相对误差 5.2e-9,所有 10 组参数都在 1e-9 量级以下——反向公式没问题。
2.3 ISAB:诱导点把 O(K²) 砍成 O(K·m)#
SAB 的注意力矩阵是 K×K。K=8 无所谓,K=3000(全 A 股)就是 900 万个注意力权重每层每样本。ISAB(Induced Set Attention Block)的解法是引入 m 个可学习的诱导点(inducing points) I:
- 诱导点先「采访」集合:,m×K 注意力,把 K 个资产的信息压缩进 m 个槽位;
- 集合再「查阅」摘要:,K×m 注意力,每个资产从 m 个槽位取回自己需要的上下文。
两步都是线性于 K,总复杂度 O(K·m),m 固定(如 16、32)。实测前向耗时:
| 集合大小 K | SAB 全注意力 | ISAB (m=16) | 加速 |
|---|---|---|---|
| 64 | 0.8ms | 0.5ms | 1.7x |
| 256 | 11.9ms | 1.8ms | 6.6x |
| 1024 | 198.8ms | 7.2ms | 27.7x |
| 2048 | 807.1ms | 14.6ms | 55x |
K=2048(接近全 A 股主板规模)时 55 倍加速,且曲线斜率清晰地一个是 2、一个是 1(log-log 图见下文)。这不是工程优化,是复杂度阶的差异。
三、实验:组合拥挤度聚合任务#
3.1 任务设计——故意造一个「必须看成对交互」的目标#
K=8 个资产,每个 4 维特征。目标:
第一项 DeepSets 闭着眼能学;第二项是真·成对交互——资产两两距离决定,任何逐元素编码都无法精确表达。权重 3:0.5 故意让交互项主导。训练 3000 条 / 测试 1000 条,噪声 σ=0.05。
3.2 主实验结果#
| 模型 | 测试集 R² | 训练集 R² | 训练耗时 |
|---|---|---|---|
| SetTransformer (SAB+PMA) | 0.843 | 0.880 | 6s |
| DeepSets-mean | 0.831 | 0.858 | 1s |
| 统计聚合(mean/std/max/min)+Ridge | 0.830 | — | <1s |

三个诚实的观察:
第一,SetTransformer 赢了,但只赢 1.2 个点。 不是论文里常见的十几个点碾压。原因:K=8 的集合很小,RBF 相似度均值是个相当平滑的统计量,DeepSets 的 mean 池化 + 32 维隐层已经能用「分布矩」隐式近似它(std 池化本身就携带了散布信息——注意统计聚合+Ridge 也到了 0.830,因为 std/max/min 特征刚好与两两距离强相关)。交互项可以被单元素统计量近似到什么程度,决定了注意力的边际收益。
第二,注意力真的学到了相似度结构。 挑一个含高度相似资产对的测试样本,SAB 注意力矩阵 A 与真实相似度矩阵 exp(-‖xᵢ-xⱼ‖²/2) 的热区位置吻合(封面图中、左两幅),PMA 池化权重也偏离了均匀的 1/8——模型确实在「按内容分配注意力」,不是学了个平均数。
第三,置换不变性严格成立。 打乱 8 个资产的输入顺序,输出最大偏移 1.44e-15(float64 舍入零)。注意力是等变的、PMA 是不变的,结构保证不靠训练。
3.3 小样本翻车:注意力先吃数据#
把训练集从 3000 砍到 300,其他不变:
| 模型 | train R² | test R² |
|---|---|---|
| SetTransformer | 0.917 | 0.527 |
| DeepSets-mean | 0.860 | 0.798 |

SetTransformer 训练集拟合更好(0.92 > 0.86),测试集却崩了(0.53 < 0.80)——教科书级过拟合。原因很朴素:SAB 的 Wq/Wk/Wv 三组投影 + 注意力的组合自由度,参数量和假设空间都远大于 DeepSets 的单个 φ 网络。数据少的时候,更强的表达力就是更大的方差。 金融场景里「每个月一个组合快照」这种数据量(几百条),上注意力大概率是给自己挖坑。
四、五个陷阱#
陷阱一:「注意力比池化强」——看任务。 目标若是逐资产量的和/均值(组合收益、总市值加权暴露),DeepSets 结构完全够,注意力多出来的参数纯属噪声源。只有目标真的依赖元素间关系(拥挤度、配对、相对排序)时 SAB 才有结构优势。我们的实验里交互项占主导也只赢 1.2 个点——先想清楚你的 y 里有多少成对成分。
陷阱二:「PMA 总比 mean 池化好」——种子向量也是参数。 PMA 在「少数资产决定输出」的任务上(如识别组合里最危险的一只)优势明显;在「人人平等贡献」的任务上退化成一个学出来的近似均匀权重,还多花了参数。上一篇 DeepSets 的教训在这里对偶成立:池化选择要匹配目标的聚合语义。
陷阱三:「ISAB 是免费加速」——m 是信息瓶颈。 55 倍加速的代价是把 K 个资产先压进 m 个槽位。若集合里的有效模式数超过 m(比如 30 个行业板块、m=16),诱导点摘要必然有损。m 要按「集合里独立结构的数量」定,不是越小越快越好。
陷阱四:「等变+不变=交互自动学会」——小样本下学不会。 结构给了你学交互的可能性,不保证学出来。n=300 实验里 SetTransformer 的注意力有充分自由度去拟合噪声,测试集 R² 只剩 0.53。数据量 < 参数量的 10 倍时,先用 DeepSets 或手工聚合特征打底。
陷阱五:「合成任务赢了就上实盘」——真实拥挤度没有干净标签。 本文的 y 是造出来的 RBF 相似度,真实拥挤度要靠持仓重叠、成交拥挤、因子暴露等代理变量拼接,标签噪声比 σ=0.05 大一个数量级以上。结构优势会被标签噪声稀释——先在你的真实标签上测信噪比,再决定值不值得上注意力。
五、结论#
- Set Transformer = DeepSets + 显式成对交互:SAB 让资产两两相见,PMA 让池化按内容分配权重,ISAB 用 m 个诱导点把 O(K²) 砍成 O(K·m)(K=2048 实测 55 倍)。
- 交互任务上有真实但温和的优势:R² 0.843 vs 0.831,赢在结构、赢得不多——因为许多交互统计量能被单元素编码+池化近似。
- 数据量是硬门槛:n=300 时被 DeepSets 反杀 27 个点,注意力的表达力在小样本下是负资产。
- 手写 einsum 反向传播梯度校验 5.2e-9,置换偏移 1.4e-15——实现干净,结论可复现。
组合建模的工具箱到这里齐了:手工聚合(最便宜)→ DeepSets(置换不变打底)→ Set Transformer(成对交互,数据够再上)。按数据量和任务的交互浓度选,别按论文年份选。
风险提示:本文全部实验基于合成数据,用于验证方法性质而非产生投资信号。实盘应用前需在真实持仓与拥挤度代理数据上独立验证。文中代码为教学实现,未考虑生产环境的数值稳定性与性能要求。