Una introducción a los métodos de Advantage Actor Critic: ¡juguemos a Sonic the Hedgehog!

Desde el comienzo de este curso, hemos estudiado dos métodos diferentes de aprendizaje por refuerzo:

  • Métodos basados ​​en valores (Q-learning, Deep Q-learning): donde aprendemos una función de valor que mapeará cada par de acciones de estado a un valor. Gracias a estos métodos, encontramos la mejor acción a tomar para cada estado: la acción con el mayor valor. Esto funciona bien cuando tiene un conjunto finito de acciones.
  • Métodos basados ​​en políticas (REFORZAR con gradientes de política): donde optimizamos directamente la política sin utilizar una función de valor. Esto es útil cuando el espacio de acción es continuo o estocástico. El principal problema es encontrar una buena función de puntuación para calcular qué tan buena es una política. Usamos las recompensas totales del episodio.

Pero ambos métodos tienen grandes inconvenientes. Por eso, hoy estudiaremos un nuevo tipo de método de Aprendizaje por Refuerzo que podemos llamar “método híbrido”: Actor Crítico . Usaremos dos redes neuronales:

  • un crítico que mide qué tan buena es la acción tomada (basada en valores)
  • un actor que controla cómo se comporta nuestro agente (basado en políticas)

Dominar esta arquitectura es esencial para comprender los algoritmos de vanguardia, como la optimización de políticas próximas (también conocida como PPO). PPO se basa en Advantage Actor Critic.

¡E implementarás un agente Advantage Actor Critic (A2C) que aprende a jugar a Sonic the Hedgehog!

La búsqueda de un mejor modelo de aprendizaje

El problema con los gradientes de políticas

El método Policy Gradient tiene un gran problema. Estamos en una situación de Montecarlo, esperando hasta el final del episodio para calcular la recompensa. Podemos concluir que si tenemos una recompensa alta ( R (t) ), todas las acciones que tomamos fueron buenas, incluso si algunas fueron realmente malas.

Como podemos ver en este ejemplo, incluso si A3 fue una mala acción (dio lugar a recompensas negativas), todas las acciones se promediarán como buenas porque la recompensa total fue importante.

Como consecuencia, para tener una política óptima,necesitamos muchas muestras. Esto produce un aprendizaje lento, porque se necesita mucho tiempo para converger.

¿Qué pasa si, en cambio, podemos hacer una actualización en cada paso de tiempo?

Presentando al actor crítico

El modelo Actor Critic es una mejor función de puntuación. En lugar de esperar hasta el final del episodio como hacemos en Monte Carlo REINFORCE, hacemos una actualización en cada paso (TD Learning).

Debido a que hacemos una actualización en cada paso de tiempo, no podemos usar las recompensas totales R (t). En cambio, necesitamos entrenar un modelo crítico que se aproxime a la función de valor (recuerde que la función de valor calcula cuál es la recompensa futura máxima esperada dado un estado y una acción). Esta función de valor reemplaza la función de recompensa en el gradiente de política que calcula las recompensas solo al final del episodio.

Cómo funciona el actor crítico

Imagina que juegas un videojuego con un amigo que te proporciona algunos comentarios. Eres el actor y tu amigo es el crítico.

Al principio, no sabes cómo jugar, así que pruebas algunas acciones al azar. El crítico observa su acción y proporciona comentarios.

Al aprender de estos comentarios, actualizará su política y mejorará en ese juego.

Por otro lado, su amigo (crítico) también actualizará su propia forma de proporcionar comentarios para que pueda ser mejor la próxima vez.

Como podemos ver, la idea de Actor Critic es tener dos redes neuronales. Estimamos ambos:

Ambos corren en paralelo.

Debido a que tenemos dos modelos (Actor y Crítico) que deben ser entrenados, significa que tenemos dos conjuntos de pesos (? Para nuestra acción yw para nuestro Crítico) que deben optimizarse por separado:

El proceso de la crítica del actor

En cada paso de tiempo t, tomamos el estado actual (St) del entorno y lo pasamos como entrada a través de nuestro Actor y nuestro Crítico.

Nuestra Política toma el estado, genera una acción (At) y recibe un nuevo estado (St + 1) y una recompensa (Rt + 1).

Gracias a ello:

  • el crítico calcula el valor de tomar esa acción en ese estado
  • el Actor actualiza sus parámetros de política (pesos) usando este valor q

Gracias a sus parámetros actualizados, el Actor produce la siguiente acción a realizar en At + 1 dado el nuevo estado St + 1. El crítico luego actualiza sus parámetros de valor:

A2C y A3C

Presentamos la función Advantage para estabilizar el aprendizaje

Como vimos en el artículo sobre mejoras en Deep Q Learning, los métodos basados ​​en valores tienen una alta variabilidad.

Para reducir este problema, hablamos de usar la función de ventaja en lugar de la función de valor.

La función de ventaja se define así:

Esta función nos dirá la mejora en comparación con el promedio de la acción tomada en ese estado. En otras palabras, esta función calcula la recompensa extra que obtengo si realizo esta acción. La recompensa adicional es la que supera el valor esperado de ese estado.

Si A (s, a)> 0: nuestro gradiente se empuja en esa dirección.

Si A (s, a) <0 (nuestra acción es peor que el valor promedio de ese estado), nuestro gradiente se empuja en la dirección opuesta.

El problema de implementar esta función de ventaja es que requiere dos funciones de valor: Q (s, a) y V (s). Afortunadamente, podemos utilizar el error TD como un buen estimador de la función de ventaja.

Dos estrategias diferentes: asincrónica o sincrónica

Tenemos dos estrategias diferentes para implementar un agente actor crítico:

  • A2C (también conocido como Advantage Actor Critic)
  • A3C (también conocido como actor crítico de ventaja asincrónica)

Por eso trabajaremos con A2C y no con A3C. Si desea ver una implementación completa de A3C, consulte el excelente artículo A3C de Arthur Juliani y la implementación de Doom.

En A3C, no utilizamos la repetición de experiencia ya que esto requiere mucha memoria. En cambio, ejecutamos de forma asincrónica diferentes agentes en paralelo en múltiples instancias del entorno. Cada trabajador (copia de la red) actualizará la red global de forma asincrónica.

Por otro lado, la única diferencia en A2C es que actualizamos sincrónicamente la red global. Esperamos a que todos los trabajadores hayan terminado su formación y hayan calculado sus gradientes para promediarlos, para actualizar nuestra red global.

¿Elegir A2C o A3C?

El problema de A3C se explica en este impresionante artículo. Debido a la naturaleza asincrónica de A3C, algunos trabajadores (copias del Agente) jugarán con una versión anterior de los parámetros. Por lo tanto, la actualización agregada no será óptima.

Es por eso que A2C espera a que cada actor termine su segmento de experiencia antes de actualizar los parámetros globales. Luego, reiniciamos un nuevo segmento de experiencia con todos los actores paralelos que tienen los mismos nuevos parámetros.

Como consecuencia, el entrenamiento será más cohesivo y más rápido.

Implementando un agente A2C que juega a Sonic the Hedgehog

A2C en la práctica

En la práctica, como se explica en esta publicación de Reddit, la naturaleza sincrónica de A2C significa que no necesitamos diferentes versiones (diferentes trabajadores) de A2C.

Cada trabajador en A2C tendrá el mismo conjunto de ponderaciones ya que, a diferencia de A3C, A2C actualiza a todos sus trabajadores al mismo tiempo.

De hecho, creamos múltiples versiones de entornos (digamos ocho) y luego las ejecutamos en paralelo.

El proceso será el siguiente:

  • Crea un vector de n entornos utilizando la biblioteca de multiprocesamiento
  • Crea un objeto corredor que maneja los diferentes entornos, ejecutándose en paralelo.
  • Tiene dos versiones de la red:
  1. step_model: que genera experiencias a partir de entornos
  2. train_model: que entrena las experiencias.

Cuando el corredor da un paso (modelo de un solo paso), este realiza un paso para cada uno de los n entornos. Esto genera una gran cantidad de experiencia.

Luego calculamos el gradiente de una vez usando train_model y nuestro lote de experiencia.

Finalmente, actualizamos el modelo de pasos con los nuevos pesos.

Recuerde que calcular el gradiente de una vez es lo mismo que recopilar datos, calcular el gradiente para cada trabajador y luego promediar. ¿Por qué? Porque sumar las derivadas (suma de gradientes) es lo mismo que tomar las derivadas de la suma . Pero el segundo es más elegante y una mejor forma de usar la GPU.

A2C con Sonic the Hedgehog

Entonces, ahora que entendemos cómo funciona A2C en general, ¡podemos implementar nuestro agente A2C jugando Sonic! Este video muestra la diferencia de comportamiento de nuestro agente entre 10 min de entrenamiento (izquierda) y 10 h de entrenamiento (derecha).

La implementación está aquí en el repositorio de GitHub, y el cuaderno explica la implementación. Te doy el modelo guardado entrenado con aproximadamente 10h + en GPU.

Esta implementación es mucho más compleja que las implementaciones anteriores. Comenzamos a implementar algoritmos de última generación, por lo que debemos ser cada vez más eficientes con nuestro código. Por eso, en esta implementación, separaremos el código en diferentes objetos y archivos.

¡Eso es todo! Acabas de crear un agente que aprende a jugar a Sonic the Hedgehog. ¡Eso es genial! Podemos ver que con 10 horas de entrenamiento, nuestro agente no entiende el bucle, por ejemplo, por lo que necesitaremos usar una arquitectura más estable: PPO.

Tómate un tiempo para considerar todos los logros que has logrado desde el primer capítulo de este curso: pasamos de juegos de texto simples (OpenAI taxi-v2) a juegos complejos como Doom y Sonic the Hedgehog usando arquitecturas cada vez más poderosas. ¡Y eso es fantástico!

La próxima vez aprenderemos sobre Proximal Policy Gradients, la arquitectura que ganó el OpenAI Retro Contest. Entrenaremos a nuestro agente para jugar Sonic the Hedgehog 2 y 3 y esta vez, ¡terminará niveles completos!

No olvide implementar cada parte del código usted mismo. Es muy importante intentar modificar el código que te di. Intente agregar épocas, cambiar la arquitectura, cambiar la velocidad de aprendizaje, etc. Experimentar es la mejor manera de aprender, ¡así que diviértete!

Si le gustó mi artículo, haga clic en? a continuación tantas veces como le haya gustado el artículo para que otras personas lo vean aquí en Medium. ¡Y no olvides seguirme!

Este artículo es parte de mi curso de aprendizaje de refuerzo profundo con TensorFlow? ️. Consulte el plan de estudios aquí.

Si tiene alguna idea, comentario o pregunta, no dude en comentar a continuación o enviarme un correo electrónico: hola [arroba] simoninithomas [punto] com, o enviarme un tweet a @ThomasSimonini.

Curso de aprendizaje por refuerzo profundo:

¿Estamos haciendo una versión en video del curso de aprendizaje de refuerzo profundo con Tensorflow ? donde nos centramos en la parte de implementación con tensorflow aquí.

Parte 1: Introducción al aprendizaje por refuerzo

Parte 2: Profundizar en el aprendizaje por refuerzo con Q-Learning

Parte 3: Introducción a Deep Q-Learning: juguemos a Doom

Parte 3+: Mejoras en Deep Q Learning: DQN doble en duelo, repetición de experiencia priorizada y objetivos Q fijos

Parte 4: Introducción a los gradientes de políticas con Doom y Cartpole

Parte 6: Optimización de políticas próximas (PPO) con Sonic the Hedgehog 2 y 3

Parte 7: Aprendizaje impulsado por la curiosidad simplificado Parte I