Introducción al aprendizaje por refuerzo. Parte 5: políticas de gradiente

Markel Sanz Ausin
7 min readNov 25, 2020

En esta parte cambiaremos ligeramente de tema para hablar de los algoritmos de políticas de gradiente (Policy Gradient algorithms) [1], y derivaremos el gradiente de la política de forma matemática.

Entre las formas de clasificar los algoritmos de aprendizaje por refuerzo que hemos descrito en la parte anterior, nos hemos dejado una verdaderamente importante. Los algoritmos se pueden clasificar en algoritmos basados en el valor (Value-Based) y los algoritmos basados en la política (Policy-Based).

Los algoritmos que utilizan únicamente una función de valor o de acción-valor sin implementar una política de forma explicita, entran en el grupo de los algoritmos basados en el valor. Estos algoritmos no te dicen qué acción debes tomar explícitamente, sino que te indican cuánta recompensa recibirás desde cada estado o estado-acción. Por la tanto, tú debes decidir qué acción tomar tras ver estos valores. Un ejemplo puede ser tomar siempre la acción con el valor-Q más alto. Otro ejemplo podría ser seguir una política ε-voraz. Entre los algoritmos basados en el valor están Q-Learning, DQN, y los demás algoritmos vistos hasta ahora.

Los algoritmos que implementan una política que decide qué acción tomar en cada momento de forma explícita, entran en el grupo de algoritmos basados en la política.

Estos algoritmos definen una política que decide las probabilidades de tomar cada acción para cada estado.

Es decir, está función no nos dice cuánta recompensa recibirá el agente desde cada estado. No aprende ni una función de valor V(s) ni una de acción-valor Q(s,a). Estos algoritmos definen solamente una función de política (Policy Function) π(a|s) que estima la probabilidad de tomar cada posible acción desde cada estado.

Comparacion de los algoritmos basados en el valor y en la política [1]

  • Ventajas de los algoritmos basados en el valor:
    1. Se pueden entrenar fuera de la política (off-policy) más fácilmente.
    2. Bastante más eficientes respecto a la cantidad de datos necesaria para aprender (sample efficiency).
    3. Menor varianza.
  • Ventajas de los algoritmos basados en la política:
    1. Pueden representar acciones continuas, por lo que son mejores para entornos estocásticos y entornos con acciones continuas o de muchas dimensiones (high-dimensional).
    2. Optimizan directamente la función que nos interesa optimizar (la política), sin intermediarios.
    3. Convergen más rápido.

Algoritmos Actor-Crítico

Existe un tercer grupo de algoritmos, que intenta combinar lo mejor de ambos mundos: los algoritmos actor-crítico (actor-critic). Para ello, estos algoritmos utilizan tanto una función de valor como una función de política. De estos algoritmos hablaremos más en el futuro, pero aquí hay un esquema de dónde se sitúan.

Derivando el gradiente de la política [2]

Si prefieres no leer cómo se deriva el gradiente de la política, puedes saltarte esta sección.

Ahora nos centraremos en los algoritmos basados en la política (Policy-Based) para el caso de las políticas estocásticas. Como hemos mencionado antes, estos algoritmos usan una función probabilística que determina la probabilidad de tomar cada acción desde cada estado: π(a|s). En el futuro hablaremos del gradiente de las políticas deterministas. Normalmente, las políticas estocásticas se escriben con el símbolo π, y el proceso de muestreo de una acción se escribe a ~ π(a|s). Las políticas deterministas se escriben con el símbolo μ, y el proceso de elegir una acción se escribe a = μ(s).

La política óptima (optimal policy) será aquella que consiga el retorno más alto posible en una trayectoria finita τ. La esperanza del retorno, que es lo que queremos maximizar, se define como:

Definición de la esperanza del retorno.

Utilizaremos el ascenso de gradiente (gradient ascent) para mover los parámetros de nuestra función en la dirección que nos haga aumentar la esperanza del retorno, lo que hará que aumenten las recompensas recibidas. Para poder ejecutar el algoritmo de ascenso de gradiente, debemos calcular el gradiente de esta función. Y cambiaremos los parámetros θ de nuestra política π en la dirección que nos marque el ascenso del gradiente del retorno:

Ascenso de gradiente para mejorar los parámetros de nuestra política.

Para calcular el gradiente del retorno ∇ J(π), empezaremos por calcular el gradiente de la función de política ∇ π(τ). Para ello, utilizaremos dos trucos que nos permitirán simplificar notablemente los cálculos. El primero consiste en multiplicar el gradiente a calcular por la constante π(τ)/π(τ). El gradiente de nuestra función de política con respecto a los parámetros θ es entonces:

Multiplicamos el gradiente de la política por la constante para facilitar el cálculo.

Y el segundo truco es recordar que la derivada de ln(x) es igual a 1/x. Por lo tanto, la derivada de ln(f(x)) es igual a (1/f(x)) * f´(x). Para simplificar la notación, generalizaremos el logaritmo como ¨log¨ de aquí en adelante. Por lo tanto, el gradiente de nuestra función de política es:

Gradiente de la política

Ahora que hemos calculado el gradiente de la política, usémoslo para calcular el gradiente del retorno, que es lo que realmente deseamos maximizar. Ésta es la política de gradiente final que usaremos.

Ésta es la versión más simple del gradiente de la política para los algoritmos basados en la política.

De esta forma, moveremos los parámetros de nuestra política en la dirección que aumente R(τ).

Esta versión de las políticas de gradiente tiene una varianza alta, y no es del todo adecueda para entornos complicados. Por ahora nos servirá, pero en la parte siguiente veremos cómo se puede mejorar. Implementemos un algoritmo que utilice este gradiente para mejorar la política.

El código

Puedes encontrar el código ejecutable que utiliza TensorFlow en este enlace (o la versión que usa PyTorch en este enlace).

Implementaremos el código de la misma forma que en las partes anteriores. Lo primero que cambiaremos será la arquitectura de la red neuronal, que actuará de política. A diferencia de las partes anteriores, nuestra red neuronal debe ser capaz de generar probabilidades, por lo que creamos una distribución categórica, ya que las acciones son discretas. En el futuro usaremos otras distribuciones más adecuadas para acciones continuas. A esta distribución le pasaremos los valores de la última capa de la red neuronal. Esa distribución nos proporcionará las probabilidades de escoger cada una de las acciones. También tendremos que calcular los logaritmos de esas probabilidades.

Ahora que ya tenemos la red neuronal que define nuestra política, definamos la función que usaremos para entrenarla, usando el gradiente de la política que hemos derivado arriba.

Crearemos una función que reciba los estados, las acciones, y los retornos que usaremos para entrenar el algoritmo en cada iteración. Le pasaremos los estados a la red neuronal, y ésta generará las probabilidades y sus logaritmos para cada estado del lote (batch). Después crearemos una máscara para quedarnos solo con las probabilidades de la acción seleccionada por la política e ignorar las demás probabilidades. Y por último, nuestra función de pérdida será la multiplicación de el retorno y el logaritmo de la probabilidad de cada acción, que es exactamente el gradiente de la política, como hemos definido en la parte anterior. Por último minimizaremos esa función de pérdida para entrenar nuestra red neuronal.

Para terminar, ejecutaremos el bucle principal donde recolectar los estados y las acciones, acumular las recompensas de todo el episodio para formar el retorno, y pasárselos a la función para entrenar la red neuronal.

Resultado de entrenar un agente con las políticas de gradiente.

Esta vez cambiaremos de entorno; usaremos el entorno Acrobot, en el cual el agente debe aprender a mover el brazo hasta que la punta del brazo quede por encima de la linea horizontal. Cuanto menos tarde, mejor recompensa obtendrá el agente. El resultado de entrenar este algoritmo se puede ver en la animación de la izquierda.

Puedes encontrar el código ejecutable que utiliza TensorFlow en este enlace (o la versión que usa PyTorch en este enlace).

Referencias

[1] Curso de David Silver en la UCL sobre RL

[2] SpinUp OpenAI

[3] Sutton, R. S., & Barto, A. G. (2018). Reinforcement learning: An introduction. MIT press.

Mi repositorio de GitHub con algoritmos frecuentes de aprendizaje por refuerzo profundo (en desarrollo): https://github.com/markelsanz14/independent-rl-agents

--

--