搜索最佳架构和超参数¶
有时候(或经常)我们并不确切知道哪种架构最适合我们的数据。在人工智能领域,某种架构可能在一个数据集上表现最佳,而在另一个数据集上表现不佳。为了帮助找到最佳解决方案,本Notebook将使用PyTorch Tabular中的两个主要功能。其中一个是Sweep,它运行PyTorch Tabular中所有可用架构的默认超参数,以寻找可能最适合我们数据的架构。之后,我们将使用Tuner来搜索在Sweep中找到的最佳架构的最佳超参数。
数据¶
首先,我们创建一个合成数据集,该数据集混合了数值特征和分类特征,并具有多个分类目标。这意味着我们需要用相同的特征集来预测多个列。
常见配置¶
data_config = DataConfig(
target=[
"target"
],
continuous_cols=num_col_names,
categorical_cols=cat_col_names,
)
trainer_config = TrainerConfig(
batch_size=32,
max_epochs=50,
early_stopping="valid_accuracy",
early_stopping_mode="max",
early_stopping_patience=3,
checkpoints="valid_accuracy",
load_best=True,
progress_bar="none"
)
optimizer_config = OptimizerConfig()
模型搜索¶
https://pytorch-tabular.readthedocs.io/en/latest/apidocs_coreclasses/#pytorch_tabular.model_sweep
让我们训练所有可用的模型(“高内存”)。如果其中一些返回“OOM”,这意味着您当前的batch_size内存不足。您可以忽略该模型或在TrainerConfig中减少batch_size。
在下面的表格中,我们可以看到我们的数据集的最佳模型(使用默认超参数)。但我们对此并不满意,因此在这种情况下,我们将选择前两个模型,并使用调优器寻找更好的超参数,以获得更好的结果。
备注:每次运行笔记本时,结果可能会有所不同,因此您可能会看到我们在下一部分中使用的不同顶级模型。
模型调优器¶
https://pytorch-tabular.readthedocs.io/en/latest/apidocs_coreclasses/#pytorch_tabular.TabularModelTuner
太棒了!!现在我们知道了最佳模型,接下来选取前两个模型并调整它们的超参数,以期找到更好的结果。
我们可以使用两种主要策略: - 网格搜索(grid_search):搜索所有已定义的超参数,但请记住,您添加的每个新字段都会显著增加总训练时间。如果您配置了4个优化器、4层、2个激活函数和2个丢弃率,这意味着会进行64次(4 * 4 * 2 * 2)训练。 - 随机搜索(random_search):将随机获得每个已定义模型的“n_trials”超参数设置。这对于更快的训练很有用,但请记住,这不会测试所有超参数。
有关所有超参数选项的更多信息:https://pytorch-tabular.readthedocs.io/en/latest/apidocs_model/
有关超参数空间如何工作的更多信息:https://pytorch-tabular.readthedocs.io/en/latest/tutorials/10-Hyperparameter%20Tuning/#define-the-hyperparameter-space
让我们定义一些超参数。
PS:这个笔记本是为了示范这些函数,并不意味着这是值得尝试的最佳超参数。
search_space_category_embedding = {
"optimizer_config__optimizer": ["Adam", "SGD"],
"model_config__layers": ["128-64-32", "1024-512-256", "32-64-128", "256-512-1024"],
"model_config__activation": ["ReLU", "LeakyReLU"],
"model_config__embedding_dropout": [0.0, 0.2],
}
model_config_category_embedding = CategoryEmbeddingModelConfig(task="classification")
search_space_ft_transformer = {
"optimizer_config__optimizer": ["Adam", "SGD"],
"model_config__input_embed_dim": [32, 64],
"model_config__num_attn_blocks": [3, 6, 8],
"model_config__ff_hidden_multiplier": [4, 8],
"model_config__transformer_activation": ["GEGLU", "LeakyReLU"],
"model_config__embedding_dropout": [0.0, 0.2],
}
model_config_ft_transformer = FTTransformerConfig(task="classification")
让我们将所有搜索空间和模型配置添加到列表中。
重要 它们必须具有相同的顺序和相同的长度
tuner = TabularModelTuner(
data_config=data_config,
model_config=model_configs,
optimizer_config=optimizer_config,
trainer_config=trainer_config
)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
tuner_df = tuner.tune(
train=train,
validation=valid,
search_space=search_spaces,
strategy="grid_search", # 随机搜索
# n_trials=5,
metric="accuracy",
mode="max",
progress_bar=True,
verbose=False # 如果希望记录每个试验的指标和参数,请将True设为。
)
太棒了!!!我们现在知道了针对我们的数据集最佳的架构和可能的超参数。也许结果还不够好,但至少可以减少选项。有了这些结果,我们将更清楚哪些是可以更好地探索的最佳超参数,以及哪些超参数不值得继续使用。
探索架构论文也是一个好主意,这样如果有可能,可以进一步指导你找到最佳的超参数。
训练后,最佳模型将保存在输出变量中,名称为 "best_model"。因此,如果您对结果满意并希望在未来使用该模型,可以调用 "save_model" 进行保存。