Transformers 中的 PatchTST 模型详解:基于 Patch 与通道独立的多元时序预测与自监督表征学习
2026/9/8 20:25:25 网站建设 项目流程

Transformers 中的 PatchTST 模型详解:基于 Patch 与通道独立的多元时序预测与自监督表征学习

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

导读

本文围绕 🤗 Transformers 开源仓库中 PatchTST 时间序列 Transformer 模型展开,涵盖其核心设计思想(子序列级 Patch 切分、通道独立、掩码自监督预训练)、完整配置参数说明,以及其在预测(Prediction)、分类(Classification)、回归(Regression)与预训练(Pretraining)四大任务上的实际用法。读完本文,你将能够基于 PatchTSTConfig 从零配置模型、加载预训练权重,并把 PatchTST 应用到多元时间序列的长程预测与表征学习中。

PatchTST 是什么:模型概述

PatchTST(Patch Time Series Transformer)最早由 Yuqi Nie、Nam H. Nguyen、Phanwadee Sinthong 与 Jayant Kalagnanam 在论文《A Time Series is Worth 64 Words: Long-term Forecasting with Transformers》中提出。该模型于 2023-11-13 被贡献至 Hugging Face Transformers 仓库,并由 IBM 与 Hugging Face 团队共同维护,相关实现位于 src/transformers/models/patchtst/。

从论文摘要看,PatchTST 的设计目标是为多元时间序列预测自监督表征学习提供一种高效的 Transformer 方案。它的有效性来自两个关键组件:

  1. 子序列级 Patch 切分(patching):把时间序列分割成若干子序列片段(patch),作为 Transformer 的输入 token;
  2. 通道独立(channel-independence):每个通道是一条单变量时间序列,所有序列共享同一套 embedding 与 Transformer 权重。

论文指出 Patch 化设计天然带来三重收益:

  • 局部语义信息被保留在 embedding 中;
  • 在给定相同回看窗口(look-back window)时,注意力图的计算量与内存占用呈平方级缩减
  • 模型可以关注更长的历史

而通道独立的 Patch 时间序列 Transformer(PatchTST)与当时的 SOTA Transformer 模型相比,能显著提升长程预测精度;同时论文将其应用于自监督预训练任务,在大型数据集上取得了优于有监督训练的下游微调性能,跨数据集迁移掩码预训练表征也能带来 SOTA 级别的预测精度。

注意:原文模型论文于 2022-11-27 发布,模型于 2023-11-13 贡献到 Transformers。仓库当前文档声明该模型默认检查点为ibm-granite/granite-timeseries-patchtst(见 configuration_patchtst.py 的@auto_docstring装饰器)。

架构总览

在 Transformers 仓库的实现里,PatchTST 前向数据流可以清晰概括为一条流水线。以 PatchTSTModel.forward 为入口,处理过程依次为:

  1. 输入缩放PatchTSTScaler根据配置对输入past_values做标准化,返回缩放后的数据及loc(均值)、scale(标准差);
  2. Patch 化PatchTSTPatchify沿时间维用unfold把缩放后的序列切成[batch_size, num_channels, num_patches, patch_length]的张量;
  3. 掩码(可选):若开启预训练掩码(do_mask_input),PatchTSTMasking随机或按预测式掩码 patch;
  4. Transformer EncoderPatchTSTEncoder先通过PatchTSTEmbedding将每个 patch 线性投影为d_model维向量,再加上PatchTSTPositionalEncoding,随后堆叠多层PatchTSTEncoderLayer
  5. 输出:Encoder 输出的last_hidden_state形状为[batch_size, num_channels, num_patches, d_model](若use_cls_token=True则为num_patches+1)。

关键模块类(如PatchTSTAttentionPatchTSTEncoderLayerPatchTSTPatchifyPatchTSTMasking、各类 scaler 与 head)均定义在 modeling_patchtst.py 中。其中PatchTSTEncoderLayer按「时间维注意力 →(可选)通道维注意力 → 前馈网络」的三子层结构组织,允许各通道分别 attend 时间位置,也可通过channel_attention=True开启通道之间的互相注意力。

快速上手:配置与基本使用

PatchTSTConfig是模型的配置类,位于 configuration_patchtst.py,源码 docstring 给出了最简用法:

from transformers import PatchTSTConfig, PatchTSTModel # Initializing an PatchTST configuration with 12 time steps for prediction configuration = PatchTSTConfig(prediction_length=12) # Randomly initializing a model (with random weights) from the configuration model = PatchTSTModel(configuration) # Accessing the model configuration configuration = model.config

这里有一个值得注意的细节:直接构造的是随机初始化权重的模型,用于训练从零开始。若要进行推理或迁移学习,应使用PatchTSTForPrediction.from_pretrained("namctin/patchtst_etth1_forecast")之类的方式加载 Hub 上的预训练权重。仓库的attribute_map(configuration_patchtst.py)将通用命名hidden_sizenum_attention_headsnum_hidden_layers分别映射到 PatchTST 专属的d_modelnum_attention_headsnum_hidden_layers,因此从AutoConfig/AutoModel体系加载时接口与其他模型保持一致。

在 Auto API 层面,PatchTST 已注册到以下映射(见 auto_mappings.py 与 modeling_auto.py):

  • AutoConfigPatchTSTConfig
  • AutoModelPatchTSTModel
  • 时间序列分类映射(MODEL_FOR_TIME_SERIES_CLASSIFICATION_MAPPING)→PatchTSTForClassification
  • 时间序列回归映射(MODEL_FOR_TIME_SERIES_REGRESSION_MAPPING)→PatchTSTForRegression

PatchTSTConfig 全部参数详解

以下参数表综合自 configuration_patchtst.py 的默认值与 docstring,均以实际仓库实现为准。

输入与数据形状

参数类型默认值说明
num_input_channelsint1输入序列的通道数,即多元时间序列的变量维度
context_lengthint32输入序列(回看窗口)的时间步长度
prediction_lengthint24模型要输出的预测水平(horizon)
scalingstr/bool/None"std"输入缩放方式。"mean"用均值缩放,"std"用标准差缩放,None表示不缩放;若传True等价于"mean"

关于scaling,代码层面在 modeling_patchtst.py 的PatchTSTScaler中选择底层 scaler:"mean"/TruePatchTSTMeanScaler"std"PatchTSTStdScaler,其余 →PatchTSTNOPScaler(恒等缩放)。PatchTSTStdScaler沿时间维统计locscale并执行(data - loc) / scale标准化,且设置minimum_scale=1e-5防止除零;PatchTSTMeanScaler则用加权平均绝对值作为缩放因子。

输出与损失

参数类型默认值说明
distribution_outputstr"student_t"loss="nll"时使用的分布发射头,可选"student_t""normal""negative_binomial"
lossstr/None"mse"模型损失。参数化分布对应负对数似然"nll",点估计对应均方误差"mse"
num_targetsint1回归/分类任务的输出目标数;对分类任务即类别数
output_rangelist/NoneNone回归任务的输出值范围,用于约束模型输出值落在给定区间内
num_parallel_samplesint100概率预测时并行生成的样本数

从实现看,loss == "mse"时 head 使用线性层(点估计),否则根据distribution_output构造StudentTOutputNormalOutputNegativeBinomialOutput(三者来自 time_series_utils.py 的公共实现),训练时以负对数似然为损失。若设置output_range=[low, high],回归头在线性输出后套用torch.sigmoid(x) * (high - low) + low把预测值约束到区间内(见 modeling_patchtst.py)。

Patch 切分

参数类型默认值说明
patch_lengthint1patch 切分的片段长度
patch_strideint1patch 切分的滑动步长

patch 数量由PatchTSTPatchify计算:num_patches = (max(context_length, patch_length) - patch_length) // patch_stride + 1(modeling_patchtst.py)。若context_length <= patch_length会抛出异常,因为序列长度必须大于 patch 长度。对回看窗口不整除的残余部分,实现会用sequence_start = context_length - new_sequence_length从序列末尾对齐开始切片(即只取能被 patch 完全覆盖的最后一段),这是把一段长历史“浓缩”为若干 token 的关键。

Transformer 结构

参数类型默认值说明
num_hidden_layersint3Encoder 层数
d_modelint128Embedding / 隐藏维度(通用命名hidden_size映射到它)
num_attention_headsint4每层注意力头数
share_embeddingboolTrue是否让所有通道共享输入 embedding
channel_attentionboolFalse是否在 Transformer 中开启通道注意力块,让各通道互相 attend
ffn_dimint512Transformer 前馈网络中间层维度
norm_typestr"batchnorm"每层归一化类型,可选"batchnorm""layernorm"
norm_epsfloat1e-5归一化分母中用于数值稳定的小量
attention_dropoutfloat0.0注意力 dropout 概率(配置类属性,默认 0.0)
positional_dropoutfloat0.0位置编码层 dropout
path_dropoutfloat0.0残差路径(drop path)dropout
ff_dropoutfloat0.0前馈网络两层之间的 dropout
biasboolTrue前馈网络是否加 bias
activation_functionstr"gelu"Transformer 中的激活函数,支持"gelu""relu"
pre_normboolTrueTrue时归一化在自注意力之前(Pre-LN);否则在残差块之后
positional_encoding_typestr"sincos"位置编码类型,支持"random""sincos"
use_cls_tokenboolFalse是否使用 cls token
init_stdfloat0.02截断正态权重初始化的标准差

其中PatchTSTBatchNorm是一种把 BatchNorm 应用到时间维(sequence)的实现:先transpose(1, 2)再执行nn.BatchNorm1d(d_model)(modeling_patchtst.py),这与普通 NLP Transformer 的 LayerNorm 归一化维度策略不同,是 PatchTST 官方实现保留的风格,可通过norm_type切换。

sincos位置编码沿用 Transformer 原始三角函数方案,并做了去均值、按std*10归一化的处理,且参数被设为requires_grad=False(不参与训练);random位置编码则为可学习的nn.Parameter(modeling_patchtst.py)。若use_cls_token=True,位置编码长度会 +1,cls token 会拼接在 patch token 序列最前面。

预训练掩码

参数类型默认值说明
do_mask_inputboolNone预训练阶段是否对输入施加掩码
mask_typestr"random"掩码类型,目前仅支持"random""forecast"
random_mask_ratiofloat0.5随机预训练时对输入数据的掩码比例
num_forecast_mask_patchesint/list[2](源码默认(2,)每个 batch 样本末尾被掩码的 patch 数。若为 int,则所有样本掩码数相同;若为 list,则各样本按 list 内数值随机掩码,仅用于 forecast 预训练
channel_consistent_maskingboolFalse若为True,所有通道采用相同的掩码模式
unmasked_channel_indiceslist/NoneNone预训练时不被掩码的通道索引,取值在 1 到num_input_channels之间
mask_valueint0掩码 patch 位置填充的值

掩码逻辑分为两种,均由PatchTSTMasking调度(modeling_patchtst.py):

  • random_masking(L175-L230):按random_mask_ratio对 patch 做类 MAE 的随机掩码——按随机噪声排序,保留前len_keep个 patch,其余填充mask_valuemask_ratio必须满足0 <= ratio < 1
  • forecast_masking(L233-L298):把每个样本末尾的 K 个 patch掩掉,模拟“看过去预测未来”的任务形态;若给定 list 长度,会在 batch 内按比例混合多种掩码长度(要求每个值满足0 < K < 总 patch 数)。

两者的输出都会附带回原形状的 mask 张量,供计算仅作用于被掩码 patch 的重建损失。

五个模型类的定位与用法

仓库在 modeling_patchtst.py 中导出了五个与任务对应的模型类(__all__,见文件尾部),对应文档中的PatchTSTModelPatchTSTForPredictionPatchTSTForClassificationPatchTSTForPretrainingPatchTSTForRegression

PatchTSTModel:基础 Transformer 编码器

PatchTSTModel是只有 Encoder 的基础模型,包含缩放器(scaler)、patch 化器(patchifier)、可选掩码模块与编码器栈。它用于特征提取(feature extraction),例如为下游自定义 head 获取时间序列的表征。forward 的完整签名与示例见 PatchTSTModel,典型调用如下:

from huggingface_hub import hf_hub_download import torch from transformers import PatchTSTModel file = hf_hub_download( repo_id="hf-internal-testing/etth1-hourly-batch", filename="train-batch.pt", repo_type="dataset" ) batch = torch.load(file) model = PatchTSTModel.from_pretrained("namctin/patchtst_etth1_pretrain") # during training, one provides both past and future values outputs = model( past_values=batch["past_values"], future_values=batch["future_values"], ) last_hidden_state = outputs.last_hidden_state

其输入输出要点:

  • past_values[bs, sequence_length, num_input_channels]的过去观测序列(必填);
  • past_observed_mask[bs, sequence_length, num_input_channels]的布尔张量,1 表示观测到、0 表示缺失(NaN 被零填充的位置);缺省时全为 1;
  • future_values:供训练期提供标签的预测目标;
  • 输出PatchTSTModelOutputlast_hidden_statehidden_statesattentions外,还返回masklocscalepatch_input,方便上游任务头做反缩放与掩码重建(L748-L773)。

PatchTSTForPrediction:长程预测(确定性 + 概率性)

预测模型由PatchTSTModel+PatchTSTPredictionHead组成(L1560-L1698)。预测头会根据loss配置选择线性点估计头,或student_t/normal/negative_binomial分布头;share_projection(默认True)决定所有通道是否共享同一投影层,use_cls_token/pooling_type决定如何把 patch 维聚合到预测。文档示例:

from huggingface_hub import hf_hub_download import torch from transformers import PatchTSTConfig, PatchTSTForPrediction file = hf_hub_download( repo_id="hf-internal-testing/etth1-hourly-batch", filename="train-batch.pt", repo_type="dataset" ) batch = torch.load(file) # Prediction task with 7 input channels and prediction length is 96 model = PatchTSTForPrediction.from_pretrained("namctin/patchtst_etth1_forecast") # during training, one provides both past and future values outputs = model( past_values=batch["past_values"], future_values=batch["future_values"], ) loss = outputs.loss loss.backward() # during inference, one only provides past values, the model outputs future values outputs = model(past_values=batch["past_values"]) prediction_outputs = outputs.prediction_outputs

实现上,训练损失在点估计模式为MSELoss;分布模式下把 head 输出套上distribution_output.distribution(y_hat, loc, scale)计算负对数似然并用weighted_average做 mask 感知的平均(L1672-L1682)。确定性预测时模型输出会先经y_hat * scale + loc反缩放还原到原始量纲,这一点对实际使用至关重要。

若需概率性预测(不确定性量化),可调用model.generate(past_values=..., past_observed_mask=...):分布头下会采样num_parallel_samples条路径,返回SamplePatchTSTOutput.sequences,形状为[bs, num_samples, prediction_length, num_input_channels](L1701-L1746)。

PatchTSTForPretraining:掩码自监督预训练

自监督预训练通过掩码 patch 重建实现,整体等价于针对时间序列的 MAE 风格任务:先随机或 forecast 掩码,再让模型重建被掩码的部分,用 MSE 只统计被掩码 patch 的损失。类构造时会强制把do_mask_input置为True(L1212-L1218)。文档示例同时覆盖两种掩码策略的配置写法:

from huggingface_hub import hf_hub_download import torch from transformers import PatchTSTConfig, PatchTSTForPretraining file = hf_hub_download( repo_id="hf-internal-testing/etth1-hourly-batch", filename="train-batch.pt", repo_type="dataset" ) batch = torch.load(file) # Config for random mask pretraining config = PatchTSTConfig( num_input_channels=7, context_length=512, patch_length=12, stride=12, mask_type='random', random_mask_ratio=0.4, use_cls_token=True, ) # Config for forecast mask pretraining config = PatchTSTConfig( num_input_channels=7, context_length=512, patch_length=12, stride=12, mask_type='forecast', num_forecast_mask_patches=5, use_cls_token=True, ) model = PatchTSTForPretraining(config) # during training, one provides both past and future values outputs = model(past_values=batch["past_values"]) loss = outputs.loss loss.backward()

(注:示例中stride=12属于 docstring 的历史别名写法;在当前配置类中对应参数名为patch_stride,请以 PatchTSTConfig 定义为准。)

预训练头PatchTSTMaskPretrainHeadd_model维的隐藏态线性映射回patch_length维以重建 patch(L1179-L1204);若use_cls_token=True会先剔除 cls token 再计算重建。masked loss 的具体计算为:(mse(x_hat, patch_input).mean(-1) * mask).sum() / (mask.sum() + 1e-10)(L1309-L1312),即只对掩码 patch 求平均。预训练得到的 Encoder 表征可迁移到下游数据集或微调到预测任务。

PatchTSTForClassification:时间序列分类

把 PatchTST 用于时间序列分类时,配置中num_targets表示类别数。分类头先按use_cls_token(取首个 token)或pooling_typemean/max池化)把 patch 维聚合为每个通道的向量,flatten后经线性层映射到num_targets(L1324-L1358)。类初始化时会自动关闭掩码(若do_mask_input=True会发出警告并置为False)。文档示例:

from transformers import PatchTSTConfig, PatchTSTForClassification # classification task with two input channels and 3 classes config = PatchTSTConfig( num_input_channels=2, num_targets=3, context_length=512, patch_length=12, stride=12, use_cls_token=True, ) model = PatchTSTForClassification(config=config) # during inference, one only provides past values past_values = torch.randn(20, 512, 2) outputs = model(past_values=past_values) labels = outputs.prediction_logits

提供target_values标签时,forward 内部使用CrossEntropyLoss计算分类损失(L1437-L1440),输出为PatchTSTForClassificationOutput.lossprediction_logits

PatchTSTForRegression:时间序列回归

回归模型将整个序列池化为num_channels * d_model维向量,再用线性/分布头投影到num_targets个目标值(L1749-L1834)。同样,构造回归模型时会自动关闭掩码。文档示例:

from transformers import PatchTSTConfig, PatchTSTForRegression # Regression task with 6 input channels and regress 2 targets model = PatchTSTForRegression.from_pretrained("namctin/patchtst_etth1_regression") # during inference, one only provides past values, the model outputs future values past_values = torch.randn(20, 512, 6) outputs = model(past_values=past_values) regression_outputs = outputs.regression_outputs

回归模式下可设置output_range约束输出区间,也可以像预测任务一样配合loss="nll"使用分布头获得概率式输出并调用generate采样(L1911-L1951)。

从源码理解 PatchTST 的实现细节

数据形状流转

理解 PatchTST 的关键在于其张量维度转换,测试文件 test_modeling_patchtst.py 中构造输入的方式直观展示了这一约定:

  • 模型输入past_values[bs, context_length, num_input_channels]
  • patch 化后:[bs, num_input_channels, num_patches, patch_length]
  • Encoder 输出隐藏态:[bs, num_input_channels, num_patches, d_model](token 序列维被移到通道之后);
  • 预测输出:[bs, prediction_length, num_input_channels]

注意力实现与加速后端

PatchTSTEncoderLayer的第一子层把 batch 与通道维合并为bs * num_channels,使时间 token 之间做标准自注意力;只有开启channel_attention时才额外执行一次沿通道维的注意力(L464-L543)。注意力接口通过ALL_ATTENTION_FUNCTIONS.get_interfaceconfig._attn_implementation分发,类声明支持 flash attention 与 SDPA(_supports_flash_attn = True_supports_sdpa = True_supports_flex_attn = True,见 modeling_patchtst.py),即可以在较新 GPU 上通过attn_implementation="flash_attention_2""sdpa"进一步加速,且不需要past_key_values缓存式生成(模型不带因果解码结构)。

测试与验证

PatchTST 的统一测试套件位于 tests/models/patchtst/test_modeling_patchtst.py,通过ModelTesterMixinPipelineTesterMixin覆盖了 5 个模型类的配置序列化、前向输出、注意力输出(has_attentions = True)、梯度、断点续训等通用契约,并注册了 feature-extraction pipeline。该测试中还为分类任务生成target_values标签、为预训练移除future_values(L184-L200),可作为理解不同任务输入约定的参考。

使用技巧与注意事项

根据模型文档(Usage tips)与源码约束,使用 PatchTST 时值得留意以下几点:

  1. 一个模型家族覆盖多种任务:除长程预测外,同一套 patch + 通道独立骨架可直接复用到时间序列分类(PatchTSTForClassification)与回归(PatchTSTForRegression),无需为不同任务重写骨干。
  2. 观察掩码要配套使用:真实数据常含缺失值,替换 NaN 为 0 后必须同时传入past_observed_mask,否则缩放统计会被缺失值污染。
  3. 反缩放是预测正确性的关键:确定性预测返回的是还原后的原始量纲值;若自行取隐藏态接自定义头,需自行应用y_hat * scale + loc
  4. Patch 参数决定 token 数与算力patch_lengthpatch_stride共同决定num_patches,即注意力序列长度;patch 越大、stride 越大,token 越少、注意力的时间和内存开销越小,这也是该模型能处理更长历史的根因。
  5. 预训练 vs. 微调:构造预测/分类/回归模型时do_mask_input会被自动关闭;预训练任务在预训练完骨干后,可通过共享权重把任务头接到PatchTSTModel上做有监督微调。

延伸资源

  • 仓库内该模型的中文可阅读源码入口:模型实现、模型配置、测试套件;
  • 原始论文《A Time Series is Worth 64 Words: Long-term Forecasting with Transformers》(Yuqi Nie et al.)以及原作者的官方 PatchTST 参考实现,贡献者 namctin、gsinthong、diepi、vijaye12、wmgifford 与 kashif 在论文发布次日即把模型代码合入本仓库;
  • 模型家族(ibm-granite/granite-timeseries-patchtst等)可直接用上述from_pretrained方式加载用于推理或微调,若需概率式预测请配合loss="nll"generate()使用。

【免费下载链接】transformers🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and multimodal models, for both inference and training.项目地址: https://gitcode.com/GitHub_Trending/tra/transformers

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询