Reinforcement Learning es una rama de inteligencia artificial que basa su aprendizaje en el concepto de "prueba y error". Todo algoritmo de Reinforcement Learning presenta a un agente que actúa en un entorno y recibe una recompensa (positiva o negativa) por cada una de sus acciones. El objetivo de un agente es encontrar una estrategia que maximize su recompensa a largo plazo.
Por cada escalón de tiempo t:
- El Agente:
- Recibe recompensa rt
- Recibe observación st
- Emite acción at
- El Entorno:
- Recibe acción at y la ejecuta. La ejecución de la acción at modifica el entorno.
- Emite recompensa rt+1
- Emite observación st+1
El entorno para este taller es el juego del 4 en raya. Incluso para un juego tan "sencillo" como el 4 en raya, hay 4,531,985,219,092 posibles estados.
El set de posibles estados de un entorno se denomina S. Cada valor denota una posible representación del estado de un entorno. st es la representación del entorno para cada instante t. Normalmente, escoger una buena representación del estado st no es fácil, y una buena representacion puede simplificar mucho la tarea de aprendizaje.
Para este taller, la representación será una matriz de 2 dimensiones, que representa el tablero del 4 en raya, nos referiremos al estado como Board (tablero en ingles). Boardij denotara el estado de la casilla en la fila i y columna j. Boardij = 0: casilla vacia. Boardij = 1: ficha del jugador 1. Boardij = 2: ficha del jugador 2.
El set de posibles acciones disponibles en un entorno se denomina A. Para este taller, un estado st tendrá un máximo de 7 acciones posibles, A = [0, 1, 2, 3, 4, 5, 6]. Cada acción representa la acción de colocar un ficha en una de las 7 columnas del tablero. En caso de que en un estado st la columna número i este llena, no se podra colocar una ficha en ella, con lo cual la acción ai no se podrá ejecutar en el estado st.
Cuando se ejecuta una acción at en el entorno, este se modifica. Tras la modificación, el entorno presenta un nuevo estado st+1 junto con una recompensa rt+1 al agente.
Cada posible acción, en cada estado, tiene asociada una recompensa. Una recompensa mide, a corto plazo, lo buena o mala que es una acción en un estado concreto.
Para este taller nos interesa ganar la partida. Con lo cual una acción que gane la partida otorgará al agente una recompensa de +1, cualquier otro movimiento otorgara una recompensa de 0.
Por cada instante t el agente "observa" el estado st. Tras "observar" el estado st, el agente escoge que acción at va a ejecutar usando una estrategia representada por la letra griega . Una estrategia es un mapeado de estados a acciones, y es todo lo necesario para definir el comportamiento de un agente. representa el mapeado de un estado st a una acción at. La tarea de "aprendizaje" de un agente en reinforcement learning es la tarea de encontrar una estrategia que maximize su recompensa a largo plazo a partir de recompensas a corto plazo.
MCTS es un método de Monte Carlo. Los métodos de Monte Carlo son métodos de aproximación estadísticos que se basan en la siguiente idea: hay un fenómeno que queremos estudiar. Este fenómeno es generalmente una expresión matemática compleja, con lo que intentamos aproximarlo. Para ello, tenemos acceso a un modelo (un simulador) del entorno donde ocurre este fenómeno. Utilizando el modelo podemos generar muchas simulaciones. Con ellas, podemos calcular estadísticas pertinentes del fenómeno que queremos estudiar. En el campo de inteligencia artificial para videojuegos, el modelo suele ser las reglas del juego. Dado un estado st en un entorno, el fenómeno a averiguar es el valor de cada posible acción at en un estado st. Si tenemos una aproximación del valor real de cada acción posible at para cada estado st, podemos escoger la acción de mayor valor en cada momento t para jugar de forma óptima.
Monte Carlo Tree Search - Upper Confidence Bound applied to Trees (MCTS-UCT) es un algoritmo que se usa para aproximar la estrategia óptima para un agente a cada paso de la partida. MCTS-UCT se usa para responder a la siguiente pregunta. Dado un estado st ¿Qué acción at nos dará una mayor recompensa a largo plazo? Que es lo mismo que preguntar ¿Qué acción tiene mas probabilidades de ganar la partida? Si un agente utiliza MCTS-UCT en cada uno de sus turnos, está aproximando en todo momento la decisión óptima.
La idea de MCTS-UCT es la próxima. Para averiguar que acción at tomar en st, simulamos muchisimas partidas, con cada partida aprendemos estadisticas que nos informan sobre lo buena (o mala) que es una acción en el estado st. Con estas estadísticas, escogemos que acciones vamos descartando y que acciones prometedoras seguimos investigando.
El algoritmo de MCTS-UCT se divide en 4 fases, seleccion, expansion, simulacion y retropropagacion (backpropagation).
- wi: número de victorias acumuladas en el nodo hijo i.
- ni: número de simulaciones acumuladas en el nodo hijo i.
- Ni: número de simulaciones acumuladas en el nodo actualmente seleccionado.
- c: parametro de exploracion, es una constante. Nos permite escoger entre los dos términos de la equación de UCB1. Un c grande da más importancia a la exploracion. Un c pequeño (c < 1) da más importancia a la explotación. Ver (ingles) explotación-vs-exploración
Esta fase empieza seleccinando el nodo raiz R. En caso de que todos los movimientos se hayan seleccionado al menos una vez, aplicamos la fórmula UCB1 a todos los nodos hijo y seleccionamos el que de un valor mayor. Es decir, el nodo hijo i que reciba el valor UCB1 mas alto sera seleccionado. Este proceso se repite hasta que se seleccione un nodo que no este completamente expandido (que tenga nodos hijo que nunca hayan sido seleccionados) o al llegar un nodo hoja / terminal. Si seleccionamos un nodo el cual tiene algún movimiento que no se haya expandido, expandimos uno de estos movimientos no seleccionados, terminado la fase de selección.
El paso mas sencillo. Una vez se ha seleccionado un nuevo hacemos dos cosas. Primero, lo añadimos al game tree que se esta construyendo en la ejecución de MCTS-UCT. Segundo, lo iniciamos con contadores para diferentes estadísticas que serviran para guiar la fase de selección en futuras iteraciones. Viendo la equacion de UCB1 las estadísticas que nos interesa guardar son:
- wi: número de victorias acumuladas en el nodo hijo i.
- ni: número de veces que el nodo hijo i ha sido seleccionado.
En términos generales, una simulación es una sucesion de acciones por partes de todos los agentes que cambian el entorno hasta llegar a un estado terminal. En un game tree, una simulacion empieza en el estado s correspondiente a un nodo raiz y se toman acciones posibles que llevan a otros nodos. La simulacion termina cuando se llega a un nodo hoja / terminal.
Terminada la expansión del nodo escogido, comenzamos una simulacion del juego (en este taller 4 en raya) desde este nodo. Cada una de las acciones escogidas durante toda la simulacion son aleatorias (los dos agentes juegan movimientos aleatorios). Otros terminos utilizados para hablar de simulaciones en la literaturas son rollout o playout.
Nota: Exceptuando el nodo donde comienza la simulacion todos los otros nodos por los que se pasa en cada simulacion NO forman parte del game tree que se esta formando durante MCTS-UCT.
El resultado de la simulación se propaga por todos los nodos del game tree empezando por el nodo creado en la fase de expansión y terminando en el nodo raiz del game tree. Para actualizar las estadísticas basta con actualizar el número de simulaciones y victorias (en caso de que la simulación haya sido victoriosa) en cada uno de los nodos. Este proceso también se conoce como backpropagation.
El uso de las estadisticas calculadas durante las previas fases es la de seleccionar una accion at para tomar en el movimiento numero t. Donde st es el estado correspondiente al nodo raiz del game tree generado por MCTS-UCT. Inspeccionamos a todos los nodos hijo correspondientes al nodo raiz y tomamos el que tiene un valor mayor de posibilidad de victoria. Tomamos la accion asignada al nodo hijo c cuyas estadisticas maximizen la equacion:
- wc: número de victorias acumuladas en el nodo hijo c.
- nc: número de simulaciones acumuladas en el nodo hijo c.
¡Implementa el algoritmo MCTS-UCT en python para jugar al 4 en raya contra una inteligencia artificial!
Necesitarás Python 2.7 para este ejercicio. La implementación del algoritmo no requiere ninguna herramienta que no venga dentro de la distribucion estandard de Python 2.7. El script solo tiene una dependencia: colorama
, un módulo para imprimir texto con colores en la terminal, su uso en este ejercicio es puramente estético ¿Pero quién no quiero tener texto de colores en la terminal? Para instalar colorama
:
pip install colorama
El script MCTS.py
contiene todo el código necesario para los dos talleres. También es el único archivo que deberá ser modificado durante los talleres. Su contenido está escrito en inglés para facilitar busquedas relacionadas en internet. Los comentarios están en español. Utiliza los comentarios dentro del codigo como documentación del mismo.
Para jugar una partida entre 2 humanos ejecuta: python MCTS.py