Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Aprenentatge per reforç profund

Material d’ampliació: no forma part del recorregut principal d’aquest bloc. Cal haver llegit Aprenentatge per reforç i Xarxes neuronals.

Espais d’estats continus

Al rover de Mart l’estat era un número de l’1 al 6. La majoria de problemes reals no són així:

  • Si el rover es mou per una línia de 6 km, l’estat pot ser 2.7 km o 4.81 km: qualsevol valor real.
  • Un camió autònom necessita la posició (x, y), l’orientació (un angle) i les tres velocitats corresponents: un estat de 6 números.
  • Un helicòpter necessita la posició en tres dimensions, tres angles d’orientació i les seves sis velocitats: 12 números.

Quan l’estat és un vector de números reals, parlem d’un espai d’estats continu. Hi ha infinits estats possibles i ja no podem escriure la funció Q en una taula. La solució és aprendre-la amb una xarxa neuronal.

L’entorn Lunar Lander

Lunar Lander és una simulació clàssica per experimentar amb aprenentatge per reforç: has de fer aterrar un mòdul lunar suaument sobre una plataforma marcada amb dues banderes. Està disponible a la biblioteca Gymnasium, que ofereix entorns de simulació per a aprenentatge per reforç.

Estat: 8 números.

  • Posició (x, y) i velocitat (horitzontal i vertical)
  • Angle d’inclinació i velocitat angular
  • Dos valors 0 o 1 que diuen si cada pota toca a terra

Accions: 4 possibles a cada pas.

AccióQuè fa
0No fer res: la gravetat estira el mòdul cap avall
1Motor esquerre: empeny el mòdul cap a la dreta
2Motor principal: empeny el mòdul cap amunt
3Motor dret: empeny el mòdul cap a l’esquerra

Recompensa: està dissenyada per afavorir un bon aterratge.

  • Puja quan el mòdul s’acosta a la plataforma i quan va més a poc a poc; baixa quan s’allunya, accelera o s’inclina.
  • +10 per cada pota que toca a terra.
  • Un petit cost cada vegada que s’encén un motor: 0.3 el principal i 0.03 els laterals. Així aprèn a estalviar combustible.
  • Al final: +100 si aterra bé, -100 si s’estavella.

Es considera resolt quan un episodi suma almenys 200 punts. Amb un factor de descompte proper a 1 (per exemple, \(\gamma = 0.985\)), l’agent té en compte recompenses llunyanes, com la de l’aterratge.

Així s’interactua amb l’entorn. Cada volta del bucle és un quartet (estat, acció, recompensa, nou estat):

# pip install "gymnasium[box2d]"
import gymnasium as gym

env = gym.make("LunarLander-v3")
state, info = env.reset(seed=42)

total = 0
done = False
while not done:
    action = env.action_space.sample()  # de moment, una acció a l'atzar
    next_state, reward, terminated, truncated, info = env.step(action)
    total += reward
    state = next_state
    done = terminated or truncated      # ha aterrat, s'ha estavellat o s'ha acabat el temps

print(f"Recompensa total: {total:.1f}")  # amb accions a l'atzar, molt negativa
env.close()

Aprendre Q amb una xarxa neuronal

La idea del Deep Q-Network (DQN) és fer servir una xarxa neuronal per aproximar la funció Q.

La xarxa

  • Entrada: l’estat, 8 números.
  • Capes ocultes: per exemple, dues de 64 neurones amb ReLU.
  • Sortida: 4 neurones, una per acció. Cada una estima \(Q(s, a)\) per a aquella acció.

Una primera idea seria donar a la xarxa l’estat i l’acció (codificada en one-hot, 12 entrades en total) i fer-li retornar un sol valor. Però llavors caldrien quatre passades per decidir cada acció. Amb quatre sortides, una sola passada dona els quatre valors, i l’agent tria l’acció amb el més alt. És una regressió amb quatre sortides: la xarxa no prediu directament l’acció, sinó el valor de cada acció.

import torch.nn as nn

q_network = nn.Sequential(
    nn.Linear(8, 64), nn.ReLU(),
    nn.Linear(64, 64), nn.ReLU(),
    nn.Linear(64, 4),  # Q(s, a) per a cadascuna de les 4 accions
)

D’on surten les dades d’entrenament?

Per entrenar una xarxa necessitem parells d’entrada i sortida desitjada. Aquí no tenim cap dataset: els exemples surten de l’equació de Bellman.

  1. L’agent juga i guarda cada quartet \((s, a, R(s), s’)\).
  2. Per a cada quartet, l’objectiu és el costat dret de l’equació de Bellman, calculat amb la xarxa actual:

\[ y = R(s) + \gamma \max_{a’} Q(s’, a’) \]

  1. La xarxa s’entrena perquè la seva predicció \(Q(s, a)\) s’acosti a \(y\), amb l’error quadràtic com a pèrdua.

Al principi la xarxa té pesos a l’atzar i els objectius són dolents. Però cada recompensa real que observa l’agent hi aporta informació, i a poc a poc les estimacions milloren.

L’algoritme

  1. Inicialitza la xarxa amb pesos a l’atzar.
  2. Repeteix:
    • Juga al Lunar Lander i guarda els quartets en una memòria d’experiències (replay buffer), que només conserva els més recents (per exemple, els 10.000 últims).
    • Agafa a l’atzar un mini-lot de quartets de la memòria, calcula els seus objectius \(y\) i fa un pas d’entrenament.

Agafar els quartets a l’atzar, i no en l’ordre en què s’han jugat, evita que la xarxa aprengui només dels últims segons de joc, que són molt semblants entre ells.

Explorar o explotar

Mentre aprèn, quina acció ha de triar l’agent? Si sempre tria la que la xarxa creu millor, pot quedar-se encallat: si al principi la xarxa creu, per casualitat, que el motor principal sempre és dolent, no el provarà mai i mai descobrirà que de vegades és la millor opció.

La solució habitual és la política ε-greedy (èpsilon-greedy):

  • Amb probabilitat \(1 - \varepsilon\), tria l’acció amb la Q més alta (explotar el que ja sap).
  • Amb probabilitat \(\varepsilon\), tria una acció a l’atzar (explorar).

Explorar massa fa que trigui a obtenir bones recompenses; explotar massa aviat li pot impedir descobrir estratègies millors. És el compromís entre exploració i explotació. El truc habitual és començar amb \(\varepsilon = 1\) (tot a l’atzar) i anar-lo reduint fins a un valor petit, com 0.01.

Estabilitzar l’entrenament

Hi ha un problema: els objectius \(y\) es calculen amb la mateixa xarxa que estem entrenant. Cada pas d’entrenament canvia la xarxa, i per tant també canvia els objectius. És com intentar encertar una diana que es mou.

La solució és fer servir una segona còpia de la xarxa, la xarxa objectiu (target network), només per calcular els objectius \(y\). Aquesta còpia segueix la xarxa principal molt a poc a poc, amb una actualització suau (soft update):

\[ W_{\text{objectiu}} := \tau , W + (1 - \tau) , W_{\text{objectiu}} \]

  • W: els pesos de la xarxa que entrenem
  • W objectiu: els pesos de la còpia que calcula els objectius
  • τ (tau): un valor petit, per exemple 0.01

En paraules senzilles: a cada pas, la xarxa objectiu s’acosta només un 1% a la xarxa principal. Els objectius canvien lentament i l’entrenament és molt més estable.

Sensibilitat als hiperparàmetres

L’aprenentatge per reforç és molt més delicat que l’aprenentatge supervisat. En supervisat, una taxa d’aprenentatge mal triada pot fer que l’entrenament trigui tres vegades més. En reforç, un valor d’ε o de τ mal triat pot fer que trigui deu o cent vegades més, o que no aprengui mai. Per això és habitual partir de valors que ja han funcionat en problemes semblants.

Més enllà del DQN

El DQN aprèn la funció Q i en dedueix la política. Funciona bé quan hi ha poques accions possibles, com al Lunar Lander. Una altra família d’algoritmes, els mètodes de gradient de política (policy gradient), aprenen directament la política: una xarxa que, donat l’estat, retorna la probabilitat de cada acció. Són els habituals quan les accions són contínues, com la força exacta de cada motor d’un robot.

Un dels més utilitzats és PPO (proximal policy optimization), que també s’ha fet servir per ajustar LLMs amb RLHF. Per als models de raonament s’han popularitzat variants com GRPO, que comparen diverses respostes al mateix problema per decidir quines reforçar. En aquest cas, l’estat és el text que el model ha escrit fins ara, cada acció és el següent token, i la recompensa arriba al final, quan es comprova la resposta.

Referències

Last change: , commit: cc6333d