|
- .. _hpo_cn:
-
- 超参数优化
- ============================
-
- 我们支持不同的搜索空间下的黑盒超参数优化。
-
- 搜索空间
- ------------
-
- 我们支持三种类型的搜索空间,请使用python字典``dict``来定义你的搜索空间。
- 对于数字列表形式的搜索空间,你可以为列表指定一个固定的长度,如果是这样,你不需要提供``cutPara``和``cutFunc``。
- 或者你可以把列表切成一个特定的长度,这个长度取决于参数``cutPara``和``cutFunc``。你应该在``cutPara``中提供参数名并在``cutFunc``中提供计算剪切长度的函数。
-
- .. code-block:: python
-
- # 数值搜索空间:
- {
- "parameterName": "xxx",
- "type": "DOUBLE" / "INTEGER",
- "minValue": xx,
- "maxValue": xx,
- "scalingType": "LINEAR" / "LOG"
- }
-
- # 数值列表搜索空间:
- {
- "parameterName": "xxx",
- "type": "NUMERICAL_LIST",
- "numericalType": "DOUBLE" / "INTEGER",
- "length": 3,
- "cutPara": ("para_a", "para_b"),
- "cutFunc": lambda x: x[0] - 1,
- "minValue": [xx,xx,xx],
- "maxValue": [xx,xx,xx],
- "scalingType": "LINEAR" / "LOG"
- }
-
- # 类别搜索空间:
- {
- "parameterName": xxx,
- "type": "CATEGORICAL"
- "feasiblePoints": [a,b,c]
- }
-
- # 固定参数作为搜索空间:
- {
- "parameterName": xxx,
- "type": "FIXED",
- "value": xxx
- }
-
- 下表列出了超参数优化算法所支持的搜索空间形式:
-
- +------------------+------------+--------------+-----------+------------+
- | 算法 | 数值 | 数值列表 | 类别 | 固定的 |
- +==================+============+==============+===========+============+
- | Grid | | | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | Random | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | Anneal | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | Bayes | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | TPE [1]_ | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | CMAES [2]_ | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | MOCMAES [3]_ | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- |Quasi random [4]_ | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
- | AutoNE [5]_ | ✓ | ✓ | ✓ | ✓ |
- +------------------+------------+--------------+-----------+------------+
-
- 添加你自己的超参数优化器(HPOptimizer)
- --------------------
-
- 如果你想添加你自己的 HPOptimizer, 你只需要完成 HPOptimizer 中的``optimize`` 函数:
-
- .. code-block:: python
-
- # 例如,创建一个随机超参数优化算法
- import random
- from autogl.module.hpo.base import BaseHPOptimizer
- class RandomOptimizer(BaseHPOptimizer):
- # 在初始化时获取基本参数
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.max_evals = kwargs.get("max_evals", 2)
-
- # 你应该做的最重要的事情是完成优化函数
- def optimize(self, trainer, dataset, time_limit=None, memory_limit=None):
- # 1. 从训练器得到搜索空间。
- space = trainer.hyper_parameter_space + trainer.model.hyper_parameter_space
- # 可选的:使用 self._encode_para (在 BaseOptimizer) 来对搜索空间进行预处理
- # 如果使用 _encode_para, NUMERICAL_LIST 将扩展为 双精度浮点数 或 整数,LOG尺度类型将改为线性,CATEGORICAL中的可行点将改为离散数。
- # 您还应该使用_decode_para将参数类型转换回来。
- current_space = self._encode_para(space)
-
- # 2. 定义你自己的性能函数。
- def fn(dset, para):
- current_trainer = trainer.duplicate_from_hyper_parameter(para)
- current_trainer.train(dset)
- loss, self.is_higher_better = current_trainer.get_valid_score(dset)
- # 为了方便起见,损失分数越高越好;如果是负数,那么我们就应该把损失分数降到最低。
- if self.is_higher_better:
- loss = -loss
- return current_trainer, loss
-
- # 3. 定义如何获得超参数建议,它应该返回一个参数字典。你可以使用历史实验来得到新的建议。
- def get_random(history_trials):
- hps = {}
- for para in current_space:
- # 因为我们之前使用了_encode_para函数,所以我们应该只处理DOUBLE、INTEGER和DISCRETE函数
- if para["type"] == "DOUBLE" or para["type"] == "INTEGER":
- hp = random.random() * (para["maxValue"] - para["minValue"]) + para["minValue"]
- if para["type"] == "INTEGER":
- hp = round(hp)
- hps[para["parameterName"]] = hp
- elif para["type"] == "DISCRETE":
- feasible_points = para["feasiblePoints"].split(",")
- hps[para["parameterName"]] = random.choice(feasible_points)
- return hps
-
- # 4. 运行算法。对于每个回合,根据历史信息获得一组参数并进行评估。
- best_trainer, best_para, best_perf = None, None, None
- self.trials = []
- for i in range(self.max_evals):
- # 在这个例子中,我们不需要历史追踪。因此我们为history_trails传入None
- new_hp = get_random(None)
- # 可选的:如果你使用参数 _encode_para,也要提供参数 _decode_para 。 para_for_trainer 撤销 _encode_para 中的所有转换,并在需要时将双精度浮点数转换为整数。para_for_hpo 只将双精度浮点数转换为整数。
- para_for_trainer, para_for_hpo = self._decode_para(new_hp)
- current_trainer, perf = fn(dataset, para_for_trainer)
- self.trials.append((para_for_hpo, perf))
- if not best_perf or perf < best_perf:
- best_perf = perf
- best_trainer = current_trainer
- best_para = para_for_trainer
-
- # 5. 返回最优训练器和参数。
- return best_trainer, best_para
-
-
- .. [1] Bergstra, James S., et al. "Algorithms for hyper-parameter optimization." Advances in neural information processing systems. 2011.
- .. [2] Arnold, Dirk V., and Nikolaus Hansen. "Active covariance matrix adaptation for the (1+ 1)-CMA-ES." Proceedings of the 12th annual conference on Genetic and evolutionary computation. 2010.
- .. [3] Voß, Thomas, Nikolaus Hansen, and Christian Igel. "Improved step size adaptation for the MO-CMA-ES." Proceedings of the 12th annual conference on Genetic and evolutionary computation. 2010.
- .. [4] Bratley, Paul, Bennett L. Fox, and Harald Niederreiter. "Programs to generate Niederreiter's low-discrepancy sequences." ACM Transactions on Mathematical Software (TOMS) 20.4 (1994): 494-495.
- .. [5] Tu, Ke, et al. "Autone: Hyperparameter optimization for massive network embedding." Proceedings of the 25th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining. 2019.
|