Mejoras en Deep Q Learning: DQN doble en duelo, repetición de experiencia priorizada y arreglos

Este artículo es parte del curso de aprendizaje de refuerzo profundo con Tensorflow? ️. Consulta el plan de estudios aquí.

En nuestro último artículo sobre Deep Q Learning con Tensorflow, implementamos un agente que aprende a jugar una versión simple de Doom. En la versión de video, entrenamos a un agente de DQN que juega Space Invaders.

Sin embargo, durante el entrenamiento, vimos que había mucha variabilidad.

Deep Q-Learning se introdujo en 2014. Desde entonces, se han realizado muchas mejoras. Entonces, hoy veremos cuatro estrategias que mejoran - dramáticamente - la capacitación y los resultados de nuestros agentes de DQN:

  • objetivos Q fijos
  • DQN dobles
  • duelo DQN (también conocido como DDQN)
  • Reproducción de experiencia priorizada (también conocida como PER)

Implementaremos un agente que aprende a jugar al corredor Doom Deadly. Nuestra IA debe navegar hacia el objetivo fundamental (el chaleco) y asegurarse de que sobrevivan al mismo tiempo matando enemigos.

Objetivos Q fijos

Teoría

Vimos en el artículo de Deep Q Learning que, cuando queremos calcular el error TD (también conocido como la pérdida), calculamos la diferencia entre el objetivo TD (Q_target) y el valor Q actual (estimación de Q).

Pero no tenemos ni idea del verdadero objetivo de TD. Necesitamos estimarlo. Usando la ecuación de Bellman, vimos que el objetivo de TD es solo la recompensa de tomar esa acción en ese estado más el valor Q más alto descontado para el siguiente estado.

Sin embargo, el problema es que usamos los mismos parámetros (pesos) para estimar el objetivo y el valor de Q. Como consecuencia, existe una gran correlación entre el objetivo TD y los parámetros (w) que estamos cambiando.

Por lo tanto, significa que en cada paso del entrenamiento, nuestros valores Q cambian, pero también cambia el valor objetivo. Entonces, nos estamos acercando a nuestro objetivo, pero el objetivo también se está moviendo. ¡Es como perseguir un objetivo en movimiento! Esto conduce a una gran oscilación en el entrenamiento.

Es como si fueras un vaquero (la estimación Q) y quisieras atrapar a la vaca (el objetivo Q), debes acercarte (reducir el error).

En cada paso de tiempo, intentas acercarte a la vaca, que también se mueve en cada paso de tiempo (porque usas los mismos parámetros).

Esto conduce a un camino de persecución muy extraño (una gran oscilación en el entrenamiento).

En su lugar, podemos usar la idea de Q-objetivos fijos introducidos por DeepMind:

  • Usando una red separada con un parámetro fijo (llamémoslo w-) para estimar el objetivo TD.
  • En cada paso de Tau, copiamos los parámetros de nuestra red DQN para actualizar la red de destino.

Gracias a este procedimiento, tendremos un aprendizaje más estable porque la función objetivo permanece fija por un tiempo.

Implementación

Implementar objetivos q fijos es bastante sencillo:

  • Primero, creamos dos redes ( DQNetwork, TargetNetwork)
  • Luego, creamos una función que tomará nuestros DQNetworkparámetros y los copiará a nuestroTargetNetwork
  • Finalmente, durante el entrenamiento, calculamos el objetivo de TD utilizando nuestra red objetivo. Actualizamos la red de destino con DQNetworkcada taupaso ( taues un hiperparámetro que definimos).

DQN dobles

Teoría

Hado van Hasselt introdujo las DQN dobles, o aprendizaje doble. Este método resuelve el problema de la sobreestimación de los valores Q.

Para comprender este problema, recuerde cómo calculamos el TD Target:

Al calcular el objetivo de TD, nos enfrentamos a un problema simple: ¿cómo estamos seguros de que la mejor acción para el siguiente estado es la acción con el valor Q más alto?

Sabemos que la precisión de los valores q depende de la acción que intentamos y de los estados vecinos que exploramos.

Como consecuencia, al comienzo de la capacitación no tenemos suficiente información sobre la mejor acción a tomar. Por lo tanto, tomar el valor máximo de q (que es ruidoso) como la mejor acción a tomar puede conducir a falsos positivos. Si las acciones no óptimas reciben regularmente un valor Q más alto que la mejor acción óptima, el aprendizaje será complicado.

La solución es: cuando calculamos el objetivo Q, usamos dos redes para desacoplar la selección de acción de la generación del valor Q objetivo. Nosotros:

  • utilice nuestra red DQN para seleccionar cuál es la mejor acción a tomar para el siguiente estado (la acción con el valor Q más alto).
  • use nuestra red objetivo para calcular el valor Q objetivo de tomar esa acción en el siguiente estado.

Por tanto, Double DQN nos ayuda a reducir la sobreestimación de los valores q y, como consecuencia, nos ayuda a entrenar más rápido y tener un aprendizaje más estable.

Implementación

Duelo de DQN (también conocido como DDQN)

Teoría

Recuerde que los valores Q corresponden a lo bueno que es estar en ese estado y realizar una acción en ese estado Q (s, a).

Entonces podemos descomponer Q (s, a) como la suma de:

  • V (s) : el valor de estar en ese estado
  • A (s, a) : la ventaja de tomar esa acción en ese estado (cuánto mejor es tomar esta acción en comparación con todas las demás acciones posibles en ese estado).

Con DDQN, queremos separar el estimador de estos dos elementos, usando dos nuevos flujos:

  • uno que estima el valor de estado V (s)
  • uno que estima la ventaja para cada acción A (s, a)

Y luego combinamos estos dos flujos a través de una capa de agregación especial para obtener una estimación de Q (s, a).

¿Espere? Pero, ¿por qué necesitamos calcular estos dos elementos por separado si luego los combinamos?

Al desacoplar la estimación, nuestro DDQN puede aprender intuitivamente qué estados son (o no) valiosos sin tener que aprender el efecto de cada acción en cada estado (ya que también calcula V (s)).

Con nuestro DQN normal, necesitamos calcular el valor de cada acción en ese estado. Pero, ¿de qué sirve si el valor del estado es malo? ¿De qué sirve calcular todas las acciones en un estado cuando todas estas acciones conducen a la muerte?

Como consecuencia, al desacoplar podemos calcular V (s). Esto es particularmente útil para los estados donde sus acciones no afectan el medio ambiente de manera relevante. En este caso, no es necesario calcular el valor de cada acción. Por ejemplo, moverse hacia la derecha o hacia la izquierda solo importa si existe riesgo de colisión. Y, en la mayoría de los estados, la elección de la acción no tiene ningún efecto sobre lo que sucede.

Será más claro si tomamos el ejemplo del documento Dueling Network Architectures for Deep Reinforcement Learning.

Vemos que los flujos de la red de valor prestan atención (el desenfoque naranja) a la carretera y, en particular, al horizonte donde se generan los coches. También presta atención a la partitura.

Por otro lado, el flujo de ventaja en el primer cuadro de la derecha no presta mucha atención a la carretera, porque no hay autos en frente (por lo que la elección de la acción es prácticamente irrelevante). Pero, en el segundo cuadro se presta atención, ya que hay un coche inmediatamente delante de él, y la elección de la acción es crucial y muy relevante.

Con respecto a la capa de agregación, queremos generar los valores q para cada acción en ese estado. Podríamos tener la tentación de combinar las corrientes de la siguiente manera:

Pero si hacemos eso, caeremos en elcuestión de identificabilidad , es decir, dado Q (s, a) no podemos encontrar A (s, a) y V (s).

Y no poder encontrar V (s) y A (s, a) dados Q (s, a) será un problema para nuestra propagación hacia atrás. Para evitar este problema, podemos forzar a nuestro estimador de función de ventaja a tener 0 de ventaja en la acción elegida.

Para hacer eso, restamos la ventaja promedio de todas las acciones posibles del estado.

Por tanto, esta arquitectura nos ayuda a acelerar el entrenamiento. Podemos calcular el valor de un estado sin calcular Q (s, a) para cada acción en ese estado. Y puede ayudarnos a encontrar valores Q mucho más confiables para cada acción al desacoplar la estimación entre dos corrientes.

Implementación

Lo único que debe hacer es modificar la arquitectura DQN agregando estos nuevos flujos:

Repetición de experiencia priorizada

Teoría

La repetición de experiencia priorizada (PER) fue presentada en 2015 por Tom Schaul. La idea es que algunas experiencias pueden ser más importantes que otras para nuestro entrenamiento, pero pueden ocurrir con menos frecuencia.

Debido a que muestreamos el lote de manera uniforme (seleccionando las experiencias al azar), estas ricas experiencias que ocurren rara vez tienen prácticamente ninguna posibilidad de ser seleccionadas.

Por eso, con PER, intentamos cambiar la distribución muestral usando un criterio para definir la prioridad de cada tupla de experiencia.

Queremos aprovechar la experiencia prioritaria donde hay una gran diferencia entre nuestra predicción y el objetivo de TD, ya que significa que tenemos mucho que aprender al respecto.

Usamos el valor absoluto de la magnitud de nuestro error TD:

Y ponemos esa prioridad en la experiencia de cada búfer de reproducción.

Pero no podemos simplemente hacer una priorización codiciosa, porque conducirá a entrenar siempre las mismas experiencias (que tienen una gran prioridad) y, por lo tanto, a un ajuste excesivo.

Entonces introducimos la priorización estocástica, que genera la probabilidad de ser elegido para una repetición.

Como consecuencia, durante cada paso de tiempo, obtendremos unlote de muestras con esta distribución de probabilidad y capacitar a nuestra red en ella.

Pero todavía tenemos un problema aquí. Recuerde que con Experience Replay normal, usamos una regla de actualización estocástica. Como consecuencia, la forma en que muestreamos las experiencias debe coincidir con la distribución subyacente de la que provienen.

Cuando tenemos una experiencia normal, seleccionamos nuestras experiencias en una distribución normal; en pocas palabras, seleccionamos nuestras experiencias al azar. No hay sesgo, porque cada experiencia tiene la misma probabilidad de ser aprovechada, por lo que podemos actualizar nuestras ponderaciones normalmente.

Pero , debido a que usamos muestreo prioritario, se abandona el muestreo puramente aleatorio. Como consecuencia, introducimos un sesgo hacia muestras de alta prioridad (más posibilidades de ser seleccionado).

Y, si actualizamos nuestros pesos normalmente, corremos el riesgo de un ajuste excesivo. Es probable que las muestras que tienen alta prioridad se utilicen para la capacitación muchas veces en comparación con las experiencias de baja prioridad (= sesgo). Como consecuencia, actualizaremos nuestras ponderaciones con solo una pequeña parte de las experiencias que consideramos realmente interesantes.

Para corregir este sesgo, utilizamos ponderaciones muestrales de importancia (IS) que ajustarán la actualización reduciendo las ponderaciones de las muestras que se ven con frecuencia.

Los pesos correspondientes a muestras de alta prioridad tienen muy poco ajuste (porque la red verá estas experiencias muchas veces), mientras que los correspondientes a muestras de baja prioridad tendrán una actualización completa.

El papel de b es controlar en qué medida estas ponderaciones muestrales de importancia afectan el aprendizaje. En la práctica, el parámetro b se templa a 1 durante la duración del entrenamiento, porque estos pesos son más importantes al final del aprendizaje cuando nuestros valores q comienzan a converger. La naturaleza imparcial de las actualizaciones es más importante cerca de la convergencia, como se explica en este artículo.

Implementación

Esta vez, la implementación será un poco más elegante.

En primer lugar, no podemos simplemente implementar PER ordenando todos los búferes de reproducción de experiencias de acuerdo con sus prioridades. Esto no será eficaz en absoluto debido a O (nlogn) para la inserción y O (n) para el muestreo.

Como se explica en este artículo realmente bueno, necesitamos usar otra estructura de datos en lugar de ordenar una matriz: un árbol de suma sin clasificar .

Un árbol de suma es un árbol binario, es decir, un árbol con solo un máximo de dos hijos para cada nodo. Las hojas (los nodos más profundos) contienen los valores de prioridad y una matriz de datos que apunta a las hojas contiene las experiencias.

Actualizar el árbol y el muestreo será realmente eficiente (O (log n)).

Luego, creamos un objeto de memoria que contendrá nuestro árbol de suma y datos.

A continuación, para muestrear un minibatch de tamaño k, el rango [0, total_priority] se dividirá en k rangos. Se muestrea uniformemente un valor de cada rango.

Finalmente, las transiciones (experiencias) que corresponden a cada uno de estos valores muestreados se recuperan del árbol de suma.

Será mucho más claro cuando profundicemos en los detalles completos en el cuaderno.

Agente de Doom Deathmatch

Este agente es un Dueling Double Deep Q Learning con PER y objetivos q fijos.

Realizamos un video tutorial de la implementación: El cuaderno está aquí

¡Eso es todo! Acabas de crear un agente más inteligente que aprende a jugar a Doom. ¡Increíble! Recuerda que si quieres tener un agente con muy buen rendimiento, ¡necesitas muchas más horas de GPU (unos dos días de formación)!

Sin embargo, con solo 2-3 horas de entrenamiento en CPU (sí, CPU), nuestro agente entendió que necesitaban matar enemigos antes de poder avanzar. Si avanzan sin matar enemigos, serán asesinados antes de obtener el chaleco.

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, agregar valores Q fijos, cambiar la tasa de aprendizaje, usar un entorno más difícil ... y así sucesivamente. ¡Experimenta, diviértete!

Recuerde que este fue un artículo importante, así que asegúrese de comprender realmente por qué usamos estas nuevas estrategias, cómo funcionan y las ventajas de usarlas.

En el próximo artículo, aprenderemos sobre un método híbrido asombroso entre algoritmos de aprendizaje por refuerzo basados ​​en valores y basados ​​en políticas. Ésta es una línea de base para los algoritmos más avanzados : Advantage Actor Critic (A2C). ¡Implementarás un agente que aprende a jugar Outrun!

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!

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

¡Sigue aprendiendo, mantente genial!

¿Curso de aprendizaje de refuerzo profundo con Tensorflow? ️

? Silaba

? Versión de video

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 5: Introducción a los métodos Advantage Actor Critic: ¡juguemos a Sonic the Hedgehog!

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