A3C (Asynchronous Advantage Actor‑Critic)¶
A3C сочетает преимущества policy‑based и value‑based подходов: несколько асинхронных рабочих агентов параллельно исследуют среду и обновляют общую (глобальную) сеть, используя функцию преимущества. Данная PyTorch реализация использует многопроцессность с общей глобальной сетью и оптимизатором SharedAdam.
Компоненты¶
- Глобальная сеть: Общие параметры Actor (политики) и Critic (оценки V) в едином модуле
Net - Воркеры: Независимые процессы, каждый со своей средой и локальной копией сети
- SharedAdam: Оптимизатор с общим состоянием между процессами для согласованного обновления параметров
- Advantage: TD-ошибка используется для взвешивания градиентов политики и обновления функции ценности
Теория (на базе реализации)¶
Архитектура сети¶
Модуль Net объединяет Actor и Critic:
Ветвь Actor: - Вход → Linear(s_dim, 256) → ReLU6 - → mu: Linear(256, a_dim) → Tanh → масштабирование *2 (диапазон действий: [-2, 2]) - → sigma: Linear(256, a_dim) → Softplus + 0.001 (для численной стабильности)
Ветвь Critic: - Вход → Linear(s_dim, 256) → ReLU6 - → value: Linear(256, 1)
Политика (Actor) — Гауссовское распределение¶
Актор выводит среднее \(\mu(s)\) и стандартное отклонение \(\sigma(s)\). Действия семплируются из:
Для многомерных действий базовое нормальное распределение оборачивается в Independent распределение.
Лог-вероятность:
Функция ценности (Critic)¶
Критик оценивает ценность состояния \(V_\phi(s)\). Temporal difference ошибка:
Потеря ценности (среднеквадратичная ошибка):
N-шаговые возвраты с бутстрэпом¶
Реализация использует правильные n-шаговые возвраты с бутстрэпом:
Если эпизод завершается, \(V_\phi(s_{t+n}) = 0\).
Функция потерь¶
Потеря политики (с регуляризацией энтропии):
где \(H[\pi]\) — энтропия политики.
Общая потеря:
Advantage (TD-ошибка) отсоединяется при вычислении потери политики для предотвращения обратного распространения через функцию ценности.
Асинхронность и синхронизация¶
Реализация использует torch.multiprocessing для параллельного обучения:
- Вычисление градиентов: Каждый воркер вычисляет градиенты на своей локальной сети
- Отправка градиентов: Локальные градиенты передаются в параметры глобальной сети (
gp._grad = lp.grad) - Клиппинг градиентов: Глобальные градиенты обрезаются (max_norm=40.0) для стабильности
- Шаг оптимизатора: SharedAdam обновляет параметры глобальной сети
- Получение параметров: Локальная сеть загружает обновленные глобальные параметры (
load_state_dict)
Эта процедура push-and-pull выполняется каждые update_global_iter шагов или при завершении эпизода.
Гиперпараметры¶
lr: Скорость обучения для SharedAdam (по умолчанию: 1e-4)gamma: Коэффициент дисконтирования (по умолчанию: 0.99)n_workers: Количество параллельных воркеров (по умолчанию: количество CPU)max_episodes: Общее количество эпизодов (по умолчанию: 10)max_ep_step: Максимум шагов в эпизоде (по умолчанию: 200)update_global_iter: Частота глобальных обновлений (по умолчанию: 10)- Коэффициент энтропии: 0.005 (жестко задан в функции потерь)
- Размер скрытого слоя: 256 (жестко задан в архитектуре Net)
Алгоритм обучения (псевдокод)¶
# Глобальная настройка
global_net = Net(s_dim, a_dim).share_memory()
optimizer = SharedAdam(global_net.parameters(), lr)
# Каждый воркер выполняется параллельно:
def worker_process(worker_id):
local_net = Net(s_dim, a_dim)
local_net.load_state_dict(global_net.state_dict()) # Начальная синхронизация
env = env_function(worker_id)
while global_episodes < max_episodes:
s = env.reset()
buffer_s, buffer_a, buffer_r = [], [], []
episode_reward = 0
for t in range(max_ep_step):
# Выбор действия
a = local_net.choose_action(s)
s', r, done = env.step(clip(a, action_space))
# Сохранение перехода
buffer_s.append(s)
buffer_a.append(a)
buffer_r.append(r)
episode_reward += r
# Условие обновления
if t % update_global_iter == 0 or done:
# Вычисление n-шаговых возвратов с бутстрэпом
if done:
v_s_ = 0
else:
v_s_ = local_net.forward(s')[2] # оценка ценности
# Обратное накопление
returns = []
for r in reversed(buffer_r):
v_s_ = r + gamma * v_s_
returns.insert(0, v_s_)
# Вычисление потерь
loss = local_net.loss_func(buffer_s, buffer_a, returns)
# Отправка градиентов в глобальную сеть, получение обновленных параметров
optimizer.zero_grad()
loss.backward()
transfer_gradients(local_net, global_net)
clip_grad_norm(global_net.parameters(), max_norm=40.0)
optimizer.step()
local_net.load_state_dict(global_net.state_dict())
# Очистка буферов
buffer_s, buffer_a, buffer_r = [], [], []
if done:
record_episode(episode_reward)
break
s = s'
Быстрый старт¶
Полный пример обучения A3C на окружении B747 для отслеживания синусоидального угла тангажа:
import numpy as np
import torch
from tensoraerospace.envs.b747 import ImprovedB747Env
from tensoraerospace.signals.standard import sinusoid_vertical_shift
from tensoraerospace.utils import convert_tp_to_sec_tp, generate_time_period
from tensoraerospace.agent.a3c import Agent, setup_global_params
# Установка random seed
SEED = 42
np.random.seed(SEED)
torch.manual_seed(SEED)
# Создание временной базы и опорного сигнала
dt = 0.1
_tp = generate_time_period(tn=20, dt=dt)
tps = convert_tp_to_sec_tp(_tp, dt=dt)
number_time_steps = len(_tp)
reference_signals = np.reshape(
sinusoid_vertical_shift(
tp=np.asarray(tps),
frequency=0.05,
amplitude=np.deg2rad(1.0),
vertical_shift=0.0,
),
[1, -1],
)
# Начальное состояние: [u, w, q, theta]
init_state = np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32)
# Настройка гиперпараметров
setup_global_params(
max_episodes=3000,
max_ep_step=number_time_steps,
gamma=0.99,
update_global_iter=10,
lr=1e-4,
)
# Функция-фабрика окружения
def make_env(worker_id: int):
return ImprovedB747Env(
initial_state=init_state,
reference_signal=reference_signals,
number_time_steps=number_time_steps,
dt=dt,
initial_elevator_deg=0.0,
)
# Создание и обучение агента
agent = Agent(
env_function=make_env,
gamma=0.99,
n_workers=4,
lr=1e-4,
max_episodes=3000,
max_ep_step=number_time_steps,
update_global_iter=10,
render=False,
run_in_main=True, # Установите False для многопроцессности
log_dir="runs/a3c_b747",
)
# Обучение
agent.train()
# Оценка
eval_env = make_env(0)
obs, _ = eval_env.reset()
agent.gnet.eval()
episode_reward = 0.0
with torch.no_grad():
terminated = truncated = False
while not (terminated or truncated):
obs_tensor = torch.from_numpy(np.array(obs).reshape(1, -1).astype(np.float32))
mu, _, _ = agent.gnet.forward(obs_tensor)
action = mu.cpu().numpy().reshape(-1)
obs, reward, terminated, truncated, _ = eval_env.step(action)
episode_reward += reward
print(f"Оценка награды: {episode_reward:.4f}")
eval_env.close()
agent.close()
Мониторинг с помощью TensorBoard¶
Метрики включают: - Loss/w*/total: Общая потеря для каждого воркера - Loss/w*/value: Потеря ценности (TD ошибка) - Loss/w*/policy: Потеря политики - Loss/w*/entropy: Энтропия политики - Performance/w*/episode_reward: Награды за эпизод - Performance/w*/moving_avg_reward: Скользящее среднее
Лучшие практики
- Используйте
run_in_main=Trueдля notebook/отладки - Установите
run_in_main=Falseиn_workers=8для продакшн обучения - Действия автоматически обрезаются по
env.action_space.low/high - Sigma имеет минимальное значение 0.001 для численной стабильности
- Следите в TensorBoard за коллапсом энтропии или расхождением потери ценности
Продвинутый пример: Обучение на окружении B747¶
Полный пример демонстрирует обучение агента A3C на окружении ImprovedB747Env для отслеживания синусоидального опорного сигнала угла тангажа.
Настройка и создание окружения¶
import numpy as np
import torch
import matplotlib.pyplot as plt
from queue import Empty
from tensoraerospace.envs.b747 import ImprovedB747Env
from tensoraerospace.signals.standard import sinusoid_vertical_shift
from tensoraerospace.utils import convert_tp_to_sec_tp, generate_time_period
from tensoraerospace.agent.a3c import Agent, setup_global_params
# Установка random seed для воспроизводимости
SEED = 42
np.random.seed(SEED)
torch.manual_seed(SEED)
# Создание временной базы
dt = 0.1 # секунды
_tp = generate_time_period(tn=20, dt=dt)
tps = convert_tp_to_sec_tp(_tp, dt=dt)
number_time_steps = len(_tp)
print(f"Длина эпизода: {number_time_steps} шагов ({number_time_steps * dt:.1f} секунд)")
# Генерация синусоидального опорного сигнала для угла тангажа (theta)
reference_signals = np.reshape(
sinusoid_vertical_shift(
tp=np.asarray(tps),
frequency=0.05, # Гц
amplitude=np.deg2rad(1.0), # амплитуда 1 градус
vertical_shift=0.0,
),
[1, -1],
)
# Определение начального состояния: [u, w, q, theta]
init_state = np.array([0.0, 0.0, 0.0, 0.0], dtype=np.float32)
# Создание окружения
env = ImprovedB747Env(
initial_state=init_state,
reference_signal=reference_signals,
number_time_steps=number_time_steps,
dt=dt,
initial_elevator_deg=0.0,
)
print(f"Пространство наблюдений: {env.observation_space}")
print(f"Пространство действий: {env.action_space}")
Настройка и создание агента¶
# Настройка гиперпараметров
setup_global_params(
max_episodes=3000,
max_ep_step=number_time_steps,
gamma=0.99,
update_global_iter=10,
lr=1e-4,
)
# Функция-фабрика окружения
def make_env(worker_id: int):
"""Создает окружение для каждого воркера."""
return ImprovedB747Env(
initial_state=init_state,
reference_signal=reference_signals,
number_time_steps=number_time_steps,
dt=dt,
initial_elevator_deg=0.0,
)
# Создание агента A3C
agent = Agent(
env_function=make_env,
gamma=0.99,
n_workers=4, # Используем 4 параллельных воркера
lr=1e-4,
max_episodes=3000,
max_ep_step=number_time_steps,
update_global_iter=10,
render=False,
run_in_main=True, # Установите False для настоящей многопроцессности
log_dir="runs/a3c_b747",
)
print("Агент A3C успешно создан!")
Обучение агента¶
import time
print("Запуск обучения A3C...\n")
episode_rewards = []
start_time = time.time()
# Запуск обучения (синхронный если run_in_main=True)
agent.train()
# Сбор наград из очереди
while True:
try:
r = agent.res_queue.get_nowait()
except Empty:
break
if r is None:
break
episode_rewards.append(float(r))
training_time = time.time() - start_time
print(f"\nОбучение завершено за {training_time:.2f} секунд")
print(f"Всего эпизодов: {len(episode_rewards)}")
print(f"Финальная награда (скользящее среднее): {episode_rewards[-1]:.4f}")
График прогресса обучения¶
plt.figure(figsize=(12, 5))
plt.plot(episode_rewards, label='Скользящее среднее награды', alpha=0.7)
# Добавление сглаженного тренда
window = 50
if len(episode_rewards) >= window:
smoothed = np.convolve(episode_rewards, np.ones(window)/window, mode='valid')
plt.plot(range(window-1, len(episode_rewards)), smoothed,
'r-', linewidth=2, label=f'Сглаженное (MA{window})')
plt.grid(True, alpha=0.3)
plt.xlabel('Эпизод')
plt.ylabel('Награда (скользящее среднее)')
plt.title('Прогресс обучения A3C на окружении B747')
plt.legend()
plt.tight_layout()
plt.show()
Оценка обученной политики¶
# Детерминированная оценка с использованием среднего политики
eval_env = make_env(0)
obs, info = eval_env.reset()
agent.gnet.eval()
episode_reward = 0.0
terminated = False
truncated = False
with torch.no_grad():
while not (terminated or truncated):
obs_tensor = torch.from_numpy(np.array(obs).reshape(1, -1).astype(np.float32))
mu, sigma, value = agent.gnet.forward(obs_tensor)
# Используем среднее для детерминированной политики
action = mu.cpu().numpy().reshape(-1)
obs, reward, terminated, truncated, info = eval_env.step(action)
episode_reward += float(reward)
print(f"Детерминированная оценка награды: {episode_reward:.4f}")
# График отслеживания угла тангажа
eval_env.unwrapped.model.plot_transient_process(
'theta',
tps,
reference_signals[0],
to_deg=True,
figsize=(15, 4)
)
eval_env.close()
agent.close()
Мониторинг с помощью TensorBoard¶
Доступные метрики: - Loss/w*/total: Общая потеря для каждого воркера - Loss/w*/value: Потеря функции ценности (квадрат TD ошибки) - Loss/w*/policy: Потеря политики (отрицательное ожидаемое преимущество) - Loss/w*/entropy: Энтропия политики (мера исследования) - Performance/w*/episode_reward: Сырые награды за эпизод - Performance/w*/moving_avg_reward: Экспоненциально взвешенное скользящее среднее
Ожидаемые результаты¶
После 3000 эпизодов обучения: - Агент учится отслеживать синусоидальный опорный сигнал тангажа с амплитудой ~1° - Финальное скользящее среднее награды: примерно от -1.6 до -2.0 - Ошибка отслеживания тангажа: < 0.5° среднеквадратичное
Советы для улучшения производительности¶
- Увеличьте длительность обучения: 10000+ эпизодов для лучшей сходимости
- Настройте гиперпараметры:
- Уменьшите
lr(5e-5) для более стабильного обучения - Увеличьте
update_global_iter(20-30) для более плавных градиентов - Используйте больше воркеров: Установите
run_in_main=Falseиn_workers=8для более быстрого обучения - Настройте опорный сигнал: Попробуйте разные частоты и амплитуды
- Следите за TensorBoard: Отслеживайте коллапс энтропии или расхождение потери ценности
Документация API¶
Agent¶
Agent(env_function, gamma=DEFAULT_GAMMA, n_workers=None, lr=DEFAULT_LR, max_episodes=DEFAULT_MAX_EP, max_ep_step=DEFAULT_MAX_EP_STEP, update_global_iter=DEFAULT_UPDATE_GLOBAL_ITER, render=False, run_in_main=False, log_dir='runs/a3c', wandb_project=None, wandb_entity=None, wandb_run_name=None, wandb_tags=None, wandb_config=None)
¶
Simple A3C Agent wrapper around multiprocessing Workers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env_function
|
Callable[[int], Env]
|
callable that returns a new env for a given worker id. |
required |
gamma
|
float
|
discount factor. |
DEFAULT_GAMMA
|
n_workers
|
Optional[int]
|
number of worker processes. |
None
|
lr
|
float
|
learning rate for SharedAdam. |
DEFAULT_LR
|
max_episodes
|
int
|
total episodes to run per global counter. |
DEFAULT_MAX_EP
|
max_ep_step
|
int
|
max steps per episode. |
DEFAULT_MAX_EP_STEP
|
update_global_iter
|
int
|
frequency to push/pull. |
DEFAULT_UPDATE_GLOBAL_ITER
|
render
|
bool
|
render from worker w0 (optional). |
False
|
Note: For unit tests or debugging, set run_in_main=True to avoid spawning processes. The single worker will run in the main process.
Configure A3C agent wrapper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env_function
|
Callable[[int], Env]
|
Factory returning an environment per worker id. |
required |
gamma
|
float
|
Discount factor. |
DEFAULT_GAMMA
|
n_workers
|
Optional[int]
|
Number of worker processes; defaults to CPU count. |
None
|
lr
|
float
|
Learning rate for optimizer. |
DEFAULT_LR
|
max_episodes
|
int
|
Total episodes to run. |
DEFAULT_MAX_EP
|
max_ep_step
|
int
|
Max steps per episode. |
DEFAULT_MAX_EP_STEP
|
update_global_iter
|
int
|
Sync frequency for global net updates. |
DEFAULT_UPDATE_GLOBAL_ITER
|
render
|
bool
|
Whether to render from worker 0. |
False
|
run_in_main
|
bool
|
If True, run worker inline for debugging/tests. |
False
|
log_dir
|
str
|
TensorBoard log directory. |
'runs/a3c'
|
train(num_episodes=None, *, max_steps=None, save_best=False, save_path=None, verbose=True, **kwargs)
¶
Launch training across worker processes (unified interface).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_episodes
|
Optional[int]
|
Override for |
None
|
max_steps
|
Optional[int]
|
Override for |
None
|
save_best
|
bool
|
Reserved for API consistency. |
False
|
save_path
|
Optional[str]
|
Reserved for API consistency. |
None
|
verbose
|
bool
|
Reserved for symmetry. |
True
|
**kwargs
|
Any
|
Currently unused. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict
|
Summary dictionary ( |
dict
|
|
close()
¶
Close TensorBoard writer and cleanup resources.
get_param_env()
¶
Return serializable configuration of the agent.
save(path=None, save_gradients=False)
¶
Save A3C agent to the specified directory.
Saves the global actor-critic network and configuration. Optionally saves the shared optimizer state for resuming training.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path | None
|
Base save directory. If None, saves to the current working directory. |
None
|
save_gradients
|
bool
|
If True, also save optimizer state dict. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Path |
Path
|
The directory where the model was saved. |
load(path, env_function=None, load_gradients=False)
classmethod
¶
Load an A3C agent from a checkpoint directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path]
|
Directory containing saved model files. |
required |
env_function
|
Optional[Callable[[int], Env]]
|
Factory returning an environment per worker id. Required because A3C needs environments for its workers. |
None
|
load_gradients
|
bool
|
If True, restore optimizer state. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Agent |
'Agent'
|
Reconstructed agent. |
from_pretrained(repo_name, env_function=None, access_token=None, version=None, load_gradients=False)
classmethod
¶
Load pretrained model from a local directory or Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Path to a local folder or a Hugging Face repo id
(e.g. |
required |
env_function
|
Optional[Callable[[int], Env]]
|
Factory returning an environment per worker id (required). |
None
|
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 state for continued training. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
Agent |
'Agent'
|
Initialized agent. |
publish_to_hub(repo_name, folder_path, access_token=None)
¶
Upload a saved model folder to Hugging Face Hub.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_name
|
str
|
Repository id on Hugging Face (e.g. |
required |
folder_path
|
Union[str, Path]
|
Local folder produced by :meth: |
required |
access_token
|
Optional[str]
|
Hugging Face access token. |
None
|
Worker¶
Worker(gnet, opt, global_ep, global_ep_r, res_queue, name, num_actions, num_observations, MAX_EP, MAX_EP_STEP, GAMMA, update_global_iter, env_function=None, env=None, render=False, writer=None, global_step=None, global_env_step=None)
¶
Bases: Process
Worker process class for asynchronous agent training.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Env
|
Environment for agent training. |
None
|
gnet
|
Net
|
Global model for shared training. |
required |
opt
|
SharedAdam
|
Optimizer for global network. |
required |
global_ep
|
Value
|
Global episode counter. |
required |
global_ep_r
|
Value
|
Global total reward counter across all processes. |
required |
res_queue
|
Queue
|
Queue for storing results. |
required |
name
|
int
|
Process number. |
required |
num_actions
|
int
|
Number of possible actions in the environment. |
required |
num_observations
|
int
|
Number of observations (state variables) in the environment. |
required |
MAX_EP
|
int
|
Maximum number of episodes. |
required |
MAX_EP_STEP
|
int
|
Maximum number of steps per episode. |
required |
GAMMA
|
float
|
Discount factor for future rewards. |
required |
update_global_iter
|
int
|
Frequency of global model updates. |
required |
render
|
bool
|
Whether to render the environment. Defaults to False. |
False
|
writer
|
Optional[SummaryWriter]
|
TensorBoard writer. Defaults to None. |
None
|
global_step
|
Optional[Value]
|
Global step counter. Defaults to None. |
None
|
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique process name. |
g_ep |
Value
|
Global episode counter. |
g_ep_r |
Value
|
Global total reward counter. |
res_queue |
Queue
|
Results queue. |
gnet |
Net
|
Global neural network. |
opt |
SharedAdam
|
Optimizer for updating global network. |
lnet |
Net
|
Local neural network. |
env |
Env
|
OpenAI Gym environment. |
gamma |
float
|
Discount factor. |
max_ep |
int
|
Maximum number of episodes. |
max_ep_step |
int
|
Maximum number of steps per episode. |
update_global_iter |
int
|
Frequency of global network updates. |
render |
bool
|
Whether to render the environment. |
writer |
Optional[SummaryWriter]
|
TensorBoard writer. |
global_step |
Optional[Value]
|
Global step counter. |
Initialize worker process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env_function
|
Optional[Callable[[int], Env]]
|
Factory callable taking worker id and returning
a fresh env. The env is created inside |
None
|
env
|
Optional[Env]
|
Legacy/direct env instance. Provided for backward compatibility (and for single-process tests); DO NOT use this path with real multi-process training because a single env would be shared across forked workers. |
None
|
gnet
|
Net
|
Global shared network. |
required |
opt
|
SharedAdam
|
Shared optimizer. |
required |
global_ep
|
Any
|
Shared episode counter. |
required |
global_ep_r
|
Any
|
Shared reward accumulator. |
required |
res_queue
|
Queue
|
Queue for results. |
required |
name
|
int
|
Worker id. |
required |
num_actions
|
int
|
Action dimension. |
required |
num_observations
|
int
|
Observation dimension. |
required |
MAX_EP
|
int
|
Max episodes to run. |
required |
MAX_EP_STEP
|
int
|
Max steps per episode. |
required |
GAMMA
|
float
|
Discount factor. |
required |
update_global_iter
|
int
|
Steps between syncs with global net. |
required |
render
|
bool
|
Whether to render (only worker 0 typically). |
False
|
writer
|
Optional[MetricWriter]
|
TensorBoard writer for metrics. |
None
|
global_step
|
Any | None
|
Shared global update counter (push_and_pull count). |
None
|
global_env_step
|
Any | None
|
Shared global env-step counter (incremented
once per |
None
|
run()
¶
Execute worker process containing agent training.
Network¶
Net(s_dim, a_dim)
¶
Bases: Module
Neural network for policy and value function approximation in RL.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s_dim
|
int
|
State space dimension. |
required |
a_dim
|
int
|
Action space dimension. |
required |
Attributes:
| Name | Type | Description |
|---|---|---|
s_dim |
int
|
State space dimension. |
a_dim |
int
|
Action space dimension. |
a1 |
Linear
|
First policy layer. |
mu |
Linear
|
Mean layer of policy distribution. |
sigma |
Linear
|
Standard deviation layer of policy distribution. |
c1 |
Linear
|
First value function layer. |
v |
Linear
|
Value function output layer. |
distribution |
Distribution
|
Distribution for modeling agent actions. |
Create network layers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s_dim
|
int
|
State dimension. |
required |
a_dim
|
int
|
Action dimension. |
required |
forward(x)
¶
Perform one forward pass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Input data, environment state. |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: Predicted mu, sigma, |
Tensor
|
and value for the given state. |
choose_action(s)
¶
Select agent action based on current state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
Tensor
|
Current environment state. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
np.ndarray: Selected action. |
loss_func(s, a, v_t)
¶
Compute loss function for network training.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
Tensor
|
States. |
required |
a
|
Tensor
|
Actions. |
required |
v_t
|
Tensor
|
Target state value function values. |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
torch.Tensor: Loss function value. |
Optimizer¶
SharedAdam(params, lr=0.001, betas=(0.9, 0.99), eps=1e-08, weight_decay=0)
¶
Bases: Adam
Adam optimizer with shared state for multi-process training.
This optimizer stores its internal state tensors (step counter, exp_avg, exp_avg_sq) in shared memory so multiple worker processes can update a single set of parameters consistently.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
Iterable[Parameter]
|
Parameters to optimize. |
required |
lr
|
float
|
Learning rate. Defaults to |
0.001
|
betas
|
Tuple[float, float]
|
Coefficients used for computing running averages of gradient and
its square. Defaults to |
(0.9, 0.99)
|
eps
|
float
|
Term added to the denominator for numerical stability. Defaults to
|
1e-08
|
weight_decay
|
float
|
Weight decay (L2 penalty). Defaults to |
0
|
Initialize shared Adam optimizer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
Iterable[Parameter]
|
Iterable of parameters to optimize. |
required |
lr
|
float
|
Learning rate. |
0.001
|
betas
|
Tuple[float, float]
|
Beta coefficients for Adam moments. |
(0.9, 0.99)
|
eps
|
float
|
Numerical stability term. |
1e-08
|
weight_decay
|
float
|
L2 weight decay. |
0
|
Утилиты¶
setup_global_params(*, max_episodes=DEFAULT_MAX_EP, max_ep_step=DEFAULT_MAX_EP_STEP, gamma=DEFAULT_GAMMA, update_global_iter=DEFAULT_UPDATE_GLOBAL_ITER, lr=DEFAULT_LR)
¶
Update defaults used by Agent.
This matches the previous TF API name to ease migration.
Детали реализации¶
Ключевые особенности¶
- Единая сеть: Один модуль
Netс общими слоями, снижающий потребление памяти - Активация ReLU6: Более стабильные градиенты по сравнению со стандартным ReLU
- Клиппинг градиентов: Максимальная норма 40.0 предотвращает взрывающиеся градиенты
- Регуляризация энтропии: Коэффициент 0.005 поощряет исследование
- SharedAdam: Состояние оптимизатора разделяется между процессами для согласованных обновлений
- Правильный бутстрэп: N-шаговые возвраты включают ценность терминального состояния, когда эпизод продолжается
Преимущества перед синхронными методами¶
- Параллельный сбор опыта: Несколько воркеров исследуют одновременно
- Некоррелированные сэмплы: Разные воркеры в разных состояниях снижают корреляцию
- Без буфера повторов: Онлайн обучение снижает требования к памяти
- Естественное исследование: Асинхронность обеспечивает разнообразие без ε-greedy
Советы по отладке¶
- Используйте
run_in_main=Trueдля запуска одного воркера без многопроцессности - Проверяйте TensorBoard на расхождение потерь или коллапс энтропии
- Уменьшайте
lrесли обучение нестабильно - Увеличивайте
update_global_iterдля более стабильных градиентов - Убедитесь, что окружение правильно инициализировано для воспроизводимости
Источники¶
- Asynchronous Methods for Deep Reinforcement Learning (Mnih et al., 2016)
- PyTorch Multiprocessing Best Practices
Протестированные окружения¶
- Unity ML-Agents окружения
- Gymnasium задачи непрерывного управления
- TensorAeroSpace LinearLongitudinal* окружения
- Кастомные аэрокосмические окружения управления
