超参数优化
深度学习模型是时间序列预测的最新技术。在最近的大型竞赛(如 M 系列)中,它们已经超越了统计方法和基于树的方法,并且在工业界得到了越来越多的应用。然而,它们的性能受超参数选择的影响很大。选择最优配置(这个过程称为超参数调整)对于获得最佳性能至关重要。
超参数调整的主要步骤包括
- 定义训练集和验证集。
- 定义搜索空间。
- 使用搜索算法采样配置,训练模型,并在验证集上进行评估。
- 选择并保存最佳模型。
通过 Neuralforecast
,我们使用 Auto
模型自动化和简化了超参数调整过程。库中的每个模型都有一个 Auto
版本(例如,AutoNHITS
,AutoTFT
),可以在默认或用户定义的搜索空间上执行自动超参数选择。
Auto
模型可以使用两个后端:Ray 的 Tune
库和 Optuna
,它们提供了用户友好和简化的 API,并包含了它们的大部分功能。
在本教程中,我们将详细展示如何使用 Tune
和 Optuna
后端实例化和训练具有自定义搜索空间的 AutoNHITS
模型,安装和使用 HYPEROPT
搜索算法,并使用最优超参数的模型进行预测。
您可以使用 Google Colab 的 GPU 运行这些实验。
1. 安装 Neuralforecast
2. 加载数据
在此示例中,我们将使用 AirPasengers
,这是一个流行的数据集,包含 1949 年至 1960 年间美国每月的航空公司乘客数量。加载 utils
方法中所需格式的数据。有关数据输入格式的更多详细信息,请参阅 https://nixtla.github.io/neuralforecast/examples/data_format.html。
unique_id | ds | y | |
---|---|---|---|
0 | 1.0 | 1949-01-31 | 112.0 |
1 | 1.0 | 1949-02-28 | 118.0 |
2 | 1.0 | 1949-03-31 | 132.0 |
3 | 1.0 | 1949-04-30 | 129.0 |
4 | 1.0 | 1949-05-31 | 121.0 |
3. Ray 的 Tune 后端
首先,我们展示如何使用 Tune
后端。此后端基于 Ray 的 Tune
库,这是一个可扩展的超参数调整框架。它是机器学习社区中流行的库,被许多公司和研究实验室使用。如果您计划使用 Optuna
后端,可以跳过此部分。
3.a 定义超参数网格
每个 Auto
模型都包含一个默认搜索空间,该空间已在多个大型数据集上进行了广泛测试。搜索空间使用字典指定,其中键对应于模型的超参数,值是一个 Tune
函数,用于指定如何对超参数进行采样。例如,使用 randint
均匀采样整数,使用 choice
采样列表中的值。
3.a.1 默认超参数网格
可以通过 Auto
模型的 get_default_config
函数访问默认搜索空间字典。如果您希望使用默认参数配置但想更改一个或多个超参数空间而不更改其他默认值,这会很有用。
要提取默认配置,您需要定义: * h
: 预测范围。 * backend
: 要使用的后端。 * n_series
: 可选,唯一时间序列的数量,仅适用于多变量模型。
在此示例中,我们将使用 h=12
并使用 ray
作为后端。我们将使用默认超参数空间,但仅更改 random_seed
范围和 n_pool_kernel_size
。
3.a.2 自定义超参数网格
更一般地,用户可以通过完全指定超参数搜索空间字典来定义针对特定数据集和任务量身定制的完全自定义搜索空间。
在以下示例中,我们优化了 learning_rate
和两个 NHITS
特定超参数:n_pool_kernel_size
和 n_freq_downsample
。此外,我们还使用搜索空间修改了默认超参数,例如 max_steps
和 val_check_steps
。
重要提示
配置字典在不同模型之间不可互换,因为它们具有不同的超参数。有关每个模型超参数的完整列表,请参阅 https://nixtla.github.io/neuralforecast/models.html。
3.b 实例化 Auto 模型
要实例化一个 Auto 模型,您需要定义
h
: 预测范围。loss
: 来自neuralforecast.losses.pytorch
的训练和验证损失函数。config
: 超参数搜索空间。如果为None
,Auto
类将使用预定义的建议超参数空间。search_alg
: 搜索算法(来自tune.search
),默认为随机搜索。有关不同搜索算法选项的更多信息,请参阅 https://docs.rayai.org.cn/en/latest/tune/api_docs/suggestion.html。backend
: 要使用的后端,默认为ray
。如果为optuna
,Auto
类将使用Optuna
后端。num_samples
: 探索的配置数量。
在此示例中,我们将预测范围 h
设置为 12,使用 MAE
损失进行训练和验证,并使用 HYPEROPT
搜索算法。
提示
样本数量
num_samples
是一个关键参数!较大的值通常会产生更好的结果,因为我们在搜索空间中探索了更多的配置,但这会增加训练时间。较大的搜索空间通常需要更多的样本。一般来说,我们建议将num_samples
设置为高于 20。在此示例中,我们为演示目的设置了 10。
3.c 使用 Core 类训练模型和进行预测
接下来,我们使用 Neuralforecast
类训练 Auto
模型。在此步骤中,Auto
模型将自动执行超参数调整,训练多个具有不同超参数的模型,在验证集上生成预测,并评估它们。最佳配置根据验证集上的误差进行选择。仅存储并在推理期间使用最佳模型。
使用 fit
方法的 val_size
参数控制验证集的长度。在这种情况下,我们将验证集设置为预测范围的两倍。
超参数调整的结果可在 Auto
模型的 results
属性中获取。使用 get_dataframe
方法将结果获取为 pandas 数据框。
loss | time_this_iter_s | done | timesteps_total | episodes_total | training_iteration | trial_id | experiment_id | 日期 | 时间戳 | … | config/input_size | config/learning_rate | config/loss | config/max_steps | config/n_freq_downsample | config/n_pool_kernel_size | config/random_seed | config/val_check_steps | config/valid_loss | logdir | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 21.173204 | 3.645993 | False | NaN | NaN | 2 | e20dbd9b | f62650f116914e18889bb96963c6b202 | 2023-10-03_11-19-14 | 1696346354 | … | 24 | 0.000415 | MAE() | 100 | [168, 24, 1] | [16, 8, 1] | 7 | 50 | MAE() | /Users/cchallu/ray_results/_train_tune_2023-10… |
1 | 33.843426 | 3.756614 | False | NaN | NaN | 2 | 75e09199 | f62650f116914e18889bb96963c6b202 | 2023-10-03_11-19-22 | 1696346362 | … | 24 | 0.000068 | MAE() | 100 | [24, 12, 1] | [16, 8, 1] | 4 | 50 | MAE() | /Users/cchallu/ray_results/_train_tune_2023-10… |
2 | 17.750280 | 8.573898 | False | NaN | NaN | 2 | 0dc5925a | f62650f116914e18889bb96963c6b202 | 2023-10-03_11-19-36 | 1696346376 | … | 24 | 0.001615 | MAE() | 100 | [1, 1, 1] | [2, 2, 2] | 8 | 50 | MAE() | /Users/cchallu/ray_results/_train_tune_2023-10… |
3 | 24.573055 | 6.987517 | False | NaN | NaN | 2 | 352e03ff | f62650f116914e18889bb96963c6b202 | 2023-10-03_11-19-50 | 1696346390 | … | 24 | 0.003405 | MAE() | 100 | [1, 1, 1] | [2, 2, 2] | 5 | 50 | MAE() | /Users/cchallu/ray_results/_train_tune_2023-10… |
4 | 474221.937500 | 4.912362 | False | NaN | NaN | 2 | 289bdd5e | f62650f116914e18889bb96963c6b202 | 2023-10-03_11-20-00 | 1696346400 | … | 24 | 0.080117 | MAE() | 100 | [168, 24, 1] | [16, 8, 1] | 5 | 50 | MAE() | /Users/cchallu/ray_results/_train_tune_2023-10… |
接下来,我们使用 predict
方法使用最优超参数预测未来 12 个月。
unique_id | ds | AutoNHITS | |
---|---|---|---|
0 | 1.0 | 1961-01-31 | 442.346680 |
1 | 1.0 | 1961-02-28 | 439.409821 |
2 | 1.0 | 1961-03-31 | 477.709930 |
3 | 1.0 | 1961-04-30 | 503.884064 |
4 | 1.0 | 1961-05-31 | 521.344421 |
4. Optuna 后端
在本节中,我们将展示如何使用 Optuna
后端。Optuna
是一个轻量级且多功能的超参数优化平台。如果您计划使用 Tune
后端,可以跳过此部分。
4.a 定义超参数网格
每个 Auto
模型都包含一个默认搜索空间,该空间已在多个大型数据集上进行了广泛测试。搜索空间通过一个返回字典的函数指定,其中键对应于模型的超参数,值是一个 suggest
函数,用于指定如何对超参数进行采样。例如,使用 suggest_int
均匀采样整数,使用 suggest_categorical
采样列表中的值。有关更多详细信息,请参阅 https://docs.optuna.cn/en/stable/reference/generated/optuna.trial.Trial.html。
4.a.1 默认超参数网格
可以通过 Auto
模型的 get_default_config
函数访问默认搜索空间字典。如果您希望使用默认参数配置但想更改一个或多个超参数空间而不更改其他默认值,这会很有用。
要提取默认配置,您需要定义: * h
: 预测范围。 * backend
: 要使用的后端。 * n_series
: 可选,唯一时间序列的数量,仅适用于多变量模型。
在此示例中,我们将使用 h=12
并使用 optuna
作为后端。我们将使用默认超参数空间,但仅更改 random_seed
范围和 n_pool_kernel_size
。
3.a.2 自定义超参数网格
更一般地,用户可以通过完全指定超参数搜索空间函数来定义针对特定数据集和任务量身定制的完全自定义搜索空间。
在以下示例中,我们优化了 learning_rate
和两个 NHITS
特定超参数:n_pool_kernel_size
和 n_freq_downsample
。此外,我们还使用搜索空间修改了默认超参数,例如 max_steps
和 val_check_steps
。
4.b 实例化 Auto 模型
要实例化一个 Auto 模型,您需要定义
h
: 预测范围。loss
: 来自neuralforecast.losses.pytorch
的训练和验证损失函数。config
: 超参数搜索空间。如果为None
,Auto
类将使用预定义的建议超参数空间。search_alg
: 搜索算法(来自optuna.samplers
),默认为 TPESampler (Tree-structured Parzen Estimator)。有关不同搜索算法选项的更多信息,请参阅 https://docs.optuna.cn/en/stable/reference/samplers/index.html。backend
: 要使用的后端,默认为ray
。如果为optuna
,Auto
类将使用Optuna
后端。num_samples
: 探索的配置数量。
重要提示
Tune
和Optuna
的配置字典和搜索算法不可互换!请为每个后端使用适当类型的搜索算法和自定义配置字典。
4.c 使用 Core 类训练模型和进行预测
使用 fit
方法的 val_size
参数控制验证集的长度。在这种情况下,我们将验证集设置为预测范围的两倍。
超参数调整的结果可在 Auto
模型的 results
属性中获取。使用 trials_dataframe
方法将结果获取为 pandas 数据框。
编号 | 值 | 开始时间 | 完成时间 | 持续时间 | params_learning_rate | params_n_freq_downsample | params_n_pool_kernel_size | params_random_seed | 状态 | |
---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 2.964735e+01 | 2023-10-23 19:13:30.251719 | 2023-10-23 19:13:33.007086 | 0 days 00:00:02.755367 | 0.000074 | [24, 12, 1] | [2, 2, 2] | 2 | COMPLETE |
1 | 1 | 2.790444e+03 | 2023-10-23 19:13:33.007483 | 2023-10-23 19:13:35.823089 | 0 days 00:00:02.815606 | 0.026500 | [24, 12, 1] | [2, 2, 2] | 10 | COMPLETE |
2 | 2 | 2.193000e+01 | 2023-10-23 19:13:35.823607 | 2023-10-23 19:13:38.599414 | 0 days 00:00:02.775807 | 0.000337 | [168, 24, 1] | [2, 2, 2] | 7 | COMPLETE |
3 | 3 | 1.147799e+08 | 2023-10-23 19:13:38.600149 | 2023-10-23 19:13:41.440307 | 0 days 00:00:02.840158 | 0.059274 | [1, 1, 1] | [16, 8, 1] | 5 | COMPLETE |
4 | 4 | 2.140740e+01 | 2023-10-23 19:13:41.440833 | 2023-10-23 19:13:44.184860 | 0 days 00:00:02.744027 | 0.000840 | [168, 24, 1] | [16, 8, 1] | 5 | COMPLETE |
5 | 5 | 1.606544e+01 | 2023-10-23 19:13:44.185291 | 2023-10-23 19:13:46.945672 | 0 days 00:00:02.760381 | 0.005477 | [1, 1, 1] | [16, 8, 1] | 8 | COMPLETE |
6 | 6 | 1.301640e+04 | 2023-10-23 19:13:46.946108 | 2023-10-23 19:13:49.805633 | 0 days 00:00:02.859525 | 0.056746 | [1, 1, 1] | [16, 8, 1] | 3 | COMPLETE |
7 | 7 | 4.972713e+01 | 2023-10-23 19:13:49.806278 | 2023-10-23 19:13:52.577180 | 0 days 00:00:02.770902 | 0.000021 | [24, 12, 1] | [2, 2, 2] | 9 | COMPLETE |
8 | 8 | 2.138879e+01 | 2023-10-23 19:13:52.577678 | 2023-10-23 19:13:55.372792 | 0 days 00:00:02.795114 | 0.007136 | [1, 1, 1] | [2, 2, 2] | 9 | COMPLETE |
9 | 9 | 2.094145e+01 | 2023-10-23 19:13:55.373149 | 2023-10-23 19:13:58.125058 | 0 days 00:00:02.751909 | 0.004655 | [1, 1, 1] | [2, 2, 2] | 6 | COMPLETE |
接下来,我们使用 predict
方法使用最优超参数预测未来 12 个月。
unique_id | ds | AutoNHITS | |
---|---|---|---|
0 | 1.0 | 1961-01-31 | 445.272858 |
1 | 1.0 | 1961-02-28 | 469.633423 |
2 | 1.0 | 1961-03-31 | 475.265289 |
3 | 1.0 | 1961-04-30 | 483.228516 |
4 | 1.0 | 1961-05-31 | 516.583496 |
5. 图表
最后,我们比较由 AutoNHITS
模型使用两个后端生成的预测结果。
参考文献
- Cristian Challu, Kin G. Olivares, Boris N. Oreshkin, Federico Garza, Max Mergenthaler-Canseco, Artur Dubrawski (2021). NHITS: Neural Hierarchical Interpolation for Time Series Forecasting. Accepted at AAAI 2023.
- James Bergstra, Remi Bardenet, Yoshua Bengio, and Balazs Kegl (2011). “Algorithms for Hyper-Parameter Optimization”. In: Advances in Neural Information Processing Systems. url: https://proceedings.neurips.cc/paper/2011/file/86e8f7ab32cfd12577bc2619bc635690-Paper.pdf
- Kirthevasan Kandasamy, Karun Raju Vysyaraju, Willie Neiswanger, Biswajit Paria, Christopher R. Collins, Jeff Schneider, Barnabas Poczos, Eric P. Xing (2019). “Tuning Hyperparameters without Grad Students: Scalable and Robust Bayesian Optimisation with Dragonfly”. Journal of Machine Learning Research. url: https://arxiv.org/abs/1903.06694
- Lisha Li, Kevin Jamieson, Giulia DeSalvo, Afshin Rostamizadeh, Ameet Talwalkar (2016). “Hyperband: A Novel Bandit-Based Approach to Hyperparameter Optimization”. Journal of Machine Learning Research. url: https://arxiv.org/abs/1603.06560