Italian translation - Chapter 8 completed

pull/309/head
Roberto Pauletto 3 years ago
parent d536c72830
commit e9ef76d75f

@ -0,0 +1,320 @@
# Introduzione a Reinforcement Learning e Q-Learning
![Riepilogo di reinforcement in machine learning in uno sketchnote](../../../sketchnotes/ml-reinforcement.png)
> Sketchnote di [Tomomi Imura](https://www.twitter.com/girlie_mac)
Il reinforcement learning (apprendimento per rinforzo) coinvolge tre concetti importanti: l'agente, alcuni stati e un insieme di azioni per stato. Eseguendo un'azione in uno stato specifico, l'agente riceve una ricompensa. Si immagini di nuovo il gioco per computer Super Mario. Si è Mario, ci si trova in un livello di gioco, in piedi accanto a un dirupo. Sopra a Mario c'è una moneta. L'essere Mario, in un livello di gioco, in una posizione specifica... questo è il proprio stato. Spostarsi di un passo a destra (un'azione) porterebbe Mario oltre il limite e questo darebbe un punteggio numerico basso. Tuttavia, premendo il pulsante di salto si farà segnare un punto e si rimarrà vivi. Questo è un risultato positivo e dovrebbe assegnare un punteggio numerico positivo.
Usando reinforcement learning e un simulatore (il gioco), si può imparare a giocare per massimizzare la ricompensa che consiste nel rimanere in vita e segnare più punti possibile.
[![Introduzione al Reinforcement Learning](https://img.youtube.com/vi/lDq_en8RNOo/0.jpg)](https://www.youtube.com/watch?v=lDq_en8RNOo)
> 🎥 Fare clic sull'immagine sopra per ascoltare Dmitry discutere sul reinforcement learning
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/45/)
## Prerequisiti e Configurazione
In questa lezione si sperimenterà del codice in Python. Si dovrebbe essere in grado di eseguire il codice di Jupyter Notebook da questa lezione, sul proprio computer o da qualche parte nel cloud.
Si può aprire [il notebook della lezione](notebook.ipynb) e seguire questa lezione per sviluppare.
> **Nota:** Se si sta aprendo questo codice dal cloud, occorre anche recuperare il file [`rlboard.py`](../rlboard.py) , che viene utilizzato nel codice del notebook. Aggiungerlo alla stessa directory del notebook.
## Introduzione
In questa lezione si esplorerà il mondo di **[Pierino e il lupo](https://it.wikipedia.org/wiki/Pierino_e_il_lupo)**, ispirato a una fiaba musicale di un compositore russo, [Sergei Prokofiev](https://it.wikipedia.org/wiki/Sergei_Prokofiev). Si userà **Reinforcement Learning** per permettere a Pierino di esplorare il suo ambiente, raccogliere gustose mele ed evitare di incontrare il lupo.
**Reinforcement Learning** (RL) è una tecnica di apprendimento che permette di apprendere un comportamento ottimale di un **agente** in un certo **ambiente** eseguendo molti esperimenti. Un agente in questo ambiente dovrebbe avere un **obiettivo**, definito da una **funzione di ricompensa**.
## Lambiente
Per semplicità, si considera il mondo di Pierino come una tavola di gioco quadrata di dimensioni `width` X `height`, (larghezza X altezza), in questo modo:
![L'ambiente di Pierino](../images/environment.png)
Ogni cella in questa tavola può essere:
* **terra**, sulla quale possono camminare Pierino e le altre creature.
* **acqua**, sulla quale ovviamente non è possibile camminare.
* un **albero** o un **prato**, un luogo dove riposarsi.
* una **mela**, che rappresenta qualcosa che Pierino sarebbe felice di trovare per nutrirsi.
* un **lupo**, che è pericoloso e dovrebbe essere evitato.
C'è un modulo Python separato, [`rlboard.py`](../rlboard.py), che contiene il codice per lavorare con questo ambiente. Poiché questo codice non è importante per comprendere i concetti esposti, si importerà il modulo e lo si utilizzerà per creare la tavola di gioco di esempio (blocco di codice 1):
```python
from rlboard import *
width, height = 8,8
m = Board(width,height)
m.randomize(seed=13)
m.plot()
```
Questo codice dovrebbe stampare un'immagine dell'ambiente simile a quella sopra.
## Azioni e policy
In questo esempio, l'obiettivo di Pierino sarebbe quello di trovare una mela, evitando il lupo e altri ostacoli. Per fare ciò, può essenzialmente camminare finché non trova una mela.
Pertanto, in qualsiasi posizione, può scegliere tra una delle seguenti azioni: su, giù, sinistra e destra.
Si definiranno queste azioni come un dizionario e si mapperanno su coppie di corrispondenti cambiamenti di coordinate. Ad esempio, lo spostamento a destra (`R`) corrisponderebbe a una coppia `(1,0)`. (blocco di codice 2):
```python
actions = { "U" : (0,-1), "D" : (0,1), "L" : (-1,0), "R" : (1,0) }
action_idx = { a : i for i,a in enumerate(actions.keys()) }
```
Per riassumere, la strategia e l'obiettivo di questo scenario sono i seguenti:
- **La strategia** del nostro agente (Pierino) è definita da una cosiddetta **policy**. Una policy è una funzione che restituisce l'azione ad ogni dato stato. In questo caso, lo stato del problema è rappresentato dalla tavola di gioco, inclusa la posizione attuale del giocatore.
- **L'obiettivo** del reinforcement learning è alla fine imparare una buona policy che consentirà di risolvere il problema in modo efficiente. Tuttavia, come linea di base, si considera la policy più semplice chiamata **random walk**.
## Random walk (passeggiata aleatoria)
Prima si risolve il problema implementando una strategia di random walk. Tramite random walk, si sceglierà casualmente l'azione successiva tra quelle consentite, fino a raggiungere la mela (blocco di codice 3).
1. Implementare random walk con il codice seguente:
```python
def random_policy(m):
return random.choice(list(actions))
def walk(m,policy,start_position=None):
n = 0 # numero di passi
# imposta posizione iniziale
if start_position:
m.human = start_position
else:
m.random_start()
while True:
if m.at() == Board.Cell.apple:
return n # successo!
if m.at() in [Board.Cell.wolf, Board.Cell.water]:
return -1 # mangiato dal lupo o annegato
while True:
a = actions[policy(m)]
new_pos = m.move_pos(m.human,a)
if m.is_valid(new_pos) and m.at(new_pos)!=Board.Cell.water:
m.move(a) # esegue la mossa effettiva
break
n+=1
walk(m,random_policy)
```
La chiamata a `walk` dovrebbe restituire la lunghezza del percorso corrispondente, che può variare da una esecuzione all'altra.
1. Eseguire l'esperimento di walk un certo numero di volte (100 ad esempio) e stampare le statistiche risultanti (blocco di codice 4):
```python
def print_statistics(policy):
s,w,n = 0,0,0
for _ in range(100):
z = walk(m,policy)
if z<0:
w+=1
else:
s += z
n += 1
print(f"Average path length = {s/n}, eaten by wolf: {w} times")
print_statistics(random_policy)
```
Notare che la lunghezza media di un percorso è di circa 30-40 passi, che è parecchio, dato che la distanza media dalla mela più vicina è di circa 5-6 passi.
Si può anche vedere come appare il movimento di Pierino durante la passeggiata aleatoria:
![La passeggiata aleatoria di Pierino](../images/random_walk.gif)
## Funzione di ricompensa
Per rendere la policy più intelligente, occorre capire quali mosse sono "migliori" di altre. Per fare questo, si deve definire l'obiettivo.
L'obiettivo può essere definito in termini di una **funzione di ricompensa**, che restituirà un valore di punteggio per ogni stato. Più alto è il numero, migliore è la funzione di ricompensa. (blocco di codice 5)
```python
move_reward = -0.1
goal_reward = 10
end_reward = -10
def reward(m,pos=None):
pos = pos or m.human
if not m.is_valid(pos):
return end_reward
x = m.at(pos)
if x==Board.Cell.water or x == Board.Cell.wolf:
return end_reward
if x==Board.Cell.apple:
return goal_reward
return move_reward
```
Una cosa interessante delle funzioni di ricompensa è che nella maggior parte dei casi viene *data una ricompensa sostanziale solo alla fine del gioco*. Ciò significa che l'algoritmo dovrebbe in qualche modo ricordare i passaggi "buoni" che portano a una ricompensa positiva alla fine e aumentare la loro importanza. Allo stesso modo, tutte le mosse che portano a cattivi risultati dovrebbero essere scoraggiate.
## Q-Learning
Un algoritmo che verrà trattato qui si chiama **Q-Learning**. In questo algoritmo, la policy è definita da una funzione (o una struttura dati) chiamata **Q-Table**. Registra la "bontà" di ciascuna delle azioni in un dato stato.
Viene chiamata Q-Table perché spesso è conveniente rappresentarla come una tabella o un array multidimensionale. Poiché la tavola di gioco ha dimensioni `width` x `height`, si può rappresentare la tabella Q usando un array numpy con forma `width` x `height` x `len(actions)`: (blocco di codice 6)
```python
Q = np.ones((width,height,len(actions)),dtype=np.float)*1.0/len(actions)
```
Notare che si inizializzano tutti i valori della Q-Table con un valore uguale, in questo caso - 0.25. Ciò corrisponde alla policy di "random walk", perché tutte le mosse in ogni stato sono ugualmente buone. Si può passare la Q-Table alla funzione `plot` per visualizzare la tabella sulla tavola di gioco: `m.plot (Q)`.
![L'ambiente di Pierino](../images/env_init.png)
Al centro di ogni cella è presente una "freccia" che indica la direzione di spostamento preferita. Poiché tutte le direzioni sono uguali, viene visualizzato un punto.
Ora si deve eseguire la simulazione, esplorare l'ambiente e apprendere una migliore distribuzione dei valori della Q-Table, che consentirà di trovare il percorso verso la mela molto più velocemente.
## Essenza di Q-Learning: Equazione di Bellman
Una volta che si inizia il movimento, ogni azione avrà una ricompensa corrispondente, vale a dire che si può teoricamente selezionare l'azione successiva in base alla ricompensa immediata più alta. Tuttavia, nella maggior parte degli stati, la mossa non raggiungerà l'obiettivo di raggiungere la mela, e quindi non è possibile decidere immediatamente quale direzione sia migliore.
> Si ricordi che non è il risultato immediato che conta, ma piuttosto il risultato finale, che sarà ottenuto alla fine della simulazione.
Per tenere conto di questa ricompensa ritardata, occorre utilizzare i principi della **[programmazione dinamica](https://it.wikipedia.org/wiki/Programmazione_dinamica)**, che consentono di pensare al problema in modo ricorsivo.
Si supponga di essere ora nello stato *s*, e di voler passare allo stato *s* successivo. In tal modo, si riceverà la ricompensa immediata *r(s,a)*, definita dalla funzione di ricompensa, più qualche ricompensa futura. Se si suppone che la Q-Table rifletta correttamente l'"attrattiva" di ogni azione, allora allo stato *s'* si sceglierà *un'azione a* che corrisponde al valore massimo di *Q(s',a')*. Pertanto, la migliore ricompensa futura possibile che si potrebbe ottenere allo stato *s* sarà definita come `max`<sub>a'</sub>*Q(s',a')* (il massimo qui è calcolato su tutte le possibili azioni *a'* allo stato *s'*).
Questo dà la **formula** di Bellman per calcolare il valore della Q-Table allo stato *s*, data l'azione *a*:
<img src="../images/bellmaneq.gif"/>
Qui y è il cosiddetto **fattore di sconto** che determina fino a che punto si dovrebbe preferire il premio attuale a quello futuro e viceversa.
## Algoritmo di Apprendimento
Data l'equazione di cui sopra, ora si può scrivere pseudo-codice per l'algoritmo di apprendimento:
* Inizializzare Q-Table Q con numeri uguali per tutti gli stati e le azioni
* Impostare la velocità di apprendimento α ← 1
* Ripetere la simulazione molte volte
1. Iniziare in una posizione casuale
1. Ripetere
1. Selezionare un'azione *a* nello stato *s*
2. Eseguire l'azione trasferendosi in un nuovo stato *s'*
3. Se si incontra una condizione di fine gioco o la ricompensa totale è troppo piccola, uscire dalla simulazione
4. Calcolare la ricompensa *r* nel nuovo stato
5. Aggiornare Q-Function secondo l'equazione di Bellman: *Q(s,a)* ← *(1-α)Q(s,a)+α(r+γ max<sub>a'</sub>Q(s',a'))*
6. *s* ← *s'*
7. Aggiornare la ricompensa totale e diminuire α.
## Sfruttamento contro esplorazione
Nell'algoritmo sopra, non è stato specificato come esattamente si dovrebbe scegliere un'azione al passaggio 2.1. Se si sceglie l'azione in modo casuale, si **esplorerà** casualmente l'ambiente e molto probabilmente si morirà spesso e si esploreranno aree in cui normalmente non si andrebbe. Un approccio alternativo sarebbe **sfruttare** i valori della Q-Table già noti, e quindi scegliere l'azione migliore (con un valore Q-Table più alto) allo stato *s*. Questo, tuttavia, impedirà di esplorare altri stati ed è probabile che non si potrebbe trovare la soluzione ottimale.
Pertanto, l'approccio migliore è trovare un equilibrio tra esplorazione e sfruttamento. Questo può essere fatto scegliendo l'azione allo stato *s* con probabilità proporzionali ai valori nella Q-Table. All'inizio, quando i valori della Q-Table sono tutti uguali, corrisponderebbe a una selezione casuale, ma man mano che si impara di più sull'ambiente, si sarà più propensi a seguire il percorso ottimale consentendo all'agente di scegliere il percorso inesplorato una volta ogni tanto.
## Implementazione Python
Ora si è pronti per implementare l'algoritmo di apprendimento. Prima di farlo, serve anche una funzione che converta i numeri arbitrari nella Q-Table in un vettore di probabilità per le azioni corrispondenti.
1. Creare una funzione `probs()`:
```python
def probs(v,eps=1e-4):
v = v-v.min()+eps
v = v/v.sum()
return v
```
Aggiungere alcuni `eps` al vettore originale per evitare la divisione per 0 nel caso iniziale, quando tutte le componenti del vettore sono identiche.
Esegure l'algoritmo di apprendimento attraverso 5000 esperimenti, chiamati anche **epoche**: (blocco di codice 8)
```python
for epoch in range(5000):
# Sceglie il punto iniziale
m.random_start()
# Inizia a viaggiare
n=0
cum_reward = 0
while True:
x,y = m.human
v = probs(Q[x,y])
a = random.choices(list(actions),weights=v)[0]
dpos = actions[a]
m.move(dpos,check_correctness=False) # si consente al giocatore di spostarsi oltre la tavola di gioco, il che fa terminare l'episodioepisode
r = reward(m)
cum_reward += r
if r==end_reward or cum_reward < -1000:
lpath.append(n)
break
alpha = np.exp(-n / 10e5)
gamma = 0.5
ai = action_idx[a]
Q[x,y,ai] = (1 - alpha) * Q[x,y,ai] + alpha * (r + gamma * Q[x+dpos[0], y+dpos[1]].max())
n+=1
```
Dopo aver eseguito questo algoritmo, la Q-Table dovrebbe essere aggiornata con valori che definiscono l'attrattiva delle diverse azioni in ogni fase. Si può provare a visualizzare la Q-Table tracciando un vettore in ogni cella che punti nella direzione di movimento desiderata. Per semplicità, si disegna un piccolo cerchio invece di una punta di freccia.
<img src="../images/learned.png"/>
## Controllo della policy
Poiché la Q-Table elenca l'"attrattiva" di ogni azione in ogni stato, è abbastanza facile usarla per definire la navigazione efficiente in questo mondo. Nel caso più semplice, si può selezionare l'azione corrispondente al valore Q-Table più alto: (blocco di codice 9)
```python
def qpolicy_strict(m):
x,y = m.human
v = probs(Q[x,y])
a = list(actions)[np.argmax(v)]
return a
walk(m,qpolicy_strict)
```
> Se si prova più volte il codice sopra, si potrebbe notare che a volte "si blocca" e occorre premere il pulsante STOP nel notebook per interromperlo. Ciò accade perché potrebbero esserci situazioni in cui due stati "puntano" l'uno all'altro in termini di Q-Value ottimale, nel qual caso gli agenti finiscono per spostarsi tra quegli stati indefinitamente.
## 🚀 Sfida
> **Attività 1:** modificare la funzione `walk` per limitare la lunghezza massima del percorso di un certo numero di passaggi (ad esempio 100) e osservare il codice sopra restituire questo valore di volta in volta.
> **Attività 2:** Modificare la funzione di `walk` in modo che non torni nei luoghi in cui è già stata in precedenza. Ciò impedirà la ricorsione di `walk`, tuttavia, l'agente può comunque finire per essere "intrappolato" in una posizione da cui non è in grado di fuggire.
## Navigazione
Una policy di navigazione migliore sarebbe quella usata durante l'addestramento, che combina sfruttamento ed esplorazione. In questa policy, si selezionerà ogni azione con una certa probabilità, proporzionale ai valori nella Q-Table. Questa strategia può comunque portare l'agente a tornare in una posizione già esplorata, ma, come si può vedere dal codice sottostante, risulta in un percorso medio molto breve verso la posizione desiderata (ricordare che `print_statistics` esegue la simulazione 100 volte ): (blocco di codice 10)
```python
def qpolicy(m):
x,y = m.human
v = probs(Q[x,y])
a = random.choices(list(actions),weights=v)[0]
return a
print_statistics(qpolicy)
```
Dopo aver eseguito questo codice, si dovrebbe ottenere una lunghezza media del percorso molto più piccola rispetto a prima, nell'intervallo 3-6.
## Indagare il processo di apprendimento
Come accennato, il processo di apprendimento è un equilibrio tra esplorazione e sfruttamento delle conoscenze acquisite sulla struttura del problema spazio. Si è visto che i risultati dell'apprendimento (la capacità di aiutare un agente a trovare un percorso breve verso l'obiettivo) sono migliorati, ma è anche interessante osservare come si comporta la lunghezza media del percorso durante il processo di apprendimento:
<img src="../images/lpathlen1.png"/>
Gli apprendimenti possono essere riassunti come:
- **La lunghezza media del percorso aumenta**. Quello che si vede qui è che all'inizio la lunghezza media del percorso aumenta. Ciò è probabilmente dovuto al fatto che quando non si sa nulla dell'ambiente, è probabile rimanere intrappolati in cattive condizioni, acqua o lupo. Man mano che si impara di più e si inizia a utilizzare questa conoscenza, è possibile esplorare l'ambiente più a lungo, ma non si conosce ancora molto bene dove si trovano le mele.
- **La lunghezza del percorso diminuisce, man mano che si impara di più**. Una volta imparato abbastanza, diventa più facile per l'agente raggiungere l'obiettivo e la lunghezza del percorso inizia a diminuire. Tuttavia, si è ancora aperti all'esplorazione, quindi spesso ci si allontana dal percorso migliore e si esplorano nuove opzioni, rendendo il percorso più lungo che ottimale.
- **La lunghezza aumenta bruscamente**. Quello che si osserva anche su questo grafico è che ad un certo punto la lunghezza è aumentata bruscamente. Questo indica la natura stocastica del processo e che a un certo punto si possono "rovinare" i coefficienti della Q-Table sovrascrivendoli con nuovi valori. Idealmente, questo dovrebbe essere ridotto al minimo diminuendo il tasso di apprendimento (ad esempio, verso la fine dell'allenamento, si regolano i valori di Q-Table solo di un piccolo valore).
Nel complesso, è importante ricordare che il successo e la qualità del processo di apprendimento dipendono in modo significativo da parametri come il tasso di apprendimento, il decadimento del tasso di apprendimento e il fattore di sconto. Questi sono spesso chiamati **iperparametri**, per distinguerli dai **parametri**, che si ottimizzano durante l'allenamento (ad esempio, i coefficienti della Q-Table). Il processo per trovare i valori migliori degli iperparametri è chiamato **ottimizzazione degli iperparametri** e merita un argomento a parte.
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/46/)
## Incarico: [Un mondo più realistico](assignment.it.md)

@ -0,0 +1,27 @@
# Un mondo più realistico
Nella situazione citata, Pierino riusciva a muoversi quasi senza stancarsi o avere fame. In un mondo più realistico, ci si deve sedere e riposare di tanto in tanto, e anche nutrirsi. Si rende questo mondo più realistico, implementando le seguenti regole:
1. Spostandosi da un luogo all'altro, Pierino perde **energia** e accumula un po' di **fatica**.
2. Pierino può guadagnare più energia mangiando mele.
3. Pierino può recuperare energie riposando sotto l'albero o sull'erba (cioè camminando in una posizione nella tabola di gioco con un un albero o un prato - campo verde)
4. Pierino ha bisogno di trovare e uccidere il lupo
5. Per uccidere il lupo, Pierino deve avere determinati livelli di energia e fatica, altrimenti perde la battaglia.
## Istruzioni
Usare il notebook originale [notebook.ipynb](../notebook.ipynb) come punto di partenza per la propria soluzione.
Modificare la funzione di ricompensa in base alle regole del gioco, eseguire l'algoritmo di reinforcement learning per apprendere la migliore strategia per vincere la partita e confrontare i risultati della passeggiata aleatoria con il proprio algoritmo in termini di numero di partite vinte e perse.
> **Nota**: in questo nuovo mondo, lo stato è più complesso e oltre alla posizione umana include anche la fatica e i livelli di energia. Si può scegliere di rappresentare lo stato come una tupla (Board,energy,fatigue) - (Tavola, Energia, Fatica), o definire una classe per lo stato (si potrebbe anche volerla derivare da `Board`), o anche modificare la classe `Board` originale all'interno di [rlboard.py](../rlboard.py).
Nella propria soluzione, mantenere il codice responsabile della strategia di passeggiata aleatoria e confrontare i risultati del proprio algoritmo con la passeggiata aleatoria alla fine.
> **Nota**: potrebbe essere necessario regolare gli iperparametri per farlo funzionare, in particolare il numero di epoche. Poiché il successo del gioco (lotta contro il lupo) è un evento raro, ci si può aspettare un tempo di allenamento molto più lungo.
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| | Viene presentato un notebook con la definizione delle nuove regole del mondo, l'algoritmo di Q-Learning e alcune spiegazioni testuali. Q-Learning è in grado di migliorare significativamente i risultati rispetto a random walk. | Viene presentato il notebook, viene implementato Q-Learning e migliora i risultati rispetto a random walk, ma non in modo significativo; o il notebook è scarsamente documentato e il codice non è ben strutturato | Vengono fatti alcuni tentativi di ridefinire le regole del mondo, ma l'algoritmo Q-Learning non funziona o la funzione di ricompensa non è completamente definita |

@ -0,0 +1,340 @@
# CartPole Skating
Il problema risolto nella lezione precedente potrebbe sembrare un problema giocattolo, non propriamente applicabile a scenari di vita reale. Questo non è il caso, perché anche molti problemi del mondo reale condividono questo scenario, incluso Scacchi o Go. Sono simili, perché anche in quei casi si ha una tavolo di gioco con regole date e uno **stato discreto**.
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/47/)
## Introduzione
In questa lezione si applicheranno gli stessi principi di Q-Learning ad un problema con **stato continuo**, cioè uno stato dato da uno o più numeri reali. Ci si occuperà del seguente problema:
> **Problema**: se Pierino vuole scappare dal lupo, deve essere in grado di muoversi più velocemente. Si vedrà come Pierino può imparare a pattinare, in particolare, a mantenere l'equilibrio, utilizzando Q-Learning.
![La grande fuga!](../images/escape.png)
> Pierino e i suoi amici diventano creativi per sfuggire al lupo! Immagine di [Jen Looper](https://twitter.com/jenlooper)
Si userà una versione semplificata del bilanciamento noto come **problema** CartPole. Nel mondo cartpole, c'è un cursore orizzontale che può spostarsi a sinistra o a destra, e l'obiettivo è bilanciare un palo verticale sopra il cursore.
<img alt="un cartpole" src="../images/cartpole.png" width="200"/>
## Prerequisiti
In questa lezione si utilizzerà una libreria chiamata **OpenAI Gym per** simulare **ambienti** diversi. Si può eseguire il codice di questa lezione localmente (es. da Visual Studio Code), nel qual caso la simulazione si aprirà in una nuova finestra. Quando si esegue il codice online, potrebbe essere necessario apportare alcune modifiche, come descritto [qui](https://towardsdatascience.com/rendering-openai-gym-envs-on-binder-and-google-colab-536f99391cc7).
## OpenAI Gym
Nella lezione precedente, le regole del gioco e lo stato sono state date dalla classe `Board` sviluppata nel codice. Qui si utilizzerà uno speciale **ambiente di simulazione**, che simulerà la fisica dietro il palo di bilanciamento. Uno degli ambienti di simulazione più popolari per addestrare gli algoritmi di reinforcement learning è chiamato a [Gym](https://gym.openai.com/), mantenuto da [OpenAI](https://openai.com/). Con questo gym è possibile creare **ambienti** diversi da una simulazione cartpole a giochi Atari.
> **Nota**: si possono vedere altri ambienti disponibili da OpenAI Gym [qui](https://gym.openai.com/envs/#classic_control).
Innanzitutto, si installa gym e si importano le librerie richieste (blocco di codice 1):
```python
import sys
!{sys.executable} -m pip install gym
import gym
import matplotlib.pyplot as plt
import numpy as np
import random
```
## Esercizio: inizializzare un ambiente cartpole
Per lavorare con un problema di bilanciamento del cartpole, è necessario inizializzare l'ambiente corrispondente. Ad ogni ambiente è associato uno:
- **Spazio di osservazione** che definisce la struttura delle informazioni ricevute dall'ambiente. Per il problema del cartpole, si riceve la posizione del palo, la velocità e alcuni altri valori.
- **Spazio di azione** che definisce le possibili azioni. In questo caso lo spazio delle azioni è discreto e consiste di due azioni: **sinistra** e **destra**. (blocco di codice 2)
1. Per inizializzare, digitare il seguente codice:
```python
env = gym.make("CartPole-v1")
print(env.action_space)
print(env.observation_space)
print(env.action_space.sample())
```
Per vedere come funziona l'ambiente, si esegue una breve simulazione di 100 passaggi. Ad ogni passaggio, si fornisce una delle azioni da intraprendere: in questa simulazione si seleziona casualmente un'azione da `action_space`.
1. Eseguire il codice qui sotto e guardare a cosa porta.
✅ Ricordare che è preferibile eseguire questo codice sull'installazione locale di Python! (blocco di codice 3)
```python
env.reset()
for i in range(100):
env.render()
env.step(env.action_space.sample())
env.close()
```
Si dovrebbe vedere qualcosa di simile a questa immagine:
![carrello non in equilibrio](../images/cartpole-nobalance.gif)
1. Durante la simulazione, sono necessarie osservazioni per decidere come agire. Infatti, la funzione step restituisce le osservazioni correnti, una funzione di ricompensa e il flag done che indica se ha senso continuare o meno la simulazione: (blocco di codice 4)
```python
env.reset()
done = False
while not done:
env.render()
obs, rew, done, info = env.step(env.action_space.sample())
print(f"{obs} -> {rew}")
env.close()
```
Si finirà per vedere qualcosa di simile nell'output del notebook:
```text
[ 0.03403272 -0.24301182 0.02669811 0.2895829 ] -> 1.0
[ 0.02917248 -0.04828055 0.03248977 0.00543839] -> 1.0
[ 0.02820687 0.14636075 0.03259854 -0.27681916] -> 1.0
[ 0.03113408 0.34100283 0.02706215 -0.55904489] -> 1.0
[ 0.03795414 0.53573468 0.01588125 -0.84308041] -> 1.0
...
[ 0.17299878 0.15868546 -0.20754175 -0.55975453] -> 1.0
[ 0.17617249 0.35602306 -0.21873684 -0.90998894] -> 1.0
```
Il vettore di osservazione restituito ad ogni passo della simulazione contiene i seguenti valori:
- Posizione del carrello
- Velocità del carrello
- Angolo del palo
- Tasso di rotazione del palo
1. Ottenere il valore minimo e massimo di quei numeri: (blocco di codice 5)
```python
print(env.observation_space.low)
print(env.observation_space.high)
```
Si potrebbe anche notare che il valore della ricompensa in ogni fase della simulazione è sempre 1. Questo perché l'obiettivo è sopravvivere il più a lungo possibile, ovvero mantenere il palo in una posizione ragionevolmente verticale per il periodo di tempo più lungo.
✅ Infatti la simulazione CartPole si considera risolta se si riesce a ottenere la ricompensa media di 195 su 100 prove consecutive.
## Discretizzazione dello stato
In Q-Learning, occorre costruire una Q-Table che definisce cosa fare in ogni stato. Per poterlo fare, è necessario che lo stato sia **discreto**, più precisamente, dovrebbe contenere un numero finito di valori discreti. Quindi, serve un qualche modo per **discretizzare** le osservazioni, mappandole su un insieme finito di stati.
Ci sono alcuni modi in cui si può fare:
- **Dividere in contenitori**. Se è noto l'intervallo di un certo valore, si può dividere questo intervallo in un numero di **bin** (contenitori) e quindi sostituire il valore con il numero di contenitore a cui appartiene. Questo può essere fatto usando il metodo di numpy [`digitize`](https://numpy.org/doc/stable/reference/generated/numpy.digitize.html). In questo caso, si conoscerà con precisione la dimensione dello stato, perché dipenderà dal numero di contenitori selezionati per la digitalizzazione.
✅ Si può usare l'interpolazione lineare per portare i valori a qualche intervallo finito (ad esempio, da -20 a 20), e poi convertire i numeri in interi arrotondandoli. Questo dà un po' meno controllo sulla dimensione dello stato, specialmente se non sono noti gli intervalli esatti dei valori di input. Ad esempio, in questo caso 2 valori su 4 non hanno limiti superiore/inferiore sui loro valori, il che può comportare un numero infinito di stati.
In questo esempio, si andrà con il secondo approccio. Come si potrà notare in seguito, nonostante i limiti superiore/inferiore non definiti, quei valori raramente assumono valori al di fuori di determinati intervalli finiti, quindi quegli stati con valori estremi saranno molto rari.
1. Ecco la funzione che prenderà l'osservazione dal modello e produrrà una tupla di 4 valori interi: (blocco di codice 6)
```python
def discretize(x):
return tuple((x/np.array([0.25, 0.25, 0.01, 0.1])).astype(np.int))
```
1. Si esplora anche un altro metodo di discretizzazione utilizzando i contenitori: (blocco di codice 7)
```python
def create_bins(i,num):
return np.arange(num+1)*(i[1]-i[0])/num+i[0]
print("Sample bins for interval (-5,5) with 10 bins\n",create_bins((-5,5),10))
ints = [(-5,5),(-2,2),(-0.5,0.5),(-2,2)] # Intervallo di valori per ogni parametro
nbins = [20,20,10,10] # numero di contenitori per ogni parametro
bins = [create_bins(ints[i],nbins[i]) for i in range(4)]
def discretize_bins(x):
return tuple(np.digitize(x[i],bins[i]) for i in range(4))
```
1. Si esegue ora una breve simulazione e si osservano quei valori discreti dell'ambiente. Si può provare `discretize` e `discretize_bins` e vedere se c'è una differenza.
✅ discretize_bins restituisce il numero del contenitore, che è in base 0. Quindi per i valori della variabile di input intorno a 0 restituisce il numero dalla metà dell'intervallo (10). In discretize, non interessava l'intervallo dei valori di uscita, consentendo loro di essere negativi, quindi i valori di stato non vengono spostati e 0 corrisponde a 0. (blocco di codice 8)
```python
env.reset()
done = False
while not done:
#env.render()
obs, rew, done, info = env.step(env.action_space.sample())
#print(discretize_bins(obs))
print(discretize(obs))
env.close()
```
✅ Decommentare la riga che inizia con env.render se si vuole vedere come viene eseguito l'ambiente. Altrimenti si può eseguirlo in background, che è più veloce. Si userà questa esecuzione "invisibile" durante il processo di Q-Learning.
## La struttura di Q-Table
Nella lezione precedente, lo stato era una semplice coppia di numeri da 0 a 8, e quindi era conveniente rappresentare Q-Table con un tensore numpy con una forma di 8x8x2. Se si usa la discretizzazione dei contenitori, è nota anche la dimensione del vettore di stato, quindi si può usare lo stesso approccio e rappresentare lo stato con un array di forma 20x20x10x10x2 (qui 2 è la dimensione dello spazio delle azioni e le prime dimensioni corrispondono al numero di contenitori che si è scelto di utilizzare per ciascuno dei parametri nello spazio di osservazione).
Tuttavia, a volte non sono note dimensioni precise dello spazio di osservazione. Nel caso della funzione `discretize`, si potrebbe non essere mai sicuri che lo stato rimanga entro certi limiti, perché alcuni dei valori originali non sono vincolati. Pertanto, si utilizzerà un approccio leggermente diverso e si rappresenterà Q-Table con un dizionario.
1. Si usa la coppia *(state, action)* come chiave del dizionario e il valore corrisponderà al valore della voce Q-Table. (blocco di codice 9)
```python
Q = {}
actions = (0,1)
def qvalues(state):
return [Q.get((state,a),0) for a in actions]
```
Qui si definisce anche una funzione `qvalues()`, che restituisce un elenco di valori di Q-Table per un dato stato che corrisponde a tutte le azioni possibili. Se la voce non è presente nella Q-Table, si restituirà 0 come predefinito.
## Far partire Q-Learning
Ora si è pronti per insegnare a Pierino a bilanciare!
1. Per prima cosa, si impostano alcuni iperparametri: (blocco di codice 10)
```python
# iperparametri
alpha = 0.3
gamma = 0.9
epsilon = 0.90
```
Qui, `alfa` è il **tasso di apprendimento** che definisce fino a che punto si dovranno regolare i valori correnti di Q-Table ad ogni passaggio. Nella lezione precedente si è iniziato con 1, quindi si è ridotto `alfa` per abbassare i valori durante l'allenamento. In questo esempio lo si manterrà costante solo per semplicità e si potrà sperimentare con la regolazione dei valori `alfa` in un secondo momento.
`gamma` è il **fattore di sconto** che mostra fino a che punto si dovrà dare la priorità alla ricompensa futura rispetto alla ricompensa attuale.
`epsilon` è il **fattore di esplorazione/sfruttamento** che determina se preferire l'esplorazione allo sfruttamento o viceversa. In questo algoritmo, nella percentuale `epsilon` dei casi si selezionerà l'azione successiva in base ai valori della Q-Table e nel restante numero di casi verrà eseguita un'azione casuale. Questo permetterà di esplorare aree dello spazio di ricerca che non sono mai state viste prima.
✅ In termini di bilanciamento - la scelta di un'azione casuale (esplorazione) agirebbe come un pugno casuale nella direzione sbagliata e il palo dovrebbe imparare a recuperare l'equilibrio da quegli "errori"
### Migliorare l'algoritmo
E' possibile anche apportare due miglioramenti all'algoritmo rispetto alla lezione precedente:
- **Calcolare la ricompensa cumulativa media**, su una serie di simulazioni. Si stamperanno i progressi ogni 5000 iterazioni e si farà la media della ricompensa cumulativa in quel periodo di tempo. Significa che se si ottengono più di 195 punti, si può considerare il problema risolto, con una qualità ancora superiore a quella richiesta.
- **Calcolare il risultato cumulativo medio massimo**, `Qmax`, e si memorizzerà la Q-Table corrispondente a quel risultato. Quando si esegue l'allenamento si noterà che a volte il risultato cumulativo medio inizia a diminuire e si vuole mantenere i valori di Q-Table che corrispondono al miglior modello osservato durante l'allenamento.
1. Raccogliere tutte le ricompense cumulative ad ogni simulazione nel vettore `rewards` per ulteriori grafici. (blocco di codice 11)
```python
def probs(v,eps=1e-4):
v = v-v.min()+eps
v = v/v.sum()
return v
Qmax = 0
cum_rewards = []
rewards = []
for epoch in range(100000):
obs = env.reset()
done = False
cum_reward=0
# == esegue la simulazione ==
while not done:
s = discretize(obs)
if random.random()<epsilon:
# sfruttamento - sceglie l'azione in accordo alle probabilità di Q-Table
v = probs(np.array(qvalues(s)))
a = random.choices(actions,weights=v)[0]
else:
# esplorazione - sceglie causalmente l'azione
a = np.random.randint(env.action_space.n)
obs, rew, done, info = env.step(a)
cum_reward+=rew
ns = discretize(obs)
Q[(s,a)] = (1 - alpha) * Q.get((s,a),0) + alpha * (rew + gamma * max(qvalues(ns)))
cum_rewards.append(cum_reward)
rewards.append(cum_reward)
# == Stampa periodicamente i risultati a calcola la ricompensa media ==
if epoch%5000==0:
print(f"{epoch}: {np.average(cum_rewards)}, alpha={alpha}, epsilon={epsilon}")
if np.average(cum_rewards) > Qmax:
Qmax = np.average(cum_rewards)
Qbest = Q
cum_rewards=[]
```
Cosa si potrebbe notare da questi risultati:
- **Vicino all'obiettivo**. Si è molto vicini al raggiungimento dell'obiettivo di ottenere 195 ricompense cumulative in oltre 100 esecuzioni consecutive della simulazione, o si potrebbe averlo effettivamente raggiunto! Anche se si ottengono numeri più piccoli, non si sa ancora, perché si ha una media di oltre 5000 esecuzioni e nei criteri formali sono richieste solo 100 esecuzioni.
- **La ricompensa inizia a diminuire**. A volte la ricompensa inizia a diminuire, il che significa che si possono "distruggere" i valori già appresi nella Q-Table con quelli che peggiorano la situazione.
Questa osservazione è più chiaramente visibile se si tracciano i progressi dell'allenamento.
## Tracciare i progressi dell'allenamento
Durante l'addestramento, si è raccolto il valore cumulativo della ricompensa a ciascuna delle iterazioni nel vettore delle ricompense `reward` . Ecco come appare quando viene riportato al numero di iterazione:
```python
plt.plot(rewards)
```
![progresso grezzo](../images/train_progress_raw.png)
Da questo grafico non è possibile dire nulla, perché a causa della natura del processo di allenamento stocastico la durata delle sessioni di allenamento varia notevolmente. Per dare più senso a questo grafico, si può calcolare la **media mobile su** una serie di esperimenti, ad esempio 100. Questo può essere fatto comodamente usando `np.convolve` : (blocco di codice 12)
```python
def running_average(x,window):
return np.convolve(x,np.ones(window)/window,mode='valid')
plt.plot(running_average(rewards,100))
```
![Progressi dell'allenamento](../images/train_progress_runav.png)
## Variare gli iperparametri
Per rendere l'apprendimento più stabile, ha senso regolare alcuni degli iperparametri durante l'allenamento. In particolare:
- **Per il tasso di apprendimento**, `alfa`, si può iniziare con valori vicini a 1 e poi continuare a diminuire il parametro. Con il tempo, si otterranno buoni valori di probabilità nella Q-Table, e quindi si dovranno modificare leggermente e non sovrascrivere completamente con nuovi valori.
- **Aumentare epsilon**. Si potrebbe voler aumentare lentamente `epsilon`, in modo da esplorare di meno e sfruttare di più. Probabilmente ha senso iniziare con un valore inferiore di `epsilone` e salire fino a quasi 1.
> **Compito 1**: giocare con i valori degli iperparametri e vedere se si riesce a ottenere una ricompensa cumulativa più alta. Si stanno superando i 195?
> **Compito 2**: per risolvere formalmente il problema, si devono ottenere 195 ricompense medie in 100 esecuzioni consecutive. Misurare questo durante l'allenamento e assicurarsi di aver risolto formalmente il problema!
## Vedere il risultato in azione
Sarebbe interessante vedere effettivamente come si comporta il modello addestrato. Si esegue la simulazione e si segue la stessa strategia di selezione dell'azione utilizzata durante l'addestramento, campionando secondo la distribuzione di probabilità in Q-Table: (blocco di codice 13)
```python
obs = env.reset()
done = False
while not done:
s = discretize(obs)
env.render()
v = probs(np.array(qvalues(s)))
a = random.choices(actions,weights=v)[0]
obs,_,done,_ = env.step(a)
env.close()
```
Si dovrebbe vedere qualcosa del genere:
![un cartpole equilibratore](../images/cartpole-balance.gif)
---
## 🚀 Sfida
> **Compito 3**: qui si stava usando la copia finale di Q-Table, che potrebbe non essere la migliore. Ricordare che si è memorizzato la Q-Table con le migliori prestazioni nella variabile `Qbest`! Provare lo stesso esempio con la Q-Table di migliori prestazioni copiando `Qbest` su `Q` e vedere se si nota la differenza.
> **Compito 4**: Qui non si stava selezionando l'azione migliore per ogni passaggio, ma piuttosto campionando con la corrispondente distribuzione di probabilità. Avrebbe più senso selezionare sempre l'azione migliore, con il valore Q-Table più alto? Questo può essere fatto usando la funzione `np.argmax` per trovare il numero dell'azione corrispondente al valore della Q-Table più alto. Implementare questa strategia e vedere se migliora il bilanciamento.
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/48/)
## Compito: [addestrare un'auto di montagna](assignment.it.md)
## Conclusione
Ora si è imparato come addestrare gli agenti a ottenere buoni risultati semplicemente fornendo loro una funzione di ricompensa che definisce lo stato desiderato del gioco e dando loro l'opportunità di esplorare in modo intelligente lo spazio di ricerca. E' stato applicato con successo l'algoritmo di Q-Learning nei casi di ambienti discreti e continui, ma con azioni discrete.
È importante studiare anche situazioni in cui anche lo stato di azione è continuo e quando lo spazio di osservazione è molto più complesso, come l'immagine dalla schermata di gioco dell'Atari. In questi problemi spesso è necessario utilizzare tecniche di apprendimento automatico più potenti, come le reti neurali, per ottenere buoni risultati. Questi argomenti più avanzati sono l'oggetto del prossimo corso di intelligenza artificiale più avanzato.

@ -0,0 +1,44 @@
# Addestrare un'Auto di Montagna
[OpenAI Gym](http://gym.openai.com) è stato progettato in modo tale che tutti gli ambienti forniscano la stessa API, ovvero gli stessi metodi di `reset`, `step` e `render` e le stesse astrazioni dello **spazio di azione** e dello **spazio di osservazione**. Pertanto dovrebbe essere possibile adattare gli stessi algoritmi di reinforcement learning a diversi ambienti con modifiche minime al codice.
## Un ambiente automobilistico di montagna
[L'ambiente Mountain Car](https://gym.openai.com/envs/MountainCar-v0/) contiene un'auto bloccata in una valle:
<img src="../images/mountaincar.png" width="300"/>
L'obiettivo è uscire dalla valle e catturare la bandiera, compiendo ad ogni passaggio una delle seguenti azioni:
| Valore | Significato |
|---|---|
| 0 | Accelerare a sinistra |
| 1 | Non accelerare |
| 2 | Accelerare a destra |
Il trucco principale di questo problema è, tuttavia, che il motore dell'auto non è abbastanza forte per scalare la montagna in un solo passaggio. Pertanto, l'unico modo per avere successo è andare avanti e indietro per aumentare lo slancio.
Lo spazio di osservazione è costituito da due soli valori:
| Num | Osservazione | Min | Max |
|-----|--------------|-----|-----|
| 0 | Posizione dell'auto | -1,2 | 0.6 |
| 1 | Velocità dell'auto | -0.07% | 0,07 |
Il sistema di ricompensa per l'auto di montagna è piuttosto complicato:
* La ricompensa di 0 viene assegnata se l'agente ha raggiunto la bandiera (posizione = 0,5) in cima alla montagna.
* La ricompensa di -1 viene assegnata se la posizione dell'agente è inferiore a 0,5.
L'episodio termina se la posizione dell'auto è maggiore di 0,5 o la durata dell'episodio è maggiore di 200.
## Istruzioni
Adattare l'algoritmo di reinforcement learning per risolvere il problema della macchina di montagna. Iniziare con il codice nel [notebook.ipynb](notebook.ipynb) esistente, sostituire il nuovo ambiente, modificare le funzioni di discretizzazione dello stato e provare ad addestrare l'algoritmo esistente con modifiche minime del codice. Ottimizzare il risultato regolando gli iperparametri.
> **Nota**: è probabile che sia necessaria la regolazione degli iperparametri per far convergere l'algoritmo.
## Rubrica
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
| -------- | --------- | -------- | ----------------- |
| | L'algoritmo di Q-Learning è stato adattato con successo dall'esempio CartPole, con modifiche minime al codice, che è in grado di risolvere il problema di catturare la bandiera in meno di 200 passaggi. | Un nuovo algoritmo di Q-Learning è stato adottato da Internet, ma è ben documentato; oppure è stato adottato l'algoritmo esistente, ma non raggiunge i risultati desiderati | Lo studente non è stato in grado di adottare con successo alcun algoritmo, ma ha compiuto passi sostanziali verso la soluzione (discretizzazione dello stato implementata, struttura dati Q-Table, ecc.) |

@ -0,0 +1,53 @@
# Introduzione al reinforcement learning
Il reinforcement learning (apprendimento per rinforzo), RL, è visto come uno dei paradigmi di base di machine learning, accanto all'apprendimento supervisionato e all'apprendimento non supervisionato. RL è tutta una questione di decisioni: fornire le decisioni giuste o almeno imparare da esse.
Si immagini di avere un ambiente simulato come il mercato azionario. Cosa succede se si impone un determinato regolamento. Ha un effetto positivo o negativo? Se accade qualcosa di negativo, si deve accettare questo _rinforzo negativo_, imparare da esso e cambiare rotta. Se è un risultato positivo, si deve costruire su quel _rinforzo positivo_.
![Pierino e il lupo](../images/peter.png)
> Pierino e i suoi amici devono sfuggire al lupo affamato! Immagine di [Jen Looper](https://twitter.com/jenlooper)
## Tema regionale: Pierino e il lupo (Russia)
[Pierino e il Lupo](https://it.wikipedia.org/wiki/Pierino_e_il_lupo) è una fiaba musicale scritta dal compositore russo [Sergei Prokofiev](https://it.wikipedia.org/wiki/Sergei_Prokofiev). È la storia del giovane pioniere Pierino, che coraggiosamente esce di casa per inseguire il lupo nella radura della foresta . In questa sezione, si addestreranno algoritmi di machine learning che aiuteranno Pierino a:
- **Esplorare** l'area circostante e costruire una mappa di navigazione ottimale
- **Imparare** a usare uno skateboard e bilanciarsi su di esso, per muoversi più velocemente.
[![Pierino e il lupo](https://img.youtube.com/vi/Fmi5zHg4QSM/0.jpg)](https://www.youtube.com/watch?v=Fmi5zHg4QSM)
> 🎥 Cliccare sull'immagine sopra per ascoltare Pierino e il Lupo di Prokofiev
## Reinforcement learning
Nelle sezioni precedenti, si sono visti due esempi di problemi di machine learning:
- **Supervisionato**, dove si ha un insieme di dati che suggeriscono soluzioni campione al problema da risolvere. [La classificazione](../../4-Classification/translations/README.it.md) e la [regressione](../../2-Regression/translations/README.it.md) sono attività di apprendimento supervisionato.
- **Non** supervisionato, in cui non si dispone di dati di allenamento etichettati. L'esempio principale di apprendimento non supervisionato è il [Clustering](../../5-Clustering/translations/README.it.md).
In questa sezione, viene presentato un nuovo tipo di problemi di apprendimento che non richiede dati di addestramento etichettati. Esistono diversi tipi di tali problemi:
- **[Apprendimento semi-supervisionato](https://wikipedia.org/wiki/Semi-supervised_learning)**, in cui si dispone di molti dati non etichettati che possono essere utilizzati per pre-addestrare il modello.
- **[Apprendimento per rinforzo](https://it.wikipedia.org/wiki/Apprendimento_per_rinforzo)**, in cui un agente impara come comportarsi eseguendo esperimenti in un ambiente simulato.
### Esempio: gioco per computer
Si supponga di voler insegnare a un computer a giocare a un gioco, come gli scacchi o [Super Mario](https://it.wikipedia.org/wiki/Mario_(serie_di_videogiochi)). Affinché il computer possa giocare, occorre prevedere quale mossa fare in ciascuno degli stati di gioco. Anche se questo può sembrare un problema di classificazione, non lo è, perché non si dispone di un insieme di dati con stati e azioni corrispondenti. Sebbene si potrebbero avere alcuni dati come partite di scacchi esistenti o registrazioni di giocatori che giocano a Super Mario, è probabile che tali dati non coprano a sufficienza un numero adeguato di possibili stati.
Invece di cercare dati di gioco esistenti, **Reinforcement Learning** (RL) si basa sull'idea di *far giocare il computer* molte volte e osservare il risultato. Quindi, per applicare il Reinforcement Learning, servono due cose:
- **Un ambiente** e **un simulatore** che permettono di giocare molte volte un gioco. Questo simulatore definirebbe tutte le regole del gioco, nonché possibili stati e azioni.
- **Una funzione di ricompensa**, che informi di quanto bene si è fatto durante ogni mossa o partita.
La differenza principale tra altri tipi di machine learning e RL è che in RL in genere non si sa se si vince o si perde finchè non si finisce il gioco. Pertanto, non è possibile dire se una determinata mossa da sola sia buona o meno: si riceve una ricompensa solo alla fine del gioco. L'obiettivo è progettare algoritmi che consentano di addestrare un modello in condizioni incerte. Si imparerà a conoscere un algoritmo RL chiamato **Q-learning**.
## Lezioni
1. [Introduzione a reinforcement learning e al Q-Learning](../1-QLearning/translations/README.it.md)
2. [Utilizzo di un ambiente di simulazione in palestra](../2-Gym/translations/README.it.md)
## Crediti
"Introduzione al Reinforcement Learning" è stato scritto con ♥️ da [Dmitry Soshnikov](http://soshnikov.com)
Loading…
Cancel
Save