Phase 09 - Lesson 06

Policy Gradient — REINFORCE do Zero

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

Pare de estimar o valor. Parametrize a política diretamente, calcule o gradiente do retorno esperado, suba a colina. Williams (1992) escreveu isso em um único teorema. É por isso que o PPO, o GRPO e todo loop de RL de LLM existem.

Tipo: Build Linguagens: Python Pré-requisitos: Fase 3 · 03 (Backpropagation), Fase 9 · 03 (Monte Carlo), Fase 9 · 04 (TD Learning) Tempo: ~75 minutos

O Problema

O Q-learning e o DQN parametrizam a função de valor. Você escolhe as ações por argmax Q. Isso funciona bem para ações discretas e estados discretos. No entanto, falha quando as ações são contínuas (como fazer argmax sobre um torque de 10 dimensões?) ou quando você deseja uma política estocástica (argmax é determinístico por construção).

Em vez disso, os gradientes de política parametrizam a política. π_θ(a | s) é uma rede neural que gera uma distribuição sobre as ações. Colete amostras dela para agir. Calcule o gradiente do retorno esperado em relação a θ. Suba a colina. Sem argmax. Sem recursão de Bellman. Apenas ascensão de gradiente em J(θ) = E_{π_θ}[G].

O teorema REINFORCE (Williams 1992) nos diz que esse gradiente é computável: ∇J(θ) = E_π[ G · ∇_θ log π_θ(a | s) ]. Execute um episódio. Calcule o retorno. Multiplique por ∇ log π_θ(a | s) em cada passo. Tire a média. Ascensão de gradiente. Pronto.

Todo algoritmo de RL para LLM em 2026 — PPO, DPO, GRPO — é um refinamento do REINFORCE. Compreendê-lo profundamente é o pré-requisito para o restante desta fase, bem como para a Fase 10 · 07 (implementação de RLHF) e a Fase 10 · 08 (DPO).

O Conceito

Gradiente de política: política softmax, gradiente log-π, atualização ponderada pelo retorno

O teorema do gradiente de política. Para qualquer política π_θ parametrizada por θ:

∇J(θ) = E_{τ ~ π_θ}[ Σ_{t=0}^{T} G_t · ∇_θ log π_θ(a_t | s_t) ]

onde G_t = Σ_{k=t}^{T} γ^{k-t} r_{k+1} é o retorno descontado a partir do passo t. A expectativa é sobre trajetórias completas τ amostradas a partir de π_θ.

A prova é curta. Diferencie J(θ) = Σ_τ P(τ; θ) G(τ) sob a expectativa. Use ∇P(τ; θ) = P(τ; θ) ∇ log P(τ; θ) (o truque da derivada do logaritmo). Fatore log P(τ; θ) = Σ log π_θ(a_t | s_t) + termos do ambiente que não dependem de θ. Os termos do ambiente desaparecem. Duas linhas de álgebra geram o teorema.

Truques de redução de variância. O REINFORCE padrão (vanilla) possui uma variância altíssima — os retornos são ruidosos, ∇ log π é ruidoso e o produto deles é extremamente ruidoso. Duas correções padrão:

  1. Subtração de baseline. Substitua G_t por G_t - b(s_t) para qualquer baseline b(s_t) que não dependa de a_t. Não enviesado porque E[b(s_t) · ∇ log π(a_t | s_t)] = 0. Escolha comum: b(s_t) = V̂(s_t) aprendido por um crítico → actor-critic (Lição 07).
  2. Reward-to-go. Substitua Σ_t G_t · ∇ log π_θ(a_t | s_t) por Σ_t G_t^{from t} · ∇ log π_θ(a_t | s_t). Apenas os retornos futuros importam para uma determinada ação — as recompensas passadas contribuem apenas com ruído de média zero.

Combinando-os, obtemos:

∇J ≈ (1/N) Σ_{i=1}^{N} Σ_{t=0}^{T_i} [ G_t^{(i)} - V̂(s_t^{(i)}) ] · ∇_θ log π_θ(a_t^{(i)} | s_t^{(i)})

que é o REINFORCE com baseline — o ancestral direto do A2C (Lição 07) e do PPO (Lição 08).

Parametrização de política softmax. Para ações discretas, a escolha padrão é:

π_θ(a | s) = exp(f_θ(s, a)) / Σ_{a'} exp(f_θ(s, a'))

onde f_θ é qualquer rede neural que gera uma pontuação por ação. O gradiente possui uma forma limpa:

∇_θ log π_θ(a | s) = ∇_θ f_θ(s, a) - Σ_{a'} π_θ(a' | s) ∇_θ f_θ(s, a')

ou seja, a pontuação da ação tomada menos seu valor esperado sob a política.

Política gaussiana para ações contínuas. π_θ(a | s) = N(μ_θ(s), σ_θ(s)). ∇ log N(a; μ, σ) possui uma forma fechada. Isso é tudo de que o SAC da Fase 9 · 07 precisa.

Implementação

Passo 1: rede de política softmax

def policy_logits(theta, state_features):
    return [dot(theta[a], state_features) for a in range(N_ACTIONS)]

def softmax(logits):
    m = max(logits)
    exps = [exp(l - m) for l in logits]
    Z = sum(exps)
    return [e / Z for e in exps]

Use uma política linear (um vetor de pesos por ação) para um ambiente tabular. Para o Atari, substitua por uma CNN e mantenha a cabeça softmax.

Passo 2: amostragem e log-probabilidade

def sample_action(probs, rng):
    x = rng.random()
    cum = 0
    for a, p in enumerate(probs):
        cum += p
        if x <= cum:
            return a
    return len(probs) - 1

def log_prob(probs, a):
    return log(probs[a] + 1e-12)

Passo 3: rollout com log-probs capturadas

def rollout(theta, env, rng, gamma):
    trajectory = []
    s = env.reset()
    while not done:
        logits = policy_logits(theta, s)
        probs = softmax(logits)
        a = sample_action(probs, rng)
        s_next, r, done = env.step(s, a)
        trajectory.append((s, a, r, probs))
        s = s_next
    return trajectory

Passo 4: atualização do REINFORCE

def reinforce_step(theta, trajectory, gamma, lr, baseline=0.0):
    returns = compute_returns(trajectory, gamma)
    for (s, a, _, probs), G in zip(trajectory, returns):
        advantage = G - baseline
        grad_log_pi_a = [-p for p in probs]
        grad_log_pi_a[a] += 1.0
        for i in range(N_ACTIONS):
            for j in range(len(s)):
                theta[i][j] += lr * advantage * grad_log_pi_a[i] * s[j]

O gradiente ∇ log π(a|s) = e_a - π(·|s) (vetor one-hot de a menos as probabilidades) é o coração dos gradientes de política softmax. Grave isso na memória muscular.

Passo 5: baselines

Uma média móvel de G sobre episódios recentes é uma redução de variância suficiente para fazer um GridWorld 4×4 funcionar; leva cerca de 500 episódios para convergir. Atualize a baseline para um V̂(s) aprendido e você terá o actor-critic.

Armadilhas

  • Explosão de gradientes. Os retornos podem ser enormes. Sempre normalize G para ~N(0, 1) ao longo do lote antes de multiplicar por ∇ log π.
  • Colapso de entropia. A política converge prematuramente para uma ação quase determinística, parando de explorar e ficando travada. Correção: adicione um bônus de entropia β · H(π(·|s)) ao objetivo.
  • Alta variância. O REINFORCE padrão (vanilla) precisa de milhares de episódios. Uma baseline de crítico (Lição 07) ou a região de confiança do TRPO/PPO (Lição 08) é a correção padrão.
  • Ineficiência de amostragem. Ser on-policy significa que você descarta cada transição após uma única atualização. Correções off-policy por meio de amostragem por importância (importance sampling) trazem os dados de volta, ao custo de variância (a razão do PPO é um peso IS clipado).
  • Gradientes não estacionários. O mesmo gradiente de 100 episódios atrás usa uma π antiga. Métodos on-policy atualizam a cada poucos rollouts por esse motivo.
  • Atribuição de crédito. Sem reward-to-go, as recompensas passadas contribuem apenas com ruído. Sempre use reward-to-go.

Casos de Uso

Em 2026, o REINFORCE raramente é executado diretamente, mas a sua fórmula de gradiente está em toda parte:

Caso de uso Método derivado
Controle contínuo PPO / SAC com política gaussiana
RLHF de LLM PPO com penalidade KL, rodando em política no nível do token
Raciocínio de LLM (DeepSeek) GRPO — REINFORCE com baseline relativo ao grupo, sem crítico
Multiagente REINFORCE com crítico centralizado (MADDPG, COMA)
Robótica com ações discretas A2C, A3C, PPO
Configurações apenas de preferência DPO — REINFORCE reescrito como uma perda de verossimilhança de preferência, sem amostragem

Quando você lê loss = -advantage * log_prob em um script de treinamento de 2026, isso é o REINFORCE com baseline. Artigos inteiros (DPO, GRPO, RLOO) são truques de redução de variância em cima desta única linha.

Entrega

Salve como outputs/skill-policy-gradient-trainer.md:

---
name: policy-gradient-trainer
description: Produce a REINFORCE / actor-critic / PPO training config for a given task and diagnose variance issues.
version: 1.0.0
phase: 9
lesson: 6
tags: [rl, policy-gradient, reinforce]
---

Given an environment (discrete / continuous actions, horizon, reward stats), output:

1. Policy head. Softmax (discrete) or Gaussian (continuous) with parameter counts.
2. Baseline. None (vanilla), running mean, learned `V̂(s)`, or A2C critic.
3. Variance controls. Reward-to-go on by default, return normalization, gradient clip value.
4. Entropy bonus. Coefficient β and decay schedule.
5. Batch size. Episodes per update; on-policy data freshness contract.

Refuse REINFORCE-no-baseline on horizons > 500 steps. Refuse continuous-action control with a softmax head. Flag any run with `β = 0` and observed policy entropy < 0.1 as entropy-collapsed.

Exercícios

  1. Fácil. Implemente o REINFORCE no GridWorld 4×4 com uma política softmax linear. Treine por 1.000 episódios sem baseline. Plote a curva de aprendizado; meça a variância (desvio padrão dos retornos).
  2. Médio. Adicione uma baseline de média móvel. Treine novamente. Compare a eficiência de amostragem e a variância com a execução vanilla. Em quanto a baseline reduz os passos para a convergência?
  3. Difícil. Adicione um bônus de entropia β · H(π). Faça uma busca (sweep) sobre β ∈ {0, 0.01, 0.1, 1.0}. Plote o retorno final e a entropia da política. Onde fica o ponto ideal (sweet spot) nesta tarefa?

Termos-Chave

Termo O que dizem por aí O que realmente significa
Policy gradient "Treinar a política diretamente" `∇J(θ) = E[G · ∇ log π_θ(a
REINFORCE "O algoritmo original de PG" Williams (1992); retornos de Monte Carlo multiplicados pelo gradiente do logaritmo da política.
Truque da derivada do logaritmo "Estimador de função score" ∇P(τ;θ) = P(τ;θ) · ∇ log P(τ;θ); torna tratáveis os gradientes de expectativas.
Baseline "Redução de variância" Qualquer b(s) subtraído de G; não enviesado porque E[b · ∇ log π] = 0.
Reward-to-go "Apenas retornos futuros importam" G_t^{from t} em vez do G_0 completo; correto e com menor variância.
Bônus de entropia "Incentivar a exploração" O termo `+β · H(π(·
On-policy "Treinar no que acabou de ver" A expectativa do gradiente é em relação à política atual — não é possível reutilizar dados antigos diretamente.
Vantagem (Advantage) "Quão melhor que a média" A(s, a) = G(s, a) - V(s); a quantidade sinalizada pela qual o REINFORCE com baseline multiplica.

Leitura Adicional

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