Содержание
  1. Параметры модели и гиперпараметры
  2. Study, trial и objective на заполненном журнале
  3. Пространство suggest_int и suggest_float
  4. Train, validation, test
  5. Pruning и промежуточные метрики
  6. Известный квадратный objective
  7. Optuna, Ray Tune и MLflow
  8. Частые вопросы
Обзоры

Обзор Optuna: подбор гиперпараметров модели

13 ноября 2026 · 9 минут чтения

Обзор Optuna: подбор гиперпараметров модели начинается с разделения двух сущностей. Параметры модели настраиваются обучением на данных. Гиперпараметры задаёт человек до запуска обучения: глубина дерева, скорость обучения, число слоёв. Optuna перебирает комбинации гиперпараметров и сравнивает результаты trials.

Параметры модели и гиперпараметры

Параметры модели — это веса и смещения, которые алгоритм подбирает сам в процессе обучения на train-выборке. Гиперпараметры задаются до старта обучения и управляют тем, как именно будет идти этот процесс. В дереве решений это глубина и минимальное число объектов в листе, в градиентном бустинге — скорость обучения и число деревьев, в нейросети — размер батча и learning rate.

Разделение важно для постановки задачи оптимизации. Optuna выбирает значения гиперпараметров. Пользовательская objective-функция определяет, как обучить модель на train-выборке и вернуть метрику качества. Сохранение обученной модели нужно организовать отдельно.

Смешение уровней даёт две типичные ошибки. Первая: гиперпараметры смешивают с обучаемыми весами; число эпох относится к задаваемому бюджету обучения и тоже может быть гиперпараметром. Вторая: гиперпараметр фиксируется константой в коде, хотя именно его стоило перебирать. Различайте обучаемые величины, например веса, и настройки процесса обучения: последние могут задавать также расписание изменения learning rate.

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

Study, trial и objective на заполненном журнале

Документация Optuna описывает базовый порядок так: создаётся объект study, а функция objective передаётся методу optimize(). Функции, которые оптимизируются, по соглашению называют objective. Цель — найти значение x, минимизирующее выход objective. В ходе оптимизации Optuna многократно вызывает objective с разными значениями x.

Разберём заполненный учебный журнал для минимизации validation loss. Значения заданы искусственно для чтения структуры study; обучение по ним не проводилось:

Trial depth lr value (validation loss)
trial0 2 0.1 0.42
trial1 4 0.05 0.35
trial2 6 0.01 0.38

Лучший trial в этом журнале — trial1 со значением 0.35. Study — контейнер, который хранит все trials и их результаты. Trial — один запуск objective с конкретным набором гиперпараметров. Objective — функция, которую Optuna вызывает на каждом trial.

Контракт objective в этом примере: получить гиперпараметры, обучить модель на train, вернуть validation loss. Test-набор в objective не передаётся. Значение best нельзя интерпретировать без названия метрики и направления: 0.35 — это validation loss при минимизации, и меньшее число здесь лучше.

Чтение журнала даёт ответ на вопрос, какой trial выбирать. Optuna хранит историю и по ней строит следующие предложения. Samplers, по документации проекта, последовательно сужают пространство поиска, опираясь на записи предложенных значений и оценок objective.

Пространство suggest_int и suggest_float

Пространство поиска задаётся внутри objective через методы suggest_*. Для целочисленного гиперпараметра, например глубины дерева, применяется suggest_int. Для вещественного, например learning rate, — suggest_float. Категориальный параметр вроде типа активации задаётся через suggest_categorical.

Документация Optuna приводит пример с логарифмической шкалой: svc_c = trial.suggest_float(«svc_c», 1e-10, 1e10, log=True). Логарифмическая шкала уместна для величин, которые меняются на порядки: скорость обучения, коэффициент регуляризации. Линейная шкала подходит для величин с узким разумным диапазоном.

Направление оптимизации задаётся при создании study. По умолчанию Optuna минимизирует возвращаемое значение. Для метрики accuracy, которую нужно максимизировать, направление указывают явно. Значение best читается вместе с названием метрики и направлением: при maximize правило выбора меняется на противоположное.

Типичная ошибка — слишком широкий диапазон без логарифмической шкалы. Диапазон от 1e-10 до 1e10 при линейном семплировании почти все значения соберёт в верхней части, и малые learning rate останутся непроверенными. Логарифмическая шкала распределяет попытки равномерно по порядкам величины.

Вторая ошибка — пересекающиеся диапазоны у зависимых параметров. Если число слоёв и ширина слоя связаны, разумно строить условное пространство: сначала выбрать тип активации, затем под него задать диапазоны остальных величин. Документация Ray Tune показывает такой define-by-run подход, где ветка relu и ветка tanh получают разные границы width и height.

Train, validation, test

Данные делят на три части, и у каждой своя роль. Train-выборка идёт на обучение модели внутри trial. Validation-выборка возвращается objective как метрика, по которой Optuna сравнивает trials. Test-выборка остаётся нетронутой до финальной проверки выбранной конфигурации.

Документация MLflow в разделе про подбор гиперпараметров описывает деление на training и validation sets. Тот же принцип применим к objective в Optuna: обучение на train, оценка на validation, возврат validation-метрики.

Выбор лучшей модели по test-набору искажает оценку качества. Test участвует в отборе, и его метрика перестаёт быть независимой. Правильный порядок: Optuna отбирает конфигурацию по validation, после чего выбранная модель один раз оценивается на test. Test не передаётся в objective.

Практический приём — фиксировать разбиение данных до запуска study. Если каждый trial делит данные заново случайным образом, trials сравниваются на разных validation-выборках, и разница между ними частично объясняется разбиением. Один и тот же seed разбиения для всех trials делает сравнение честным.

Pruning и промежуточные метрики

Pruning — досрочное прекращение слабого trial. Документация Optuna формулирует условие так: чтобы включить pruning, нужно вызывать report() и should_prune() после каждого шага итеративного обучения. Без промежуточных метрик механизм не работает.

Лимит числа trials задаёт, сколько запусков сделать. Pruning решает, какие запуски доводить до конца. Это разные рычаги: n_trials ограничивает общий объём работы, pruning экономит время внутри уже запущенных trials. Trial, который на первых эпохах показывает метрику хуже остальных, останавливается и не тратит ресурсы.

Документация проекта отмечает, что модуль pruners рассчитан на одноцелевую оптимизацию. Для многоцелевых задач механизм применяют с оговорками. В примере Ray Tune сказано, что сложные планировщики вроде AsyncHyperBandScheduler могут работать с многоцелевой оптимизацией некорректно, поскольку ожидают скалярную оценку для сравнения trials.

Порядок включения pruning: внутри цикла обучения после каждой эпохи вызывается report() с промежуточным значением метрики, затем should_prune() возвращает решение о прекращении. Если should_prune() вернула истину, в objective вызывают raise optuna.TrialPruned(), чтобы остановить trial. Выберите промежуточную метрику, подходящую для сравнения хода trials, и согласуйте её направление с настройкой study.

Известный квадратный objective

Для проверки API удобна учебная функция f(x) = (x − 2)² на диапазоне [−5, 5]. У неё известный минимум 0 при x = 2. Задача прозрачна: видно, приближается ли поиск к точке 2.

Ограничение числа trials не гарантирует попадание в точку 2. Результат случайного семплирования заранее не выдумывается. Учебный пример показывает устройство API. Качество алгоритма поиска требует отдельной проверки на вашей задаче.

PYTHON13 строк
import optuna


def objective(trial):
    x = trial.suggest_float("x", -5.0, 5.0)
    return (x - 2.0) ** 2


study = optuna.create_study(direction="minimize")
study.optimize(objective, n_trials=20)

print(study.best_params)
print(study.best_value)

Что здесь происходит по шагам. create_study создаёт контейнер с направлением минимизации. optimize вызывает objective заданное число раз. Внутри objective suggest_float предлагает значение x из диапазона, а возвращаемое число — оценка этого значения. После запуска best_params хранит лучший набор, best_value — лучшее значение.

Что менять под себя: диапазон в suggest_float, тело objective и направление в create_study. Для реальной модели тело objective обучает модель на train и возвращает validation-метрику.

Optuna, Ray Tune и MLflow

Три инструмента закрывают разные обязанности. Optuna отвечает за поиск гиперпараметров: предлагает комбинации и ведёт историю trials. Ray Tune отвечает за оркестрацию: распределяет запуски по ресурсам, ограничивает параллелизм, управляет планировщиками. MLflow отвечает за tracking: записывает параметры, метрики и артефакты экспериментов.

Инструмент Обязанность Что даёт читателю
Optuna Поиск гиперпараметров Sampler предлагает комбинации, study хранит trials
Ray Tune Оркестрация запусков Распределение по ресурсам, лимит параллельных trials
MLflow Tracking экспериментов Родительский run и дочерние runs с параметрами и метриками

Документация Ray Tune описывает интеграцию через OptunaSearch: поисковый алгоритм Optuna подключается к Tune, а ConcurrencyLimiter ограничивает число одновременных trials. В примере документации лимит выставлен в 4. Там же показан define-by-run для условных пространств и многоцелевой режим с метриками loss и gain.

Документация MLflow описывает структуру из родительского run и дочерних runs: дочерний run создаётся с флагом nested=True. Родительский run соответствует study, дочерние — отдельным trials. Параметры, метрики и модели логируются по каждому trial.

Практическая связка: Optuna ведёт поиск, Ray Tune раздаёт trials по ресурсам, MLflow сохраняет историю. Каждый инструмент можно применять отдельно. Optuna работает без Ray Tune и без MLflow, а tracking подключается тогда, когда нужно сравнивать эксперименты между запусками.

Частые вопросы

Чем гиперпараметры отличаются от параметров модели?

Параметры модель подбирает сама в ходе обучения на train-выборке: веса, смещения, коэффициенты. Гиперпараметры задаются до запуска обучения и управляют его ходом: глубина дерева, скорость обучения, размер батча. Optuna ищет значения гиперпараметров, а веса пересчитываются внутри каждого trial.

Что такое study, trial и objective?

Study — контейнер, который хранит все trials и их результаты. Trial — один запуск objective с конкретным набором гиперпараметров. Objective — функция, которую Optuna вызывает многократно с разными значениями. В учебном журнале из трёх trials лучшим оказался trial1 со значением 0.35.

Как задать пространство поиска и направление оптимизации?

Пространство задаётся внутри objective методами suggest_int, suggest_float и suggest_categorical. Для величин, меняющихся на порядки, применяют логарифмическую шкалу. Направление указывают при создании study: по умолчанию идёт минимизация, для accuracy его меняют на максимизацию.

Почему нельзя выбирать лучшую модель по test-набору?

Test-набор нужен для независимой финальной оценки выбранной конфигурации. Если по нему отбирать лучший trial, он участвует в выборе, и его метрика перестаёт быть независимой. Отбор идёт по validation, а test применяется один раз в конце.

Как pruning экономит время и чем он отличается от лимита trials?

Лимит trials задаёт общее число запусков. Pruning позволяет остановить отдельный trial по промежуточным метрикам. В цикле обучения вызывают report() и should_prune(); при решении об остановке objective вызывает raise optuna.TrialPruned(). Модуль pruners рассчитан на одноцелевую оптимизацию.

Читайте также

3 материала