UCB-разведка через ансамбли Q-функций: как перестать бояться жадной политики
Ансамбль из нескольких Q-сетей превращает разброс их оценок в бонус за исследование. Разбираем, как это работает на практике и чем отличается от epsilon-greedy.

Классический агент обучения с подкреплением исследует среду грубо: с вероятностью epsilon он делает случайное действие, а в остальных случаях жадно выбирает то, что кажется лучшим. Проблема в том, что случайность одинаково размазана по всем состояниям — агент тратит попытки там, где давно всё понятно, и недоисследует места, где реально не уверен. Ансамбли Q-функций дают другой подход: они оценивают собственную неуверенность модели и направляют разведку туда, где эта неуверенность высока.
Откуда берётся идея UCB
UCB (Upper Confidence Bound) — приём из задачи о многоруких бандитах. Вместо того чтобы выбирать руку с лучшим средним выигрышем, агент выбирает руку с лучшей верхней границей доверительного интервала: среднее плюс бонус, который тем больше, чем реже руку дёргали. Формально для бандита бонус пропорционален корню из логарифма числа шагов, делённого на число проб конкретной руки.
В полноценном RL с непрерывными состояниями честно считать «сколько раз я был в этом состоянии» невозможно — состояний слишком много, и большинство встречается ровно один раз. Поэтому нужен способ приблизить неуверенность без явного подсчёта. Здесь и появляется ансамбль.
Разброс оценок независимо обученных Q-функций в точке — это дешёвый и на удивление рабочий заменитель честного доверительного интервала.
Как ансамбль превращается в бонус
Идея прямолинейна. Вы обучаете не одну Q-сеть, а K штук — например, 5 или 10. Каждая видит свою подвыборку опыта или инициализирована своими весами, поэтому их оценки расходятся. Там, где данных много, все K сетей сходятся к близким значениям — дисперсия мала. Там, где агент почти не был, оценки гуляют — дисперсия велика.
Дальше вы строите оптимистичную оценку действия:
Q_ucb(s, a) = mean_k Q_k(s, a) + lambda * std_k Q_k(s, a)
где mean_k и std_k — среднее и стандартное отклонение по ансамблю, а lambda — коэффициент, регулирующий агрессивность разведки. При lambda = 0 вы получаете обычную жадную политику по среднему. При большом lambda агент рвётся туда, где сети спорят между собой.
Минимальный шаг обучения на PyTorch
import torch
def ensemble_ucb_action(q_nets, state, lam):
# q_nets: список из K обученных Q-сетей
with torch.no_grad():
# (K, num_actions)
qs = torch.stack([net(state) for net in q_nets])
mean = qs.mean(dim=0)
std = qs.std(dim=0, unbiased=False)
ucb = mean + lam * std
return int(ucb.argmax().item())
def train_step(q_nets, opt_list, batch, gamma):
s, a, r, s2, done = batch
for net, opt in zip(q_nets, opt_list):
# у каждой сети своя маска бутстрэпа по батчу
mask = (torch.rand(len(r)) > 0.5).float()
with torch.no_grad():
target = r + gamma * (1 - done) * net(s2).max(dim=1).values
pred = net(s).gather(1, a.unsqueeze(1)).squeeze(1)
loss = (mask * (pred - target) ** 2).mean()
opt.zero_grad()
loss.backward()
opt.step()
Это учебный каркас, а не продакшн: в реальном коде вы добавите целевые сети (target networks), replay buffer, и, скорее всего, разделите общий кодировщик признаков с K отдельными «головами» вместо K полных сетей — так дешевле по памяти и вычислениям.
Чем это отличается от соседних методов
Ансамблевый UCB часто путают с bootstrapped-подходами и с шумом в параметрах. Разница в том, как используется разброс ансамбля.
| Подход | Механизм разведки | Использование ансамбля |
|---|---|---|
| epsilon-greedy | случайное действие с вероятностью epsilon | не нужен |
| Bootstrapped DQN | на эпизод выбирается одна голова, по ней действуем жадно | сэмплирование головы = аппроксимация Томпсона |
| UCB-ансамбль | бонус mean + lambda*std на каждом шаге | явно считается дисперсия по головам |
| Шум в параметрах (NoisyNet) | обучаемый шум весов | ансамбля как такового нет |
Ключевое практическое отличие: bootstrapped-подход выбирает целую линию поведения на эпизод и потому исследует «глубоко и связно», а UCB-бонус пересчитывается на каждом шаге и толкает к жадно-оптимистичному выбору прямо сейчас. Для сред с длинными цепочками действий, где выгода видна нескоро, глубокая разведка bootstrapped иногда выигрывает. Для сред с более локальной наградой оптимистичный бонус даёт стабильный и предсказуемый прирост.
Где это ломается
Ансамбль оценивает разброс внутри обучающего распределения. Если состояние совсем чужое, все головы могут дружно ошибаться в одну сторону — и дисперсия окажется низкой там, где неуверенность на самом деле максимальна. Это известная слабость: согласованность ансамбля не гарантирует правильности.
Второй риск — вычислительная цена. K сетей это в K раз больше forward-проходов, если не разделять кодировщик. На тяжёлых наблюдениях вроде кадров игры это ощутимо.
- Число голов K. Обычно 5–10. Меньше — дисперсия шумная, больше — растёт цена без пропорциональной пользы.
- Коэффициент lambda. Начните с 1.0 и подбирайте. Слишком большой — агент вечно гоняется за шумом; слишком маленький — скатывается в жадность.
- Диверсификация голов. Разная инициализация плюс bootstrap-маски по батчу. Без диверсификации головы схлопнутся к одному ответу и дисперсия исчезнет.
- Разделяемый кодировщик. Общий ствол и K лёгких голов резко снижают стоимость почти без потери качества оценки неуверенности.
Практический чек-лист внедрения
- Возьмите рабочий DQN/DDQN как базу и убедитесь, что он сходится с epsilon-greedy.
- Замените одну голову на K голов поверх общего кодировщика.
- Добавьте bootstrap-маску в лосс каждой головы, чтобы они видели разные подвыборки.
- На инференсе выбирайте действие по mean + lambda*std.
- Логируйте среднюю дисперсию ансамбля по ходу обучения — она должна падать по мере насыщения опытом. Если не падает, головы, скорее всего, недодиверсифицированы или lambda завышена.
UCB через ансамбли — это не серебряная пуля, а компромисс: вы платите вычислениями за направленную разведку и получаете взамен более осмысленное поведение, чем слепая случайность epsilon-greedy. На средах со сложной структурой награды это часто окупается.
Prompt-инженер: Идеальные запросы для Midjourney, ChatGPT и других моделей.
Спросить за 15 ₽Источники: Chen et al., UCB Exploration via Q-Ensembles (arXiv:1706.01502), Osband et al., Deep Exploration via Bootstrapped DQN (arXiv:1602.04621)
Частые вопросы
Сколько Q-сетей держать в ансамбле?
Чем UCB-ансамбль лучше epsilon-greedy?
Как выбрать коэффициент lambda?
Обязательно ли обучать K полных сетей?
Может ли ансамбль ошибиться в оценке неуверенности?
Чем это отличается от Bootstrapped DQN?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.