Heuristic Dynamic Programming (HDP)¶
HDP (Heuristic Dynamic Programming) — это модельный метод из семейства Adaptive Critic Designs (ACD). В отличие от безмодельных подходов (таких как DDPG или SAC), HDP использует известную или обученную линеаризованную модель системы (матрицы A, B) для выполнения одношагового прогноза при улучшении актора. Сеть критика обучается оценивать скалярную функцию затрат \( J(R) \), а актор оптимизируется через обратное распространение градиента через модель для минимизации ожидаемых будущих затрат.
Основные идеи¶
- Модельный критик: Критик \( J(R) \) оценивает функцию затрат как функцию наблюдаемого состояния \( R(t) = [x(t), \theta_{ref}(t), q_{ref}(t)] \)
- Одношаговый прогноз: Актор улучшается минимизацией \( U(t) + \gamma J(R_{t+1}) \), где \( R_{t+1} \) предсказывается с использованием линеаризованной модели
- Обучение методом временных разностей: Критик обучается методом TD(0) на \( J(R_t) \approx U_t + \gamma J(R_{t+1}) \)
- Критик без действия на входе: В отличие от ADHDP или DDPG, критик HDP не принимает действие на вход — он зависит только от состояния \( R \)
Архитектура¶
| Компонент | Роль | Реализация |
|---|---|---|
| Актор \( \pi(R) \) | Генерирует управляющий сигнал \( u(t) \) | DeterministicActor (MLP с tanh выходом) |
| Критик \( J(R) \) | Оценивает скалярную функцию затрат | JCritic (MLP → скаляр) |
| Модель \( (A, B) \) | Линеаризованная динамика для прогноза | Матрицы из env.model.filt_A, env.model.filt_B |
Алгоритм¶
Цикл обучения¶
Для каждого эпизода:
Сброс окружения → x(0)
Для каждого шага t:
1. Формируем R(t) = [x(t), θ_ref(t), q_ref(t)]
2. Актор: u(t) = π(R(t)) [+ шум исследования]
3. Выполняем u(t) в окружении → x(t+1), U(t)
4. Формируем R(t+1) = [x(t+1), θ_ref(t+1), q_ref(t+1)]
# Обновление критика (TD-обучение)
5. J_target = U(t) + γ · J(R(t+1)) [bootstrap если не терминал]
6. L_critic = MSE(J(R(t)), J_target)
7. Обновляем критик градиентным спуском
# Обновление актора (модельный прогноз)
8. R'(t+1) = A · R(t) + B · π(R(t)) [прогноз модели]
9. L_actor = U(t) + γ · J(R'(t+1))
10. Обновляем актор градиентным спуском (через модель и критик)
Математическая формулировка¶
Функция потерь критика (TD-цель):
Функция потерь актора (одношаговый прогноз):
Где: - \( U_t \) — мгновенные затраты (отрицательное вознаграждение) - \( \gamma \) — коэффициент дисконтирования - \( A, B \) — матрицы линеаризованной системы
Функция затрат¶
Полезность \( U(t) \) обычно является квадратичной функцией ошибки слежения:
| Вес | Назначение |
|---|---|
| \( w_\theta \) | Штраф за ошибку угла тангажа |
| \( w_q \) | Штраф за ошибку угловой скорости |
| \( w_u \) | Штраф за величину управления |
| \( w_{\Delta u} \) | Штраф за скорость изменения управления |
Быстрый старт¶
import numpy as np
from tensoraerospace.agent.hdp import HDP
from tensoraerospace.envs.b747 import ImprovedB747Env
def step_reference(steps: int, deg: float = 5.0) -> np.ndarray:
"""Генерация ступенчатого опорного сигнала для слежения по тангажу."""
ref = np.zeros((1, steps), dtype=np.float32)
ref[:, steps // 5:] = np.deg2rad(deg)
return ref
num_steps = 800
env = ImprovedB747Env(
initial_state=np.array([0.0, 0.0, 0.0, 0.0], dtype=float),
reference_signal=step_reference(num_steps, deg=5.0),
number_time_steps=num_steps,
dt=0.02,
)
agent = HDP(
env,
gamma=0.99,
actor_lr=3e-4,
critic_lr=3e-4,
hidden_size=256,
exploration_std=0.1,
device="cpu",
# Веса функции затрат
dhp_w_theta=5.0,
dhp_w_q=0.2,
dhp_w_u=0.01,
dhp_w_du=0.02,
# Опционально: использовать PD-базовую линию для устойчивости
dhp_use_baseline=False,
)
# Обучение агента
agent.train(num_episodes=100, max_steps=num_steps)
# Сохранение обученной модели
agent.save("./hdp_b747_model")
Гиперпараметры¶
Основные параметры¶
| Параметр | По умолчанию | Описание |
|---|---|---|
gamma |
0.99 | Коэффициент дисконтирования будущих затрат |
actor_lr |
3e-4 | Скорость обучения актора |
critic_lr |
3e-4 | Скорость обучения критика |
hidden_size |
256 | Размер скрытых слоёв обеих сетей |
exploration_std |
0.1 | Стандартное отклонение гауссова шума для исследования |
Веса функции затрат¶
| Параметр | По умолчанию | Описание |
|---|---|---|
dhp_w_theta |
5.0 | Вес ошибки слежения по углу тангажа |
dhp_w_q |
0.2 | Вес ошибки слежения по угловой скорости |
dhp_w_u |
0.01 | Вес величины управления |
dhp_w_du |
0.02 | Вес скорости изменения управления (гладкость) |
dhp_use_env_cost |
True | Использовать функцию затрат окружения (если есть) |
Параметры стабилизации¶
| Параметр | По умолчанию | Описание |
|---|---|---|
dhp_use_baseline |
False | Использовать PD/PID базовый контроллер |
dhp_baseline_type |
"pd" | Тип базового контроллера: "pd" или "pid" |
dhp_baseline_kp |
0.6 | Пропорциональный коэффициент |
dhp_baseline_kd |
0.2 | Дифференциальный коэффициент |
dhp_residual_scale |
1.0 | Масштаб остаточной обученной политики |
Расписание обучения¶
| Параметр | По умолчанию | Описание |
|---|---|---|
dhp_warmstart_actor_episodes |
0 | Эпизодов для прогрева актора от базовой линии |
dhp_critic_cycle_episodes |
0 | Эпизодов для обучения только критика (чередование) |
dhp_action_cycle_episodes |
0 | Эпизодов для обучения только актора (чередование) |
Сравнение с другими ACD-методами¶
| Метод | Выход критика | Улучшение актора | Нужна модель |
|---|---|---|---|
| HDP | \( J(R) \) | Модельный прогноз | Да |
| DHP | \( \lambda = \partial J / \partial R \) | Прямой градиент | Да |
| GDHP | \( J(R), \lambda \) | И J, и градиенты | Да |
| ADHDP | \( J(R, a) \) | Градиент критика по действию | Нет |
Когда использовать HDP
Используйте HDP, когда у вас есть доступ к достаточно точной линеаризованной модели объекта управления. Метод обычно сходится быстрее безмодельных подходов для систем, где линейное приближение хорошо работает вблизи рабочей точки.
Поддерживаемые окружения¶
ImprovedB747Env— продольная динамика Boeing 747 со слежением за опорным сигналом
Пример: Слежение за ступенчатым сигналом¶
Агент HDP может быть обучен следить за ступенчатым опорным сигналом угла тангажа:
# Оценка обученного агента
obs, _ = env.reset()
done = False
theta_history = []
while not done:
action = agent.select_action(obs, evaluate=True)
obs, reward, terminated, truncated, info = env.step(action)
done = terminated or truncated
theta_history.append(obs[3]) # угол тангажа
import matplotlib.pyplot as plt
plt.plot(theta_history, label='Фактический θ')
plt.plot(env.reference_signal[0, :len(theta_history)], '--', label='Опорный')
plt.xlabel('Шаг времени')
plt.ylabel('Угол тангажа (рад)')
plt.legend()
plt.title('HDP: Слежение по тангажу')
plt.show()
Документация API¶
HDP(env, *, gamma=0.99, actor_lr=0.0003, critic_lr=0.0003, hidden_size=256, device='cpu', seed=42, exploration_std=0.1, dhp_w_theta=5.0, dhp_w_q=0.2, dhp_w_u=0.01, dhp_w_du=0.02, dhp_use_env_cost=True, dhp_use_baseline=False, dhp_baseline_type='pd', dhp_baseline_kp=0.6, dhp_baseline_ki=0.0, dhp_baseline_kd=0.2, dhp_pid_use_normalized_theta=True, dhp_pid_mode='norm', dhp_residual_scale=1.0, dhp_warmstart_actor_episodes=0, dhp_warmstart_actor_epochs=2, dhp_warmstart_actor_disable_baseline_after=True, dhp_critic_cycle_episodes=0, dhp_action_cycle_episodes=0, log_dir=None, log_every_updates=100, **kwargs)
¶
Bases: ADP
Heuristic Dynamic Programming (HDP) agent — model-based Adaptive Critic Design.
HDP is a model-based reinforcement learning algorithm from the Adaptive Critic Designs (ACD) family. It uses a known linearized system model (matrices A, B) to perform one-step lookahead for actor improvement. The critic network learns a scalar cost-to-go function J(R), while the actor is optimized by backpropagating through the model to minimize expected future cost.
The algorithm follows the framework from Prokhorov & Wunsch (1997): - Critic learns: J(R_t) ≈ U_t + γ J(R_{t+1}) - Actor minimizes: U_t + γ J(A·R_t + B·π(R_t)) via model-based lookahead
Example
import numpy as np from tensoraerospace.agent.hdp import HDP from tensoraerospace.envs.b747 import ImprovedB747Env
def step_reference(steps, deg=5.0): ... ref = np.zeros((1, steps), dtype=np.float32) ... ref[:, steps // 5:] = np.deg2rad(deg) ... return ref
env = ImprovedB747Env( ... initial_state=np.array([0.0, 0.0, 0.0, 0.0]), ... reference_signal=step_reference(800, deg=5.0), ... number_time_steps=800, ... dt=0.02, ... ) agent = HDP(env, gamma=0.99, hidden_size=256) 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. "Approximate dynamic programming for real-time control and neural modeling." Handbook of Intelligent Control, 1992.
Attributes:
| Name | Type | Description |
|---|---|---|
actor |
Neural network that outputs control action π(R). |
|
critic |
Module
|
Neural network that estimates cost-to-go J(R). |
env |
The Gymnasium-compatible environment. |
|
gamma |
Discount factor for future costs. |
Note
HDP requires an environment with:
- env.model.filt_A, env.model.filt_B: linearized system matrices
- env.reference_signal: pitch reference trajectory array
Initialize the HDP agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Any
|
Gymnasium-compatible environment. Must provide:
- |
required |
gamma
|
float
|
Discount factor for future costs. Controls the trade-off between immediate and future costs. Range: [0, 1]. Default: 0.99. |
0.99
|
actor_lr
|
float
|
Learning rate for the actor network optimizer (Adam). Default: 3e-4. |
0.0003
|
critic_lr
|
float
|
Learning rate for the critic network optimizer (Adam). Default: 3e-4. |
0.0003
|
hidden_size
|
int
|
Number of neurons in each hidden layer of both actor and critic networks. Both networks 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. Affects PyTorch, NumPy, and exploration noise. Default: 42. |
42
|
exploration_std
|
float
|
Standard deviation of Gaussian noise added to actions during training for exploration. Set to 0 for deterministic training. Default: 0.1. |
0.1
|
dhp_w_theta
|
float
|
Weight for pitch angle tracking error in the cost function. Higher values prioritize pitch tracking accuracy. Default: 5.0. |
5.0
|
dhp_w_q
|
float
|
Weight for pitch rate tracking error in the cost function. Default: 0.2. |
0.2
|
dhp_w_u
|
float
|
Weight for control magnitude penalty in the cost function. Penalizes large control inputs. Default: 0.01. |
0.01
|
dhp_w_du
|
float
|
Weight for control rate (smoothness) penalty in the cost function. Penalizes rapid changes in control. Default: 0.02. |
0.02
|
dhp_use_env_cost
|
bool
|
If True, use cost weights from the environment (e.g., ImprovedB747Env.w_pitch) when available. If False or unavailable, use dhp_w_* parameters. Default: True. |
True
|
dhp_use_baseline
|
bool
|
If True, use a PD/PID baseline controller and train the actor as a residual policy: u = u_baseline + scale * π(R). Helps stabilize training in early stages. Default: False. |
False
|
dhp_baseline_type
|
str
|
Type of baseline controller: 'pd' (proportional- derivative) or 'pid' (with integral term). Default: 'pd'. |
'pd'
|
dhp_baseline_kp
|
float
|
Proportional gain for the baseline controller. Default: 0.6. |
0.6
|
dhp_baseline_ki
|
float
|
Integral gain for the baseline PID controller. Only used if dhp_baseline_type='pid'. Default: 0.0. |
0.0
|
dhp_baseline_kd
|
float
|
Derivative gain for the baseline controller. Default: 0.2. |
0.2
|
dhp_pid_use_normalized_theta
|
bool
|
If True, normalize pitch angle by max_pitch_rad before passing to PID baseline. Default: True. |
True
|
dhp_pid_mode
|
str
|
PID computation mode: 'norm' (normalized angles) or 'deg' (degrees). Default: 'norm'. |
'norm'
|
dhp_residual_scale
|
float
|
Scaling factor for the learned residual policy when using baseline. Final action: u_baseline + scale * π(R). Default: 1.0. |
1.0
|
dhp_warmstart_actor_episodes
|
int
|
Number of episodes to pre-train the actor by imitating the baseline controller via supervised learning. This initializes the actor as a stabilizing controller before ACD updates begin (paper recommendation). Default: 0 (disabled). |
0
|
dhp_warmstart_actor_epochs
|
int
|
Number of supervised learning epochs per warm-start episode. Default: 2. |
2
|
dhp_warmstart_actor_disable_baseline_after
|
bool
|
If True, disable the baseline (set dhp_use_baseline=False) after warm-start completes, so the actor takes full control. Default: True. |
True
|
dhp_critic_cycle_episodes
|
int
|
Number of episodes to train only the critic (actor frozen) in each cycle. Part of the alternating training schedule from Prokhorov & Wunsch Section III. Set to 0 to disable alternating and train both networks every step. Default: 0. |
0
|
dhp_action_cycle_episodes
|
int
|
Number of episodes to train only the actor (critic frozen) in each cycle. Works with dhp_critic_cycle_episodes for alternating training. Default: 0. |
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: 100. |
100
|
**kwargs
|
Any
|
Additional arguments passed to the base ADP class. |
{}
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If gamma is not in [0, 1]. |
ValueError
|
If exploration_std is negative. |
ValueError
|
If environment lacks required attributes (filt_A, filt_B, reference_signal). |
save(path=None, *, save_gradients=False)
¶
Save the HDP agent (actor, critic, config) to path.
Creates a timestamped subdirectory containing config.json,
actor.pth, critic.pth (and optionally optimizer state dicts).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path, None]
|
Base directory. Defaults to the current working directory. |
None
|
save_gradients
|
bool
|
Also persist optimizer states for resumed training. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
Path to the created checkpoint directory. |
from_pretrained(repo_name, access_token=None, version=None, *, load_gradients=False)
classmethod
¶
Load a pretrained HDP agent from a local directory or Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Local folder path or Hugging Face repo id
( |
required |
access_token
|
Optional[str]
|
Hugging Face access token for private repos. |
None
|
version
|
Optional[str]
|
Revision / branch / tag on Hugging Face. |
None
|
load_gradients
|
bool
|
Restore optimizer states for continued training. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
HDP |
'HDP'
|
Fully initialized agent with restored weights. |
publish_to_hub(repo_name, folder_path, access_token=None)
¶
Upload a saved HDP checkpoint folder to Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Repository id (e.g. |
required |
folder_path
|
Union[str, Path]
|
Local directory produced by :meth: |
required |
access_token
|
Optional[str]
|
Hugging Face access token. |
None
|
JCritic(input_dim, *, hidden_sizes=(256, 256), activation=nn.Tanh)
¶
Bases: Module
Critic approximating cost-to-go J(R) (HDP-style scalar 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. "Approximate dynamic programming for real-time control and neural modeling." Handbook of Intelligent Control, 1992.
- Si J., et al. "Handbook of Learning and Approximate Dynamic Programming." Wiley-IEEE Press, 2004.