Оптимизация обрезки во время кросс-валидции, имеет ли это смысл?

Вопрос или проблема

В настоящее время я пытаюсь построить модель с использованием CatBoost. Для настройки параметров я использую optuna и кросс-валидацию, а также подрезаю испытания, проверяя промежуточные оценки кросс-валидации. Вот минимальный пример:

def objective(trial):
    param = {
        "iterations": trial.suggest_int("iterations", 50, 5000),
        "boosting_type": trial.suggest_categorical(
            "boosting_type", ["Ordered", "Plain"]
        ),
        "model_shrink_mode": trial.suggest_categorical(
            "model_shrink_mode", ["Constant", "Decreasing"]
        ),
    }
    scores = []
    skf = StratifiedKFold(n_splits=nfolds)
    for k_step, (train_index, test_index) in enumerate(skf.split(X, y)):
        X_Ktrain, y_Ktrain = X.iloc[train_index], y.iloc[train_index]
        X_Kval, y_Kval = X.iloc[test_index], y.iloc[test_index]
        clf = CatBoostClassifier(**param, cat_features=X_Ktrain.select_dtype(exclude="number").columns)
        clf.fit(x_Ktrain, y_Ktrain)
        score = clf.score(X_Kval, y_Kval)
        scores.append(score)
        trial.report(score, step)

        # Обработка подрезки на основе промежуточного значения.
        if trial.should_prune():
            raise optuna.TrialPruned()
    return sum(scores) / len(scores)

Мой вопрос возникает из-за того, что подрезка optuna предназначена для работы с алгоритмами, которые могут обучаться непрерывно, поэтому я не уверен, что такой способ использования имеет смысл.

Попытка реализовать механизм кросс-валидации с Optuna на самом деле немного болезненна, так как Optuna не поддерживает интеграцию кросс-валидации с подрезкой. Если попытаться использовать ваш минимальный пример, это приведет к предупреждению, подобному этому:

UserWarning: The reported value is ignored because this `step` 21 is already reported

Причина этого заключается в том, что при выполнении разбиения кросс-валидации с N эпохами шаг может быть встречен максимум $k$ раз. Например, номер шага $1$ может быть:

trial.report(score, step)

сообщен до $3$ раз. Это вызывает конфликты во внутреннем оптимизаторе Optuna, который видит один и тот же шаг дважды. Чтобы избежать этого, можно рассмотреть возможность подрезки только во время первого разбиения кросс-валидации, что-то подобное:

if split_idx == 0:
    trial.report(avg_val_loss, (split_idx * N_EPOCHS) + epoch + 1)
    if trial.should_prune():
        raise optuna.TrialPruned()

Позволять подрезчику работать на нескольких разбиениях также проблематично, так как после завершения первого разбиения и перед началом второго разбиения может происходить значительный скачок в проверочных потерях из-за нового разбиения, однако optuna может принять этот скачок за переобучение и неправильно остановить процесс обучения.

Более того, это решение проверять подрезку исключительно во время первого разбиения является довольно разумным, поскольку если определенная конфигурация гиперпараметров полностью портит обучение и проверку в первом разбиении, скорее всего, последующие разбиения также столкнутся с подобным поведением, так как разбиения, как правило, довольно тесно связаны друг с другом и представляют собой друг друга.

Некоторую дополнительную информацию об этом можно найти здесь и здесь.

Ответ или решение

Оптимизация гиперпараметров модели с использованием Optuna в контексте кросс-валидации и обрезки (pruning) представляет собой сложную задачу, требующую тщательного подхода. В данной статье мы разберем, имеет ли смысл применение обрезки при кросс-валидации, а также предложим некоторые рекомендации по эффективному использованию Optuna в данной ситуации.

Что такое оpтимизация гиперпараметров?

Оптимизация гиперпараметров – это процесс поиска наилучших параметров модели, которые обеспечивают максимальную производительность. В случае применения Optuna, мы можем использовать его функционал для быстрого нахождения оптимальных значений, что значительно ускоряет процесс настройки модели.

Зачем использовать обрезку в Optuna?

Обрезка – это механизм, благодаря которому Optuna может прерывать обучение неэффективных экспериментальных проб (trials), что позволяет сэкономить время и ресурсы. Однако важным аспектом является то, что обрезка лучше всего работает с алгоритмами, которые способны учиться непрерывно на протяжении обучения, например, в случае сетей.

Проблема применения обрезки в кросс-валидации

Основная проблема, с которой столкнулись авторы, заключается в том, что обрезка Optuna не совсем подходит для сценариев с кросс-валидацией. Optuna не обеспечивает специальной поддержки для кросс-валидации с обрезкой, что может приводить к предупреждениям, таким как:

UserWarning: The reported value is ignored because this `step` xx is already reported

Это происходит потому, что каждый этап (step) может быть вызван несколько раз для одного и того же пробного эксперимента. Например, когда вы разбиение на K фолдов, один и тот же шаг может быть зарегистрирован K раз, что создает конфликт в внутреннем оптимизаторе Optuna.

Решение через запись промежуточных результатов

Вместо многократного вызова trial.report(score, step) для каждого фолда, разумнее рассмотреть возможность записи результатов только для первого фолда. Это позволяет избежать конфликта и сохранить точность процесса. Например:

if split_idx == 0:
    trial.report(avg_val_loss, (split_idx * N_EPOCHS) + epoch + 1)
    if trial.should_prune():
        raise optuna.TrialPruned()

Такой подход позволяет эффективно использовать обрезку и направляет Optuna на правильный путь в принятии решений о прекращении проб.

Возможность ошибок в интерпретации

Также стоит отметить, что использование обрезки во всех фолдах может привести к ложным срабатываниям, когда резкие колебания значения метрики валидности могут быть восприняты как переобучение, хотя на самом деле это может быть просто следствием новой разбиения.

Заключение

Таким образом, объединение Optuna и кросс-валидации требует осторожности и понимания ограничений каждого инструмента. Использование обрезки во время кросс-валидации может иметь смысл, если правильно реализовать процесс анализа промежуточных значений. Оптимальный подход заключается в учете только первого этапа для отчетности по метрикам производительности, избегая множественных регистрации одних и тех же значений, что минимизирует риск ошибок при использовании обрезки.

Полезные ссылки

Следуя вышеизложенным рекомендациям, вы сможете улучшить свой процесс оптимизации гиперпараметров и повысить эффективность обучения ваших моделей.

Оцените материал
Добавить комментарий

Капча загружается...