Перейти к содержанию

Action-Dependent Heuristic Dynamic Programming (ADHDP)

ADHDP (Action-Dependent Heuristic Dynamic Programming) — это безмодельный метод из семейства Adaptive Critic Designs (ACD). В отличие от HDP, которому нужна модель объекта, ADHDP обучает функцию затрат \( J(R, a) \), зависящую от действия, которая принимает на вход и состояние, и действие. Актор улучшается путём минимизации выхода критика через обратное распространение градиента.

Архитектура ADHDP

Основные идеи

  1. Критик, зависящий от действия: Критик \( J(R, a) \) оценивает функцию затрат как функцию наблюдаемого состояния \( R(t) \) и действия \( a(t) \)
  2. Безмодельный метод: Не требуется модель объекта (матрицы A, B) — критик учится напрямую из переходов окружения
  3. Онлайн TD-обучение: Критик обучается методом TD(0) на \( J(R_t, a_t) \approx U_t + \gamma J(R_{t+1}, \pi(R_{t+1})) \)
  4. Улучшение актора: Актор минимизирует \( J(R, \pi(R)) \) обратным распространением градиента через критик

Ключевое отличие: HDP vs ADHDP

Аспект HDP (модельный) ADHDP (безмодельный)
Вход критика \( J(R) \) — только состояние \( J(R, a) \) — состояние и действие
Обновление актора Модельный прогноз Градиент через критик
Нужна модель Да (матрицы A, B) Нет
Эффективность по данным Выше (использует модель) Ниже (учится на данных)

Архитектура

Компонент Роль Реализация
Актор \( \pi(R) \) Генерирует управляющий сигнал \( u(t) \) DeterministicActor (MLP с tanh выходом)
Критик \( J(R, a) \) Оценивает функцию затрат от действия QCritic (MLP: concat[R, a] → скаляр)

Алгоритм

Цикл обучения

Для каждого эпизода:
    Сброс окружения → R(0)
    Для каждого шага t:
        1. Актор: a(t) = pi(R(t)) [+ шум исследования]
        2. Выполняем a(t) в окружении → R(t+1), U(t)

        # Обновление критика (TD-обучение)
        3. a'(t+1) = pi(R(t+1))  [следующее действие от актора]
        4. J_target = U(t) + g * J(R(t+1), a'(t+1))
        5. L_critic = MSE(J(R(t), a(t)), J_target)
        6. Обновляем критик градиентным спуском

        # Обновление актора
        7. a_pi = pi(R(t))
        8. L_actor = J(R(t), a_pi)  [минимизируем выход критика]
        9. Обновляем актор градиентным спуском через критик

Математическая формулировка

Функция потерь критика (TD-цель):

\[ \mathcal{L}_{\text{critic}} = \mathbb{E}\left[ \left( J(R_t, a_t) - \left( U_t + \gamma J(R_{t+1}, \pi(R_{t+1})) \right) \right)^2 \right] \]

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

\[ \mathcal{L}_{\text{actor}} = \mathbb{E}\left[ J(R_t, \pi(R_t)) \right] \]

Где: - \( U_t \) — мгновенные затраты (отрицательное вознаграждение) - \( \gamma \) — коэффициент дисконтирования - \( \pi(R) \) — политика актора

Быстрый старт

import numpy as np
from tensoraerospace.agent import ADHDP
from tensoraerospace.envs.b747 import ImprovedB747Env

def sine_reference(steps: int, amp_deg: float = 2.0, freq_hz: float = 0.05, dt: float = 0.1):
    """Генерация синусоидального опорного сигнала для слежения по тангажу."""
    t = np.arange(steps) * dt
    ref = np.deg2rad(amp_deg) * np.sin(2 * np.pi * freq_hz * t)
    return ref.reshape(1, -1).astype(np.float32)

num_steps = 300
dt = 0.1

env = ImprovedB747Env(
    initial_state=np.array([0.0, 0.0, 0.0, 0.0], dtype=float),
    reference_signal=sine_reference(num_steps, amp_deg=2.0, freq_hz=0.05, dt=dt),
    number_time_steps=num_steps,
    dt=dt,
    include_reference_in_obs=True,
)

agent = ADHDP(
    env,
    gamma=0.99,
    actor_lr=1e-4,
    critic_lr=1e-4,
    hidden_size=128,
    exploration_std=0.02,
    device="cpu",
    # Строгий режим: канонический ADHDP без базовой линии
    paper_strict=True,
)

# Обучение агента
agent.train(num_episodes=200, max_steps=num_steps)

# Сохранение обученной модели
agent.save("./adhdp_b747_model")

Гиперпараметры

Основные параметры

Параметр По умолчанию Описание
gamma 0.99 Коэффициент дисконтирования будущих затрат
actor_lr 1e-4 Скорость обучения актора
critic_lr 1e-4 Скорость обучения критика
hidden_size 256 Размер скрытых слоёв обеих сетей
exploration_std 0.02 Стандартное отклонение гауссова шума
device "cpu" Устройство Torch ('cpu', 'cuda', 'mps')

Режим политики

Параметр По умолчанию Описание
paper_strict False Если True, каноничный ADHDP без базовой линии
policy_mode "direct" "direct" (чистый актор) или "residual" (базовая линия + актор)
residual_scale 0.2 Масштаб остаточной политики при использовании базовой линии

Выбор действия

Параметр По умолчанию Описание
action_selection "actor" "actor" (сеть актора) или "critic_gradient" (оптимизация в стиле HDPy)
action_grad_steps 0 Шагов градиента для оптимизации действия через критик
action_grad_lr 0.0 Скорость обучения для оптимизации действия
action_momentum 0.0 Импульс для сглаживания: u = mu_prev + (1-m)u_new
action_max_abs 1.0 Максимальная амплитуда действия (конверт безопасности)

Базовый контроллер

Параметр По умолчанию Описание
baseline_type "pid" Тип базового контроллера: "pd" или "pid"
baseline_kp -24.6295 Пропорциональный коэффициент (настроен для B747)
baseline_ki -0.2486 Интегральный коэффициент
baseline_kd -7.8179 Дифференциальный коэффициент
pid_i_clip 1.0 Ограничение интеграла (anti-windup)

Расписание обучения (раздел III статьи)

Параметр По умолчанию Описание
baseline_warmup_episodes 0 Эпизодов с базовой линией для прогрева критика
critic_warmup_episodes 0 Эпизодов с замороженным актором
critic_cycle_episodes 0 Эпизодов на цикл обучения критика (чередование)
action_cycle_episodes 0 Эпизодов на цикл обучения актора (чередование)
warmstart_actor_episodes 0 Эпизодов имитации базовой линии (прогрев)

Рандомизация траекторий

Параметр По умолчанию Описание
initial_state_noise_std 0.0 Шум начального состояния
reference_roll_steps 0 Максимальный сдвиг опорного сигнала
reference_noise_std 0.0 Шум, добавляемый к опорному сигналу

Persistent Excitation

Статья (раздел III) подчёркивает важность persistent excitation для стабильного обучения. Вместо сильного шума в действиях используйте рандомизацию траекторий (initial_state_noise_std, reference_roll_steps), чтобы агент видел разнообразные условия.

Стратегии стабилизации

ADHDP предлагает несколько стратегий для стабилизации обучения:

1. Строгий режим (Paper-Strict)

agent = ADHDP(env, paper_strict=True)
Каноничный ADHDP: чистая политика актора, без базовой линии, без BC-регуляризатора.

2. Остаточная политика

agent = ADHDP(env, policy_mode="residual", residual_scale=0.2)
Актор обучает остаточную коррекцию поверх PID-базовой линии: u = u_pid + 0.2 * pi(R).

3. Прогрев актора

agent = ADHDP(env, warmstart_actor_episodes=10, warmstart_actor_epochs=2)
Предобучение актора имитации базовой линии методом supervised learning перед ACD-обновлениями.

4. Чередующееся обучение

agent = ADHDP(env, critic_cycle_episodes=5, action_cycle_episodes=5)
Обучаем критик 5 эпизодов (актор заморожен), затем актор 5 эпизодов (критик заморожен).

Сравнение с другими методами

Метод Критик Модель Обучение
ADHDP \( J(R, a) \) Не нужна Онлайн TD
HDP \( J(R) \) Нужна Модельный прогноз
DHP \( \lambda = \partial J / \partial R \) Нужна Градиентный
DDPG \( Q(s, a) \) Не нужна Replay + target networks

ADHDP vs DDPG

ADHDP — каноничный actor-critic из статьи без современных трюков стабилизации (replay buffer, target networks). Для лучшей эффективности и стабильности на практике используйте DDPG или SAC. ADHDP ценен для исследований и понимания основ ACD.

Поддерживаемые окружения

  • ImprovedB747Env — продольная динамика Boeing 747 со слежением за опорным сигналом

Унифицированный интерфейс обучения

ADHDP реализует общую унифицированную сигнатуру train() из BaseRLModel:

agent.train(num_episodes=200, max_steps=500)

ADHDP‑специфичные параметры, принимаемые через **kwargs:

  • show_progress (bool, устаревший псевдоним verbose) — управляет индикатором прогресса tqdm.
  • progress_desc (str) — подпись описания tqdm.

Документация API

ADHDP(env, *, paper_strict=False, gamma=0.99, actor_lr=0.0001, critic_lr=0.0001, hidden_size=256, device='cpu', seed=42, policy_mode='direct', residual_scale=0.2, use_baseline_in_critic_phases=False, action_momentum=0.0, action_max_abs=1.0, action_selection='actor', action_grad_steps=0, action_grad_lr=0.0, action_grad_step_clip=0.0, action_grad_u_l2=0.0, action_grad_du_l2=0.0, actor_update_mode='minimize_critic', actor_distill_coef=1.0, actor_distill_steps=10, actor_distill_lr=0.03, distill_execute_teacher=False, teacher_rollout_noise_std=0.0, exploration_std=0.02, critic_updates_per_step=1, actor_updates_per_step=1, initial_state_noise_std=0.0, reference_roll_steps=0, reference_noise_std=0.0, baseline_warmup_episodes=0, critic_warmup_episodes=0, critic_cycle_episodes=0, action_cycle_episodes=0, use_env_cost=True, warmstart_actor_episodes=0, warmstart_actor_epochs=2, baseline_type='pid', baseline_kp=-24.6295, baseline_ki=-0.2486, baseline_kd=-7.8179, pid_i_clip=1.0, actor_bc_l2=0.0, actor_bc_decay=1.0, log_dir=None, log_every_updates=500, wandb_project=None, wandb_entity=None, wandb_run_name=None, wandb_tags=None, wandb_config=None)

Bases: BaseRLModel

Action-Dependent Heuristic Dynamic Programming (ADHDP) agent.

ADHDP is a model-free reinforcement learning algorithm from the Adaptive Critic Designs (ACD) family. Unlike HDP which requires a plant model, ADHDP learns an action-dependent cost-to-go function J(R, a) that directly takes both state and action as inputs. The actor is improved by minimizing this critic output via backpropagation through the critic network.

The algorithm follows the framework from Prokhorov & Wunsch (1997): - Critic learns: J(R_t, a_t) ≈ U_t + γ J(R_{t+1}, π(R_{t+1})) - Actor minimizes: J(R_t, π(R_t)) via gradient through critic

This is the canonical, paper-style actor-critic without modern stabilization tricks (replay buffer, target networks). It uses online TD(0) learning.

Example

import numpy as np from tensoraerospace.agent import ADHDP from tensoraerospace.envs.b747 import ImprovedB747Env

def sine_ref(steps, amp_deg=2.0, freq_hz=0.05, dt=0.1): ... t = np.arange(steps) * dt ... return (np.deg2rad(amp_deg) * np.sin(2np.pifreq_hz*t)).reshape(1,-1)

env = ImprovedB747Env( ... initial_state=np.zeros(4), ... reference_signal=sine_ref(300), ... number_time_steps=300, ... dt=0.1, ... include_reference_in_obs=True, ... ) agent = ADHDP(env, paper_strict=True, gamma=0.99) agent.train(num_episodes=100)

References
  • Prokhorov D.V., Wunsch D.C. "Adaptive Critic Designs." IEEE Trans. Neural Networks, vol. 8, no. 5, pp. 997-1007, 1997.
  • Werbos P.J. "A menu of designs for reinforcement learning over time." Neural Networks for Control, MIT Press, 1990.

Attributes:

Name Type Description
actor

Neural network that outputs control action π(R).

critic

Neural network that estimates action-dependent cost-to-go J(R, a).

env

The Gymnasium-compatible environment.

gamma

Discount factor for future costs.

paper_strict

If True, uses canonical ADHDP without baseline mixing.

Initialize the ADHDP agent.

Parameters:

Name Type Description Default
env Any

Gymnasium-compatible environment with Box observation and action spaces. For best results, use ImprovedB747Env with include_reference_in_obs=True.

required
paper_strict bool

If True, enforce canonical ADHDP configuration: - No residual baseline in executed policy - No baseline substitution during critic-only phases - No BC regularizer This matches the original Prokhorov & Wunsch formulation. Default: False.

False
gamma float

Discount factor for future costs. Range: [0, 1]. Default: 0.99.

0.99
actor_lr float

Learning rate for the actor network optimizer (Adam). Default: 1e-4.

0.0001
critic_lr float

Learning rate for the critic network optimizer (Adam). Default: 1e-4.

0.0001
hidden_size int

Number of neurons in each hidden layer of both actor and critic networks. Both use two hidden layers with Tanh activation. Default: 256.

256
device Union[str, device]

Torch device for computation ('cpu', 'cuda', 'mps', or torch.device instance). Default: 'cpu'.

'cpu'
seed int

Random seed for reproducibility. Default: 42.

42
policy_mode str

Policy composition mode: - "direct": Pure actor output (default for paper_strict) - "residual": u = u_baseline + residual_scale * pi(R) Default: "direct".

'direct'
residual_scale float

Scale of learned residual when policy_mode="residual". Default: 0.2.

0.2
use_baseline_in_critic_phases bool

If True, execute baseline controller during critic-only training phases. Default: False.

False
action_momentum float

Momentum for action smoothing: u = mu_prev + (1-m)u_new. Range: [0, 1). Default: 0.0 (disabled).

0.0
action_max_abs float

Maximum action magnitude (safety envelope) in normalized units. Range: (0, 1]. Default: 1.0.

1.0
action_selection str

How to select actions: - "actor": Use actor network pi(R) (default) - "critic_gradient": Optimize action by minimizing J(R,a) w.r.t. a Default: "actor".

'actor'
action_grad_steps int

Number of gradient steps for critic-based action optimization (only used if action_selection="critic_gradient"). Default: 0.

0
action_grad_lr float

Learning rate for action optimization. Default: 0.0.

0.0
action_grad_step_clip float

Maximum step size for action gradient updates. Default: 0.0 (no clipping).

0.0
action_grad_u_l2 float

L2 regularization on action magnitude during action optimization. Default: 0.0.

0.0
action_grad_du_l2 float

L2 regularization on action change (trust region) during action optimization. Default: 0.0.

0.0
actor_update_mode str

Actor training mode: - "minimize_critic": Minimize J(R, pi(R)) via backprop through critic - "distill_critic_gradient": Supervised distillation of critic-gradient policy Default: "minimize_critic".

'minimize_critic'
actor_distill_coef float

Loss coefficient for distillation mode. Default: 1.0.

1.0
actor_distill_steps int

Gradient steps per distillation target. Default: 10.

10
actor_distill_lr float

Learning rate for distillation optimization. Default: 0.03.

0.03
exploration_std float

Standard deviation of Gaussian noise added to actions during training. Default: 0.02.

0.02
critic_updates_per_step int

Number of critic gradient updates per environment step (MATLAB-style "epochs per step"). Default: 1.

1
actor_updates_per_step int

Number of actor gradient updates per environment step. Default: 1.

1
initial_state_noise_std float

Standard deviation of noise added to initial state for trajectory randomization (persistent excitation). Default: 0.0.

0.0
reference_roll_steps int

Maximum random roll (shift) of reference signal at episode start. Default: 0.

0
reference_noise_std float

Standard deviation of noise added to reference signal. Default: 0.0.

0.0
baseline_warmup_episodes int

Episodes running only baseline controller for critic warmup (paper Section III). Default: 0.

0
critic_warmup_episodes int

Episodes with frozen actor (critic-only training). Default: 0.

0
critic_cycle_episodes int

Episodes per critic-only cycle in alternating training schedule. Default: 0 (no alternating).

0
action_cycle_episodes int

Episodes per actor-only cycle in alternating training schedule. Default: 0.

0
use_env_cost bool

If True, use environment's cost_total instead of shaped reward for TD target. Default: True.

True
warmstart_actor_episodes int

Episodes to pre-train actor by imitating baseline via supervised learning. Default: 0.

0
warmstart_actor_epochs int

Supervised epochs per warmstart episode. Default: 2.

2
baseline_type str

Baseline controller type: "pd" or "pid". Default: "pid".

'pid'
baseline_kp float

Proportional gain for baseline (tuned for B747). Default: -24.6295.

-24.6295
baseline_ki float

Integral gain for PID baseline. Default: -0.2486.

-0.2486
baseline_kd float

Derivative gain for baseline. Default: -7.8179.

-7.8179
pid_i_clip float

Anti-windup integral clipping for PID. Default: 1.0.

1.0
actor_bc_l2 float

L2 regularization coefficient keeping actor close to baseline (behavioral cloning). Default: 0.0.

0.0
actor_bc_decay float

Decay rate for actor_bc_l2 per episode. Default: 1.0.

1.0
log_dir Union[str, Path, None]

Directory path for TensorBoard logs. If None, logging is disabled. Default: None.

None
log_every_updates int

Frequency of logging (every N gradient updates). Default: 500.

500

Raises:

Type Description
ValueError

If observation or action space is not Box-like.

predict(*args, **kwargs)

Compatibility wrapper around select_action.

Accepts either
  • predict(state)
  • predict(state, deterministic=True/False)

train(num_episodes=1, *, max_steps=None, save_best=False, save_path=None, verbose=True, **kwargs)

Train the ADHDP agent (unified interface).

Parameters:

Name Type Description Default
num_episodes int

Number of training episodes.

1
max_steps Optional[int]

Optional per-episode step cap.

None
save_best bool

Unused by ADHDP; accepted for API consistency.

False
save_path Optional[str]

Unused by ADHDP; accepted for API consistency.

None
verbose bool

If True, show a tqdm progress bar.

True
**kwargs Any

Algorithm-specific options. Recognized keys:

  • show_progress (bool, legacy): overrides verbose.
  • progress_desc (str): tqdm description label.
{}

Returns:

Name Type Description
dict dict

Training summary dictionary. Currently minimal.

load(*args, **kwargs)

Load model weights from a directory created by save().

from_dir(folder) classmethod

Instantiate env+agent from save() directory (config.json + actor/critic).

from_pretrained(repo_name, access_token=None, version=None, load_gradients=False) classmethod

Load pretrained model from local directory or Hugging Face Hub.

Parameters:

Name Type Description Default
repo_name str

Path to local folder with weights or repository name in format namespace/repo_name on Hugging Face Hub.

required
access_token Optional[str]

Access token for private HF repository.

None
version Optional[str]

Revision / branch / tag of HF repository.

None
load_gradients bool

If True, also load optimizer states so training can be continued (requires save_gradients=True at save time).

False

Returns:

Name Type Description
ADHDP 'ADHDP'

Fully initialised agent with loaded weights.

QCritic(obs_dim, act_dim, *, hidden_sizes=(256, 256), activation=nn.Tanh)

Bases: Module

Critic approximating cost-to-go Q(s, a) (adaptive critic).

DeterministicActor(obs_dim, act_dim, *, hidden_sizes=(256, 256), action_low=None, action_high=None)

Bases: Module

Deterministic actor with tanh output scaled to env action bounds.

Источники

  • Prokhorov D.V., Wunsch D.C. "Adaptive Critic Designs." IEEE Transactions on Neural Networks, vol. 8, no. 5, pp. 997-1007, 1997.
  • Werbos P.J. "A menu of designs for reinforcement learning over time." Neural Networks for Control, MIT Press, 1990.
  • Si J., et al. "Handbook of Learning and Approximate Dynamic Programming." Wiley-IEEE Press, 2004.