1

我正在做我的第一个 ML-with-optuna 项目。我的问题是如何为多个 NN 初始化探测一组超参数,在一次试验中的每次运行仍然需要修剪?

我假设初始化有相当大的影响,我不想因为运气不好而剔除好的HP。

据我所知,每个试验代表一组 HP。因此,如果我想对它们进行多次初始化评估,我会在每次试验中执行多次训练。但在一次试验中,我只能为每个时间戳报告一个值。

我必须在没有 optuna 的情况下实现这个吗?我是否应该采用一种方法,让 optuna 首先建议一组 HP,然后为下一次试验修复它?或者你知道用 optuna 实现这一目标的一些好方法吗?

提前谢谢了!

编辑1;添加一个最小的代码示例:

from random import randrange
import optuna


def objective(trial):
    """
    return x * 20 + random_offset
    multiplication calculated iteratively to enable pruning
    """

    x = trial.suggest_float("x", 0, 10)

    random_offset = randrange(0, 1000)
    temp = 1
    res_temp = None
    for i in range(20):
        temp += x
        res_temp = temp + random_offset
        trial.report(res_temp, i)

        if trial.should_prune():
            raise optuna.TrialPruned()

    return res_temp


if __name__ == '__main__':
    study = optuna.create_study(pruner=optuna.pruners.MedianPruner())

    study.optimize(objective, n_trials=20)

    print("best params:", study.best_params)
    print("best value:", study.best_value)

此示例尝试在 0 到 10 的范围内找到“x”,从而最小化“x * 20”。显而易见的答案是 0。目标函数是基于迭代求和计算结果;它使用修剪。遗憾的是,由于随机偏移,目标函数是嘈杂的。这是作为训练 NN 的隐喻。迭代是训练循环,x 是超参数,偏移量是网络的随机初始化。

由噪声引起的问题是您无法确定超参数的质量,因为结果可能由随机偏移量支配。这可能会导致选择次优的 x。如果我是对的,那么增加试验次数以消除随机性可能不起作用,因为 optuna 可能会建议基于旧超参数的新超参数。所以不幸的观察会阻碍进一步的进展。

因此,我认为最好对同一组 hyperpramters 多次评估目标,并且只记住最好的“运行”。

所以我的问题是如何最好地消除噪音?我的假设是否正确,即仅增加试验次数不是最佳方法,您将如何实施重复评估?

4

1 回答 1

0

由于您的目标现在也取决于随机性,因此最好按照您的假设多次评估目标。

但更好的是尝试确定随机性来自哪里,是来自种子数吗?如果没有,那么你真的需要更多的试验和对完整时代的更多评估。

从optuna 示例中看起来像这样。在每个 epoch 或 step 中,模型都会针对相同的参数进行 n_train_iter 次评估。

import numpy as np
from sklearn.datasets import load_iris
from sklearn.linear_model import SGDClassifier
from sklearn.model_selection import train_test_split

import optuna

X, y = load_iris(return_X_y=True)
X_train, X_valid, y_train, y_valid = train_test_split(X, y)
classes = np.unique(y)


def objective(trial):
    alpha = trial.suggest_float("alpha", 0.0, 1.0)
    clf = SGDClassifier(alpha=alpha)
    n_train_iter = 100

    for step in range(n_train_iter):
        clf.partial_fit(X_train, y_train, classes=classes)

        intermediate_value = clf.score(X_valid, y_valid)
        trial.report(intermediate_value, step)

        if trial.should_prune():
            raise optuna.TrialPruned()

    return clf.score(X_valid, y_valid)


study = optuna.create_study(
    direction="maximize",
    pruner=optuna.pruners.MedianPruner(
        n_startup_trials=5, n_warmup_steps=30, interval_steps=10
    ),
)
study.optimize(objective, n_trials=20)

您可以拨打电话走得更远

X_train, X_valid, y_train, y_valid = train_test_split(X, y)

多次只是为了找到最佳的客观价值。

于 2022-02-01T04:14:39.417 回答