第 30 课 卷积、注意力、Transformer 与时间分块¶
RNN 把历史压进状态,卷积沿时间寻找反复出现的局部形状,注意力让相隔很远的位置直接比较。本课沿着这三条路线,理解复杂序列模型为何出现。
同一种三日形状可能出现在任何位置¶
研究员小周观察一段二十日行情时,常会注意到局部形状。例如,前两天波动逐渐收窄,第三天成交量放大并向上突破。这个三日形状可能出现在窗口开头,也可能出现在第十天附近。普通全连接网络会把“第 1 天、第 2 天、第 3 天”与“第 10 天、第 11 天、第 12 天”当成不同列,需要为不同位置重新学习权重。
我们更希望制作一枚可以沿时间滑动的印章。它每次查看连续三天,用同一套规则打分。无论形状出现在窗口哪里,只要局部排列相似,分数就会相似。这种沿数据移动并重复使用同一组权重的计算叫作卷积。处理一维时间序列时,常称为一维卷积;由多层卷积组成的神经网络通常简称 CNN。
先用五日收益做一次手算。为了方便,表中的 1 表示 1%。我们设计一枚三日过滤器,权重依次为 -0.5、0 和 0.5。它实际上在比较窗口最后一天与第一天。中间一天暂时不影响分数。
五日收益 -1, 2, 1, -1, 1
三日过滤器权重 -0.5, 0, 0.5
窗口 1 [-1, 2, 1] 得分 (-0.5)×(-1) + 0×2 + 0.5×1 = 1.0
窗口 2 [ 2, 1, -1] 得分 (-0.5)×2 + 0×1 + 0.5×(-1) = -1.5
窗口 3 [ 1, -1, 1] 得分 (-0.5)×1 + 0×(-1) + 0.5×1 = 0.0
第一个窗口从 -1 上升到 1,得到正分;第二个窗口从 2 下降到 -1,得到负分;第三个窗口首尾相同,得到零。真实 CNN 会同时训练许多过滤器,每枚过滤器可以观察收益、成交量、振幅等多项输入。过滤器权重由损失函数学习,研究者无需手工指定,不过这个数字例子揭示了卷积最重要的两点。小窗口负责提取局部模式,同一组权重会在不同位置重复使用。
flowchart LR
accTitle: 三日卷积窗口沿五日序列滑动
accDescr: 同一组三个权重先作用于第1到第3天,再作用于第2到第4天,最后作用于第3到第5天,三个得分共同形成局部模式序列
days["五日输入<br/>-1 2 1 -1 1"] --> w1["窗口 1<br/>第 1 至 3 天<br/>得分 1.0"]
days --> w2["窗口 2<br/>第 2 至 4 天<br/>得分 -1.5"]
days --> w3["窗口 3<br/>第 3 至 5 天<br/>得分 0.0"]
w1 --> features["局部特征序列<br/>1.0 -1.5 0.0"]
w2 --> features
w3 --> features
三行 Python 怎样复现这枚滑动印章¶
下面的代码只完成刚才的三次手算。输入是五个收益数字和三个过滤器权重,输出应为 [1.0, -1.5, 0.0]。它没有训练网络,目的是让读者看清“取窗口、逐项相乘、求和、向右移动”四个动作。
returns = [-1, 2, 1, -1, 1]
kernel = [-0.5, 0, 0.5]
scores = []
for start in range(3):
window = returns[start:start + 3]
score = sum(x * w for x, w in zip(window, kernel))
scores.append(score)
print(scores)
range(3) 让起点依次取 0、1、2,因为五日序列中只能放下三个完整的三日窗口。切片语句取出当前三天,zip 把每项输入与对应权重配成一对,sum 再把三个乘积相加。最后把分数放入列表。真实卷积层会一次处理许多样本、特征和过滤器,还会使用自动求导学习权重,基础动作仍可以追溯到这段循环。
卷积后还会接激活函数、归一化或汇总层。多层卷积能把短形状继续组合成长形状。第一层可能识别三日变化,第二层再把相邻的局部结果组合成更长结构。网络越深,能够覆盖的历史范围越大,同时也更容易过拟合,因此仍要与简单移动平均、线性模型和树模型比较。
时间卷积为何必须尊重先后顺序¶
图像卷积通常可以同时查看一个像素左边和右边,因为整张图在预测时已经可见。时间序列不同。若我们要在第 10 天结束后形成预测,卷积不能偷偷读取第 11 天。只使用当前与过去位置的卷积叫作因果卷积。
实现卷积时经常需要在序列边缘补数,这叫作填充。若照搬图像中的对称填充或居中窗口,模型可能让当前位置连接到右侧未来数据。最直接的检查方法,是保存一份早期输出,再在数据末尾添加几行未来数据。若新增未来行改变了早期预测,时间边界很可能存在问题。
时间卷积网络通常简称 TCN。它常把因果卷积与扩张卷积结合。普通三日卷积查看连续三格;扩张距离为 2 时,它查看第 1、3、5 格;距离为 4 时,它查看第 1、5、9 格。随着层数增加,网络不必逐日经过很长链条,就能覆盖更远历史。
TCN 还常使用残差连接。残差连接允许输入绕过若干层,与新计算结果相加,给梯度提供较短通路。它能帮助较深网络训练,却无法纠正未来填充、错误标签和不合理成本。与 RNN 相比,卷积的各个时间位置可以同时计算,通常更容易并行;它如何聚合长期信息,则由窗口大小、扩张距离和层数共同决定。
当今天想直接询问某个遥远日期¶
RNN 让第 1 天的信息逐步经过第 2、3、4 天,最后到达第 5 天。即使 LSTM 改善了长期通道,信息仍要沿时间顺序传递。注意力提供另一条路线。今天的位置可以直接与窗口里的每个历史位置比较,并按匹配程度取回信息。
可以把这个过程想成一次图书馆检索。今天的研究问题是一张检索单;每个历史日期都有一张索引标签,也保存一段真正的内容。模型先比较检索单与所有索引标签,再决定从每个日期取回多少内容。
注意力把这三类角色分别称为 Query、Key 和 Value,中文常译为查询、键和值。Query 表达当前正在寻找什么,Key 表达每个位置可以用什么线索被找到,Value 保存匹配以后真正汇总的内容。三者通常由同一份输入经过不同权重变换得到。
| 名称 | 在计算中的职责 | 图书馆类比 | 时间序列中的直觉 |
|---|---|---|---|
| Query | 提出当前匹配要求 | 读者的检索问题 | 今天正在寻找怎样的历史状态 |
| Key | 提供每个位置的匹配线索 | 每本书的索引标签 | 每个日期有什么可供比较的特征 |
| Value | 保存要被取回的内容 | 书中真正的内容 | 每个日期准备贡献给当前表示的信息 |
用四个日期手算一次注意力¶
假设今天的 Query 与四个历史 Key 比较后,得到匹配分数 1、2、0 和 1。分数越高,表示当前查询与该位置越相似。为了把这些分数转换成非负且总和为 1 的比例,模型常使用 softmax。softmax 会先把较高分数放大,再统一归一化。上面四个分数经过转换后,大约得到 0.20、0.53、0.07 和 0.20。
假设四个位置的 Value 简化为 -1、0.5、2 和 -0.5。注意力输出就是各项 Value 按权重相乘后相加。
第 1 个位置贡献 0.20 × (-1) = -0.20
第 2 个位置贡献 0.53 × 0.5 = 0.265
第 3 个位置贡献 0.07 × 2 = 0.14
第 4 个位置贡献 0.20 × (-0.5)= -0.10
最终汇总结果约为 0.105
第 2 个位置匹配权重最高,所以它贡献较大。第 3 个位置权重低,但 Value 数值较大,仍产生一定影响。真实模型中的 Query、Key 和 Value 都是向量,匹配通常通过向量点积计算。把第 \(i\) 个查询和全部键放在一起,常见的缩放点积注意力写成下面形式。
公式中的 \(QK^{\mathsf T}\) 计算查询与各个键的匹配分数,\(d_k\) 是键向量的维度。除以平方根用于防止维度较高时分数过大,softmax 再把分数变成权重,最后乘以 \(V\) 完成加权汇总。初学阶段先掌握这条计算路线即可,无需手推矩阵导数。
自注意力让一条序列内部互相比较¶
当 Query、Key 和 Value 都来自同一条序列时,这种计算叫作自注意力。每个日期都可以形成自己的 Query,并直接查看其他日期的 Key 与 Value。第 60 天回看第 2 天只需要一次匹配,不必让信息连续穿过五十八次状态更新。
直接连接远距离位置带来计算代价。长度为 \(L\) 的序列需要比较大约 \(L\times L\) 对位置。序列从 100 增加到 200,比较数量大约从一万增加到四万。长分钟序列或全市场资产序列会迅速占用显存和时间,这也是后面引入时间分块和稀疏连接的原因之一。
注意力权重也不能直接升级为金融因果解释。某个日期获得高权重,只说明当前网络在这次前向计算中更多使用了它。多层网络、多个注意力头和后续前馈层还会继续改变结果,共同市场状态也可能同时影响两个日期。权重图适合寻找诊断线索,因果主张仍需要替换输入、删除日期、跨期复现和更严格的研究设计。
为什么同时需要多个注意力头¶
一套 Query、Key 和 Value 只能形成一种比较空间。多头注意力会并行建立多套变换,每一套叫作一个头。某个头可能更常连接邻近日期,另一个头可能更常连接财报附近,第三个头可能关注收益与成交量组合。训练目标不会保证这些分工恰好对应人类概念,因此“这个头就是趋势”仍需额外验证。
多个头的结果会拼接并再次变换,交给后续网络。头数增加会带来更多参数与计算。若四个头已经足够,继续增加到十六个却只让训练损失降低,验证结果没有改善,额外容量很可能只是在记忆噪声。
Transformer 是一组部件的合作¶
Transformer 经常与注意力放在一起提到,但一个完整编码器还包含前馈网络、残差连接、归一化和位置信息。注意力负责在不同位置之间交换信息,前馈网络负责对每个位置的表示做非线性变换,残差连接帮助原信息与新信息共同传递,归一化帮助数值保持稳定。
注意力只比较内容,本身不知道谁在前、谁在后。若把同一组输入日期完全打乱,又没有加入位置提示,模型很难区分第一天与第六十天。位置编码会把顺序信息加入每个位置。金融数据还要面对周末、节假日、停牌和不等间隔,位置编号应与交易日历和缺失处理一起设计。
flowchart TB
accTitle: Transformer 编码器的一层数据流
accDescr: 序列特征先加入位置信息,自注意力负责位置之间交换信息,残差与归一化保留原输入并稳定数值,前馈网络再逐位置变换,最终形成新的序列表示
input["历史序列特征"] --> pos["加入位置编码<br/>告诉模型先后顺序"]
pos --> attn["多头自注意力<br/>不同日期直接比较"]
pos --> add1["第一次残差相加与归一化"]
attn --> add1
add1 --> ff["前馈网络<br/>逐位置非线性变换"]
add1 --> add2["第二次残差相加与归一化"]
ff --> add2
add2 --> output["更新后的序列表示"]
用于逐时预测时,还要考虑因果遮罩。遮罩像一块挡板,使第 10 个位置无法读取第 11 个位置。若整个六十日输入窗口都发生在预测时点以前,编码器可以在窗口内部双向比较,因为这些历史在下单时已经可见;标签期仍必须位于窗口之后。模型内部允许双向观察,不会放宽数据与成交边界。
时间分块为何能缩短长序列¶
假设输入有 240 根日 K 线。标准注意力需要处理 240 个位置并比较大量位置对。若把每 10 天打包成一块,就得到 24 个较大的位置。每块先把十天的开高低收、成交量和其他特征压缩成一个向量,Transformer 再比较这些向量。这种连续分组常叫作 Patch,可以理解为时间片段。

图中左侧是按时间排列的 K 线,中间把相邻 K 线装入多个时间片段,随后由注意力比较片段,右侧才形成预测并进入风险检查。分块首先降低了序列长度,也让每个位置表达一小段局部形状。单日噪声可能在块内得到一定平滑,模型关注的单位从“一根 K 线”变成“十日形状”。
压缩也会损失细节。重大单日跳空若与九个普通日期混在一起,影响可能被稀释。块长度为 5、10 还是 20,步长是否重叠,都会改变模型看到的时间尺度。五日块接近一周交易节奏,二十日块接近一个月,但这种日历解释只能作为提出候选值的理由,最后仍要在验证期比较,并保留不分块与简单滚动统计基线。
时间分块、序列编码和资产间比较可以装进同一个模型,研究时却不宜一次全部加入。先比较局部卷积有没有增加有效信息,再单独检查长距离注意力,随后加入 Patch,最后才考虑资产之间的关系。每一步都保留前一版作为基线,结果变化才能找到来源。
同一天的不同资产也可以互相比较¶
前面的注意力沿时间连接不同日期。另一种做法是在同一个交易日连接不同资产,通常称为横截面注意力。例如,模型处理某只汽车股时,可以同时参考当日行业内其他股票、市场指数和供应链公司表示。它试图学习资产之间的相对关系。
若每天包含 500 只股票,两两比较会产生约 25 万个位置对。股票数量还会随上市、退市、停牌和股票池规则变化。历史输入必须使用当时真实可见的股票集合,不能拿今天仍存续的公司名单回填过去,否则会造成幸存者偏差。
模型也可能把行业或市值暴露当作容易利用的捷径。加入横截面注意力以后,应检查行业集中度、市值分布、市场方向暴露和股票池变化。分行业计算、稀疏连接或先聚合行业表示可以降低成本,不过每种简化都会改变假设,需要单独消融。
消融实验怎样回答“复杂部件是否真的有用”¶
消融实验是逐项拿掉或加入一个组件,观察研究结论怎样变化。它像检修一台由多块零件组成的机器。若同时更换发动机、轮胎和燃料,即使速度提高,也无法知道哪一项起作用。复杂模型研究应一次只改变一个主要部件,并保持数据、标签、时间切分、训练预算、随机种子与交易规则一致。
| 版本 | 与上一版相比唯一的主要变化 | 它要回答的问题 |
|---|---|---|
| A | 线性或树模型基线 | 复杂序列结构是否有必要 |
| B | 加入一维 CNN | 可重复的局部形状是否提供增量 |
| C | 用 TCN 扩大历史范围 | 更长的卷积观察范围是否有帮助 |
| D | 使用简单自注意力 | 远距离直接连接是否提供增量 |
| E | 在 D 上加入 Patch | 分块是否改善效率、稳定性或泛化 |
| F | 在 E 上加入横截面注意力 | 资产之间的关系是否提供额外样本外信息 |
每一级都应记录参数量、训练时间、预测指标、多个随机种子的变化范围、扣费后组合、换手、风险暴露与故障次数。如果 E 只在一个种子或一个 Patch 长度上领先,邻近长度全部失效,这个部件仍然脆弱。消融的价值在于允许研究者得出“这个复杂部件没有稳定增量”的结论,而不是强迫每一级都胜出。
一张选择表帮助定位起点¶
| 模型 | 主要能力 | 计算特点 | 常见风险 | 适合先问的问题 |
|---|---|---|---|---|
| CNN | 用共享过滤器寻找局部形状 | 易并行,参数相对节省 | 观察范围受窗口和层数限制 | 局部 K 线或成交量形状是否重复出现 |
| TCN | 用因果扩张卷积覆盖更长历史 | 易并行,梯度路径较短 | 填充方向可能泄漏未来 | 长期信息能否通过卷积层级提取 |
| RNN、LSTM | 逐步更新内部状态 | 符合顺序阅读直觉 | 长序列较慢,状态可能成为瓶颈 | 过去信息是否需要持续更新与遗忘 |
| Transformer | 让不同位置直接比较 | 并行度高,长序列成本大 | 数据需求高,注意力图易被误读 | 遥远日期之间是否存在可重复联系 |
| Patch Transformer | 先压缩局部块,再进行注意力 | 位置数减少,可整合局部形状 | 细节损失,块长度敏感 | 长序列是否能按自然时间尺度分组 |
这张表用于选择实验起点,不负责给出答案。数据规模很小、特征主要是结构化因子时,线性和树模型可能更可靠;高频长序列、局部形状明确时,卷积值得优先尝试;需要远距离比较且样本充足时,注意力才有更充分理由。最终选择仍要回到相同时间验证与交易约束。
复杂模型最低限度要报告什么¶
复杂结构的预测指标略有改善,还不足以结束研究。报告至少需要包含简单规则、线性模型、树模型和一个轻量序列基线;所有模型使用相同特征截止时间、标签、验证窗口、费用和风险限制。参数更多的模型应运行多个预先确定的随机种子,展示平均、范围与失败次数。
训练资源也要记录。一个模型每次重训需要多少时间,线上预测延迟多长,显存不足时会怎样失败,依赖库升级后是否还能复现,都会影响实际可用性。如果预测优势很小,却带来十倍换手、十倍计算和更难排查的故障,简单模型可能给出更好的整体方案。
还要专门做时间截断测试。删除预测时点之后的全部数据,早期特征与预测应保持不变;改变窗口末尾以后,过去已经生成的样本不应被重新标准化;因果卷积和遮罩应通过小型人工数组验证。越复杂的网络,越需要用简单数字构造单元测试。
容易弄错的地方¶
| 容易出现的做法 | 为什么会误导 | 更稳妥的检查 |
|---|---|---|
| 把图像卷积直接搬到行情 | 对称窗口可能读取右侧未来位置 | 使用因果卷积,并做新增未来行测试 |
| 把高注意力权重解释为因果 | 权重只描述当前网络中的信息使用 | 配合输入扰动、删除日期和样本外检验 |
| 只报告最好的 Patch 长度 | 多次尝试后挑最佳会放大选择偏差 | 预先给出范围,展示邻近长度与无 Patch 基线 |
| 同时加入 Patch、新特征和横截面注意力 | 结果变化无法归因到单一部件 | 一次只改变一项,建立完整消融阶梯 |
| Transformer 使用更多数据和训练时间 | 比较条件不同,优势可能来自额外资源 | 统一数据与预算,并单独报告规模效应 |
| 只看最佳随机种子 | 偶然初始化会被误写成模型能力 | 预先运行多个种子并报告分布 |
| 预测指标提高就直接上线 | 换手、费用、风险和故障可能吞掉增量 | 回到账本、压力测试与模拟盘检查 |
一分钟自测¶
长度 120 的序列,每 10 天组成一个不重叠 Patch,会得到多少个位置?如果某个注意力位置权重最高,能否据此宣布该日期导致了未来收益?
查看答案
会得到 12 个 Patch 位置。注意力权重高只说明该位置在当前模型计算中被使用得较多,无法单独排除共同原因和其他替代解释,因此不能直接宣布因果关系。本课术语¶
| 词语 | 先这样理解 |
|---|---|
| 卷积 | 用同一组小窗口权重沿序列寻找局部模式 |
| CNN | 由一层或多层卷积组成的神经网络 |
| 因果卷积 | 预测当前位置时只连接当前与过去的卷积 |
| 扩张卷积 | 按一定间隔取样,以较少层数扩大观察范围 |
| 注意力 | 按查询与键的匹配程度加权汇总值 |
| 自注意力 | Query、Key 和 Value 都来自同一条序列的注意力 |
| Transformer | 由注意力、前馈层、残差、归一化和位置信息组成的结构 |
| 位置编码 | 向模型补充序列先后位置的信息 |
| Patch | 把连续若干时间位置打包成一个较大单元 |
| 消融实验 | 一次改变一个组件,用来检查它是否提供独立增量 |
机器学习阶段综合作业¶
回到你一直使用的毕业研究问题,为它安排三级对照。第一级使用简单规则或线性模型,第二级使用树模型,第三级从 RNN、CNN、TCN 或 Transformer 中选择一个。为每一级写清输入形状、标签时点、训练窗口、验证窗口、测试窗口和可执行成交时点。
随后制作一张消融表。每一行只改变一个组件,并提前写好这个组件值得保留的最低证据,例如多个滚动窗口平均改善、邻近参数仍然稳定、扣费后增量为正、多个种子大部分成功。也要允许最终结论停在简单基线。这张表会直接进入第 33 课毕业报告的模型选择部分。
课后练习¶
-
卷积计算。 五日序列使用三日窗口、步长为 1、不填充,共有几个窗口?若序列长度改成八日,窗口数量又是多少?
提示与答案
五日序列有第 1 至 3、第 2 至 4、第 3 至 5 三个窗口。八日序列共有 `8 - 3 + 1 = 6` 个完整窗口。 -
注意力计算。 三个位置的权重为 0.2、0.5 和 0.3,对应 Value 为 -1、2 和 0.5。请计算加权结果。
提示与答案
逐项相乘后相加,结果为 `0.2 × (-1) + 0.5 × 2 + 0.3 × 0.5 = 0.95`。 -
时间排错。 一维卷积在生成第 10 天预测时使用了第 11 天输入。最可能的问题是什么,怎样构造测试?
提示与答案
卷积窗口或填充方向没有遵守因果顺序。可以在第 11 天以后替换成极端数值,检查第 10 天及以前输出是否改变。 -
设计消融。 研究者同时加入 Patch、横截面注意力和一组新特征后,模型表现提高。请把它拆成能够定位原因的实验顺序。
提示与答案
先固定原特征比较无 Patch 与 Patch,再在胜出结构上单独加入横截面注意力,最后把新特征作为独立版本。所有版本保持时间切分、训练预算和交易规则相同。 -
研究判断。 Patch Transformer 在最佳种子上超过线性模型,所有种子的平均结果没有优势,扣费后更差。你会怎样写结论?
评价要点
当前证据不足以支持保留复杂模型。应完整报告种子分布与费用结果,检查实现和参数敏感性,并让简单基线继续作为主要方案。只有新的独立数据提供稳定增量,才有理由重新评估。
五日数字已经把几种复杂结构落回可检查的动作。卷积沿时间重复一组权重,注意力让当前位置直接比较历史位置,Transformer 再加入位置、残差和前馈层,Patch 用细节换取更短的序列。每增加一个组件,都回到消融表中单独比较,复杂度才有明确来路。