🔴 Сложный ⏱️ 60 минут

Байесовская оптимизация

📋 Содержание урока

Байесовская оптимизация 🎯

Представь, что ты подбираешь гиперпараметры для крупной нейросети — скорость обучения, размер батча, количество слоёв, коэффициент регуляризации. Каждый отдельный запуск — это не доля секунды, как вычисление квадратичной функции, а полноценное обучение модели: несколько часов работы GPU, а для по-настоящему больших моделей — иногда сутки. Сеточный поиск (grid search) или случайный поиск (random search) в такой ситуации ведут себя расточительно: они выбирают следующую точку для проверки, полностью игнорируя всё, что уже узнано из предыдущих запусков. Ты потратил три часа GPU-времени, обучил модель с конкретным набором гиперпараметров, получил результат — и в следующий момент случайный или сеточный поиск с тем же успехом мог бы выбрать точку по соседству с уже проверенной заведомо плохой конфигурацией, просто потому что не умеет учиться на опыте.

Байесовская оптимизация решает именно эту проблему: она превращает каждый дорогой вызов «чёрного ящика» в информацию, которая явно используется для выбора следующей, максимально информативной точки проверки. Вместо того чтобы перебирать пространство гиперпараметров вслепую, алгоритм строит вероятностную модель того, как ведёт себя целевая функция, и на каждом шаге спрашивает: какая из ещё не проверенных точек с наибольшей вероятностью даст улучшение, учитывая всё, что мы уже знаем? Именно поэтому байесовская оптимизация лежит в основе таких популярных инструментов автоматического подбора гиперпараметров, как Optuna и Hyperopt, а также встроена в облачные ML-платформы — Google Vertex AI Vizier, AWS SageMaker Automatic Model Tuning, Azure ML Hyperdrive. Когда цена одного эксперимента измеряется часами GPU-времени и реальными деньгами, разница между «найти хорошие гиперпараметры за 50 запусков» и «найти их за 500 запусков» — это разница на порядок в бюджете и во времени до выхода модели в продакшен.

Ты уже прошёл целую линейку методов оптимизации «чёрного ящика» — генетические алгоритмы (урок 296), которые работают с популяцией решений через отбор и скрещивание, рой частиц PSO (урок 297), который движется коллективно, ведомый личной и общей памятью, и имитацию отжига (урок 298), которая управляет готовностью принимать временные ухудшения через температуру. У всех этих методов есть общая черта: они исследуют пространство решений эвристически, без явной модели того, где именно стоит ожидать хорошего результата. Байесовская оптимизация в этом смысле — качественно другой инструмент: она explicit-но моделирует неопределённость своих предсказаний и явно решает, где именно потратить следующий дорогой вызов с максимальной пользой, а не просто «пробует» очередную точку по заданной эвристике.

В этом уроке ты разберёшь, как формально устроена задача оптимизации дорогого чёрного ящика, что такое суррогатная модель и почему для неё почти всегда выбирают гауссовский процесс — модель, которая предсказывает не только ожидаемое значение функции, но и неопределённость этого предсказания в каждой точке. Ты увидишь, как из этой неопределённости строится функция приобретения (acquisition function) — и подробно разберёшь Expected Improvement, самый популярный её вариант. А затем соберёшь всё это в полный цикл байесовской оптимизации и честно сравнишь её с методами, которые ты уже знаешь, — по числу вызовов «чёрного ящика», которое требуется каждому из них, чтобы найти хорошее решение.

История

Корни байесовской оптимизации уходят в 1964 год, когда американский инженер Харольд Кушнер (Harold J. Kushner) опубликовал статью «A New Method of Locating the Maximum Point of an Arbitrary Multipeak Curve in the Presence of Noise» — «Новый метод поиска максимума произвольной многопиковой кривой в присутствии шума». Кушнер предложил моделировать неизвестную одномерную функцию как случайный процесс и на каждом шаге выбирать точку для следующего измерения так, чтобы максимизировать вероятность найти значение выше текущего лучшего — по сути, это уже была идея функции приобретения, просто сформулированная для конкретной инженерной задачи и без общего названия для всего подхода.

Формальную основу байесовской оптимизации как самостоятельного направления заложил литовский математик Йонас Мокус (Jonas Mockus) в 1970-е годы. Вместе с соавторами он ввёл понятие ожидаемого улучшения (Expected Improvement) и предложил общую байесовскую схему поиска экстремума: строить апостериорное распределение над возможными функциями, согласующимися с уже собранными наблюдениями, и выбирать следующую точку, максимизируя критерий, учитывающий это распределение. Именно Мокус закрепил за подходом название «байесовский», потому что в основе лежит байесовское обновление — апостериорное знание о функции пересчитывается каждый раз, когда приходит новое наблюдение, ровно так же, как в байесовской статистике обновляется распределение вероятностей параметра модели при поступлении новых данных.

Следующий важный шаг случился в инженерии, а не в статистике: в 1998 году Дональд Джонс (Donald R. Jones), Маттиас Шонлау (Matthias Schonlau) и Уильям Уэлч (William J. Welch) опубликовали статью «Efficient Global Optimization of Expensive Black-Box Functions», представив алгоритм EGO (Efficient Global Optimization) — практичную реализацию байесовской оптимизации на основе гауссовских процессов и Expected Improvement, ориентированную на инженерные задачи вроде проектирования крыла самолёта или формы автомобильного кузова, где один вызов «чёрного ящика» означал часы или сутки компьютерного моделирования методом конечных элементов. Десятилетие спустя байесовская оптимизация пришла и в машинное обучение: в 2012 году Джаспер Снук (Jasper Snoek), Хьюго Ларошель (Hugo Larochelle) и Райан Адамс (Ryan P. Adams) опубликовали статью «Practical Bayesian Optimization of Machine Learning Algorithms», показав, что тот же подход систематически превосходит ручной подбор, сеточный и случайный поиск при настройке гиперпараметров нейросетей — их система Spearmint стала одной из первых широко используемых библиотек байесовской оптимизации для ML-задач. Следом появились Hyperopt (Джеймс Бергстра с соавторами, 2011–2013) и, в 2019 году, Optuna от японской компании Preferred Networks — инструмент с удобным define-by-run API, который сегодня стал одним из стандартов индустрии для автоматического подбора гиперпараметров.

Постановка задачи: оптимизация дорогого чёрного ящика

Интуиция

Представь, что ты настраиваешь печь для обжига керамики, у которой десятки регулировок — температура на разных этапах, скорость нагрева, время выдержки. Единственный способ узнать, получится ли хорошее изделие при конкретной комбинации настроек, — это провести полный цикл обжига, который занимает целый день. Ты физически не можешь перебрать тысячи комбинаций: каждая проверка стоит дня работы печи, электричества и материала. В такой ситуации любая стратегия перебора, которая не учится на предыдущих попытках, — расточительна по своей природе. Именно это и есть задача оптимизации дорогого «чёрного ящика»: у тебя есть функция, значение которой в точке можно узнать только ценой дорогого эксперимента, о её внутреннем устройстве ничего не известно заранее, и градиент недоступен в принципе — функция не дифференцируема (или её производная не поддаётся аналитическому или даже численному вычислению за разумное время).

Формальное определение

Задача оптимизации дорогого чёрного ящика. Дана функция $f: X \to \mathbb{R}$, определённая на некотором множестве $X$ (пространстве гиперпараметров, конфигураций, конструктивных решений). Про $f$ известно только то, что:

  • вычисление $f(x)$ в конкретной точке $x$ требует значительных затрат времени и/или ресурсов (эксперимент, симуляция, полное обучение модели);
  • $f$ не имеет доступного аналитического выражения и не даёт информации о своём градиенте;
  • каждое отдельное значение $f(x)$, возможно, зашумлено (повторный эксперимент в той же точке $x$ может дать слегка иной результат).

Требуется найти $x^* = \arg\min_{x \in X} f(x)$ (или $\arg\max$, в зависимости от постановки), затратив как можно меньше вызовов функции $f$.

Ключевое отличие этой постановки от всех предыдущих методов курса — в самом критерии успеха. У градиентных методов, генетических алгоритмов, PSO и имитации отжига качество измеряется тем, насколько близко к оптимуму сходится алгоритм за заданное число итераций, а сами итерации по умолчанию считаются условно дешёвыми. В задаче оптимизации дорогого чёрного ящика именно число вызовов $f$ — главный дефицитный ресурс, и алгоритм оценивается в первую очередь по тому, насколько мало вызовов ему требуется для достижения приемлемого качества.

Примеры

Пример 1: стоимость подбора гиперпараметров нейросети в деньгах и времени. Пусть одно полное обучение модели занимает 4 часа на облачном GPU-инстансе стоимостью $2 в час — одна проверка обходится в $8 и 4 часа календарного времени. Если пространство гиперпараметров — 5 параметров, и для сеточного поиска взять всего по 5 значений на каждый (довольно грубая сетка), получится $5^5 = 3125$ комбинаций: $3125 \cdot 8 = \$25,000$ и $3125 \cdot 4 = 12,500$ часов — больше полутора лет непрерывной работы одного GPU-инстанса. Байесовская оптимизация, которая типично находит сопоставимое по качеству решение за 50–100 вызовов, обойдётся в $400$–$800$ и 200–400 часов (8–17 дней) — разница на два порядка и по деньгам, и по времени.

Пример 2: инженерное проектирование как чёрный ящик. Проектирование формы крыла самолёта или кузова автомобиля с точки зрения аэродинамического сопротивления — классическая область применения EGO и байесовской оптимизации задолго до её прихода в машинное обучение. Один вызов «чёрного ящика» здесь — это запуск CFD-симуляции (вычислительной гидродинамики), моделирующей обтекание конкретной геометрии воздушным потоком, и может занимать от нескольких часов до нескольких суток на кластере. Градиент аэродинамического сопротивления по параметрам геометрии крыла не выражается аналитически — сопротивление считается численно через решение системы дифференциальных уравнений, и получить производную напрямую нельзя.

Пример 3: дорогой чёрный ящик с долгим циклом обратной связи. Представь A/B-тестирование гиперпараметров рекомендательной системы напрямую на живых пользователях — например, подбор коэффициента, регулирующего баланс между разнообразием и точностью рекомендаций. Один «вызов» здесь — это не часы вычислений, а недели работы эксперимента на реальном трафике, прежде чем накопится статистически значимый результат по метрике удержания пользователей. Здесь цена вызова измеряется не только вычислительными ресурсами, но и упущенной выгодой: пока идёт эксперимент с заведомо неоптимальными настройками, часть пользователей получает худший продукт.

Почему это важно

Понимание того, что именно число вызовов, а не число итераций внутреннего цикла алгоритма, является главным ограниченным ресурсом, — это отправная точка для выбора правильного инструмента. Если вызов целевой функции стоит микросекунды, разница между 50 и 5000 вызовами не имеет значения, и вполне можно использовать random search или эволюционные методы с их относительно щедрым аппетитом к числу оценок. Но как только каждый вызов начинает стоить часы GPU-времени или реальные деньги, экономия каждого отдельного вызова становится приоритетом номер один — и именно ради этого приоритета байесовская оптимизация жертвует простотой и вычислительной дешевизной самого алгоритма (о чём пойдёт речь дальше) ради минимизации числа обращений к дорогому чёрному ящику.

Суррогатная модель: гауссовский процесс

Интуиция

Представь картографа, исследующего неизвестную горную гряду. У него нет спутниковых снимков — единственный способ узнать высоту рельефа в точке — отправить туда экспедицию, а это долго и дорого. После нескольких экспедиций у картографа накопилась горстка точек с точно известной высотой. Дальше он вынужден достраивать карту рельефа между этими точками — и делает это не наугад: вблизи уже исследованных точек он уверен в своих оценках высоты (рельеф вряд ли резко меняется на коротких расстояниях), а в областях, далёких от любой экспедиции, его оценки — чистая догадка с большой неопределённостью. Суррогатная модель в байесовской оптимизации решает ровно ту же задачу: она строит дешёвое приближение дорогой функции $f$ по уже собранным точкам-наблюдениям, и, что критически важно, явно указывает, насколько она уверена в своём прогнозе в каждой конкретной точке пространства.

Именно эта вторая часть — явная оценка неопределённости, а не только точечный прогноз, — и есть то, что отличает суррогатную модель байесовской оптимизации от обычной регрессии. Обычная регрессия (например, полином, подогнанный по точкам) даёт одно число-предсказание в любой точке и молчит о том, насколько этому числу можно доверять. Гауссовский процесс (Gaussian Process, GP) — стандартный выбор суррогатной модели именно потому, что естественным образом даёт оба этих компонента сразу: и ожидаемое значение функции в точке, и дисперсию — меру неопределённости этого ожидания.

Формальное определение

Гауссовский процесс как суррогатная модель. Гауссовский процесс — это распределение вероятностей над функциями, полностью задаваемое функцией среднего $m(x)$ (обычно принимается равной нулю) и функцией ковариации (ядром) $k(x, x')$, которая определяет, насколько сильно коррелируют значения функции в точках $x$ и $x'$. Стандартный выбор ядра — гауссовское (RBF, radial basis function):

$$k(x, x') = \exp\left(-\frac{(x - x')^2}{2 l^2}\right)$$

где $l$ — длина корреляции (length scale): чем она больше, тем более гладкой (медленно меняющейся) считается функция, и тем на большем расстоянии сохраняется значимая корреляция между точками.

Пусть накоплены наблюдения $X = (x_1, \dots, x_n)$ со значениями $y = (y_1, \dots, y_n)$ (возможно, зашумлёнными с дисперсией шума $\sigma_n^2$). Тогда апостериорное предсказание гауссовского процесса в новой точке $x_*$ задаётся формулами

$$\mu(x_*) = k_*^\top (K + \sigma_n^2 I)^{-1} y, \qquad \sigma^2(x_*) = k(x_*, x_*) - k_*^\top (K + \sigma_n^2 I)^{-1} k_*$$

где $K$ — матрица ковариаций между всеми парами уже наблюдённых точек ($K_{ij} = k(x_i, x_j)$), а $k_*$ — вектор ковариаций между новой точкой $x_*$ и каждой из уже наблюдённых точек.

Эти формулы выглядят громоздко, но их смысл прозрачен: предсказание $\mu(x_*)$ — это взвешенная комбинация уже известных значений $y$, где вес каждого наблюдения определяется тем, насколько оно коррелирует (по ядру $k$) с новой точкой $x_*$. А неопределённость $\sigma^2(x_*)$ начинается с максимума $k(x_*, x_*)$ (обычно равного 1 для нормированного ядра) и уменьшается ровно на ту величину, которую «объясняют» уже сделанные наблюдения, — чем ближе $x_*$ к уже исследованным точкам, тем сильнее падает неопределённость.

Примеры

Пример 1: числовой расчёт апостериорного среднего и дисперсии по двум наблюдениям. Пусть подбирается логарифм скорости обучения, нормированный на отрезок $[0, 1]$, и уже собраны два наблюдения: $x_1 = 0{,}1$ с валидационным лоссом $y_1 = 0{,}75$ и $x_2 = 0{,}8$ с лоссом $y_2 = 0{,}68$. Используем RBF-ядро с $l = 0{,}2$ и почти нулевым шумом. Считаем ковариацию между двумя наблюдениями: расстояние $|x_1 - x_2| = 0{,}7$, значит $k(x_1, x_2) = \exp(-0{,}7^2 / (2 \cdot 0{,}2^2)) = \exp(-6{,}125) \approx 0{,}00219$ — точки далеко друг от друга, и корреляция между ними ничтожна, матрицу $K$ можно с хорошей точностью считать диагональной.

Хотим предсказать в точке $x_* = 0{,}3$: $k(x_*, x_1) = \exp(-0{,}2^2/0{,}08) = \exp(-0{,}5) \approx 0{,}6065$, $k(x_*, x_2) = \exp(-0{,}5^2/0{,}08) = \exp(-3{,}125) \approx 0{,}0439$. Учитывая почти диагональную $K$ (обратная матрица близка к единичной):

$$\mu(0{,}3) \approx 0{,}6065 \cdot 0{,}75 + 0{,}0439 \cdot 0{,}68 \approx 0{,}485$$

$$\sigma^2(0{,}3) \approx 1 - (0{,}6065^2 + 0{,}0439^2) \approx 1 - 0{,}370 = 0{,}630, \quad \sigma(0{,}3) \approx 0{,}794$$

Точка $x_* = 0{,}3$ расположена ближе к $x_1$, чем к $x_2$, поэтому прогноз $0{,}485$ смещён ближе к $y_1 = 0{,}75$, чем к $y_2 = 0{,}68$ — но при этом оба веса $k(x_*, x_1)$ и $k(x_*, x_2)$ заметно меньше единицы, значит и итоговая неопределённость всё ещё велика: $\sigma(0{,}3) \approx 0{,}79$, почти столько же, сколько неопределённость в области, где вообще не было наблюдений.

Пример 2: неопределённость почти исчезает вблизи наблюдённой точки. Теперь предскажем в точке $x_* = 0{,}75$, которая находится всего в $0{,}05$ от наблюдения $x_2 = 0{,}8$: $k(0{,}75, x_2) = \exp(-0{,}05^2/0{,}08) = \exp(-0{,}03125) \approx 0{,}969$, а до далёкой $x_1$: $k(0{,}75, x_1) = \exp(-0{,}65^2/0{,}08) \approx 0{,}0051$. Тогда:

$$\mu(0{,}75) \approx 0{,}0051 \cdot 0{,}75 + 0{,}969 \cdot 0{,}68 \approx 0{,}663, \qquad \sigma^2(0{,}75) \approx 1 - (0{,}0051^2 + 0{,}969^2) \approx 0{,}061, \quad \sigma(0{,}75) \approx 0{,}246$$

Неопределённость здесь почти в три раза меньше, чем в точке $0{,}3$ ($0{,}246$ против $0{,}794$) — потому что $0{,}75$ находится совсем рядом с реально наблюдённой точкой $0{,}8$, и гауссовский процесс уверенно экстраполирует значение оттуда. Это в точности та интуиция про картографа: рядом с экспедицией — уверенность, далеко от неё — почти полное незнание.

Пример 3: длина корреляции определяет, насколько «нервной» считается функция. Возьмём две точки на расстоянии $0{,}3$ друг от друга и сравним ковариацию при коротком и длинном масштабе корреляции. При $l = 0{,}1$ (модель считает функцию быстро меняющейся): $k = \exp(-0{,}3^2/(2\cdot0{,}01)) = \exp(-4{,}5) \approx 0{,}011$ — корреляция почти нулевая уже на этом небольшом расстоянии, суррогатная модель почти не доверяет экстраполяции даже на короткую дистанцию. При $l = 1{,}0$ (модель считает функцию гладкой): $k = \exp(-0{,}3^2/2) = \exp(-0{,}045) \approx 0{,}956$ — корреляция почти максимальна, модель уверенно распространяет знание об одной точке на довольно широкую окрестность. Выбор $l$ — это, по сути, гипотеза о том, насколько «шероховато» ведёт себя целевая функция, и на практике библиотеки байесовской оптимизации подбирают $l$ автоматически, максимизируя правдоподобие уже собранных наблюдений при каждом обновлении модели.

Почему это важно

Именно наличие явной оценки неопределённости $\sigma(x)$, а не только точечного прогноза $\mu(x)$, отличает суррогатную модель байесовской оптимизации от обычной регрессии и делает возможным следующий шаг алгоритма — осмысленный выбор, куда именно направить следующий дорогой вызов. Без оценки неопределённости у алгоритма был бы только один разумный ход: пойти туда, где суррогатная модель предсказывает наилучшее значение. Это чистая эксплуатация (exploitation), и она рискует навсегда застрять в первой же правдоподобно хорошей области, даже не заметив, что где-то ещё, в совершенно неисследованной части пространства, скрывается решение намного лучше. Явная неопределённость даёт алгоритму второй сигнал — «здесь я почти ничего не знаю, возможно, стоит проверить» — и именно комбинация этих двух сигналов лежит в основе следующего компонента метода, функции приобретения.

Функция приобретения и Expected Improvement

Интуиция

Вернись к картографу из предыдущего раздела. У него есть карта с оценкой высоты в каждой точке и оценкой того, насколько он этой оценке доверяет. Куда отправить следующую дорогую экспедицию? Наивный ответ — туда, где предполагаемая высота максимальна (для задачи поиска пика). Но это игнорирует то, что где-то далеко, в почти неисследованной области с огромной неопределённостью, вполне может скрываться более высокая вершина, о которой карта просто ничего не говорит. Разумная стратегия — учитывать оба фактора одновременно: и то, насколько хороша точка по прогнозу, и то, насколько велик шанс, что реальность там окажется значительно лучше прогноза именно из-за неопределённости. Функция приобретения (acquisition function) — это правило, которое превращает пару чисел $(\mu(x), \sigma(x))$ в единственную оценку «насколько многообещающа точка $x$ для следующей дорогой проверки», взвешивая exploitation (доверие хорошему прогнозу) и exploration (готовность рискнуть ради высокой неопределённости).

Формальное определение

Expected Improvement (ожидаемое улучшение). Пусть решается задача минимизации, и $f_{\text{best}}$ — наилучшее (наименьшее) значение целевой функции среди уже сделанных наблюдений. Улучшение в точке $x$ определяется как $I(x) = \max(f_{\text{best}} - f(x),\ 0)$ — положительная величина, если новая точка окажется лучше текущего лучшего результата, и ноль иначе. Так как истинное $f(x)$ неизвестно, но известно апостериорное распределение гауссовского процесса $f(x) \sim \mathcal{N}(\mu(x), \sigma^2(x))$, можно вычислить математическое ожидание улучшения в явном виде:

$$\mathrm{EI}(x) = \begin{cases} \bigl(f_{\text{best}} - \mu(x) - \xi\bigr)\, \Phi(Z) \;+\; \sigma(x)\, \varphi(Z), & \sigma(x) > 0 \\[4pt] 0, & \sigma(x) = 0 \end{cases}, \qquad Z = \frac{f_{\text{best}} - \mu(x) - \xi}{\sigma(x)}$$

где $\Phi$ и $\varphi$ — функция распределения и плотность стандартного нормального распределения, а $\xi \ge 0$ — небольшой параметр (часто $\xi \approx 0{,}01$), явно повышающий требовательность к «значимости» улучшения и тем самым слегка подталкивающий поиск в сторону exploration.

Формула на первый взгляд пугает, но у неё прозрачная анатомия: первое слагаемое $(f_{\text{best}} - \mu(x) - \xi)\Phi(Z)$ растёт, когда прогноз $\mu(x)$ заметно лучше текущего рекорда, — это вклад exploitation. Второе слагаемое $\sigma(x)\varphi(Z)$ растёт вместе с неопределённостью $\sigma(x)$ независимо от того, каков сам прогноз, — это вклад exploration. Следующая точка для дорогого вызова выбирается как $x_{\text{next}} = \arg\max_x \mathrm{EI}(x)$ — точка, где эта дешёвая (в отличие от самой $f$) формула достигает максимума.

Примеры

Пример 1: сравнение exploration-точки и exploitation-точки на одних и тех же данных. Продолжим численный пример из предыдущего раздела: $f_{\text{best}} = 0{,}68$ (лучшее из двух наблюдений), $\xi = 0{,}01$. Для точки $x = 0{,}3$ были посчитаны $\mu \approx 0{,}485$, $\sigma \approx 0{,}794$. Тогда $Z = (0{,}68 - 0{,}485 - 0{,}01)/0{,}794 \approx 0{,}233$, и, используя табличные значения $\Phi(0{,}233) \approx 0{,}592$, $\varphi(0{,}233) \approx 0{,}388$:

$$\mathrm{EI}(0{,}3) \approx 0{,}185 \cdot 0{,}592 + 0{,}794 \cdot 0{,}388 \approx 0{,}110 + 0{,}308 = 0{,}418$$

Для точки $x = 0{,}75$ были посчитаны $\mu \approx 0{,}663$, $\sigma \approx 0{,}246$. Тогда $Z = (0{,}68 - 0{,}663 - 0{,}01)/0{,}246 \approx 0{,}029$, $\Phi(0{,}029) \approx 0{,}512$, $\varphi(0{,}029) \approx 0{,}399$:

$$\mathrm{EI}(0{,}75) \approx 0{,}007 \cdot 0{,}512 + 0{,}246 \cdot 0{,}399 \approx 0{,}004 + 0{,}098 = 0{,}102$$

Значение $\mathrm{EI}(0{,}3) \approx 0{,}418$ более чем в четыре раза превышает $\mathrm{EI}(0{,}75) \approx 0{,}102$ — несмотря на то, что прогноз в точке $0{,}75$ намного ближе к текущему рекорду ($0{,}663$ против $0{,}68$), чем прогноз в точке $0{,}3$ ($0{,}485$ против $0{,}68$, и это даже лучше по среднему!). Именно огромная неопределённость в точке $0{,}3$ ($\sigma \approx 0{,}79$ против $\sigma \approx 0{,}25$) делает её намного более привлекательной кандидатурой для следующего дорогого вызова — там просто больше шансов на неожиданно хороший результат.

Пример 2: граничный случай — точка совпадает с уже наблюдённой. Пусть $x = x_2 = 0{,}8$ — точка, в которой значение уже точно известно ($y_2 = 0{,}68$). При почти нулевом шуме гауссовский процесс в точности интерполирует в наблюдённых точках: $\mu(0{,}8) = 0{,}68$, $\sigma(0{,}8) \approx 0$. По определению формулы, при $\sigma(x) = 0$ полагается $\mathrm{EI}(x) = 0$ — и это логично: незачем платить за дорогой вызов там, где ответ уже точно известен, никакого улучшения относительно самого себя быть не может.

Пример 3: параметр $\xi$ как явный рычаг «требовательности». Возьмём точку с $\mu(x) = 0{,}67$, $\sigma(x) = 0{,}05$ (хороший прогноз, малая неопределённость) при $f_{\text{best}} = 0{,}68$. При $\xi = 0$: $Z = (0{,}68-0{,}67)/0{,}05 = 0{,}2$, $\Phi(0{,}2)\approx0{,}579$, $\varphi(0{,}2)\approx0{,}391$, $\mathrm{EI} \approx 0{,}01\cdot0{,}579+0{,}05\cdot0{,}391\approx0{,}0058+0{,}0196=0{,}0254$. При увеличенном $\xi=0{,}03$: $Z=(0{,}68-0{,}67-0{,}03)/0{,}05=-0{,}4$, $\Phi(-0{,}4)\approx0{,}345$, $\varphi(-0{,}4)\approx0{,}368$, $\mathrm{EI}\approx(-0{,}02)\cdot0{,}345+0{,}05\cdot0{,}368\approx-0{,}0069+0{,}0184=0{,}0115$ — значение почти вдвое упало. Больший $\xi$ требует более убедительного, «с запасом» улучшения, прежде чем присвоить точке высокую оценку, — а значит относительно повышает привлекательность точек с высокой неопределённостью (где второе, exploration-слагаемое $\sigma\varphi(Z)$ играет большую роль) по сравнению с точками, которые лишь незначительно лучше среднего.

Почему это важно

Expected Improvement — не единственная возможная функция приобретения (есть, например, Probability of Improvement — вероятность улучшения без учёта его величины, и Upper Confidence Bound — прогноз плюс неопределённость с заданным весом), но именно она стала стандартом по умолчанию почти во всех библиотеках байесовской оптимизации, потому что математически корректно учитывает не только вероятность улучшения, но и его ожидаемую величину, автоматически балансируя exploration и exploitation в одной-единственной, дешёво вычисляемой формуле. Без такой функции суррогатная модель осталась бы просто регрессией с оценкой неопределённости, не дающей никакого практического правила выбора следующей точки, — именно acquisition function превращает суррогатное моделирование в работающую стратегию поиска.

Полный цикл байесовской оптимизации и сравнение с другими методами

Интуиция

Собери воедино всё, что ты уже разобрал: у тебя есть дорогая функция, которую нельзя вызывать часто; суррогатная модель, которая по накопленным наблюдениям предсказывает среднее и неопределённость в любой точке; и функция приобретения, которая превращает это предсказание в единственное число «насколько стоит проверить эту точку прямо сейчас». Остаётся замкнуть всё это в цикл: сделать вызов, обновить модель, найти самую многообещающую следующую точку, повторить — пока не кончится бюджет дорогих вызовов.

Формальное определение

Цикл байесовской оптимизации. Дан бюджет $N$ вызовов дорогой функции $f$. Начать с небольшого числа $n_0$ случайных (или заданных вручную) начальных точек, чтобы было с чего строить первую суррогатную модель. Затем на каждой итерации $t = n_0 + 1, \dots, N$:

  1. Обучить (или переобучить) суррогатную модель — гауссовский процесс — по всем накопленным парам $(x_i, y_i)$, включая подбор гиперпараметров ядра (например, длины корреляции $l$) максимизацией правдоподобия данных.
  2. Максимизировать функцию приобретения $\mathrm{EI}(x)$ по всему пространству $X$, найдя следующую кандидатную точку $x_t = \arg\max_x \mathrm{EI}(x)$ — эта оптимизация дешёвая (суррогатная модель — не настоящий чёрный ящик) и обычно решается стандартным численным методом вроде L-BFGS с несколькими случайными рестартами.
  3. Вызвать настоящую дорогую функцию: $y_t = f(x_t)$ — это единственный шаг цикла, потребляющий дефицитный бюджет.
  4. Добавить пару $(x_t, y_t)$ к накопленным наблюдениям и обновить $f_{\text{best}}$, если $y_t$ оказалось лучше текущего рекорда.
  5. Повторять, пока не исчерпан бюджет $N$ вызовов, и вернуть точку с наилучшим найденным значением.

Примеры

Пример 1: упрощённая иллюстрация цикла на 1D-функции за несколько итераций. Продолжим сквозной пример подбора логарифма скорости обучения на отрезке $[0, 1]$, где меньшее значение валидационного лосса — лучше. Ниже — упрощённая, иллюстративная трасса из четырёх итераций (точные числа подобраны для наглядности механики цикла, а не как результат полного пересчёта гауссовского процесса на каждом шаге):

Итерация Точка $x$ $f(x)$ (валид. лосс) Лучшее на данный момент Что произошло
Старт $0{,}10$ и $0{,}80$ $0{,}75$ и $0{,}68$ $0{,}68$ Две случайные начальные точки — без них ещё нечем обучать суррогатную модель
1 $0{,}30$ $0{,}40$ $0{,}40$ Максимум EI (см. предыдущий раздел, $\mathrm{EI}\approx0{,}418$) — сочетание удалённости от известных точек и разумного прогноза
2 $0{,}55$ $0{,}58$ $0{,}40$ Максимум EI ушёл в непокрытый разрыв между $0{,}3$ и $0{,}8$ — там самая большая неопределённость, чистое исследование
3 $0{,}20$ $0{,}37$ $0{,}37$ Неопределённость вокруг лидера $x=0{,}3$ уже сократилась после итерации 1, и EI сместился в сторону точной доводки рядом с ним

Обрати внимание на итерацию 2: алгоритм сознательно выбрал точку с результатом хуже текущего лидера ($0{,}58 > 0{,}40$) — это не ошибка, а осознанная плата за исследование региона, о котором суррогатная модель почти ничего не знала. Если бы этот регион на самом деле скрывал провал ещё глубже, чем найденный в точке $0{,}3$, алгоритм бы его обнаружил; тот факт, что он этого не обнаружил, — тоже ценная информация, которая сужает неопределённость по всему региону сразу.

Пример 2: псевдокод полного цикла.

def bayesian_optimization(f, bounds, n_init, n_total):
    X, y = random_sample(bounds, n_init)
    y = [f(x) for x in X]
    for t in range(n_init, n_total):
        gp = fit_gaussian_process(X, y)
        x_next = maximize_expected_improvement(gp, bounds, best=min(y))
        y_next = f(x_next)          # единственный дорогой вызов за всю итерацию
        X.append(x_next)
        y.append(y_next)
    best_idx = argmin(y)
    return X[best_idx], y[best_idx]

Обрати внимание на структуру: внутри цикла ровно один вызов настоящей дорогой функции f(x_next) за итерацию — всё остальное (обучение гауссовского процесса, максимизация EI) работает с дешёвой суррогатной моделью и может занимать секунды даже при том, что сам f стоит часы.

Пример 3: число вызовов — байесовская оптимизация против других методов курса. Пусть нужно подобрать 5 непрерывных гиперпараметров нейросети. Сеточный поиск даже с грубой сеткой по 5 значений на параметр требует $5^5=3125$ вызовов — неприемлемо. По результатам классической работы Бергстра и Бенджио (2012) о случайном поиске, random search с порядка 60 вызовами часто достигает качества, сравнимого со сплошным перебором тысяч сеточных комбинаций, — но именно потому, что не пытается покрыть всё пространство, а просто рассеивает точки по нему равномерно случайно. Генетический алгоритм или PSO с популяцией 30 особей и 40–50 поколениями потребуют порядка $1200$–$1500$ вызовов — на порядок больше, чем нужно для аккуратной эволюционной сходимости. Байесовская оптимизация на той же задаче типично находит сопоставимое или лучшее решение за $50$–$100$ вызовов — потому что каждая следующая точка выбирается не случайно и не по эвристике роя или отбора, а по явному расчёту, где именно ожидаемая выгода от дорогого вызова максимальна.

Пример 4: обратная сторона — рост стоимости самой суррогатной модели. Плата за эту эффективность — вычислительная стоимость самого гауссовского процесса: обращение матрицы $(K + \sigma_n^2 I)^{-1}$ в формулах апостериорного среднего и дисперсии стоит $O(n^3)$ операций, где $n$ — число уже накопленных наблюдений. При $n=50$ наблюдениях это не проблема, но при переходе к $n=200$ стоимость обращения матрицы вырастает в $(200/50)^3 = 64$ раза. Именно поэтому классическая GP-based байесовская оптимизация редко используется для бюджетов свыше нескольких сотен вызовов — переобучение суррогатной модели на каждой итерации само начинает стоить заметное время, сводя на нет часть выигрыша от экономии дорогих вызовов. Дополнительная сложность — размерность пространства: максимизация функции приобретения сама по себе становится всё труднее с ростом числа гиперпараметров, а гауссовский процесс с одним общим ядром на все координаты начинает плохо различать, какие из десятков измерений на самом деле важны. На практике классическая байесовская оптимизация на гауссовских процессах хорошо работает примерно до 15–20 измерений; за этим пределом качество её решений начинает уступать более простым методам или требует специальных модификаций (снижение размерности, структурированные ядра, разбиение пространства).

Почему это важно

Сопоставление байесовской оптимизации с методами предыдущих трёх уроков даёт практическое правило выбора инструмента, а не абстрактное «байесовская оптимизация лучше». Она особенно выгодна ровно тогда, когда каждый вызов чёрного ящика стоит очень дорого — часы GPU-времени, сутки инженерного моделирования, недели живого A/B-теста, — а число доступных вызовов принципиально ограничено десятками или несколькими сотнями. В этом режиме экономия каждого лишнего вызова перевешивает накладные расходы на переобучение суррогатной модели. Но при большом бюджете вызовов (тысячи и больше) или при высокой размерности пространства (десятки и сотни гиперпараметров) кубическая стоимость GP и деградация качества акцизиционной оптимизации в высокой размерности делают эволюционные методы или даже простой random search более практичным выбором. Осознанный подбор метода под конкретное соотношение «стоимость одного вызова / размерность пространства / доступный бюджет» — это именно то практическое умение, которое отличает специалиста, реально ускоряющего цикл разработки моделей, от того, кто бездумно применяет один и тот же инструмент к любой задаче.

Практика: 30 заданий

Базовые задания (1–10)

Задание 1: Точка $x$ уже была вызвана ровно в дорогой функции, поэтому в ней $\sigma(x) = 0$. Чему равен $\mathrm{EI}(x)$ и почему?


Задание 2: Дано: $f_{\text{best}}=10$ (минимизация), $\mu(x)=8$, $\sigma(x)=2$, $\xi=0$. Вычисли $Z$.


Задание 3: Используя результат задания 2 и значения $\Phi(1{,}0)\approx0{,}8413$, $\varphi(1{,}0)\approx0{,}2420$, вычисли $\mathrm{EI}(x)$.


Задание 4: Своими словами объясни, что означает «дорогой чёрный ящик» применительно к подбору гиперпараметров нейросети, и приведи пример измерения его стоимости.


Задание 5: Вычисли значение RBF-ядра $k(x,x')=\exp(-(x-x')^2/(2l^2))$ при $x=1$, $x'=3$, $l=1$.


Задание 6: Объясни, почему апостериорная дисперсия гауссовского процесса равна нулю точно в уже наблюдённой точке (при отсутствии шума), но не в точках рядом с ней.


Задание 7: Для сеточного поиска по 4 гиперпараметрам с 6 значениями каждого вычисли общее число комбинаций (вызовов чёрного ящика).


Задание 8: Верно ли утверждение: «Байесовская оптимизация требует, чтобы целевая функция была дифференцируемой»? Обоснуй.


Задание 9: Даны две точки-кандидата со значениями $\mathrm{EI}_1 = 0{,}35$ и $\mathrm{EI}_2 = 0{,}12$. Какую из них выберет алгоритм для следующего дорогого вызова?


Задание 10: Перечисли по порядку четыре шага полного цикла байесовской оптимизации (после начальной инициализации случайными точками).


Продвинутые задания (11–20)

Задание 11: Дано единственное наблюдение $x_1=0$, $y_1=2$, ядро $k(x,x')=\exp(-(x-x')^2/2)$ (то есть $l=1$), шум пренебрежимо мал. Вычисли $\mu(x_*)$ и $\sigma(x_*)$ в точке $x_*=1$.


Задание 12: Используя результат задания 11, при $f_{\text{best}}=2$ (единственное наблюдение — оно же лучшее) и $\xi=0$, вычисли $Z$ и $\mathrm{EI}(1)$, используя $\Phi(0{,}99)\approx0{,}8389$, $\varphi(0{,}99)\approx0{,}2444$.


Задание 13: Объясни без новых вычислений, почему $\mathrm{EI}$ в самой точке $x_1=0$ (из задания 11) обязана быть равна нулю.


Задание 14: Стоимость обращения матрицы гауссовского процесса растёт как $O(n^3)$ от числа наблюдений $n$. Во сколько раз возрастёт эта стоимость при переходе от $n=50$ к $n=200$ наблюдениям?


Задание 15: Объясни качественно, почему байесовская оптимизация с тем же бюджетом вызовов, что и случайный поиск (random search), обычно находит лучшее решение, хотя оба метода не гарантируют глобальный оптимум.


Задание 16: Сравни значение RBF-ядра для двух точек на расстоянии $0{,}3$ при $l=0{,}1$ и при $l=1{,}0$, и объясни разницу в терминах «гладкости» функции, которую предполагает модель.


Задание 17: Объясни, почему функция приобретения, которая выбирает точку исключительно по максимальной неопределённости (игнорируя прогноз $\mu(x)$ полностью), на практике работает хуже, чем Expected Improvement.


Задание 18: Объясни, почему функция приобретения, которая всегда выбирает точку с наилучшим прогнозируемым средним $\mu(x)$ (игнорируя неопределённость $\sigma(x)$ полностью), рискует застрять в локально хорошей, но не глобально оптимальной области — проведи параллель с уроком 298.


Задание 19: В Optuna при задании пространства поиска для скорости обучения на отрезке $[10^{-5}, 10^{-1}]$ рекомендуется использовать логарифмический масштаб (log=True). Объясни, почему.


Задание 20: В иллюстративном цикле из раздела «Примеры» на итерации 2 алгоритм выбрал точку $x=0{,}55$ и получил результат $0{,}58$ — хуже текущего лидера $0{,}40$. Объясни, почему это не ошибка алгоритма.


Задания-челленджи (21–30)

Задание 21: Для задачи максимизации (например, точности модели, а не лосса) выведи аналог формулы Expected Improvement, переформулировав улучшение как $I(x)=\max(f(x)-f_{\text{best}},0)$.


Задание 22: Одно обучение модели стоит 3 часа на GPU-инстансе за $2{,}5$ в час. Вычисли суммарную стоимость и суммарное календарное время (при последовательном выполнении) для (а) сеточного поиска из 4096 запусков и (б) байесовской оптимизации из 80 запусков.


Задание 23: Объясни разницу между «байесовской оптимизацией» (тема этого урока) и «байесовскими нейросетями» / «байесовским выводом о параметрах модели» — почему их легко перепутать по названию, но это разные вещи.


Задание 24: Объясни, как изменение параметра $\xi$ в формуле Expected Improvement (увеличение или уменьшение) влияет на баланс exploration и exploitation, и опиши механизм этого влияния через формулу.


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


Задание 26: Сравни концептуально классическую GP-based байесовскую оптимизацию с алгоритмом TPE (Tree-structured Parzen Estimator), который использует по умолчанию Optuna, — в чём принципиальное отличие суррогатной модели.


Задание 27: Объясни, почему байесовская оптимизация плохо подходит для задач, где один вызов целевой функции стоит микросекунды (например, вычисление простой алгебраической формулы).


Задание 28: Предложи две практические стратегии смягчения проблемы плохого масштабирования байесовской оптимизации на высокую размерность пространства гиперпараметров (свыше 20–30 параметров).


Задание 29: У команды есть бюджет ровно на 40 дорогих запусков обучения, чтобы подобрать 3 гиперпараметра. Сравни качественно ожидаемый результат сеточного поиска, случайного поиска и байесовской оптимизации при таком тесном бюджете.


Задание 30: Объясни, почему выбор ядра гауссовского процесса и его гиперпараметров (например, длины корреляции $l$) сам по себе представляет своего рода «мета-задачу подбора гиперпараметров», и опиши, как практические библиотеки решают эту проблему.


Частые ошибки

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

Равномерный, а не логарифмический масштаб для параметров вроде скорости обучения. Если задать пространство поиска для learning rate равномерным на отрезке $[10^{-5}, 10^{-1}]$ вместо логарифмического, и суррогатная модель, и функция приобретения будут работать с геометрией, не отражающей реальную структуру влияния параметра — подавляющее большинство сэмплированных точек попадёт в область, где скорость обучения слишком велика и почти всегда даёт расходящееся обучение.

Смешение байесовской оптимизации с байесовскими нейросетями. Это разные концепции, объединённые лишь общим байесовским принципом обновления апостериорного распределения при поступлении новых данных (см. разбор в задании 23) — одна работает с гиперпараметрами и дорогими вызовами, другая — с неопределённостью в весах самой модели.

Игнорирование шума в целевой функции. Валидационная точность нейросети слегка колеблется от запуска к запуску даже при фиксированных гиперпараметрах из-за случайной инициализации весов и порядка батчей. Если считать целевую функцию полностью детерминированной (нулевой шум $\sigma_n^2$) там, где на самом деле есть реальный шум, суррогатная модель начинает воспринимать случайные флуктуации как значимый сигнал и переобучаться на шуме, вместо того чтобы сглаживать его.

Применение классической GP-байесовской оптимизации к задачам с сотнями гиперпараметров или существенно дискретной структурой. За пределами примерно 20–30 измерений и при во многом комбинаторной природе пространства поиска (архитектурные решения, порядок слоёв) классический гауссовский процесс плохо справляется — для таких задач эволюционные методы из предыдущих уроков или их гибриды с байесовским подходом обычно практичнее.

Остановка оптимизации слишком рано или слишком поздно. Прекращение поиска до того, как функция приобретения успела перейти от активного исследования к точной доводке, оставляет на столе потенциальное улучшение; продолжение оптимизации далеко после практической сходимости (когда EI во всех кандидатных точках уже пренебрежимо мало) просто впустую расходует дорогой бюджет вызовов.

Главное запомнить

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

  • Суррогатная модель (чаще всего гауссовский процесс) строится по уже накопленным наблюдениям и даёт не только точечный прогноз, но и явную оценку неопределённости в каждой точке пространства.

  • Неопределённость суррогатной модели растёт по мере удаления от уже исследованных точек и падает почти до нуля вблизи них — это ключевое отличие от обычной регрессии.

  • Функция приобретения (acquisition function) превращает пару «прогноз и неопределённость» в единственное число, оценивающее, насколько многообещающа точка для следующего дорогого вызова.

  • Expected Improvement — самая популярная функция приобретения; она балансирует exploitation (доверие хорошему прогнозу) и exploration (готовность рискнуть ради высокой неопределённости) в одной формуле.

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

  • Классическая байесовская оптимизация на гауссовских процессах плохо масштабируется на большие бюджеты вызовов (кубическая стоимость обращения матрицы) и на высокую размерность пространства (обычно свыше 20–30 параметров).

  • Optuna и Hyperopt по умолчанию чаще используют не классический гауссовский процесс, а Tree-structured Parzen Estimator (TPE) — родственный, но структурно иной байесовский подход.

  • По сравнению с генетическими алгоритмами, PSO и сеточным/случайным поиском, байесовская оптимизация выигрывает именно там, где счёт идёт на десятки-сотни дорогих вызовов, а не на тысячи.

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

Связь с темами курса

Этот урок завершает содержательную часть блока «Оптимизация», и стоит оглянуться на пройденный путь целиком. Ты начинал с базовых градиентных методов — оптимизации, которая предполагает, что целевая функция дифференцируема, а градиент доступен дёшево на каждом шаге. Затем блок сознательно сместился в противоположную сторону — к методам оптимизации «чёрного ящика», где градиент недоступен в принципе. Генетические алгоритмы (урок 296) показали, как работать с существенно комбинаторными, дискретными пространствами через отбор и скрещивание целой популяции решений. Particle Swarm Optimization (урок 297) предложил альтернативу без отбора и скрещивания — рой частиц, движущийся синхронно, ведомый личной и коллективной памятью, естественно подходящий для непрерывных пространств. Имитация отжига (урок 298) показала третий, совершенно иной механизм устойчивости к локальным минимумам — управляемую готовность временно принимать ухудшения через убывающую температуру, работая при этом с единственным текущим решением, а не с популяцией.

Байесовская оптимизация — вершина этой линии рассуждений именно потому, что она единственная из четырёх методов явно моделирует неопределённость своих знаний о целевой функции и на этом основании принимает решение, куда именно направить следующий вызов. Генетические алгоритмы, PSO и имитация отжига исследуют пространство эвристически — по заданным правилам мутации, скорости роя или вероятности принятия ухудшения, — не задаваясь явным вопросом «где именно мы знаем меньше всего и стоит ли туда идти». Именно это качественное отличие и делает байесовскую оптимизацию особенно выигрышной ровно тогда, когда каждый вызов «чёрного ящика» стоит очень дорого и терять его впустую недопустимо, — а также ровно тем инструментом, который стоит за кнопкой автоматического подбора гиперпараметров в большинстве современных ML-фреймворков. Следующий, завершающий урок блока — «Multi-objective optimization», многокритериальная оптимизация — расширит эту картину на случай, когда важна не одна-единственная целевая функция, а сразу несколько конкурирующих между собой критериев одновременно: например, точность модели, задержка инференса и её размер. Многие библиотеки байесовской оптимизации, включая Optuna, поддерживают именно такую многокритериальную постановку — это естественное завершение всего пути, который ты прошёл через блок «Оптимизация».

Интересные факты

Optuna и Hyperopt по умолчанию не используют классический гауссовский процесс. Оба самых популярных инструмента байесовской оптимизации в экосистеме Python по умолчанию применяют алгоритм TPE (Tree-structured Parzen Estimator), а не GP-based подход, разобранный подробно в этом уроке, — TPE масштабируется на большее число вызовов и более высокую размерность заметно лучше классического гауссовского процесса, оставаясь при этом байесовским методом по духу: он тоже явно моделирует вероятностное распределение и явно выбирает следующую точку на его основе.

Первое применение было не в машинном обучении, а в проектировании самолётов. Алгоритм EGO (Efficient Global Optimization), заложивший практическую основу современной байесовской оптимизации, появился в 1998 году для инженерных задач — проектирования формы крыла и других аэродинамических поверхностей, где одна CFD-симуляция могла занимать сутки. В машинное обучение подход пришёл только полтора десятилетия спустя.

Облачные ML-платформы встраивают байесовскую оптимизацию «под капот». Google Vertex AI Vizier, AWS SageMaker Automatic Model Tuning и Azure ML Hyperdrive используют байесовскую оптимизацию (или её родственные варианты) как один из встроенных режимов подбора гиперпараметров, доступный без единой строчки кода, реализующего сам алгоритм, — пользователь лишь задаёт пространство поиска и бюджет вызовов.

Кубическая стоимость гауссовского процесса — это обратная сторона его же самого сильного качества. Именно точное аналитическое вычисление апостериорного распределения по всем накопленным наблюдениям, которое даёт гауссовскому процессу его надёжную оценку неопределённости, требует обращения полной матрицы ковариаций — а значит, чем больше данных накоплено, тем дороже становится каждое следующее обновление модели. Это прямо противоположно интуиции о том, что «больше данных — всегда быстрее и проще», к которой ты привык в обычном машинном обучении.

Лайфхаки

Используй логарифмический масштаб для параметров, охватывающих порядки величины. В Optuna это флаг log=True при вызове trial.suggest_float, в Hyperopt — распределение hp.loguniform. Скорость обучения, коэффициенты регуляризации L1/L2 и похожие параметры почти всегда стоит задавать именно так — иначе суррогатная модель тратит бюджет вызовов на плохо масштабированную геометрию пространства.

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

Дай алгоритму «тёплый старт» известными хорошими конфигурациями. Если у тебя уже есть разумный набор гиперпараметров из предыдущих экспериментов или из документации похожей модели, добавь его явным начальным наблюдением (study.enqueue_trial в Optuna) вместо того, чтобы полагаться исключительно на случайную инициализацию — это экономит несколько дорогих вызовов на этапе, когда суррогатная модель ещё ничего не знает.

Не переусердствуй с числом стартовых случайных точек. Слишком мало точек — суррогатная модель слишком груба для осмысленного EI; слишком много — теряется само преимущество направленного поиска. Значение по умолчанию около 10 случайных точек (n_startup_trials в Optuna) — разумный ориентир для пространств умеренной размерности, а не догма, требующая слепого копирования.

Распараллеливай независимые запуски, но осознавай цену. Optuna и Hyperopt поддерживают распределённые исследования (study с общим хранилищем), позволяя запускать несколько дорогих вызовов параллельно на разных GPU. Но чем больше запусков идёт одновременно без ожидания результатов друг друга, тем меньше «умных» решений успевает принять алгоритм между обновлениями суррогатной модели — баланс между скоростью по календарному времени и эффективностью по числу вызовов стоит настраивать осознанно, а не автоматически включать максимальный параллелизм.

При очень высокой размерности пространства сначала сократи его вручную. Если гиперпараметров больше 20–30, эффективность классической GP-байесовской оптимизации падает; часто разумнее заранее зафиксировать менее значимые параметры на разумных значениях по опыту или документации, оставив алгоритму только действительно важное подмножество (см. также задание 28).

Изучай встроенные графики важности параметров. Функции вроде optuna.visualization.plot_param_importances и plot_optimization_history помогают понять постфактум, на какие именно гиперпараметры реально ушёл дорогой бюджет вызовов и какие из них оказались наиболее влиятельными — это ценная информация для планирования следующего раунда подбора с уже суженным пространством поиска.

Ты только что закрыл последний содержательный урок целого блока «Оптимизация» — от градиентного спуска и его модификаций через генетические алгоритмы, рой частиц и имитацию отжига до байесовской оптимизации, инструмента, который стоит за кнопкой автоматического подбора гиперпараметров в большинстве современных ML-инструментов. Ты теперь понимаешь не просто «как работает Optuna», а почему она работает именно так — откуда берётся суррогатная модель, зачем нужна явная неопределённость и как формула Expected Improvement балансирует риск и расчёт. Осталось совсем немного: следующий, завершающий урок блока про многокритериальную оптимизацию соберёт всё пройденное воедино для случая, когда важен не один, а сразу несколько конкурирующих критериев качества, — и на этом целый большой блок будет закрыт полностью.

Понял тему? Закрепи в боте! 🚀

Попрактикуйся на задачах и получи персональные рекомендации от AI

💪 Начать тренировку
💬 Есть вопрос? Спроси бота!