Proto-Reinforcement Learning

Source: Deep Learning on Medium

Proto-Reinforcement Learning

Learning Reinforcement Learning

Introducción

En un articulo anterior escribí sobre el Standard Model de los algoritmos de Reinforcement Learning. Para aprender mas sobre ello me he planteado un problema simple con la idea de identificar los diferentes elementos del modelo.

Para darle una vuelta mas, he programado un algoritmo proto-RL que busca la mejor solución y he evaluado del resultado. Vamos a ello.

El problema

Tenemos una Cesta (Basket) y un numero de Surtidores (Pumper). Cada uno de ellos echa un número indeterminado de Canicas (siquiendo cierta lógica que el algoritmo desconoce). El objetivo del algoritmo es encontrar la forma de llenar la Cesta hasta el límite en el minimo numero de descargas (steps).

Standard Model

Vamos a identificar los diferentes elementos del Standard Model en este problema:

  • Environment — Es el conjunto de condiciones en los que operara (y aprende) un Agente. En nuestro caso es la Cesta con las Canicas.
  • Agent — Es el algoritmo que ejecuta y aprende a llenar la Cesta. He desarrollado dos Agentes que explicaré mas adelante: RandomBasketFiller y ProtoRLBasketFiller.
  • Reward — Es el índice que ayuda al Agente a saber cuan bien está realizando su tarea. En nuestro algoritmo el Reward quizas no es muy estandard, se obtiene calculando la media de Canicas que salen de un Surtidor concreto. Nuestro ProtoRLBasketFiller usará mas el Surtidor con una media mas alta (ese es su aprendizaje).
  • Action — es el resultado del entrenamiento del Agente y da lugar al cambio deseado en el Entorno. En nuestro caso el Agente elige entre los Surtidores que tiene a su disposición a partir de lo que ha ido aprendiendo.
  • State (estado) — es la foto del Entorno en un determinado momento. En nuestro caso si el Cesto está lleno o no.

El código

Para poder comparar y evaluar este proto-RL he creado dos Agentes (BasketFillers); uno que selecciona los Surtidores de forma totalmente aleatoría y otro que intenta aprender en cada intento.

En el segundo, he añadido un parámetro de configuración que permite establecer un balance entre acciones de exploración y explotación (quizas escriba mas adelante otro artículo sobre esto último).

Podeis encontrar el código en el siguiente repositorio en GitHub.

  • main.py — Ejecutando este fichero de inicio se lanzaran los algoritmos y pintaran los resultados que evaluaremos en la siguiente sección.
  • basket.py — Se puede decir que es el Environment por lo que es la implementación de la Cesta de Canicas. Sin misterio: se inicializa a un tamaño, se le pueden añadir Canicas, vaciar y preguntar si esta lleno.
  • basket_filler_evaluator.py — Clase que simplifica la ejecución del algoritmo de los BasketFillers multiples veces para su evaluación.
  • marble_pumper.py — Los Surtidores implementados de forma sencilla. Recordar que su lógica es totalmente desconocida para los Agentes Human(BasketFillers).
    Aqui está el secreto: un valor aleatorio que como máximo es el 10 veces el valor del índice de Surtidor.
...
return random.randrange((index*5), (index*10)+1)
  • random_basket_filler.py — La implementación del Agente que seleccion el Surtidor de forma aleatoria.
...
while not self._basket.is_full():
choice = random.randrange(self._pumper_number)
self._basket.add(MarblePumper.pull(choice))
...
  • proto_rl_basket_filler.py —Incluye la implementación del Agente con cierta inteligencia. Su objetivo es seleccionar el Surtidor del que mas Canicas cree que van a salir. Se le puede configurar el balance entre explotación y exploración.
...# Algorithm decides if explores or exploits
if random.randrange(100) < self._exploitation_percentage:
# Exploits: Gets the Pumper with max average of Marbles
choice = np.argmax(self._past_rewards_avg)
else:
# Explores: Gets one Pumper randomlys
choice = random.randrange(self._pumper_number)
...

Evaluación

Para evaluar los diferentes algoritmos vamos a utilizar un Cesto en el que caben 50.000 canicas. Tenemos 100 Surtidores que expulsan un numero de Canicas que varía (explicado en la sección anterior). Para evaluar el algoritmo los vamos a ejecutar 500 veces (el aprendizaje se acumula entre intentos).

El número mínimo de pasos (descarga de Surtidor) para llenar el Cesto es de 50. Para cada algoritmo (y variación del mismo) vamos a tener en cuenta: la ejecución que le llevo menos pasos (min), la que le llevo mas (max) y la media de pasos para las 500 ejecuciones (avg).

Caso 1
Utilizando el Agente que selecciona al azar los Surtidores (RandomBasketFiller):

  • Min: 116
  • Max: 159
  • Avg: 135.456

Caso 2
Utilizando el Agente inteligente (protoRLBasketFiller) dando prioridad a la Exploración (80%) sobre la Explotación (20%).

  • Min: 96
  • Max: 113
  • Avg: 114.606

Conclusión: Este Agente mejora el algoritmo puramente aleatorio pero dado su alto componente de Exploración no se aleja mucho de la elección de Surtidores erroneos.

Caso 4
De nuevo el Agente inteligente, pero esta vez, balanceando la Explotación (50%) y la Exploración (50%).

  • Min: 81
  • Max: 115
  • Avg: 94.24Os lo dejo a vosotrosOs lo dejo a vosotros

Conclusión: el crecimiento de la Explotación ha dado lugar a una mejora. Surge la duda si aumentandola mas los resultados van a mejorar.

Caso 4
Por último el Agente inteligente dando prioridad a la Explotación (80%) sobre Humanla Exploración (20%).

  • Min: 68
  • Max: 109
  • Avg: 78.434

Conclusión: Pues sí, mejora sustancialmente. De largo esta solución mejora las anteriores acercandose peligrosamente a la mejor posible.

¿Que pasaría si aumento aún mas la capacidad de Explotación? Os lo dejo a vosotros.

Y otra cosa, ¿sería un humano capaz de superarlo?