向 NeuralForecast 添加模型
关于如何向 NeuralForecast 添加新模型的教程
先决条件
本指南假设您对 NeuralForecast 有深入了解。
我们强烈建议您先阅读“入门”和“NeuralForecast Map”教程!
此外,请参阅CONTRIBUTING 指南,了解如何为 NeuralForecast 贡献代码的基础知识。
引言
本教程面向希望向 NeuralForecast 库添加新模型的贡献者。该库现有模块负责深度学习模型的优化、训练、选择和评估。core
类简化了在任何数据集上构建完整管道的过程,无论是工业界还是学术界,都提供了诸如 fit
和 predict
之类的用户友好方法。
向 NeuralForecast 添加新模型比从头开始构建新的 PyTorch 模型更简单。您只需编写 forward 方法即可。
它具有以下额外优势
- NeuralForecast 中现有模块已实现了深度学习模型的基本训练和评估方面。
- 与 PyTorch-Lightning 和 Tune 库集成,可实现高效优化和分布式计算。
BaseModel
类提供了通用的优化组件,例如早停和学习率调度器。- Github 上安排了自动性能测试,以确保质量标准。
- 用户可以轻松比较新模型与现有模型的性能和计算。
- 有机会接触庞大的用户和贡献者社区。
示例:简化 MLP 模型
我们将通过一个示例来介绍如何添加当前MLP模型的简化版本,该版本不包含外生协变量。
在给定时间戳 ,MLP模型将使用最后 个历史值 作为输入,预测单变量目标时间序列的未来 个值 。下图展示了模型的图示。
0. 前期准备
按照我们的贡献教程(点击此处)来设置您的开发环境。
以下是最重要步骤的简要列表
- 创建
neuralforecast
库的分支 (fork)。 - 将分支克隆到您的计算机。
- 设置一个环境,包含
neuralforecast
库、核心依赖项和nbdev
包,以便在交互式笔记本中编写模型代码。
1. 继承基类 (BaseModel
)
该库包含一个基模型类:BaseModel
。使用类属性,我们可以使该模型递归或非递归,多元或单变量,或允许使用外生输入。
a. 采样过程
训练期间,基类从TimeSeriesLoader模块接收数据集的时间序列样本。BaseModel
模型将从随机时间戳开始,采样大小为 input_size+h
的单个窗口。
b. BaseModel
的超参数
熟悉基类中指定的超参数,包括 h
(预测期)、input_size
以及诸如 learning_rate
、max_steps
等优化超参数。以下列表介绍了与窗口采样相关的超参数
h
(h):要预测的未来值的数量。input_size
(L):用作模型输入的历史值的数量。batch_size
(bs):训练期间加载器采样的时间序列数量。valid_batch_size
(v_bs):推理(验证和测试)期间加载器采样的时间序列数量。windows_batch_size
(w_bs):训练期间(从先前的时间序列中)采样的单个窗口数量,用于组成批次。inference_windows_batch_size
(i_bs):推理期间采样的单个窗口数量,用于形成每个批次。用于控制 GPU 内存。
c. 输入和输出批次形状
forward
方法接收一个字典形式的数据批次,包含以下键:
insample_y
:时间序列的历史值。insample_mask
:指示时间序列可用值的掩码(可用为 1,缺失为 0)。futr_exog
:未来的外生协变量(如果存在)。hist_exog
:历史外生协变量(如果存在)。stat_exog
:静态外生协变量(如果存在)。
如果属性 MULTIVARIATE = False
已设置,下表显示了每个张量的形状
张量 | BaseModel |
---|---|
insample_y | (w_bs , L , 1 ) |
insample_mask | (w_bs , L ) |
futr_exog | (w_bs , L +h , n_f ) |
hist_exog | (w_bs , L , n_h ) |
stat_exog | (w_bs ,n_s ) |
forward
函数应返回一个张量,其中包含每个窗口未来 h
个时间戳的预测结果。使用 loss
类的属性可以自动将输出解析为正确的形状(参见下面的示例)。
提示
由于我们使用
nbdev
,您可以轻松地在代码中添加打印语句,并在训练期间查看张量的形状。
d. BaseModel
的方法
BaseModel
类包含所有基于窗口的模型的几个常用方法,通过防止代码重复简化了新模型的开发。该类最重要的方法是:
_create_windows
:将TimeSeriesLoader中的时间序列解析为大小为input_size+h
的单个窗口。_normalization
:根据scaler
类型规范化每个窗口。_inv_normalization
:对预测结果进行逆规范化。training_step
:模型的训练步骤,在训练期间由 PyTorch-Lightning 的Trainer
类调用(fit
方法)。validation_step
:模型的验证步骤,在验证期间由 PyTorch-Lightning 的Trainer
类调用。predict_step
:模型的预测步骤,在推理期间由 PyTorch-Lightning 的Trainer
类调用(predict
方法)。
2. 创建模型文件和类
熟悉 BaseModel
类的基础知识后,下一步是创建您的特定模型。
主要步骤如下
- 在
nbs
文件夹 (https://github.com/Nixtla/neuralforecast/tree/main/nbs) 中创建文件。应命名为models.YOUR_MODEL_NAME.ipynb
。 - 添加
nbdev
文件的头部。 - 在文件中导入库。
- 定义
__init__
方法,包含模型继承的特有超参数,并实例化架构。 - 设置以下模型属性
EXOGENOUS_FUTR
:模型是否可以处理未来的外生变量(True 为是,False 为否)EXOGENOUS_HIST
:模型是否可以处理历史的外生变量(True 为是,False 为否)EXOGENOUS_STAT
:模型是否可以处理静态的外生变量(True 为是,False 为否)MULTIVARIATE
:如果模型产生多元预测(True 为是)或单变量预测(False 为否)RECURRENT
:如果模型递归地生成预测(True 为是)或直接生成预测(False 为否)
- 定义
forward
方法,该方法接收输入批次字典并返回预测结果。
a. 模型类
首先,在 nbdev
文件的顶部添加以下两个单元格。
重要
将
mlp
更改为您的模型名称,使用小写字母和下划线。稍后运行nbdev_export
时,它将在neuralforecast/models/
目录中创建一个YOUR_MODEL.py
脚本。
接下来,添加模型的依赖项。
提示
不要忘记在此单元格上添加
#| export
标签。
接下来,创建包含 init
和 forward
方法的类。以下示例展示了简化的MLP模型。我们将在代码之后解释重要细节。
提示
- 不要忘记在每个单元格上添加
#| export
标签。- 更大的架构,例如 Transformers,可能需要通过使用中间函数来拆分
forward
方法。
重要说明
基类有许多超参数,模型必须为所有超参数设置默认值(h
和 input_size
除外)。如果您不确定使用什么默认值,我们建议从现有模型中复制大多数优化和采样超参数的默认值。您可以随时更改默认值。
forward
步骤末尾的 reshape
方法用于调整输出形状。loss
类包含一个 outputsize_multiplier
属性,可根据 loss
自动调整预测输出大小。例如,对于多分位数损失 (MQLoss),模型需要为每个预测期输出每个分位数。
b. 测试和文档
nbdev
允许在开发过程中测试和记录模型。它允许用户在笔记本中迭代开发,并在同一环境中测试代码。请参阅现有模型,例如此处的完整 MLP 模型。这些文件已包含开发过程中使用的测试、文档和使用示例。
c. 使用 nbdev
将新模型导出到库
按照 CONTRIBUTING 指南,下一步是将新模型从开发笔记本导出到包含实际脚本的 neuralforecast
文件夹。
要导出模型,请在终端中运行 nbdev_export
。您应该在 neuralforecast/models/
文件夹中看到包含您模型的新文件。
3. Core 类和其他文件
最后,将模型添加到 core
类和其他文件
-
手动将模型添加到以下init 文件中。
-
使用此处的
nbdev
文件将模型添加到core
类中- 将模型添加到初始模型列表
- 将模型添加到
MODEL_FILENAME_DICT
字典(用于save
和load
函数)。
4. 将模型添加到文档
将模型添加到必要的文档页面非常重要,以便所有人都能找到文档
5. 上传到 GitHub
恭喜!按照上述步骤,模型已可用于库中。
按照我们的贡献指南的最后步骤将模型上传到 GitHub:点击此处。
其中一位维护者将审查 PR,如有必要会请求更改,并将其合并到库中。