Per iniziare con l'apprendimento automatico di un gioco a somma zero?

2

Ho una semplice somma zero, discreto, deterministico, completo gioco di informazione. Voglio apprendere a macchina una funzione di valutazione per un agente AI.

Supponiamo che ogni stato della scheda abbia ~ 20 caratteristiche identificabili che potrebbero essere ponderate per formare una funzione di valutazione.

Supponiamo che il vincolo temporale per entrambi i giocatori sia di 15 secondi per tutte le mosse dell'intero gioco, quindi ogni partita impiega fino a 30 secondi.

Mi sembra che un approccio ingenuo sarebbe quello di scorrere all'infinito ciascuna delle caratteristiche, creando agenti con un piccolo incremento / decremento della ponderazione delle caratteristiche e giocando contro di loro.

Create agent(N=0) with uniform or random weightings

While (Brendan hasn't stopped the program)

    For each F in features

       Clone agent(N) -> agent(N+1), with increased weighting of F
       Clone agent(N) -> agent(N+2), with decreased weighting of F
       Play ~20 games of agent(N+1) vs agent(N+2)

       If one agent was clearly stronger (eg. won 60%+?), then 
           N <- [the stronger agent]

Quindi lascia correre continuamente per un lungo periodo. Si spera che l'agente finale [N] abbia un strong insieme di ponderazioni.

Questo sembra inefficiente perché per 20 giochi con 20 funzionalità con giochi di 30 secondi, ci vorranno diverse ore per completare una singola iterazione del ciclo principale.

Che cos'è un algoritmo più sofisticato?

Esistono generiche implementazioni Java di tali algoritmi di apprendimento automatico che potrebbero funzionare per addestrare un agente di gioco?

    
posta Brendan Hill 05.05.2016 - 04:22
fonte

1 risposta

4

Questo è un buon candidato per Evoluzione differenziale .

DE è un minimizzatore / ottimizzatore di funzione stocastico molto semplice (ma potente) basato sulla popolazione.

Un punto chiave per l'integrazione di DE nel tuo schema è la funzione fitness:

double fitness(Agent_k)
   fit = 0

   repeat M times
      randomly extract an individual Agent_i (i <> k)

      switch (result of Agent_k vs Agent_i)
         case Agent_k wins:   fit = fit + 1
         case Agent_i wins:   fit = fit - 2
         case draw:           fit doesn't change

   return fit

vale a dire. un agente gioca contro M avversari selezionati casualmente dalla popolazione (con la sostituzione ma evitando l'auto-partita).

Il parametro M è importante: valori grandi danno una misura precisa, valori piccoli potrebbero impedire la convergenza. Vorrei iniziare con M=5 (un valore utilizzato in alcuni esperimenti relativi agli scacchi).

Uno schizzo della ricerca è:

Create a population of N agents with random weights

While (Brendan hasn't stopped the program and
       population diversity is greater than a given threshold)

   randomly select Agent_b

   randomly select Agent_i (i <> b)
   randomly select Agent_j (j <> i and j <> b)
   randomly select Agent_k (k <> j and k <> i and k <> b)

   Agent_m = Agent_i + F (Agent_j - Agent_k)

   Agent_child = crossover(Agent_b, Agent_m)

   if (fitness(Agent_child) > fitness(Agent_b)
      replace Agent_b with Agent_child

Questo è un approccio di popolazione a stato stazionario (l'alternativa è un approccio generazionale; ulteriori informazioni in Elementi essenziali della metaeuristica di Sean Luke).

Per maggiori dettagli su come DE dà un'occhiata a:

DE guiderà la ricerca verso aree promettenti dello spazio possibile (senza eseguire una ricerca sistematica come nel tuo codice).

In ogni caso questo tipo di ottimizzazione potrebbe facilmente richiedere diversi giorni.

La pagina ufficiale di DE ha implementazioni in molte lingue (anche Java ).

I would expect "crossover" to average out the parent function weightings, but how does the variation arise?

In DE c'è una "miscela" di mutazione e crossover.

(nell'immagineAgent_j=Xa,Agent_k=Xb,Agent_i=Xc.SchemadimutazionediDE,crossovernonmostrato)

Strategieevolutivetradizionalihannomutatoivettoriaggiungendolorounrumoregaussianoallozero,ma,perrimanereefficienti,loschemadimutazionehadovutoregolareladeviazionestandarddelrumoregaussianoperadattarsiaciascunparametro(anchequestaèunafunzionedeltempo).

DEusaunvettoredifferenzialeXa-Xb,alpostodelrumoregaussiano,per"perturbare" un altro vettore Xc :

Xc_ = Xc + F * (Xa - Xb)

F (peso differenziale) è un fattore di scala fornito dall'utente nell'intervallo [0.1, 1.2] .

Questa forma di mutazione (con rumore derivato dalla popolazione) assicura che lo spazio di ricerca venga cercato in modo efficiente in ogni dimensione.

For example, if the population becomes compact in one dimension, but remains widely dispersed along another, the differentials sampled from it will be small in one dimension yet large in the other. Whatever the case, step sizes will be comparable to the breadth of the region they are being used to search, even as these regions expand and contract during the course of evolution.

(da Dr.Dobb's Journal # 264 aprile 1997 p.22, "Differential Evolution" di K. Price e R. Storn)

Xc_ ( Agent_m nello pseudo-codice) viene utilizzato per produrre un vettore di prova tramite crossover con un individuo casuale ( Xi di seguito, Agent_b nello pseudo-codice ):

Xt = crossover(Xi, Xc_)

L'operatore crossover produce una prole da una serie di esperimenti binomiali: in questo modo viene stabilito quale genitore contribuisce quale parametro del trial vector.

Il migliore tra Xt e Xi ( Agent_child e Agent_b ) sopravvive.

    
risposta data 05.05.2016 - 11:35
fonte