Новости и статьи об искусственном интеллекте и нейросетях. Мы собираем и обрабатываем самую актуальную информацию из мира AI. О проекте

Статьи

Глубокое обучение с подкреплением: от 0 до 100

Статья вводит в глубокое обучение с подкреплением через пример посадки дрона, объясняя концепции, реализацию политики на нейронных сетях, функции вознаграждения и алгоритм REINFORCE. Рассматриваются проблемы вроде reward hacking и стратегии обучения. Обсуждаются будущие улучшения, такие как Actor-Critic.

29 октября 2025 г.
18 мин
5

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

Такое обучение называется обучением с подкреплением (RL) и существенно отличается от других подходов в машинном обучении. Вместо предоставления тысяч примеров правильных посадок системе дается обратная связь: положительная за удачные попытки и отрицательная за неудачи. Через множество итераций система определяет эффективные стратегии.

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

1. Обучение с подкреплением: Обзор

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

Эксперимент Павлова по классическому обусловливанию
Рис. 1. Эксперимент Павлова по классическому обусловливанию (изображение, сгенерированное ИИ Google Gemini)

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

1.1 Основные концепции

Для программной реализации на компьютерах ключевые идеи формализуются следующим образом:

  1. Агент (или актер): Это субъект из предыдущего описания, такой как собака, робот в заводе или NPC в видеоигре.
  2. Среда (или мир): Это пространство, симуляция с ограничениями или виртуальный мир игры. Среда ограничивает существование агента; внешние изменения воспринимаются агентом как воля высшей силы.
  3. Политика: Определяет действия в зависимости от ситуации, подобно правилам в организациях.
  4. Состояние: То, что агент наблюдает о текущей ситуации, как мгновенный снимок реальности — цвет светофора, скорость и расстояние для водителя.
  5. Действие: Реакция агента на состояние для достижения цели, например, встать с постели, чтобы приготовить кофе.
  6. Вознаграждение: Изменение в среде после действия. За неудачное падение — отрицательное вознаграждение, за успешное получение кофе — положительное.
Иллюстрация теоретической системы RL
Рис. 2. Иллюстрация теоретической системы RL

Большинство ключевых компонентов адаптируются под конкретную задачу.

2. Gym

После освоения основ возникает вопрос: как реализовать такую систему? Рассмотрим созданную игру для обучения агента.

Разработана специальная видеоигра, доступная для тренировки агентов машинного обучения.

Информация о запуске игры содержится в репозитории кода.

Delivery Drone

В игре Delivery Drone цель — посадить дрон (с грузом) на платформу. Для успешной посадки требуются:

  1. Близость к платформе.
  2. Низкая скорость.
  3. Вертикальная ориентация (перевернутая посадка приравнивается к аварии).

Все детали запуска доступны в репозитории.

Внешний вид игры:

Скриншот игры
Рис. 3. Скриншот созданной игры для проекта

Если дрон улетает за экран или касается земли, это считается аварией и приводит к неудаче.

State description

Дрон наблюдает 15 непрерывных значений, описывающих ситуацию:

Описание состояния дрона

Критерии успешной посадки: Дрон должен одновременно удовлетворить:

  1. Горизонтальное выравнивание: в пределах платформы (|dx| < 0.0625).
  2. Безопасная скорость подхода: менее 0.3.
  3. Горизонтальная ориентация: наклон менее 20° (|angle| < 0.111).
  4. Правильная высота: нижняя часть дрона касается верха платформы.

Это аналогично параллельной парковке: требуется точное положение, угол и низкая скорость.

How can someone design a policy?

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

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

Deep Learning to build a policy?

Для обработки непрерывных состояний (как точные координаты дрона) и сложных поведений используются нейронные сети. Нейронные сети позволяют работать с вероятностями действий: "Какое действие наиболее вероятно в текущем состоянии?".

Сеть принимает состояние как вектор или набор векторов. Для игры с дроном состояние:

Вектор состояния (из 2D-игры с дроном)

Дрон наблюдает абсолютное положение, скорости, ориентацию, топливо, положение платформы и производные метрики. Непрерывное состояние:

Формула вектора состояния

Каждый компонент представляет:

Описание компонентов состояния

Все компоненты нормализованы в диапазоны [0,1] или [-1,1] для стабильного обучения сети.

Пространство действий (три независимых бинарных ускорителя)

Каждый ускоритель обрабатывается отдельно:

  • Основной ускоритель (вверх).
  • Левый ускоритель (по часовой стрелке).
  • Правый ускоритель (против часовой стрелки).

Каждое действие сэмплируется из биномиального распределения, давая 3 независимых бинарных решения на шаг.

Политика нейронной сети (вероятностная с биномиальным сэмплированием)

Пусть fθ(s) — выходы сети после сигмоидной активации. Политика использует независимые биномиальные распределения:

Формула политики

Минимальный эскиз на Python (из реализации):

# Формирование вектора состояния из DroneState
s = np.array([
    state.drone_x, state.drone_y,
    state.drone_vx, state.drone_vy,
    state.drone_angle, state.drone_angular_vel,
    state.drone_fuel,
    state.platform_x, state.platform_y,
    state.distance_to_platform,
    state.dx_to_platform, state.dy_to_platform,
    state.speed,
    float(state.landed), float(state.crashed)
])
# Выходы сети — вероятности для каждого ускорителя (после сигмоиды)
action_probs = policy(torch.tensor(s, dtype=torch.float32))
# Форма: (3,)
# Сэмплирование каждого ускорителя независимо из биномиального

dist = Bernoulli(probs=action_probs)
action = dist.sample()
# Форма: (3,), напр. [1, 0, 1] — основной + правый ускорители

Это демонстрирует преобразование физических наблюдений игры в 15-мерный нормализованный вектор состояния и генерацию независимых бинарных решений для ускорителей.

Code setup (part 1): Imports and game socket setup

Сначала запускается сокетный слушатель игры. В директории delivery_drone репозитория выполняется:

pip install -r requirements.txt # Запускать один раз для установки модулей
python socket_server.py --render human --port 5555 --num-games 1 # Запускать для игры в сокетном режиме

ПРИМЕЧАНИЕ: Для кода требуется PyTorch. Убедитесь в его установке заранее.

import os
import torch
import torch.nn as nn
import math
import numpy as np
from torch.distributions import Bernoulli
# Импорт сокетного клиента игры
from delivery_drone.game.socket_client import DroneGameClient, DroneState
# Настройка клиента и подключение
client = DroneGameClient()
client.connect()

How to design a reward function?

Что делает функцию вознаграждения эффективной? Это наиболее сложная часть RL, требующая значительного времени на отладку.

Функция вознаграждения — суть любой реализации RL. Она определяет желаемое и нежелаемое поведение. Каждое действие оценивается накопленным вознаграждением за проявленные черты. Для мягкой посадки дрона положительные баллы за близость к платформе и низкую скорость, отрицательные за аварии или расход топлива — агент максимизирует сумму.

Преимущество: Лучший способ оценки эффективного вознаграждения

При обучении политики важно не только наличие вознаграждения, но и его относительная ценность. Это основа преимущества.

Преимущество указывает: "Было ли это действие лучше или хуже ожидаемого?"

Формула преимущества

В реализации:

  1. Сбор нескольких эпизодов и расчет их возвратов (дисконтированных сумм вознаграждений).
  2. Вычисление базовой линии как среднего возврата по эпизодам.
  3. Расчет преимущества = возврат – базовая линия для каждого шага.
  4. Нормализация преимуществ (среднее=0, std=1) для стабильности.

Почему это помогает:

  • Действия с положительным преимуществом — лучше среднего — повышают вероятность.
  • Действия с отрицательным — хуже среднего — снижают вероятность.
  • Снижает дисперсию градиентных обновлений (стабильное обучение).

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

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

Функция вознаграждения

Краткая заметка о обратно пропорциональном (нелинейном) масштабировании вознаграждения

Для вознаграждения, обратно пропорционального значению состояния (например, расстоянию от 0 до ~1.41), используются функции: высокое вознаграждение при нулевом расстоянии, низкое при большом.

График экспоненциально затухающей функции
Рис. 4. Гауссова функция масштабирования

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

Вспомогательные функции:

def inverse_quadratic(x, decay=20, scaler=10, shifter=0):
    """Вознаграждение квадратично уменьшается с расстоянием"""
    return scaler / (1 + decay * (x - shifter)**2)

def scaled_shifted_negative_sigmoid(x, scaler=10, shift=0, steepness=10):
    """Масштабированная и сдвинутая сигмоидная функция"""
    return scaler / (1 + np.exp(steepness * (x - shift)))

def calc_velocity_alignment(state: DroneState):
    """Расчет выравнивания скорости дрона с оптимальным направлением к платформе.
    Возвращает косинусное сходство: 1.0 = идеальное, -1.0 = противоположное"""
    # Оптимальное направление: от дрона к платформе
    optimal_dx = -state.dx_to_platform
    optimal_dy = -state.dy_to_platform
    optimal_norm = math.sqrt(optimal_dx**2 + optimal_dy**2)
    if optimal_norm < 1e-6:  # Уже на платформе
        return 1.0
    optimal_dx /= optimal_norm
    optimal_dy /= optimal_norm
    # Направление текущей скорости
    velocity_norm = state.speed
    if velocity_norm < 1e-6:  # Не движется
        return 0.0
    velocity_dx = state.drone_vx / velocity_norm
    velocity_dy = state.drone_vy / velocity_norm
    # Косинусное сходство
    return velocity_dx * optimal_dx + velocity_dy * optimal_dy

Код текущей функции вознаграждения:

def calc_reward(state: DroneState):
    rewards = {}
    total_reward = 0
    # 1. Штраф за время — на основе расстояния (больше при удаленности)
    minimum_time_penalty = 0.3
    maximum_time_penalty = 1.0
    rewards['time_penalty'] = -inverse_quadratic(
        state.distance_to_platform, decay=50, scaler=maximum_time_penalty - minimum_time_penalty
    ) - minimum_time_penalty
    total_reward += rewards['time_penalty']
    # 2. Расстояние и выравнивание скорости — ТОЛЬКО над платформой
    velocity_alignment = calc_velocity_alignment(state)
    dist = state.distance_to_platform
    rewards['distance'] = 0
    rewards['velocity_alignment'] = 0
    # Ключевое условие: дрон над платформой (dy > 0) для положительных вознаграждений
    if dist > 0.065 and state.dy_to_platform > 0:
        # Вознаграждение за движение к платформе при выравнивании
        if velocity_alignment > 0:
            rewards['distance'] = state.speed * scaled_shifted_negative_sigmoid(dist, scaler=4.5)
            rewards['velocity_alignment'] = 0.5
        total_reward += rewards['distance']
        total_reward += rewards['velocity_alignment']
    # 3. Штраф за угол — на основе расстояния
    abs_angle = abs(state.drone_angle)
    max_angle = 0.20
    max_permissible_angle = ((max_angle - 0.111) * dist) + 0.111
    excess = abs_angle - max_permissible_angle
    rewards['angle'] = -max(excess, 0)
    total_reward += rewards['angle']
    # 4. Штраф за скорость — за чрезмерную
    rewards['speed'] = 0
    speed = state.speed
    max_speed = 0.4
    if dist < 1:
        rewards['speed'] = -2 * max(speed - 0.1, 0)
    else:
        rewards['speed'] = -1 * max(speed - max_speed, 0)
    total_reward += rewards['speed']
    # 5. Штраф за вертикальное положение — за нахождение ниже платформы
    rewards['vertical_position'] = 0
    if state.dy_to_platform > 0:
        # Дрон над платформой (ХОРОШО)
        rewards['vertical_position'] = 0
    else:
        # Дрон ниже платформы (ПЛОХО!)
        rewards['vertical_position'] = state.dy_to_platform * 4.0  # Отрицательный штраф
    total_reward += rewards['vertical_position']
    # 6. Терминальные вознаграждения
    rewards['terminal'] = 0
    if state.landed:
        rewards['terminal'] = 500.0 + state.drone_fuel * 100.0
    elif state.crashed:
        rewards['terminal'] = -200.0
        # Дополнительный штраф за аварию вдали от цели
        if state.distance_to_platform > 0.3:
            rewards['terminal'] -= 100.0
    total_reward += rewards['terminal']
    rewards['total'] = total_reward
    return rewards

Числа вроде 4.5, 0.065 и 4.0 получены через многочисленные эксперименты. В RL настройка гиперпараметров сочетает искусство, науку и удачу.

def compute_returns(rewards, gamma=0.99):
    """Расчет дисконтированных возвратов (G_t) для каждого шага по уравнению Беллмана
    G_t = r_t + γ*r_{t+1} + γ²*r_{t+2} + ...
    """
    returns = []
    G = 0  # Вычисление задом наперед (эффективнее)
    for r in reversed(rewards):
        G = r + gamma * G
        returns.insert(0, G)
    return returns

Функции вознаграждения требуют тщательного тестирования. Ошибка может привести к оптимизации нежелаемых стратегий, вызывая reward hacking.

Reward hacking

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

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

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

Проблемный код:

# НЕ КОПИРОВАТЬ!
# Если дрон над платформой (|dx| < 0.0625) и близко (distance < 0.25):
    corridor_reward = inverse_quadratic(distance, decay=20, scaler=15)
    # До 15 баллов за стабильность и низкую скорость:
    corridor_reward += 10  # Дополнительные 10 баллов!
    # Итого возможно: 25 балла за шаг!

Пример reward hacking:

Дрон зависает у платформы для фарминга вознаграждений
Рис. 5. Дрон научился зависать у платформы и накапливать вознаграждения
График хакнутых вознаграждений
Рис. 6. График, показывающий reward hacking дрона

Making a policy network

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

  1. Активация основного ускорителя.
  2. Активация левого ускорителя.
  3. Активация правого ускорителя.
def state_to_array(state):
    """Вспомогательная функция для преобразования DroneState в numpy-массив"""
    data = np.array([
        state.drone_x, state.drone_y,
        state.drone_vx, state.drone_vy,
        state.drone_angle, state.drone_angular_vel,
        state.drone_fuel,
        state.platform_x, state.platform_y,
        state.distance_to_platform,
        state.dx_to_platform, state.dy_to_platform,
        state.speed,
        float(state.landed), float(state.crashed)
    ])
    return torch.tensor(data, dtype=torch.float32)

class DroneGamerBoi(nn.Module):
    def __init__(self, state_dim=15):
        super().__init__()
        self.network = nn.Sequential(
            nn.Linear(state_dim, 128),
            nn.LayerNorm(128),
            nn.ReLU(),
            nn.Linear(128, 128),
            nn.LayerNorm(128),
            nn.ReLU(),
            nn.Linear(128, 64),
            nn.LayerNorm(64),
            nn.ReLU(),
            nn.Linear(64, 3),
            nn.Sigmoid()
        )

    def forward(self, state):
        if isinstance(state, DroneState):
            state = state_to_array(state)
        return self.network(state)

Вместо 23=8 комбинаций пространство действий сведено к независимым решениям по ускорителям с биномиальным сэмплированием. Это упрощает оптимизацию, обрабатывая ускорители отдельно.


Training a policy with policy gradients

Learning Strategies: When Should We Update?

Вопрос: обновлять политику после каждого действия или после полного эпизода? Выбор критичен.

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

Три способа обновления политики:

Обучение после каждого действия (обновления на шаг)

Дрон активирует ускоритель, получает вознаграждение и сразу обновляет стратегию. Это чрезмерно реактивно, как корректировка броска в баскетболе после каждого. Случайное вознаграждение не отражает качество.

Первая попытка: Такой подход приводил к случайным движениям, переобучению на удачные шаги и повторным авариям.

Обучение после полного эпизода (обновления на эпизод)

Лучше: дрон завершает попытку, оценивает исход и обновляется. Видны полные последствия, но один эпизод — слабая статистика.

Обучение на множестве эпизодов (пакетные обновления)

Оптимально: несколько (6) попыток параллельно, обновление по среднему. Усреднение снижает шум. Требует ресурсов, но эффективнее. Прост в реализации, хотя существуют лучшие методы.

Код сбора нескольких эпизодов:

def collect_episodes(client: DroneGameClient, policy: nn.Module, max_steps=300):
    """Сбор эпизодов с ранней остановкой
    Args:
        client: Сокетный клиент игры
        policy: Модуль PyTorch
        max_steps: Максимум шагов на эпизод (по умолчанию: 300)
    """
    num_games = client.num_games
    # Инициализация хранилища
    all_episodes = [{'states': [], 'actions': [], 'log_probs': [], 'rewards': [], 'done': False} for _ in range(num_games)]
    # Сброс всех игр
    game_states = [client.reset(game_id) for game_id in range(num_games)]
    step_counts = [0] * num_games  # Счетчики шагов
    while not all(ep['done'] for ep in all_episodes):
        # Пакет активных игр
        batch_states = []
        active_game_ids = []
        for game_id in range(num_games):
            if not all_episodes[game_id]['done']:
                batch_states.append(state_to_array(game_states[game_id]))
                active_game_ids.append(game_id)
        if len(batch_states) == 0:
            break
        # Пакетный вывод
        batch_states_tensor = torch.stack(batch_states)
        batch_action_probs = policy(batch_states_tensor)
        batch_dist = Bernoulli(probs=batch_action_probs)
        batch_actions = batch_dist.sample()
        batch_log_probs = batch_dist.log_prob(batch_actions).sum(dim=1)
        # Выполнение действий
        for i, game_id in enumerate(active_game_ids):
            action = batch_actions[i]
            log_prob = batch_log_probs[i]
            next_state, _, done, _ = client.step({
                "main_thrust": int(action[0]),
                "left_thrust": int(action[1]),
                "right_thrust": int(action[2])
            }, game_id)
            reward = calc_reward(next_state)
            # Хранение данных
            all_episodes[game_id]['states'].append(batch_states[i])
            all_episodes[game_id]['actions'].append(action)
            all_episodes[game_id]['log_probs'].append(log_prob)
            all_episodes[game_id]['rewards'].append(reward['total'])
            # Обновление состояния и счетчика
            game_states[game_id] = next_state
            step_counts[game_id] += 1
            # Проверка завершения
            if done or step_counts[game_id] >= max_steps:
                # Штраф за таймаут без посадки
                if step_counts[game_id] >= max_steps and not next_state.landed:
                    all_episodes[game_id]['rewards'][-1] -= 500
                all_episodes[game_id]['done'] = True
    # Возврат эпизодов
    return [(ep['states'], ep['actions'], ep['log_probs'], ep['rewards']) for ep in all_episodes]

The Maximization-Minimization Puzzle

В типичном глубоком обучении (надзором) минимизируется функция потерь:

Формула минимизации потерь

Цель — спуск к меньшим потерям (лучшим предсказаниям).

В RL цель — максимизировать общее вознаграждение:

Формула максимизации вознаграждения

Проблема: Фреймворки для минимизации. Как превратить максимизацию в минимизацию?

Простой трюк: Максимизировать J(θ) = Минимизировать -J(θ).

Функция потерь:

Формула отрицательной функции

Градиентный спуск поднимается по вознаграждению (градиентный подъем по отрицанию).

The REINFORCE Algorithm (Policy Gradient)

Теорема градиента политики (Williams, 1992) описывает градиент ожидаемого вознаграждения:

Теорема градиента политики

(Формула сложна, но элегантна в сути.)

Где:

Определения в теореме

Простыми словами:

  • Если действие at привело к высокому возврату Gt, повысьте вероятность.
  • Если к низкому — снизьте.
  • Градиент указывает корректировку весов сети.

Adding a Baseline (Variance Reduction)

Сырые возвраты Gt вызывают высокую дисперсию. Улучшение — вычитание базовой линии b(st):

Формула с базовой линией

Простейшая базовая линия — средний возврат:

Средний возврат

Это дает преимущество: At=Gt-b.

  • Положительное преимущество — лучше среднего — повышает вероятность.
  • Отрицательное — хуже — снижает.

Почему помогает: Относительная оценка clearer, чем абсолютная (100 баллов при среднем 50 — отлично).

Our Implementation

В коде посадки дрона используется REINFORCE с базовой линией:

# 1. Сбор эпизодов и расчет возвратов
returns = compute_returns(rewards, gamma=0.99)  # G_t с дисконтированием
# 2. Расчет базовой линии (среднее возвратов)
baseline = returns_tensor.mean()
# 3. Расчет преимуществ
advantages = returns_tensor - baseline
# 4. Нормализация преимуществ (дополнительное снижение дисперсии)
advantages = (advantages - advantages.mean()) / (advantages.std() + 1e-8)
# 5. Расчет потерь (отрицательный знак!)
loss = -(log_probs_tensor * advantages).mean()
# 6. Градиентный спуск
optimizer.zero_grad()
loss.backward()
optimizer.step()

Цикл повторяется до освоения посадки. Подробный код в ноутбуке.

Current Results (reward function is still quite flawed)

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

GIF успешной посадки агента
Рис. 7. Дрон чему-то научился!

Интересно, но фрустрирующе...


The persistent hovering problem: A fundamental limitation

Даже с улучшенной функцией, условной на вертикальное положение (dy_to_platform > 0), политика проявляет нежелательное поведение: при промахе дрон опускается к платформе, но зависает снизу вместо посадки.

Анализ графиков вознаграждений выявил причину: агент рационально эксплуатирует структуру.

Что происходит?

В эпизоде с зависанием снизу накопленные вознаграждения:

GIF проблемы зависания под платформой
Рис. 8. GIF, показывающий проблему "зависания под платформой"
График проблемы зависания
Рис. 9. График, показывающий reward hacking дрона

Графики показывают:

  • Вознаграждение за расстояние (оранжевый): ~+70 рано, затем плато.
  • Выравнивание скорости (зеленый): ~+30 рано, плато.
  • Штраф за время (синий): Накопление до ~-250.
  • Вертикальное положение (коричневый): До ~-200 (штраф за низ).
  • Общее вознаграждение: -400 до -600 (после таймаута).

Ключевой инсайт: Дрон опускается сверху (накапливая положительные), проходит высоту платформы и зависает снизу. Положительные прекращаются (плато на 50-60 шаге), но накапливаются штрафы. Стратегия viable, т.к. посадка рискует -200 за аварию, а зависание — -400/-600 за эпизод.

Почему так?

Функция r(s', a) видит только текущее состояние, не траекторию. На шаге не отличает:

  • Прогресс к посадке (подход сверху с контролем).
  • Эксплуатацию (колебания для фарминга).

Оба могут иметь dy_to_platform > 0, получая одинаковые баллы. Агент оптимизирует заданное.

Как исправить?

Вознаграждения должны зависеть от переходов состояний: r(s, a, s'). Это позволит:

  • Прогресс: Вознаграждение, если distance(s') < distance(s) (реальное сближение).
  • Вертикальное улучшение: Только за последовательное движение вверх относительно платформы.
  • Стабильность траектории: Штраф за быстрые изменения направления.

Это принципиальнее, чем патчи штрафами (что пробовалось без успеха). Проблема в отсутствии информации о траектории.

В следующей статье рассмотрены методы Actor-Critic и техники с временной информацией против эксплуатации. Следите за обновлениями!

Это завершает пост о простом способе глубокого обучения с подкреплением.


Next on the list

  • Системы Actor-Critic.
  • DQL.
  • PPO и GRPO.
  • Применение к системам с зрением 👀.

References

Foundational Stuff

  1. Turing, A. M. (1950). “Computing Machinery and Intelligence.”.
    • Оригинальная статья о тесте Тьюринга.
  2. Williams, R. J. (1992). “Simple Statistical Gradient-Following Algorithms for Connectionist Reinforcement Learning.” Machine Learning.
    • Алгоритм REINFORCE.
  3. Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction. MIT Press.

Classical Conditioning & Behavioral Psychology

  1. Pavlov, I. P. (1927). Conditioned Reflexes: An Investigation of the Physiological Activity of the Cerebral Cortex. Oxford University Press.
    • Эксперименты по классическому обусловливанию.
  2. Skinner, B. F. (1938). The Behavior of Organisms: An Experimental Analysis. Appleton-Century-Crofts.
    • Оперантное обусловливание и коробка Скиннера.

Policy Gradient Methods

  1. Sutton, R. S., McAllester, D., Singh, S., & Mansour, Y. (1999). “Policy Gradient Methods for Reinforcement Learning with Function Approximation.” Advances in Neural Information Processing Systems.
    • Теоретические основы градиентов политики.
  2. Schulman, J., Moritz, P., Levine, S., Jordan, M., & Abbeel, P. (2015). “High-Dimensional Continuous Control Using Generalized Advantage Estimation.” arXiv preprint arXiv:1506.02438.

Neural Networks & Deep Learning

  1. Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep Learning. MIT Press.

Online Resources

  1. Karpathy, A. “Deep Reinforcement Learning: Pong from Pixels.”
  2. Spinning Up in Deep RL by OpenAI

Code Repository

  1. Jumle, V. “Reinforcement Learning 101: Delivery Drone Landing.”

Все изображения — сгенерированы ИИ (Gemini), созданы лично или скриншоты/графики.