Transformer系列模型在Time-Series-Library中的演进
文章详细介绍了Transformer架构在时间序列分析领域的演进过程,从经典Transformer的时间序列适配开始,逐步深入到Autoformer的自相关机制、Informer的长序列高效处理技术,以及FEDformer的频域增强技术。这些模型通过创新的注意力机制、序列分解策略和频域转换方法,有效解决了传统Transformer在时间序列预测中面临的计算复杂度高、内存消耗大、周期性特征捕捉困难等挑战。
经典Transformer时间序列适配
时间序列数据具有独特的时序依赖性和周期性特征,直接将NLP领域的经典Transformer架构应用于时间序列预测面临诸多挑战。Time-Series-Library通过精心设计的适配策略,成功将Transformer架构改造为适用于时间序列分析的强大工具。
时间序列数据嵌入策略
传统Transformer的位置编码无法充分捕捉时间序列的时序特性,Time-Series-Library实现了多种专门的时间序列嵌入方法:
class DataEmbedding(nn.Module):
def __init__(self, c_in, d_model, embed_type='fixed', freq='h', dropout=0.1):
super(DataEmbedding, self).__init__()
self.value_embedding = TokenEmbedding(c_in=c_in, d_model=d_model)
self.position_embedding = PositionalEmbedding(d_model=d_model)
self.temporal_embedding = TemporalEmbedding(d_model=d_model,
embed_type=embed_type, freq=freq)
self.dropout = nn.Dropout(p=dropout)
该嵌入层融合了三种关键信息:
- 数值嵌入:使用1D卷积处理原始时间序列数值
- 位置嵌入:标准的正弦余弦位置编码
- 时间特征嵌入:专门处理时间戳信息(小时、星期、月份等)
编码器-解码器架构优化
针对时间序列预测任务,库中的经典Transformer采用了编码器-解码器架构:
多任务支持架构
经典Transformer在Time-Series-Library中支持五种核心时间序列任务:
| 任务类型 | 输入处理 | 输出处理 | 适用场景 |
|---|---|---|---|
| 长期预测 | 完整编码器-解码器 | 线性投影 | 电力负荷预测 |
| 短期预测 | 简化解码器 | 直接输出 | 股票价格预测 |
| 缺失值填充 | 仅编码器 | 重构投影 | 传感器数据修复 |
| 异常检测 | 编码特征提取 | 异常评分 | 工业设备监控 |
| 分类任务 | 全局池化 | 全连接分类 | 心电图分类 |
注意力机制的时间序列适配
传统自注意力机制在时间序列上面临计算复杂度和局部依赖性捕捉的挑战:
class FullAttention(nn.Module):
def __init__(self, mask_flag=False, factor=5,
attention_dropout=0.1, output_attention=False):
super(FullAttention, self).__init__()
self.mask_flag = mask_flag
self.output_attention = output_attention
self.dropout = nn.Dropout(attention_dropout)
库中通过以下策略优化注意力计算:
- 因果掩码:确保预测时只能看到历史信息
- 缩放点积注意力:适应时间序列的数值范围
- 多头注意力:从不同表示子空间捕捉模式
时间序列特有的归一化策略
时间序列数据通常具有非平稳特性,库中采用了特殊的归一化处理:
class StandardNorm(nn.Module):
def __init__(self):
super(StandardNorm, self).__init__()
def forward(self, x, mask=None):
if mask is not None:
masked_x = x * mask
sum_ = torch.sum(masked_x, dim=1)
count = torch.sum(mask, dim=1) + 1e-6
mean = sum_ / count
mean = mean.unsqueeze(1).repeat(1, x.shape[1], 1)
# 类似方法计算方差
else:
mean = x.mean(dim=1, keepdim=True)
std = x.std(dim=1, keepdim=True) + 1e-6
x = (x - mean) / std
return x
实际应用示例
以下是一个完整的时间序列预测Pipeline示例:
# 初始化经典Transformer模型
configs = argparse.Namespace(
enc_in=7, dec_in=7, c_out=7, seq_len=96, label_len=48, pred_len=96,
d_model=512, n_heads=8, e_layers=2, d_layers=1, d_ff=2048,
dropout=0.05, embed='timeF', freq='h', activation='gelu'
)
model = Transformer.Model(configs)
# 训练过程
def train_epoch(model, train_loader, optimizer, criterion):
model.train()
total_loss = 0
for batch_x, batch_y, batch_x_mark, batch_y_mark in train_loader:
optimizer.zero_grad()
outputs = model(batch_x, batch_x_mark, batch_y, batch_y_mark)
loss = criterion(outputs, batch_y)
loss.backward()
optimizer.step()
total_loss += loss.item()
return total_loss / len(train_loader)
性能优化技巧
针对时间序列Transformer的训练和推理优化:
- 梯度累积:处理长序列时的内存优化
- 混合精度训练:加速训练过程
- 学习率调度:余弦退火配合热重启
- 早停策略:防止过拟合到噪声模式
# 学习率调度示例
scheduler = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(
optimizer, T_0=10, T_mult=2, eta_min=1e-6
)
# 混合精度训练
scaler = torch.cuda.amp.GradScaler()
with torch.cuda.amp.autocast():
outputs = model(batch_x, batch_x_mark, batch_y, batch_y_mark)
loss = criterion(outputs, batch_y)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
通过上述适配策略,经典Transformer在Time-Series-Library中成功克服了时间序列数据的特殊性挑战,为各种时间序列分析任务提供了强大而灵活的建模能力。这种适配不仅保留了Transformer捕捉长期依赖关系的核心优势,还针对时间序列的时序特性进行了专门优化。
Autoformer自相关机制解析
Autoformer作为时间序列预测领域的重要突破,其核心创新在于引入了自相关机制(Auto-Correlation Mechanism),这一机制彻底改变了传统Transformer在时间序列建模中的注意力计算方式。自相关机制通过频域分析和时延聚合两个关键阶段,实现了对时间序列周期性依赖的高效捕获。
自相关机制的核心原理
自相关机制的核心思想是利用时间序列自身的周期性特征,通过计算序列在不同时延下的相关性来发现重要的周期模式。与传统的点积注意力不同,自相关机制在频域中计算相关性,大幅降低了计算复杂度。
# AutoCorrelation核心计算过程
def forward(self, queries, keys, values, attn_mask):
B, L, H, E = queries.shape
# 频域相关性计算
q_fft = torch.fft.rfft(queries.permute(0, 2, 3, 1).contiguous(), dim=-1)
k_fft = torch.fft.rfft(keys.permute(0, 2, 3, 1).contiguous(), dim=-1)
res = q_fft * torch.conj(k_fft)
corr = torch.fft.irfft(res, dim=-1)
# 时延聚合
if self.training:
V = self.time_delay_agg_training(values.permute(0, 2, 3, 1), corr).permute(0, 3, 1, 2)
else:
V = self.time_delay_agg_inference(values.permute(0, 2, 3, 1), corr).permute(0, 3, 1, 2)
return V.contiguous()
频域相关性发现机制
自相关机制的第一个阶段是在频域中发现周期性的依赖关系。通过快速傅里叶变换(FFT)将时间序列转换到频域,计算查询和键的频域表示之间的相关性:
数学上,这一过程可以表示为: $$ \text{Corr}(\mathbf{Q}, \mathbf{K}) = \mathcal{F}^{-1}(\mathcal{F}(\mathbf{Q}) \cdot \overline{\mathcal{F}(\mathbf{K})}) $$
其中$\mathcal{F}$表示傅里叶变换,$\overline{\cdot}$表示复共轭。这种频域计算方法将复杂度从$O(L^2)$降低到$O(L\log L)$,其中$L$是序列长度。
时延聚合策略
在获得相关性矩阵后,自相关机制采用基于top-k选择的时延聚合策略:
def time_delay_agg_training(self, values, corr):
# 选择top-k最相关的时延
top_k = int(self.factor * math.log(length))
mean_value = torch.mean(torch.mean(corr, dim=1), dim=1)
index = torch.topk(torch.mean(mean_value, dim=0), top_k, dim=-1)[1]
# 基于相关性权重进行聚合
weights = torch.stack([mean_value[:, index[i]] for i in range(top_k)], dim=-1)
tmp_corr = torch.softmax(weights, dim=-1)
# 时延聚合计算
delays_agg = torch.zeros_like(values).float()
for i in range(top_k):
pattern = torch.roll(tmp_values, -int(index[i]), -1)
delays_agg = delays_agg + pattern * tmp_corr[:, i].unsqueeze(1).unsqueeze(1).unsqueeze(1)
return delays_agg
训练与推理优化
Autoformer针对训练和推理阶段分别设计了优化策略:
| 阶段 | 优化策略 | 优势 |
|---|---|---|
| 训练阶段 | 批量归一化风格的时延聚合 | 内存效率高,适合批量训练 |
| 推理阶段 | 基于索引的时延聚合 | 计算效率高,适合单样本推理 |
与传统注意力的对比
自相关机制与传统点积注意力在多个维度上存在显著差异:
| 特性 | 传统注意力 | 自相关机制 |
|---|---|---|
| 计算复杂度 | O(L²) | O(L log L) |
| 依赖发现 | 内容相关性 | 周期性相关性 |
| 计算域 | 时域 | 频域+时域 |
| 内存占用 | 高 | 低 |
| 长序列处理 | 困难 | 高效 |
实际应用效果
在Time-Series-Library中的实现表明,自相关机制在多个时间序列任务中表现出色:
- 长周期预测:能够有效捕获周、月、年等周期性模式
- 多变量时序:处理多个相关时间序列的复杂依赖关系
- 异常检测:通过周期性模式偏离发现异常点
- 缺失值填补:利用周期性特征重建缺失数据
# Autoformer在时间序列库中的配置示例
configs = {
'factor': 3, # 自相关因子,控制top-k选择
'moving_avg': 25, # 移动平均窗口大小
'd_model': 512, # 模型维度
'n_heads': 8, # 注意力头数
'e_layers': 2, # 编码器层数
'd_layers': 1, # 解码器层数
}
自相关机制的成功在于其深刻理解了时间序列数据的本质特征——周期性。通过将传统的基于内容的注意力转换为基于周期的注意力,Autoformer不仅在计算效率上取得了突破,更在预测准确性上实现了显著提升。这一机制为后续的时间序列Transformer模型奠定了重要的理论基础和实践范例。
Informer长序列高效处理
在时间序列预测领域,长序列处理一直是一个重大挑战。传统的Transformer模型在处理长序列时面临计算复杂度高、内存消耗大的问题。Informer模型通过引入概率稀疏注意力机制(ProbSparse Attention)和自注意力蒸馏技术,有效解决了这些问题,为长序列时间序列预测提供了高效的解决方案。
核心创新:概率稀疏注意力机制
Informer的核心创新在于概率稀疏注意力机制,它通过选择性地关注最重要的查询-键值对,将注意力计算复杂度从O(L²)降低到O(L log L)。这种机制基于一个关键观察:在标准的自注意力中,大多数注意力权重都集中在少数几个"活跃"的查询上。
class ProbAttention(nn.Module):
def __init__(self, mask_flag=True, factor=5, scale=None, attention_dropout=0.1, output_attention=False):
super(ProbAttention, self).__init__()
self.factor = factor
self.scale = scale
self.mask_flag = mask_flag
self.output_attention = output_attention
self.dropout = nn.Dropout(attention_dropout)
def _prob_QK(self, Q, K, sample_k, n_top):
# 采样关键步骤:随机采样和Top-k选择
B, H, L_K, E = K.shape
_, _, L_Q, _ = Q.shape
# 随机采样K矩阵
index_sample = torch.randint(L_K, (L_Q, sample_k))
K_sample = K_expand[:, :, torch.arange(L_Q).unsqueeze(1), index_sample, :]
Q_K_sample = torch.matmul(Q.unsqueeze(-2), K_sample.transpose(-2, -1)).squeeze()
# 基于稀疏性度量选择Top-k查询
M = Q_K_sample.max(-1)[0] - torch.div(Q_K_sample.sum(-1), L_K)
M_top = M.topk(n_top, sorted=False)[1]
return Q_K, M_top
架构设计与关键组件
Informer采用编码器-解码器架构,但在传统Transformer基础上进行了多项优化:
编码器结构
自注意力蒸馏机制
Informer通过自注意力蒸馏技术进一步减少内存使用,使用一维卷积和下采样操作来压缩特征维度:
class ConvLayer(nn.Module):
def __init__(self, c_in):
super(ConvLayer, self).__init__()
self.downConv = nn.Conv1d(in_channels=c_in,
out_channels=c_in,
kernel_size=3,
padding=1,
padding_mode='circular')
self.norm = nn.BatchNorm1d(c_in)
self.activation = nn.ELU()
self.maxPool = nn.MaxPool1d(kernel_size=3, stride=2, padding=1)
def forward(self, x):
x = self.downConv(x.transpose(-1, 1))
x = self.norm(x)
x = self.activation(x)
x = self.maxPool(x)
x = x.transpose(-1, 1)
return x
多任务支持能力
Informer在Time-Series-Library中支持多种时间序列任务,展现了其强大的泛化能力:
| 任务类型 | 输入处理 | 输出处理 | 适用场景 |
|---|---|---|---|
| 长时预测 | 完整序列编码 | 多步预测输出 | 电力负荷预测 |
| 短时预测 | 标准化预处理 | 反标准化输出 | 股票价格预测 |
| 缺失值填补 | 掩码序列处理 | 重构完整序列 | 传感器数据修复 |
| 异常检测 | 单序列编码 | 异常分数输出 | 工业设备监控 |
| 分类任务 | 序列特征提取 | 类别概率输出 | 动作识别 |
性能优势与实验结果
Informer在多个基准数据集上展现出显著优势:
- 计算效率:相比标准Transformer,内存使用减少50%,训练速度提升3倍
- 预测精度:在ETTh1数据集上,96步预测的MSE达到0.098,优于传统方法
- 可扩展性:支持处理长达1000+时间步的超长序列
# Informer在Time-Series-Library中的配置示例
python -u run.py \
--task_name long_term_forecast \
--model Informer \
--data ETTh1 \
--seq_len 96 \
--label_len 48 \
--pred_len 96 \
--e_layers 2 \
--d_layers 1 \
--factor 3 \
--enc_in 7 \
--dec_in 7 \
--c_out 7
实际应用建议
在使用Informer进行长序列处理时,建议考虑以下最佳实践:
- 参数调优:根据序列长度调整
factor参数,较长序列使用较大值 - 层数配置:编码器层数通常设置为2-3层,解码器1层即可
- 序列长度:输入序列长度建议为预测长度的2-4倍
- 蒸馏策略:对于超长序列,启用自注意力蒸馏以获得更好效果
Informer的成功不仅在于其技术创新,更在于为后续的时间序列Transformer模型奠定了重要基础。其概率稀疏注意力机制的思想被许多后续模型借鉴和发展,推动了整个领域向更高效、更实用的方向发展。
FEDformer频域增强技术
FEDformer(Frequency Enhanced Decomposed Transformer)是时间序列预测领域的一项重要突破,它将频域分析技术与Transformer架构巧妙结合,有效解决了传统Transformer在长序列预测中的计算复杂度和内存消耗问题。该模型通过将注意力机制转移到频域进行操作,实现了线性时间复杂度,同时保持了优异的预测性能。
频域转换的核心思想
FEDformer的核心创新在于将时间序列从时域转换到频域进行处理。传统的Transformer在时域进行自注意力计算,其复杂度为O(N²),而FEDformer通过在频域进行线性变换,将复杂度降低到O(N)。
频域注意力机制实现
FEDformer提供了两种频域处理方式:傅里叶变换和小波变换。在Time-Series-Library的实现中,主要通过傅里叶变换版本进行频域增强:
class FourierBlock(nn.Module):
def __init__(self, in_channels, out_channels, n_heads, seq_len, modes=0, mode_select_method='random'):
super(FourierBlock, self).__init__()
# 获取频域模式
self.index = get_frequency_modes(seq_len, modes=modes, mode_select_method=mode_select_method)
self.n_heads = n_heads
self.scale = (1 / (in_channels * out_channels))
self.weights1 = nn.Parameter(
self.scale * torch.rand(self.n_heads, in_channels // self.n_heads,
out_channels // self.n_heads, len(self.index), dtype=torch.float))
self.weights2 = nn.Parameter(
self.scale * torch.rand(self.n_heads, in_channels // self.n_heads,
out_channels // self.n_heads, len(self.index), dtype=torch.float))
def forward(self, q, k, v, mask):
B, L, H, E = q.shape
x = q.permute(0, 2, 3, 1)
# 计算傅里叶系数
x_ft = torch.fft.rfft(x, dim=-1)
# 频域神经网络操作
out_ft = torch.zeros(B, H, E, L // 2 + 1, device=x.device, dtype=torch.cfloat)
for wi, i in enumerate(self.index):
if i >= x_ft.shape[3] or wi >= out_ft.shape[3]:
continue
out_ft[:, :, :, wi] = self.compl_mul1d("bhi,hio->bho", x_ft[:, :, :, i],
torch.complex(self.weights1, self.weights2)[:, :, :, wi])
# 返回时域
x = torch.fft.irfft(out_ft, n=x.size(-1))
return (x, None)
模式选择策略
FEDformer提供了两种频域模式选择方法,以适应不同的时间序列特性:
| 选择方法 | 描述 | 适用场景 |
|---|---|---|
| random | 随机选择频域模式 | 通用场景,避免过拟合 |
| low | 选择低频模式 | 强调长期趋势和周期性 |
def get_frequency_modes(seq_len, modes=64, mode_select_method='random'):
modes = min(modes, seq_len // 2)
if mode_select_method == 'random':
index = list(range(0, seq_len // 2))
np.random.shuffle(index)
index = index[:modes]
else:
index = list(range(0, modes))
index.sort()
return index
序列分解架构
FEDformer采用了序列分解策略,将时间序列分解为趋势项和周期项,分别进行处理:
多任务支持架构
在Time-Series-Library中,FEDformer支持多种时间序列分析任务:
class Model(nn.Module):
def __init__(self, configs, version='fourier', mode_select='random', modes=32):
super(Model, self).__init__()
self.task_name = configs.task_name
self.version = version
self.mode_select = mode_select
self.modes = modes
# 根据不同任务配置输出层
if self.task_name == 'imputation':
self.projection = nn.Linear(configs.d_model, configs.c_out, bias=True)
if self.task_name == 'anomaly_detection':
self.projection = nn.Linear(configs.d_model, configs.c_out, bias=True)
if self.task_name == 'classification':
self.projection = nn.Linear(configs.d_model * configs.seq_len, configs.num_class)
性能优势对比
FEDformer相比传统Transformer在多个维度都有显著改进:
| 指标 | 传统Transformer | FEDformer | 改进幅度 |
|---|---|---|---|
| 时间复杂度 | O(N²) | O(N) | 线性降低 |
| 内存消耗 | 高 | 中等 | 显著减少 |
| 长序列处理 | 困难 | 优秀 | 大幅提升 |
| 周期性捕捉 | 一般 | 优秀 | 明显改善 |
实际应用配置
在Time-Series-Library中,FEDformer的典型配置参数如下:
# 短时预测配置示例
python -u run.py \
--task_name short_term_forecast \
--model FEDformer \
--data m4 \
--e_layers 2 \
--d_layers 1 \
--modes 32 \
--mode_select random \
--d_model 512 \
--learning_rate 0.001
频域交叉注意力机制
FEDformer还实现了频域交叉注意力机制,用于编码器-解码器之间的信息传递:
class FourierCrossAttention(nn.Module):
def __init__(self, in_channels, out_channels, seq_len_q, seq_len_kv, modes=64,
mode_select_method='random', activation='tanh', num_heads=8):
super(FourierCrossAttention, self).__init__()
self.activation = activation
# 分别获取查询和键值的频域模式
self.index_q = get_frequency_modes(seq_len_q, modes=modes, mode_select_method=mode_select_method)
self.index_kv = get_frequency_modes(seq_len_kv, modes=modes, mode_select_method=mode_select_method)
这种设计使得模型能够在频域进行高效的跨序列信息交换,特别适合处理具有复杂周期性和趋势的时间序列数据。
FEDformer的频域增强技术为时间序列分析提供了新的视角,通过将计算转移到频域,不仅大幅降低了计算复杂度,还增强了对时间序列周期性和趋势特征的捕捉能力,成为长序列预测任务中的重要基准模型。
总结
Transformer系列模型在Time-Series-Library中的演进展现了从基础适配到创新突破的完整发展路径。经典Transformer通过数据嵌入策略和架构优化为时间序列分析奠定了基础;Autoformer引入自相关机制,通过频域分析和时延聚合高效捕捉周期性特征;Informer采用概率稀疏注意力和自注意力蒸馏技术,大幅提升长序列处理效率;FEDformer则通过频域转换和序列分解,实现了线性时间复杂度的同时保持优异预测性能。这些模型的持续演进不仅推动了时间序列分析技术的发展,也为实际应用提供了强大而灵活的工具集。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



