超参数优化

我们支持不同的搜索空间下的黑盒超参数优化。

搜索空间

我们支持三种类型的搜索空间,请使用python字典``dict``来定义你的搜索空间。 对于数字列表形式的搜索空间,你可以为列表指定一个固定的长度,如果是这样,你不需要提供``cutPara``和``cutFunc``。 或者你可以把列表切成一个特定的长度,这个长度取决于参数``cutPara``和``cutFunc``。你应该在``cutPara``中提供参数名并在``cutFunc``中提供计算剪切长度的函数。

# 数值搜索空间:
{
    "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
}

下表列出了超参数优化算法所支持的搜索空间形式:

添加你自己的超参数优化器(HPOptimizer)

如果你想添加你自己的 HPOptimizer, 你只需要完成 HPOptimizer 中的``optimize`` 函数:

# 例如,创建一个随机超参数优化算法
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.