Home Deep Rl Sac Ppo Artikel 3
Teil 3 Generative AI

Actor-Critic-Architektur

Bild: KI-generiert mit Beuys


Actor-Critic-Architektur

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:

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:

graph LR E[Environment] -->|s, r| C[Critic V_phi] E -->|s| A[Actor pi_theta] A -->|a| E C -->|A_t| A

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:

"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

Quellen

📄 Als PDF