Reinforcement Learning 🇬🇧
Note a cura di Antonino Furnari - antonino.furnari@unict.it🔝
Università di Catania, Dipartimento di Matematica e Informatica
Note disponibili qui: http://www.antoninofurnari.github.iohttps://antoninofurnari.github.io/lecture-notes/it/data-science-python/reinforcement-learning/
In questo laboratorio vedremo alcuni esempi di algoritmi di reinforcement learning.
(Il materiale che segue è in parte ripreso da: https://spinningup.openai.com/en/latest/spinningup/rl_intro.html e da: https://pytorch.org/tutorials/intermediate/reinforcement_q_learning.html ).
I principali attori nel reinforcement learning sono l’agente e l’ambiente. L’ambiente è il mondo in cui l’agente vive e con cui interagisce. Ad ogni passo dell’interazione, l’agente vede un’osservazione (anche parziale) dello stato del mondo, e poi sceglie un’azione da intraprendere. L’ambiente cambia quando l’agente agisce su di esso, ma può anche cambiare da solo.
L’agente ottiene anche una reward dall’ambiente, cioè un numero che indica quanto sia buono o cattivo lo stato attuale del mondo. L’obiettivo dell’agente è massimizzare la sua ricompensa cumulativa, chiamata rendimento. I metodi di apprendimento per rinforzo sono modi in cui l’agente può apprendere i comportamenti per raggiungere il suo obiettivo.
Altri termini importanti da conoscere per il reinforcement learning sono:
- Stati: una descrizione completa dello stato dell’ambiente;
- Osservazioni: una osservazione (anche parziale) di uno stato;
- Policy: una regola usata dall’agente per intraprendere una azione in quando viene osservato un dato stato: $a_t = \pi (s_t)$;
- Ritorno: un valore che cumula le reward $r_t$ ottenute al tempo $t$ su un orizzonte finito o infinito.
L’obiettivo di un algoritmo di reinforcement learning è in genere quello di apprendere una policy che cerchi di massimizzare il ritorno $R_{t_0} = \sum_{t=t_0}^{\infty} \gamma^{t - t_0} r_t$. Il parametro di sconto, $\gamma$, è una costante tra $0$ e $1$ che permette di pesare maggiormente le reward ottenute più di recente rispetto a quelle ricevute più lontano nel passato.
1. Q-Learning e Deep Q-Learning
L’idea principale alla base del Q-learning è quella di modellare una funzione $Q^*: Stato \times Azioni \rightarrow \mathbb{R}$, in grado di prevedere il valore di return qualora dovessimo scegliere una data azione in un dato stato. Se avessimo questa funzione, potremmo facilmente costruire una policy che massimizzi il ritorno:
\begin{align}\pi^*(s) = \arg\max_a \ Q^*(s, a)\end{align}
Il deep Q-Learning, in particolare, segue l’approccio di approssimare $Q^*$ mediante una rete neurale.
Per apprendere $Q$, sfrutteremo il fatto che la funzione $Q$ obbedisce all’equazione di Bellman:
\begin{align}Q(s, a) = r + \gamma Q(s’, \pi(s’))\end{align}
Dove $s’$ è lo stato che si ottiene effettuando l’azione $a$ nello stato $s$.
La differenza tra i due lati dell’uguaglianza è nota come errore di differenza temporale (temporal difference error), $\delta$:
\begin{align}\delta = Q(s, a) - (r + \gamma \max_a Q(s’, a))\end{align}
In pratica, per evitare catastrophic forgetting (ovvero un fenomeno in cui il modello peggiora le proprie prestazioni su episodi vecchi man mano che apprende i nuovi), utilizzeremo una vecchia copia della rete che approssima $Q$ nel secondo membro dell’equazione precedente. La copia sarà aggiornata ogni $10$ episodi copiando i pesi della rete che apporssima $Q$ e verrà chiamata target network.
Minimizzare questo errore può essere visto come un problema di regressione risolvibile con una loss MSE $\mathcal{L}(\delta)$.
Calcoleremo l’errore su una serie di transizioni $B$ campionate mediante memory replay:
\begin{align}\mathcal{L} = \frac{1}{|B|}\sum_{(s, a, s’, r) \ \in \ B} \mathcal{L}(\delta)\end{align}
2. Cart Pole
Useremo come esempio per mostrare l’algoritmo di Deep Q-Learning, il task “CartPole”. In questo task, l’agente comanda un carrello con un palo attaccato su mediante un perno. Ad ogni timestep l’agente dovrà scegliere tra due azioni: spostare il carrello a sinistra o spostare il carrello a destra, in modo che il palo posizionato sul carrello stia fermo (si veda: https://pytorch.org/tutorials/intermediate/reinforcement_q_learning.html ).
Domanda 1 Considerando l’immagine sopra, il carrello dovrebbe spostarsi a destra o a sinistra? |
In questo task, la reward ottenuta è +1 per ogni timestep in cui il palo resta in piedi, mentre l’episodio termina se il palo cade troppo lontano o se il carrello si sposta di più di 2.4 unità lontano dal centro. Ciò significa che gli scenari con prestazioni migliori verranno eseguiti per una durata maggiore, accumulando una reward maggiore.
In questo task, le osservazioni è un vettore di valori reali che contiene dati quali l’accelerazione e la velocità.
Per simulare gli episodi, utilizzremo gym
(https://gym.openai.com/docs/), un toolkit pensato per l’allenamento di modelli di reinforcement learning. Possiamo installare gym
con tutte le dipendenze con il comando:
pip install gym[all]
Possiamo trovare informazioni su questo task al seguente link: https://github.com/openai/gym/wiki/CartPole-v0. Ispezioniamo in particolare le azioni disponibili:
Num | Action |
---|---|
0 | Push cart to the left |
1 | Push cart to the right |
E la struttura delle osservazioni:
Num | Observation | Min | Max |
---|---|---|---|
0 | Cart Position | -2.4 | 2.4 |
1 | Cart Velocity | -Inf | Inf |
2 | Pole Angle | ~ -0.418 rad (-24°) | ~ 0.418 rad (24°) |
3 | Pole Velocity At Tip | -Inf | Inf |
Domanda 2 Si considerino le osservazioni. In che modo sono utili ai fini dell’apprendimento della policy? |
2.1 Implementazione
Seguiremo l’implementazione disponibile qui (https://pytorch-lightning.readthedocs.io/en/latest/notebooks/lightning_examples/reinforce-learning-DQN.html) con qualche modifica.
Iniziamo con delle import:
|
|
Definiamo adesso la Deep Q-Network per approssimare Q. E’ un semplice MLP che prende in input le 4 osservazioni e restituisce due valori, uno per ogni azione.
|
|
Testiamo la rete:
|
|
torch.Size([1, 2])
Definiamo adesso una struttura per memorizzare le esperienze. Ogni esperienza è relativa a uno step di interazione di un episodio. L’esperienza per noi sarà una tupla composta da stato, azione, reward, un flag “done” che indica se dopo questa esperienza l’episodio è finito, e lo stato successivo.
|
|
Definiamo adesso un ReplayBuffer, che sarà sostanzialmente una coda di tuple Experience
nella quale è possibile inserire elementi e dalla quale è possibile campionare.
|
|
Costruiamo adesso un oggetto dataset per campionare dal replay buffer. Il dataset sarà di tipo IterableDataset
e quindi non avrà un numero preciso di elementi. Dato che il dataset contiene un riferimento al replay buffer, questo si aggiornerà automaticamente man mano che inseriamo esperienze nel buffer.
|
|
Definiamo ora una classe Agent
che ci permetterà di simulare le interazioni con l’ambiente. L’agente ingloberà l’ambiente stesso e conterà un riferimento al replay buffer.
|
|
Definiamo quindi il modulo di tipo LightningModule
per effettuare il training del modello:
|
|
Per poter visualizzare brevi video su tensorboard, installiamo moviepy
con:
pip install moviepy
Effettuiamo dunque il training:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
------------------------------------
0 | net | DQN | 898
1 | target_net | DQN | 898
------------------------------------
1.8 K Trainable params
0 Non-trainable params
1.8 K Total params
0.007 Total estimated model params size (MB)
Alla fine del training, su tensorboard vedremo dei grafici simili ai seguenti:
Domanda 3 Come mai l’andamento del numero di episodi non è perfettamente lineare rispetto all’andamento del numero di iterazioni? |
Domanda 4 Si commenti il grafico della total reward. Il modello sta apprendendo? |
Inoltre, cliccando su “images”, vedremo delle animazioni degli episodi mostrati durante il training:
Domanda 5 Si confrontino gli episodi visualizzati all’inizio del training con quelli visualizzati alla fine. Ci sono delle differenze? |
2.2 Valutazione
Per valutare le performance del modello, calcoliamo la total reward media per $100$ episodi:
|
|
167.43
Confrontiamo la reward media ottenuta con quella di una policy random. Per ottenerla specificheremo epsilon=1
:
|
|
23.6
3. Mountain Car
Vediamo adesso un secondo esempio con il task “Mountain Car”. In questo caso, l’agente comanda un carrello che deve scalare una montagna. Il motore del carrello non ha potenza sufficiente a scalare la montagna, quindi l’agente deve imparare ad andare in direzione opposta a quella del traguardo per “prendere la rincorsa”.
Dalla pagina del task (https://github.com/openai/gym/wiki/MountainCar-v0), vediamo che le osservazioni sono due:
Num | Observation | Min | Max |
---|---|---|---|
0 | position | -1.2 | 0.6 |
1 | velocity | -0.07 | 0.07 |
Mentre le azioni disponibili sono tre:
Num | Action |
---|---|
0 | push left |
1 | no push |
2 | push right |
L’agente riceve una reward pari a $-1$ per ogni time step, finché il carrello non raggiunge il traguardo, dopo di ché nessuna penalità viene data e l’episodio termine. Non c’è alcuna penalità per il fatto di scalare la collina sinistra, che una volta raggiunta si comporta come un muro.
Domanda 6 In che modo le reward definite favoriscono l’apprendimento di una policy funzionante? |
Possiamo affrontare il problema nuovamente con il Q-Learning, sfruttando lo stesso codice scritto per il problema del Cart Pole:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
------------------------------------
0 | net | DQN | 771
1 | target_net | DQN | 771
------------------------------------
1.5 K Trainable params
0 Non-trainable params
1.5 K Total params
0.006 Total estimated model params size (MB)
Alla fine del training, troveremo i seguenti log su tensorboard:
Su images, dovrebbero inoltre apparire gli episodi mostrati durante il training:
4. Acrobot
Vediamo un ulteriore task di esempio, Acrobot. In questo caso l’agente comanda un braccio robotico e ha lo scopo di portarlo al di sopra della linea orizzontale nera (si veda qui: https://www.analyticsvidhya.com/blog/2021/06/acrobot-with-deep-q-learning/):
L’agente ha a disposizione tre azioni:
- Applicare una torsione positiva;
- Applicare una torsione negativa;
- Non fare niente.
L’ambiente restituisce una reward negativa per ogni timestep, finché l’obiettivo o il numero massimo di step non vengono raggiunti.
Domanda 7 In che modo le reward definite favoriscono l’apprendimento di una policy funzionante? |
Anche in questo caso, utilizzeremo lo stesso codice visto per i task precedenti:
|
|
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0,1,2,3]
| Name | Type | Params
------------------------------------
0 | net | DQN | 1.3 K
1 | target_net | DQN | 1.3 K
------------------------------------
2.6 K Trainable params
0 Non-trainable params
2.6 K Total params
0.010 Total estimated model params size (MB)
Alla fine del training, troveremo i seguenti log su tensorboard:
Alla fine del training, su “images” troveremo degli esempi di episodi mostrati durante il training:
Esercizi
Esercizio 1 Si provi a ottimizzare l’architettura della rete che risolve il problema cartpole per migliorare le prestazioni dell’algoritmo. Si riesce far convergere l’algoritmo in un numero inferiore di episodi? |
Esercizio 2 Si ripeta l’esercizio precedente con il problema MountainCar. |
Esercizio 3 Si ripeta l’esercizio precedente con il problema Acrorobot. |
Esercizio 4 Si segua il tutorial disponibile a questo url (https://pytorch.org/tutorials/intermediate/mario_rl_tutorial.html) per implementare un agente di reinforcement learning capace di giocare a Super Mario. |
Esercizio 5 Si rifattorizzi il codice dell’esercizio precedente in modo da usare PyTorch Lightning e seguendo una struttura simile a quella vista in questo laboratorio. |
References
- Documentazione di PyTorch. http://pytorch.org/docs/stable/index.html
- Documentazione di PyTorch Lightning. https://www.pytorchlightning.ai/
- Documentazione di Gym. https://gym.openai.com/docs/
- Tutorial su deep Q-Learning e PyTorch. https://pytorch.org/tutorials/intermediate/reinforcement_q_learning.html
- Tutorial su deep Q-Learning e Lightning. https://pytorch-lightning.readthedocs.io/en/latest/notebooks/lightning_examples/reinforce-learning-DQN.html
- Tutorial su deep reinforcement learning e Super Mario. https://pytorch.org/tutorials/intermediate/mario_rl_tutorial.html
- Acrobot con Deep Q-Learning. https://www.analyticsvidhya.com/blog/2021/06/acrobot-with-deep-q-learning/