Flying memes

Q-learning con processing.org

Il reinforcement learning (o apprendimento con rinforzo) è una approcio che appartiene alla categoria dei sistemi intelligenti e che si applica a tutte quelle casistiche nelle quali un agente deve esplorare ed interagire con l’ambiente circostante.


Il principio base che sottende tutti gli algoritmi di reinforcement learning è lo stesso: ad ogni interazione con l’ambiente circostante l’agente viene premiato o punito a seconda dell’azione intrapresa in quel particolare stato. A fronte di questi premi/punizioni l’agente impara col tempo a collezionare il maggior numero di premi possibili evitando le punizioni.

Possiamo formalizzare quanto appena enunciato come segue: dato un’insieme di stati  S={s0,s1…,sn}, un’insieme di azioni A={a1,a2…,am} dobbiamo trovare una corrispondenza stato-azione (detta policy p[s,a] ) in modo da massimizzare il reward R={r1,r2…,rl} che l’ambiente ci fornisce ogniqualvolta in un determinato stato eseguiamo una determinata azione.

Chiaramente a questo enunciato devono seguire alcune considerazioni (che ci porteranno poi alla stesura dell’algoritmo Q-learning), ad esempio risulta ovvio pensare che se dall’azione che eseguo all’istante t ottengo una punizione questa non sarà (probabilmente) legata solo a quello che ho scelto di fare in quell’istante ma anche da tutte le scelte che ho fatto prima.

Ecco dunque che nasce la necessità di aggiungere una nuova definizone a quanto già espresso precedentemente, definiamo q[s,a] come la misura del premio/punizione che mi dovrebbe attendere a lungo termine se intraprendo quella azione in quello stato. Quindi una q[s,a] abbastanza alta dovrebbe rassicurare il mio agente e fargli intraprendere quell’azione in quanto, se prendiamo come esempio gli scacchi, poche mosse dopo quella che stò per fare potrei vincere.

Ottenere un buon indicatore di questa q non è esattamente facile. Per farlo deve necessariamente esplorare l’ambiente in modo da collezionare un po di ‘esperienza’ sul campo, esperienza che poi potrò utilizzare proprio per stillare la policy (perchè unendo i concetti fin qui esposti risulta ben chiaro che se dovessi mai avere la q ‘perfetta’ per ogni copia di stato/azione la mia policy si risolverebbe nell’eseguire di volta in volta l’azione con la q più alta per quello stato).

L’algoritmo Q-learning che stò per enunciare unisce il concetto di ‘calcolo della q’ al concetto di ‘elaborazione della policy’ semplicemente accontentandosi di volta in volta di scelgiere l’azione con la q più alta tra quelle disponibili in quello stato e successivamente di retro-modificare la q scelta incrementandola se l’azione (e quelle successive) hanno portato ad un premio e decrementandola viceversa.

In questo modo dopo un certo numero di ‘episodi’ la q che l’agente si è calcolato dovrebbe essere almeno vicina a quella reale.

Scrivo ora l’algoritmo del Q-learning cosi come descritto nei paragrafi precedenti:


Variabili iniziali:
S = {s1,s2,...sn}   # Stati  (ad esempio in un labirinto ogni casella)
A ={a1,a2,...an}    # Azioni (potrebbero non esserci tutte per ogni stato, in un labirinto
                    # potrebbero essere su, giu, sx, dx)

Setup iniziale:
q = 0               # Per ogni coppia di stato/azione
r =  0              # Per ogni coppia di stato/azione imposto il reward a zero
imposta_reward()    # Per ogni coppia di stato azione significativa ( ad esempio in un
                    # labirinto l'uscita) imposto un
                    # reward diverso dallo zero ( ad esempio uscita: +10, rovi: -5 )
stati_terminali = s1,s2  # Vanno identificati gli stati terminali (quelli in cui,
                         # cioè l'episodio finisce - ad esempio l'uscaita dal labirinto)
stato_corrente = stato_inizale      # Va impostato uno stato iniziale
azione_corrente = azione_iniziale   # Va impostata la prima azione
alpha = xx          # costante, indica quanto la variazione dei q futuri incida sul q
                    # corrente
gamma = xx          # costante, indica quanto 'ridimensionare' la variazione dei q futuri 

Algoritmo:
Finche la policy non converge:
   prossimo_stato   =  recupera_prossimo_stato(stato_corrente,azione_corrente)
   reward = recupera_reward(stato_corrente,azione_corrente)
   prossima_azione =  recupera_l_azione_col_q_maggiore(prossimo_stato)
   q[stato_corrente,azione_corrente] =  q[stato_corrente,azione_corrente] + alpha * ( reward +
                                        gamma * q[prossimo_stato,prossima_azione] -
                                        q[stato_corrente,azione_corrente])

   # se prossimo_stato è una stato terminale stato_corrente deve tornare ad
   # essere stato_iniziale a meno che la policy non si sia stabilizzata.
   stato_corrente = prossimo_stato
   azione_corrente = prossima_azione
end

Ho implementato questo algoritmo in Processing.org ma a differenza del post precedente non posso visualizzarlo nel browser in quanto computazionalmente è troppo impegnativo; potere comunque scaricarlo dal mio accounti di GitHub.

Q-learning in processing.org

Q-learning in processing.org

Ecco la spiegazione del programma: il quadrato arancio è lo stato terminale, e frutta al nostro agente +1 di ricompensa, i bordi invece quando colpiti fruttano -1 (quindi l’agente tenderà ad evitarli). Dopo qualche minuto dovreste cominciare a notare dei cambiamenti di colore sulla griglia, le celle con q negativo tendono a colorarsi di blu mentre quelle con q positivo tendono ad un viola molto acceso.

L’agente è rappresentato da un quadrato verde e viene disegnato con un scia al seguito; tale scia rappresenta (e lo vedremo meglio la prossima volta) il modo in cui la variazione di q si distribuisce sulle scelte precedenti.

Se avete la pazienza di attendere 5-6 minuti dovreste scorgere con chiarezza una specie di ‘percorso più chiaro’, rappresentato da tutte quelle celle che hanno un q positivo, che parte dallo stato iniziale e guida l’agente verso quello terminale.

Scarica Q-learning con Processing.org dal mio account di GitHub

Tags: , , ,