Optuna 在多次试验中建议相同的参数值(重复试验浪费时间和预算)

Lor*_*mum 7 python machine-learning python-3.x hyperparameters optuna

由于某种原因,Optuna TPESampler 和 RandomSampler 多次尝试对任何参数使用相同的建议整数值(也可能是浮点数和对数统一值)。我找不到办法阻止它再次建议相同的值。在 100 次试验中,有相当多的试验都是重复的。在 100 次试验中,独特的建议值计数最终约为 80-90。如果我包含更多参数进行调整,例如 3 个,我什至会看到所有 3 个参数在 100 次试验中多次获得相同的值。

就像这样。min_data_in_leaf 为 75,使用了 3 次:

[I 2020-11-14 14:44:05,320] 试验 8 完成,值:45910.54012028659 和参数:{'min_data_in_leaf': 75}。最好的是试验 4,其值:45805.19030897498。

[I 2020-11-14 14:44:07,876] 试验 9 完成,值:45910.54012028659 和参数:{'min_data_in_leaf': 75}。最好的是试验 4,其值:45805.19030897498。

[I 2020-11-14 14:44:10,447] 试验 10 完成,值:45831.75933279074 和参数:{'min_data_in_leaf': 43}。最好的是试验 4,其值:45805.19030897498。

[I 2020-11-14 14:44:13,502] 试验 11 完成,值:46125.39810101329 和参数:{'min_data_in_leaf': 4}。最好的是试验 4,其值:45805.19030897498。

[I 2020-11-14 14:44:16,547] 试验 12 完成,值:45910.54012028659 和参数:{'min_data_in_leaf': 75}。最好的是试验 4,其值:45805.19030897498。

示例代码如下:

def lgb_optuna(trial):

    rmse = []

    params = {
        "seed": 42,
        "objective": "regression",
        "metric": "rmse",
        "verbosity": -1,
        "boosting": "gbdt",
        "num_iterations":  1000,
        'min_data_in_leaf':  trial.suggest_int('min_data_in_leaf', 1, 100)
    }

    cv = StratifiedKFold(n_splits=5, random_state=42, shuffle=False)
    for train_index, test_index in cv.split(tfd_train, tfd_train[:,-1]):
        X_train, X_test = tfd_train[train_index], tfd_train[test_index]
        y_train = X_train[:,-2].copy()
        y_test = X_test[:,-2].copy()
        
        dtrain = lgb.Dataset(X_train[:,:-2], label=y_train)
        dtest = lgb.Dataset(X_test[:,:-2], label=y_test)
    
        booster_gbm = lgb.train(params, dtrain, valid_sets=dtest, verbose_eval=False)

        y_predictions = booster_gbm.predict(X_test[:,:-2])
        final_mse = mean_squared_error(y_test, y_predictions)
        final_rmse = np.sqrt(final_mse)
        rmse.append(final_rmse)

     return np.mean(rmse)

study = optuna.create_study(sampler=TPESampler(seed=42), direction='minimize') 
study.optimize(lgb_optuna, n_trials=100) 
Run Code Online (Sandbox Code Playgroud)

Nik*_*ido 7

问题是您在这一行中指定的采样器:

study = optuna.create_study(sampler=TPESampler(seed=42), direction='minimize')
Run Code Online (Sandbox Code Playgroud)

TPESampler不是统一采样器。这是一个不同的采样器,尝试从有希望的值范围中进行采样。请参阅此处此处的详细信息。这就是您看到大量重复项的原因。对于优化器来说,它们是有希望的值,然后可能以不同的组合进一步探索它们。

要进行真正的均匀采样,您应该将采样器更改为:

sampler=RandomSampler(seed)
Run Code Online (Sandbox Code Playgroud)

这不能保证不会有重复项,但值的分布会更加均匀

如果您想确保仅搜索不同的组合,则应使用GridSampler。正如文档所述:

试验建议研究期间给定搜索空间中的所有参数组合。

医生在这里

  • 我知道 GridSampler 可以工作,但它很耗时。这就是我首先想使用 TPESampler 的原因。必须有一种方法可以使用 tpe 或其他一些贝叶斯优化,而无需重复以前的试验。听起来很简单,但我不想弄乱 optuna 模块的基类。此外,我不认为 TPE 采样是这里的问题。我怀疑 TPESampler 正在使用随机采样来进行一些初创公司的试验。说40个什么的。然后切换到 TPE 采样。 (2认同)