模型#
模型参数在很大程度上取决于它们所针对的数据集。
PyTorch Forecasting 为每个模型提供了一个 .from_dataset() 方法,该方法接受一个 TimeSeriesDataSet 和无法直接从数据集中导出的额外参数,例如 learning_rate 或 hidden_size。
为了调整模型,可以使用optuna。例如,TemporalFusionTransformer的调整是通过optimize_hyperparameters()实现的。
选择架构#
选择架构的标准在很大程度上取决于使用案例。有多个选择标准需要考虑。以下是已实现模型的优缺点概述:
名称 |
协变量 |
多目标 |
回归 |
分类 |
概率 |
不确定性 |
序列间交互 |
灵活的历史长度 |
冷启动 |
所需计算资源(1-5,5为最多) |
|---|---|---|---|---|---|---|---|---|---|---|
|
x |
x |
x |
x |
2 |
|||||
|
x |
x |
x |
x |
x |
x |
x |
1 |
||
|
x |
1 |
||||||||
|
x |
x |
x |
1 |
||||||
|
x |
x |
x |
x |
x |
x [1] |
x |
3 |
||
|
x |
x |
x |
x |
x |
x |
x |
4 |
||
|
x |
x |
x |
x |
3 |
可用数据的大小和类型#
应特别考虑五个标准。
协变量的可用性#
如果你有协变量,即除了目标变量本身之外还包含有关目标信息的变量,那么你的情况将受益于能够容纳协变量的模型。一个不能使用协变量的模型是NBeats。
时间序列长度#
时间序列的长度对哪种模型表现良好有显著影响。不幸的是,大多数模型是在非常长的时间序列上创建和测试的,而在实践中,经常会遇到短时间序列或长短混合的时间序列。能够很好地利用协变量的模型,如TemporalFusionTransformer,通常在短时间序列上表现优于其他模型。从短时间序列到仅基于静态协变量进行冷启动预测是一个重要的步骤,即在没有观察历史的情况下进行预测。例如,这仅由TemporalFusionTransformer支持,但效果并不十分出色。
时间序列的数量及其相互关系#
如果你的时间序列相互关联(例如,同一公司所有产品的销售),能够学习时间序列之间关系的模型可以提高准确性。请注意,只有能够处理协变量的模型才能学习不同时间序列之间的关系。如果时间序列表示不同的实体或在整体上表现出非常相似的模式,像NBeats这样的模型也会有效。
如果你只有一个或很少的时间序列,它们应该非常长,以便深度学习方法能够很好地工作。也可以考虑更传统的方法。
预测任务的类型#
并非所有模型都能进行回归、分类或处理多个目标。有些模型专门针对单一任务。例如,NBeats只能用于没有协变量的单一目标的回归,而TemporalFusionTransformer支持多个目标,甚至支持一些是连续变量而另一些是分类变量的异质目标,即同时进行回归和分类。DeepAR可以处理多个目标,但仅适用于回归任务。
对于长期预测,NHiTS 是一个极佳的选择,因为它使用了插值功能。
支持不确定性#
并非所有模型都支持不确定性估计。那些支持的模型可能以不同的方式进行估计。 非参数模型提供的预测不受限于特定分布, 而参数模型则假设数据遵循特定分布。
如果你知道你的数据(以及可能的误差)是如何分布的,参数模型将是一个更好的选择。然而,如果你缺少这些信息或无法做出与现实相当吻合的有根据的猜测,模型的不确定性估计将受到不利影响。在这种情况下,非参数模型将表现得更好。
DeepAR 是一个参数化模型的例子,而
TemporalFusionTransformer
可以输出适合任何分布的分位数预测。
基于归一化流的模型通过提供完整概率分布的非参数估计,将这两个世界结合在一起。PyTorch Forecasting 目前不提供
对这些模型的支持,但
Pyro,一个用于概率编程的包 提供了支持,
如果你认为你的问题特别适合这种解决方案。
计算需求#
一些模型的架构更简单,参数更少,这可能导致显著不同的训练时间。然而,这并不是一个普遍规则,正如Zhuohan等人在Train Large, Then Compress: Rethinking Model Size for Efficient Training and Inference of Transformers中所展示的那样。因为时间序列模型的样本数据通常比计算机视觉或语言任务的数据要小得多,GPU通常未被充分利用,增加模型的宽度可能是充分利用GPU的有效方法。这可以提高训练速度,同时也能提高准确性。另一种提高GPU利用率的方法是增加批量大小。然而,增加批量大小可能会对训练网络的泛化能力产生不利影响。此外,考虑到通常计算资源主要用于推理/预测。训练模型的前期任务将需要开发人员的时间(也很昂贵!),但可能只是模型整个生命周期中总计算成本的一小部分。
TemporalFusionTransformer 是一个相当大的模型,但可能会从训练中受益。例如,NBeats 或 NHiTS 是高效的模型。自回归模型如 DeepAR 可能训练速度快,但在推理时可能会较慢(在 DeepAR 的情况下,这是由于多次概率性地采样结果,有效地增加了计算负担,随着样本数量的增加而线性增加。
实现新架构#
请参阅使用自定义数据并实现自定义模型教程,了解如何实现基本和更高级的模型。
每个模型都应继承自base_model中的基础模型。
- class pytorch_forecasting.models.base_model.BaseModel(dataset_parameters: Dict[str, Any] = None, log_interval: int | float = -1, log_val_interval: int | float = None, learning_rate: float | List[float] = 0.001, log_gradient_flow: bool = False, loss: 指标 = SMAPE(), logging_metrics: ModuleList = ModuleList(), reduce_on_plateau_patience: int = 1000, reduce_on_plateau_reduction: float = 2.0, reduce_on_plateau_min_lr: float = 1e-05, weight_decay: float = 0.0, optimizer_params: Dict[str, Any] = None, monotone_constraints: Dict[str, int] = {}, output_transformer: Callable = None, optimizer='adam')[来源]
新时间序列模型应继承自BaseModel。 创建的对象的
hparams将默认为__init__()中指定的参数。forward()方法应返回一个至少包含prediction条目的命名元组,该条目包含网络的输出。有关更多详细信息,请参阅函数的文档。基础模型的想法是,常见的方法不必为每个新架构重新实现。 该类是一个 [LightningModule](https://pytorch-lightning.readthedocs.io/en/latest/lightning_module.html) 并遵循其约定。然而,有一些重要的补充:
你需要指定一个
loss属性,该属性存储用于计算反向传播的MultiHorizonLoss的函数。from_dataset()方法可用于使用数据集的规格初始化网络。通常,诸如特征数量等参数可以很容易地从数据集中推导出来。此外,该方法还会存储如何将归一化预测重新缩放到未归一化预测空间的信息。重写它以传递依赖于数据集的额外参数到网络的 __init__ 方法中。transform_output()方法使用数据集中的目标归一化器重新缩放网络输出。step()方法负责计算损失、记录在logging_metrics属性中定义的额外指标以及样本预测的绘图。您可以重写此方法以添加自定义解释或向网络的前向方法传递额外参数。on_epoch_end()方法可用于计算每个周期的摘要,例如编码器长度的统计信息等,并且需要返回输出。predict()方法使用数据加载器或数据集进行预测。如果您需要默认情况下向forward传递额外的参数,请覆盖它。
要实现您自己的架构,最好先阅读使用自定义数据并实现自定义模型,并查看现有的架构以了解可能是一个好方法。
示例
class Network(BaseModel): def __init__(self, my_first_parameter: int=2, loss=SMAPE()): self.save_hyperparameters() super().__init__(loss=loss) def forward(self, x): normalized_prediction = self.module(x) prediction = self.transform_output(prediction=normalized_prediction, target_scale=x["target_scale"]) return self.to_network_output(prediction=prediction)
用于时间序列预测的BaseModel,可以从中继承
- Parameters:
log_interval (Union[int, float], optional) – 在此批次之后记录预测结果。如果小于1.0,则每批次将记录多个条目。默认为-1。
log_val_interval (Union[int, float], optional) – 在多少个批次后记录验证的预测结果。默认为 None/log_interval。
learning_rate (float, optional) – 学习率。默认为 1e-3。
log_gradient_flow (bool) – 是否记录梯度流动,这会花费时间,应仅在诊断训练失败时使用。默认为 False。
loss (Metric, 可选) – 要优化的指标,也可以是多个指标的列表。默认为 SMAPE()。
logging_metrics (nn.ModuleList[MultiHorizonMetric]) – 训练期间记录的指标列表。默认为 []。
reduce_on_plateau_patience (int) – 在达到该耐心值后,学习率将减少10倍。默认值为1000
reduce_on_plateau_reduction (float) – 当遇到平台期时学习率的减少量。默认为2.0。
reduce_on_plateau_min_lr (float) – 用于reduce on plateua学习率调度器的最小学习率。 默认值为1e-5
weight_decay (float) – 权重衰减。默认值为0.0。
optimizer_params (Dict[str, Any]) – 优化器的额外参数。默认为 {}。
monotone_constraints (Dict[str, int]) – 用于连续解码器变量的单调性约束字典,将位置(例如
"0"表示第一个位置)映射到约束(-1表示负,+1表示正,较大的数字会增加约束相对于损失的权重,但通常不需要)。此约束会显著减慢训练速度。默认为{}。output_transformer (Callable) – 将网络输出转换为预测空间的转换器。默认为None,相当于
lambda out: out["prediction"]。optimizer (str) – 优化器,可以是“ranger”、“sgd”、“adam”、“adamw”或
torch.optim或pytorch_optimizer中的优化器类名。 另外,可以传递一个类或函数,该函数以参数作为第一个参数,并接受lr参数(可选地还包括weight_decay)。默认为“adam”。
详细信息和可用模型#
有关可用模型的更多详细信息,请参阅API文档:
|
具有自回归模型附加方法的模型。 |
|
具有协变量的自回归模型的附加方法。 |
新时间序列模型应继承的BaseModel。 |
|
|
使用协变量的模型,具有额外的方法。 |
使用最后一个已知目标值进行预测的基线模型。 |
|
DeepAR 网络。 |
|
|
解码器上的MLP。 |
初始化NBeats模型 - 如果可能的话,使用其 |
|
初始化N-HiTS模型 - 如果可能,使用其 |
|
|
用于分类变量(包括分类变量组)的嵌入层。 |
可以处理零长度序列的GRU |
|
可以处理零长度序列的LSTM |
|
获取LSTM或GRU。 |
|
循环网络。 |
|
|
用于预测时间序列的时间融合变压器 - 如果可能,请使用其 |
TiDE模型的实现。 |