20、深度学习信号:LSTM、GRU、Transformer价格预测

聊到高频数据里的价格信号提取,传统方法玩到一定程度,你会发现瓶颈很明显。线性模型抓不住非线性关系,人工特征工程又累又容易过拟合。这时候,深度学习就该上场了。

我个人习惯把深度学习模型分成三代:LSTM 是第一代主力,GRU 是它的精简版,Transformer 则是新一代的王者。今天咱们就挨个聊聊,在高频价格预测这个场景下,它们各自怎么用、坑在哪里。

为什么高频数据需要深度学习?

你想想看,高频数据有几个特点:

  • 非线性极强:价格波动不是简单的线性叠加
  • 噪声巨大:信号淹没在微观结构噪声里
  • 序列依赖:当前价格受过去几百毫秒的影响

传统 ARIMA、GARCH 这类模型,说白了就是线性假设太强。深度学习模型能自动学习高阶特征,这是它们最大的优势。

核心观点:深度学习不是万能药,但在高频信号提取中,它能把传统模型甩开一个身位。前提是——你得会用。

LSTM:长短期记忆网络

LSTM 是处理时间序列的老牌选手。我在项目中遇到过一个问题:用普通 RNN 预测 1 秒后的价格,梯度消失得厉害,模型根本学不到东西。换成 LSTM 后,效果立竿见影。

LSTM 的核心是三个门:遗忘门、输入门、输出门。它们控制着信息流动,让模型能记住长期依赖。

import torch
import torch.nn as nn

class LSTMPredictor(nn.Module):
    def __init__(self, input_size=5, hidden_size=64, num_layers=2):
        super().__init__()
        self.lstm = nn.LSTM(
            input_size=input_size,
            hidden_size=hidden_size,
            num_layers=num_layers,
            batch_first=True,
            dropout=0.2
        )
        self.fc = nn.Linear(hidden_size, 1)
    
    def forward(self, x):
        # x shape: (batch, seq_len, features)
        out, (h_n, c_n) = self.lstm(x)
        # 取最后一个时间步的输出
        last_out = out[:, -1, :]
        pred = self.fc(last_out)
        return pred

实战经验:LSTM 的 hidden_size 我一般设在 32-128 之间。太小了学不到模式,太大了容易过拟合。高频数据里,我习惯用 2 层 LSTM,层数再多反而容易梯度爆炸。

GRU:更轻量,更快

GRU 是 LSTM 的简化版。它把遗忘门和输入门合并成更新门,还去掉了输出门。参数更少,训练更快。

我曾经在回测系统里对比过 LSTM 和 GRU 的性能。在同样的数据量下,GRU 训练速度快了约 30%,预测精度只差了不到 1%。如果你的交易策略对延迟敏感,GRU 是个好选择。

class GRUPredictor(nn.Module):
    def __init__(self, input_size=5, hidden_size=64, num_layers=2):
        super().__init__()
        self.gru = nn.GRU(
            input_size=input_size,
            hidden_size=hidden_size,
            num_layers=num_layers,
            batch_first=True,
            dropout=0.2
        )
        self.fc = nn.Linear(hidden_size, 1)
    
    def forward(self, x):
        out, h_n = self.gru(x)
        last_out = out[:, -1, :]
        pred = self.fc(last_out)
        return pred

避坑指南:我曾经在 GRU 上踩过一个坑——忘记设置 batch_first=True。默认情况下 batch 是第二维,数据喂进去全乱套了。检查了三天才发现。嗯,这种低级错误,犯一次就够了。

Transformer:注意力机制的革命

Transformer 原本是为 NLP 设计的,但它在时间序列预测上的表现,说实话,让我挺惊讶的。

它的核心是自注意力机制。简单说,就是模型能自己判断过去哪些时间点更重要。比如在价格突破前,往往会有一些微小的成交量变化,Transformer 能自动捕捉这种模式。

class TransformerPredictor(nn.Module):
    def __init__(self, input_size=5, d_model=64, nhead=4, num_layers=2):
        super().__init__()
        self.embedding = nn.Linear(input_size, d_model)
        self.pos_encoder = PositionalEncoding(d_model)
        
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=d_model,
            nhead=nhead,
            dim_feedforward=256,
            dropout=0.1,
            batch_first=True
        )
        self.transformer = nn.TransformerEncoder(
            encoder_layer,
            num_layers=num_layers
        )
        self.fc = nn.Linear(d_model, 1)
    
    def forward(self, x):
        x = self.embedding(x)
        x = self.pos_encoder(x)
        x = self.transformer(x)
        last_out = x[:, -1, :]
        pred = self.fc(last_out)
        return pred

关键点:Transformer 需要的数据量比 LSTM 大得多。我个人的经验是,至少要有 10 万条以上的训练样本,否则效果还不如 GRU。高频数据正好满足这个条件——你一天就能攒几十万条 tick 数据。

三种模型的对比

模型 训练速度 预测精度 数据需求 适用场景
LSTM 中等 良好 中等 通用型,适合大多数高频场景
GRU 良好 较少 低延迟策略,快速迭代
Transformer 优秀 大量 高精度预测,长序列依赖

训练时的关键技巧

模型选好了,训练才是真正的战场。我总结了几条高频数据训练的要点:

  1. 数据归一化:价格数据一定要做归一化。我习惯用 Z-score,把价格序列转成均值为 0、标准差为 1 的分布。
  2. 序列长度:高频数据里,我一般用 50-200 个时间步。太短了信息不够,太长了模型学不到。
  3. 学习率调度:刚开始用 1e-3,训练到一半降到 1e-4。这个 trick 能让模型收敛得更稳。
  4. 早停法:验证集 loss 连续 10 个 epoch 不下降就停。别让模型在训练集上死磕。

一个小技巧:训练时把 batch size 设成 32 或 64。高频数据里,batch 太大反而会让模型学不到微观模式。这是我踩过坑之后才明白的。

核心知识体系

下面这张图,是我自己梳理的深度学习信号提取框架。你可以把它当作一个路线图:

深度学习价格信号提取框架 原始高频数据 数据预处理与归一化 模型选择:LSTM / GRU / Transformer LSTM GRU Transformer 价格预测信号

从原始数据到最终的价格预测信号,每一步都有讲究。预处理做不好,再牛的模型也白搭。模型选不对,训练再久也是浪费时间。

我个人建议,刚开始做高频深度学习预测时,先从 GRU 入手。它简单、快、不容易出错。等跑通了整个流程,再尝试 Transformer 去追求那 1-2% 的精度提升。

最后提醒一句:深度学习模型在高频交易里不是银弹。市场结构会变,模型会过时。我见过太多人把模型调得天花乱坠,结果市场风格一变,回撤直接崩盘。保持对模型的敬畏,定期重新训练,这才是长久之计。