Phase 09 - Lesson 07

Actor-Critic — A2C e A3C

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

REINFORCE é ruidoso. Adicione um crítico que aprende V̂(s), subtraia-o do retorno, e você obterá uma vantagem que possui o mesmo valor esperado mas variância muito menor. Isso é actor-critic. O A2C o executa de forma síncrona; o A3C o executa entre threads. Ambos são o modelo mental de todo método moderno de deep-RL.

Tipo: Build Linguagens: Python Pré-requisitos: Fase 9 · 04 (TD Learning), Fase 9 · 06 (REINFORCE) Tempo: ~75 minutos

O Problema

O REINFORCE clássico funciona, mas sua variância é terrível. Os retornos de Monte Carlo G_t podem oscilar por um fator de mais de 10 entre os episódios. Multiplicar esse ruído por ∇ log π e tirar a média produz um estimador de gradiente que precisa de milhares de episódios para mover a política a mesma distância que você poderia movê-la com muito menos atualizações de DQN.

A variância vem do uso de retornos brutos. Se você subtrair uma linha de base (baseline) b(s_t) — qualquer função do estado, incluindo um valor aprendido —, o valor esperado permanece inalterado e a variância cai. A melhor linha de base tratável é V̂(s_t). Agora, a quantidade que multiplica ∇ log π é a vantagem:

A(s, a) = G - V̂(s)

Uma ação é boa se produziu um retorno acima da média; ruim se abaixo. O REINFORCE com um crítico aprendido é o actor-critic. O crítico fornece ao ator um professor de baixa variância. Este é o fundamento de todo método de política profunda após 2015 (A2C, A3C, PPO, SAC, IMPALA).

O Conceito

Actor-critic: rede de política mais rede de valor, resíduo de TD como vantagem

Duas redes, uma perda compartilhada:

  • Ator (Actor) π_θ(a | s): a política. Amostrada para agir. Treinada com gradiente de política.
  • Crítico (Critic) V_φ(s): estima o retorno esperado a partir do estado. Treinado para minimizar (V_φ(s) - target)².

A vantagem. Duas formas padrão:

  • Vantagem de Monte Carlo (MC): A_t = G_t - V_φ(s_t). Não tendenciosa (unbiased), maior variância.
  • Vantagem de Diferença Temporal (TD): A_t = r_{t+1} + γ V_φ(s_{t+1}) - V_φ(s_t). Tendenciosa (biased, pois usa V_φ), variância muito menor. Também chamada de resíduo de TD (TD residual) δ_t.

Vantagem n-step. Interpola entre as duas:

A_t^{(n)} = r_{t+1} + γ r_{t+2} + … + γ^{n-1} r_{t+n} + γ^n V_φ(s_{t+n}) - V_φ(s_t)

n = 1 é TD puro. n = ∞ é MC. A maioria das implementações usa n = 5 para Atari, n = 2048 para PPO no MuJoCo.

Estimativa de Vantagem Generalizada (GAE - Generalized Advantage Estimation). Schulman et al. (2016) propuseram uma média ponderada exponencialmente sobre todas as vantagens n-step:

A_t^{GAE} = Σ_{l=0}^{∞} (γλ)^l δ_{t+l}

com λ ∈ [0, 1]. λ = 0 é TD (baixa variância, alto viés/tendenciosidade). λ = 1 é MC (alta variância, não tendencioso). λ = 0.95 é o padrão de 2026 — ajuste até que o botão de viés/variância esteja onde você deseja.

A2C: actor-critic de vantagem síncrono (synchronous advantage actor-critic). Colete T passos em N ambientes paralelos. Calcule as vantagens para cada passo. Atualize o ator e o crítico no lote (batch) combinado. Repita. O irmão mais simples e escalável do A3C.

A3C: actor-critic de vantagem assíncrono (asynchronous advantage actor-critic). Mnih et al. (2016). Inicie N threads trabalhadoras (workers), cada uma executando um ambiente. Cada trabalhadora calcula gradientes localmente em seu próprio rollout e, em seguida, os aplica de forma assíncrona a um servidor de parâmetros compartilhado. Nenhum buffer de repetição (replay buffer) é necessário — as trabalhadoras se descorrelacionam ao executar trajetórias diferentes. O A3C provou que era possível treinar em CPUs em larga escala. Em 2026, o A2C baseado em GPU (ambientes paralelos em lote) domina porque as GPUs exigem lotes grandes.

A perda combinada.

L(θ, φ) = -E[ A_t · log π_θ(a_t | s_t) ] + c_v · E[(V_φ(s_t) - G_t)²] - c_e · E[H(π_θ(·|s_t))]

Três termos: perda do gradiente de política, regressão do valor, bônus de entropia. c_v ~ 0.5, c_e ~ 0.01 são pontos de partida canônicos.

Como Construir

Passo 1: um crítico

Crítico linear V_φ(s) = w · features(s) atualizado com MSE:

def critic_update(w, x, target, lr):
    v_hat = dot(w, x)
    err = target - v_hat
    for j in range(len(w)):
        w[j] += lr * err * x[j]
    return v_hat

Em um ambiente tabular, o crítico converge em poucas centenas de episódios. No Atari, substitua o crítico linear por um tronco CNN compartilhado + cabeça de valor (value head).

Passo 2: vantagem n-step

Dado um rollout de comprimento T e um V(s_T) final bootstrapped:

def compute_advantages(rewards, values, gamma=0.99, lam=0.95, last_value=0.0):
    advantages = [0.0] * len(rewards)
    gae = 0.0
    for t in reversed(range(len(rewards))):
        next_v = values[t + 1] if t + 1 < len(values) else last_value
        delta = rewards[t] + gamma * next_v - values[t]
        gae = delta + gamma * lam * gae
        advantages[t] = gae
    returns = [a + v for a, v in zip(advantages, values)]
    return advantages, returns

returns é o alvo do crítico. advantages é o que multiplica ∇ log π.

Passo 3: atualização combinada

for step_i, (x, a, _r, probs) in enumerate(traj):
    adv = advantages[step_i]
    target_v = returns[step_i]

    # critic
    critic_update(w, x, target_v, lr_v)

    # actor
    for i in range(N_ACTIONS):
        grad_logpi = (1.0 if i == a else 0.0) - probs[i]
        for j in range(N_FEAT):
            theta[i][j] += lr_a * adv * grad_logpi * x[j]

On-policy, um rollout por atualização, taxas de aprendizado separadas para o ator e para o crítico.

Passo 4: paralelização (A3C vs A2C)

  • A3C: crie N threads. Cada uma executa seu próprio ambiente e sua própria passada para frente (forward pass). Periodicamente, envia as atualizações de gradiente para um master compartilhado. Sem bloqueios (locks) no master — condições de corrida são aceitáveis, apenas adicionam ruído.
  • A2C: execute N instâncias de ambientes em um único processo, empilhe observações em um lote [N, obs_dim], passada para frente em lote (batched forward pass), passada para trás em lote (batched backward pass). Maior utilização de GPU, determinístico, mais fácil de raciocinar. O padrão em 2026.

Nosso código de demonstração é de thread única para maior clareza; reescrever para A2C em lote requer apenas três linhas de numpy.

Armadilhas Comuns

  • Viés do crítico antes do gradiente do ator. Se o crítico for aleatório, sua linha de base (baseline) não fornecerá informações úteis e você estará treinando em puro ruído. Aqueça (warm up) o crítico por algumas centenas de passos antes de ativar o gradiente de política, ou use uma taxa de aprendizado lenta para o ator.
  • Normalização da vantagem. Normalize as vantagens para média zero e desvio padrão unitário por lote. Isso estabiliza o treinamento massivamente a um custo quase nulo.
  • Tronco compartilhado (Shared trunk). Use um extrator de características compartilhado para ator e crítico em entradas de imagem, com cabeças separadas. As características compartilhadas se beneficiam de ambas as perdas.
  • Contrato on-policy. O A2C reutiliza os dados para exatamente uma atualização. Mais do que isso e seu gradiente se torna tendencioso (a correção por amostragem de importância é o que o PPO adiciona).
  • Colapso de entropia. Sem c_e > 0, a política torna-se quase determinística em poucas centenas de atualizações e para de explorar.
  • Escala de recompensa. As magnitudes de vantagem dependem da escala de recompensa. Normalize as recompensas (por exemplo, dividindo pelo desvio padrão móvel) para obter magnitudes de gradiente consistentes entre diferentes tarefas.

Como Utilizar

O A2C/A3C raramente são a escolha final em 2026, mas eles representam a arquitetura que tudo o que veio depois refina:

Método Relação com o A2C
PPO A2C + razão de importância clipada para atualizações multi-épocas
IMPALA A3C + correção off-policy V-trace
SAC (Fase 9 · 07) A2C off-policy com um crítico de valor suavizado (soft-value critic) (próxima lição)
GRPO (Fase 9 · 12) A2C sem o crítico — vantagem relativa ao grupo (group-relative advantage)
DPO A2C colapsado em uma perda de classificação de preferências (preference-ranking loss), sem amostragem
AlphaStar / OpenAI Five A2C com treinamento de liga (league training) + pré-treinamento por imitação

Se você vir "vantagem" (advantage) em um artigo de 2026, pense em actor-critic.

Entregar (Ship It)

Salve como outputs/skill-actor-critic-trainer.md:

---
name: actor-critic-trainer
description: Produce an A2C / A3C / GAE configuration for a given environment, with advantage estimation and loss weights specified.
version: 1.0.0
phase: 9
lesson: 7
tags: [rl, actor-critic, gae]
---

Given an environment and compute budget, output:

1. Parallelism. A2C (GPU batched) vs A3C (CPU async) and the number of workers.
2. Rollout length T. Steps per env per update.
3. Advantage estimator. n-step or GAE(λ); specify λ.
4. Loss weights. `c_v` (value), `c_e` (entropy), gradient clip.
5. Learning rates. Actor and critic (separate if using).

Refuse single-worker A2C on environments with horizon > 1000 (too on-policy, too slow). Refuse to ship without advantage normalization. Flag any run with `c_e = 0` and observed entropy < 0.1 as entropy-collapsed.

Exercícios

  1. Fácil. Treine o actor-critic com vantagem de MC (G_t - V(s_t)) em um GridWorld 4×4. Compare a eficiência de amostras com o REINFORCE-com-baseline-de-média-móvel da Lição 06.
  2. Médio. Mude para a vantagem de resíduo de TD (r + γ V(s') - V(s)). Meça a variância dos lotes de vantagem. Quanto ela diminui?
  3. Difícil. Implemente GAE(λ). Realize uma varredura (sweep) com λ ∈ {0, 0.5, 0.9, 0.95, 1.0}. Plote o retorno final versus a eficiência de amostras. Onde está o ponto ideal de equilíbrio entre viés e variância para esta tarefa?

Termos-Chave

Termo O que as pessoas dizem O que realmente significa
Ator (Actor) "A rede de política" `π_θ(a
Crítico (Critic) "A rede de valor" V_φ(s), atualizado pela regressão MSE para retornos / alvos de TD.
Vantagem (Advantage) "Quão melhor que a média" A(s, a) = Q(s, a) - V(s) ou seus estimadores. Multiplicador para ∇ log π.
Resíduo de TD (TD residual) "δ" δ_t = r + γ V(s') - V(s); estimativa de vantagem de um passo.
GAE "O botão de interpolação" Soma ponderada exponencialmente das vantagens n-step, parametrizada por λ.
A2C "Actor-critic síncrono" Em lotes (batched) entre ambientes; um passo de gradiente por rollout.
A3C "Actor-critic assíncrono" Threads trabalhadoras enviam gradientes para um servidor de parâmetros compartilhado. Artigo original; menos comum em 2026.
Bootstrap "Usar V no horizonte" Trunca o rollout, adiciona γ^n V(s_{t+n}) para fechar a soma.

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).