Das Varianzproblem von REINFORCE löst sich elegant durch einen zweiten Schätzer: den Critic. Dieser Artikel motiviert die Baseline aus erster Hand, leitet die Advantage-Funktion her, zeigt den Datenfluss Actor ↔ Critic ↔ Environment als Mermaid-Diagramm und implementiert ein lauffähiges Tabular Actor-Critic auf der GridWorld-Mini-Welt.
1. Das Problem: REINFORCE-Gradienten zappeln
Artikel 02 endete mit einer offenen Rechnung: REINFORCE ist erwartungstreu, aber hochvariant. Konkret zeigt sich das so:
- Eine einzelne Episode mit zufälligem Reward von +10 verschiebt alle Gradienten dieser Episode stark.
- Eine andere Episode mit Reward −5 verschiebt sie genauso stark in die Gegenrichtung.
- Im Mittel ist die Richtung korrekt – aber die Stichprobenmittelung braucht tausende Episoden.
Die zentrale Frage: Kann man dem rohen Return $G_t$ einen Referenzwert abziehen, um die „Streuung um den Erwartungswert" wegzunehmen, ohne die Richtung zu verfälschen?
2. Der Baseline-Trick: mathematisch unverzerrt
Wir ziehen vom Return eine state-abhängige Baseline $b(s)$ ab:
$$\nabla_\theta J(\theta) = \mathbb{E}\left[\nabla_\theta \log \pi_\theta(a \mid s) \cdot (G_t - b(s))\right]$$
Der Erwartungswert ändert sich dadurch nicht, weil
$$\mathbb{E}{a \sim \pi}[\nabla\theta \log \pi(a \mid s) \cdot b(s)] = b(s) \cdot \nabla_\theta \underbrace{\sum_a \pi(a \mid s)}_{= 1} = 0.$$
Die Baseline darf alles sein, solange sie nicht von der Aktion abhängt. Die optimale Baseline (im Sinne minimaler Varianz) ist der erwartete Return ab $s$ – genau das, was wir als State-Value $V^\pi(s)$ in Artikel 01 definiert haben.
3. Vom Baseline-Trick zur Advantage
Setzen wir $b(s) = V^\pi(s)$, definieren wir die Advantage:
$$A^\pi(s, a) = Q^\pi(s, a) - V^\pi(s) \approx G_t - V^\pi(s)$$
In Worten: Wie viel besser war es, in $s$ die Aktion $a$ zu wählen, statt der mittleren Aktion unter $\pi$ zu folgen? Positive Advantage → Aktion verstärken. Negative Advantage → Aktion abschwächen. Die Lernlogik wird drastisch sauberer.
Quick-Check: Wozu dient die Baseline $V(s)$ im Policy-Gradient?
4. Actor-Critic: die natürliche Architektur
Wenn die Baseline gelernt werden soll, brauchen wir einen zweiten Schätzer – den Critic $V_\phi(s)$. Damit entstehen zwei Netze (oder zwei Köpfe auf einem geteilten Backbone), die parallel trainiert werden:
- Actor $\pi_\theta(a \mid s)$ – die Policy. Wird per Policy-Gradient mit der Advantage als Gewicht aktualisiert.
- Critic $V_\phi(s)$ – der Value-Schätzer. Wird per TD-Loss gegen $r + \gamma V_\phi(s')$ aktualisiert.
Der Critic schaut zu, was passiert, und schätzt, „wie gut" der Zustand im Schnitt ist. Der Actor nutzt diese Schätzung als Referenz, um seine eigenen Entscheidungen zu bewerten. Die beiden trainieren sich gegenseitig hoch – ähnlich wie ein Schachspieler mit einem Coach, der nicht selbst zieht, aber nach jedem Zug eine Note vergibt.
Quick-Check: Welche Rolle spielt der Critic in Actor-Critic?
5. TD-Bootstrapping: kürzere Returns, geringere Varianz
Ein zweiter Hebel zur Varianzreduktion neben der Baseline ist Bootstrapping. Statt den Return $G_t$ über eine ganze Episode zu summieren, ersetzen wir den Schwanz durch den Critic:
| Schätzer | Formel | Bias | Varianz |
|---|---|---|---|
| Monte-Carlo (REINFORCE) | $G_t = \sum_{k=0}^{T-t} \gamma^k r_{t+k}$ | 0 | hoch |
| TD(0) | $\hat{G}t = r_t + \gamma V\phi(s_{t+1})$ | hoch | niedrig |
| n-step | $r_t + \gamma r_{t+1} + \dots + \gamma^n V_\phi(s_{t+n})$ | mittel | mittel |
| GAE($\lambda$) | gewichtete Mischung aller n-step-Schätzer | tunbar | tunbar |
Generalized Advantage Estimation (GAE) ist heute Standard. Sie definiert:
$$\hat{A}t^{\text{GAE}(\lambda)} = \sum{l=0}^{\infty} (\gamma \lambda)^l \delta_{t+l}, \quad \delta_t = r_t + \gamma V_\phi(s_{t+1}) - V_\phi(s_t)$$
$\lambda = 0$ gibt reines TD(0), $\lambda = 1$ Monte-Carlo. In der Praxis ist $\lambda \in [0.9, 0.97]$ üblich – PPO verwendet GAE direkt.
6. Lauffähig: Tabular Actor-Critic auf GridWorld
import numpy as np
rng = np.random.default_rng(0)
LENGTH = 7
GAMMA = 0.95
LR_A, LR_C = 0.1, 0.1
EPISODES = 2000
theta = np.zeros((LENGTH, 2)) # Actor-Logits pro Zustand
V = np.zeros(LENGTH) # Critic-Tabelle
def softmax(x):
z = x - x.max(); e = np.exp(z); return e / e.sum()
def policy_probs(s): return softmax(theta[s])
def step(s, a):
s_next = max(0, min(LENGTH - 1, s + (1 if a == 1 else -1)))
done = s_next in (0, LENGTH - 1)
if done:
r = 1.0 if s_next == LENGTH - 1 else -1.0
else:
r = 0.0
return s_next, r, done
ep_returns = []
for ep in range(EPISODES):
s = LENGTH // 2
total = 0.0
for _ in range(50):
probs = policy_probs(s)
a = int(rng.choice(2, p=probs))
s_next, r, done = step(s, a)
total += r
# TD-Advantage statt Monte-Carlo-Return.
td_target = r + (0.0 if done else GAMMA * V[s_next])
advantage = td_target - V[s]
# Critic-Update (TD-Lernen).
V[s] += LR_C * advantage
# Actor-Update (Policy-Gradient mit Advantage als Gewicht).
grad_log = -probs.copy(); grad_log[a] += 1.0
theta[s] += LR_A * grad_log * advantage
s = s_next
if done:
break
ep_returns.append(total)
print(f"Mittlerer Return (erste 200) : {np.mean(ep_returns[:200]):+.3f}")
print(f"Mittlerer Return (letzte 200): {np.mean(ep_returns[-200:]):+.3f}")
print("Gelernte V(s):")
for s in range(LENGTH):
print(f" s={s}: V={V[s]:+.2f} P(rechts)={policy_probs(s)[1]:.2f}")
Im Vergleich zu reinem REINFORCE (Artikel 02) konvergiert dieser Actor-Critic spürbar schneller und stabiler – der Critic mittelt einen Großteil des Rauschens weg. Die gelernten $V$-Werte zeigen eine klare Rampe von links (negativ) nach rechts (positiv).
Quick-Check: Warum konvergiert Actor-Critic schneller als REINFORCE?
7. Bias-Varianz-Trade-off: das eigentliche Spiel
Der Wechsel von Monte-Carlo zu TD führt einen Bias ein – $V_\phi$ ist anfangs falsch, und das vergiftet die Advantage. Im Gegenzug sinkt die Varianz dramatisch. Dieser Trade-off ist der Kern fast aller modernen Verbesserungen:
- A2C/A3C – Synchroner/asynchroner Actor-Critic mit n-step.
- GAE – Interpolation zwischen MC und TD über $\lambda$.
- TRPO/PPO – Trust-Region oben drauf (siehe Artikel 04).
- SAC – Critic statt State-Value als $Q$-Funktion, Off-Policy mit Replay (siehe Artikel 05).
"Reinforcement learning is, fundamentally, the management of bias and variance." – Aufgabe des praktischen RL-Engineers.
8. Shared vs. Separate Networks
Eine wiederkehrende Designfrage: Sollten Actor und Critic Gewichte teilen?
| Variante | Pro | Contra |
|---|---|---|
| Shared Backbone | Effizienter, gemeinsame Repräsentation | Konkurrierende Loss-Signale, Gewichtung heikel |
| Separate Networks | Saubere Trennung, unabhängige Tuning | Mehr Parameter, mehr Speicher |
PPO benutzt meistens shared (mit zwei Köpfen), SAC fast immer separate Netze. Bei kleinen Zustandsräumen ist die Wahl nahezu egal – bei großen Vision-Inputs lohnt sich shared, weil die CNN-Features beiden helfen.
9. Abschluss-Quiz
Welche Aussage zu Actor-Critic ist korrekt?
Was beschreibt die Advantage $A(s, a)$?
Welcher Effekt hat ein zu kleines $\lambda$ in GAE?
Was bedeutet 'on-policy' im Kontext klassischer Actor-Critic-Methoden?
Welcher Vorteil ergibt sich aus einem geteilten Backbone für Actor und Critic?
10. Weiterführend
- Nächster Artikel: Proximal Policy Optimization (PPO) (Artikel 04 dieser Serie).
- Querverweis: self-learning-agents/02-rl-fuer-code-agenten.
- Knowledgebase:
masteringpytorch-secondedition.md– Kapitel zu Actor-Critic.
Quellen
- Sutton & Barto – Reinforcement Learning: An Introduction, 2nd ed., Kap. 13 (Policy Gradient Methods).
- Schulman, J. et al. (2015) – High-Dimensional Continuous Control Using Generalized Advantage Estimation.
- Mnih, V. et al. (2016) – Asynchronous Methods for Deep Reinforcement Learning (A3C-Paper).