Optimización de Política Proximal (PPO)
'PPO' stands for Proximal Policy Optimization.
Unidad 8, del Curso de Aprendizaje Profundo por Reforzamiento con Hugging Face 🤗
⚠️ Una nueva versión actualizada de este artículo está disponible aquí 👉 https://huggingface.co/deep-rl-course/unit1/introduction
Este artículo es parte del Curso de Aprendizaje Profundo por Reforzamiento. Un curso gratuito desde principiante hasta experto. Consulta el plan de estudios aquí.
⚠️ Una nueva versión actualizada de este artículo está disponible aquí 👉 https://huggingface.co/deep-rl-course/unit1/introduction
Este artículo es parte del Curso de Aprendizaje Profundo por Reforzamiento. Un curso gratuito desde principiante hasta experto. Consulta el plan de estudios aquí.
En la última unidad, aprendimos sobre el Advantage Actor Critic (A2C), una arquitectura híbrida que combina métodos basados en valor y basados en política que ayudan a estabilizar el entrenamiento al reducir la varianza con:
- Implementando 🤗 ViT en Kubernetes con TF Serving
- Una Introducción Suave a la Multiplicación de Matrices de 8 bits pa...
- Desplegando 🤗 ViT en Vertex AI
- Un Actor que controla cómo se comporta nuestro agente (método basado en política).
- Un Crítico que mide qué tan buena es la acción tomada (método basado en valor).
Hoy aprenderemos sobre la Optimización de Políticas Proximales (PPO), una arquitectura que mejora la estabilidad del entrenamiento de nuestro agente evitando actualizaciones de políticas demasiado grandes. Para hacer esto, usamos una proporción que indica la diferencia entre nuestra política actual y la antigua, y recortamos esta proporción en un rango específico [ 1 − ϵ , 1 + ϵ ] [1 – \epsilon, 1 + \epsilon] [ 1 − ϵ , 1 + ϵ ].
Haciendo esto nos aseguramos de que la actualización de nuestra política no sea demasiado grande y que el entrenamiento sea más estable.
Y luego, después de la teoría, codificaremos una arquitectura de PPO desde cero utilizando PyTorch y aseguraremos nuestra implementación con CartPole-v1 y LunarLander-v2.
¿Suena emocionante? ¡Empecemos!
- La intuición detrás de PPO
- Introduciendo el Objetivo de Sustitución Recortada
- Recapitulación: La Función Objetivo de la Política
- La Función de Proporción
- La parte sin recortar de la Función Objetivo de Sustitución Recortada
- La parte recortada de la Función Objetivo de Sustitución Recortada
- Visualizar el Objetivo de Sustitución Recortada
- Caso 1 y 2: la proporción está dentro del rango
- Caso 3 y 4: la proporción está por debajo del rango
- Caso 5 y 6: la proporción está por encima del rango
- Codifiquemos nuestro Agente PPO
La intuición detrás de PPO
La idea con la Optimización de Políticas Proximales (PPO) es que queremos mejorar la estabilidad del entrenamiento de la política limitando el cambio que hacemos a la política en cada época de entrenamiento: queremos evitar tener actualizaciones de política demasiado grandes.
Por dos razones:
- Sabemos empíricamente que las actualizaciones de política más pequeñas durante el entrenamiento son más propensas a converger hacia una solución óptima.
- Un paso demasiado grande en una actualización de política puede resultar en caer “por el precipicio” (obtener una política incorrecta) y tener un tiempo largo o incluso ninguna posibilidad de recuperación.

Entonces, con PPO, actualizamos la política de manera conservadora. Para hacerlo, necesitamos medir cuánto cambió la política actual en comparación con la anterior utilizando un cálculo de proporción entre la política actual y la anterior. Y recortamos esta proporción en un rango [ 1 − ϵ , 1 + ϵ ] [1 – \epsilon, 1 + \epsilon] [ 1 − ϵ , 1 + ϵ ], lo que significa que eliminamos el incentivo para que la política actual se aleje demasiado de la antigua (de ahí el término de política proximal).
Introduciendo el Objetivo de Sustitución Recortada
Recap: La Función Objetivo de la Política
Recordemos cuál es el objetivo a optimizar en Reinforce:
La idea era que al tomar un paso de ascenso del gradiente en esta función (equivalente a tomar un descenso del gradiente de la negativa de esta función), empujaríamos a nuestro agente a tomar acciones que conduzcan a mayores recompensas y evitar acciones perjudiciales.
Sin embargo, el problema viene del tamaño del paso:
- Si es demasiado pequeño, el proceso de entrenamiento es demasiado lento
- Si es demasiado grande, hay demasiada variabilidad en el entrenamiento
Aquí con PPO, la idea es limitar nuestra actualización de política con una nueva función objetivo llamada la función objetivo sustituta con recorte, que restringirá el cambio de política en un rango pequeño usando un recorte.
Esta nueva función está diseñada para evitar actualizaciones destructivas con pesos grandes:
Estudiemos cada parte para entender cómo funciona.
La Función de Proporción
Esta proporción se calcula de la siguiente manera:
Es la probabilidad de tomar la acción a t a_t a t en el estado s t s_t s t en la política actual dividida por la anterior.
Como podemos ver, r t ( θ ) r_t(\theta) r t ( θ ) denota la proporción de probabilidad entre la política actual y la antigua:
- Si r t ( θ ) > 1 r_t(\theta) > 1 r t ( θ ) > 1 , la acción a t a_t a t en el estado s t s_t s t es más probable en la política actual que en la antigua.
- Si r t ( θ ) r_t(\theta) r t ( θ ) está entre 0 y 1, la acción es menos probable para la política actual que para la antigua.
Por lo tanto, esta proporción de probabilidad es una manera fácil de estimar la divergencia entre la política antigua y la actual.
La parte sin recorte de la función objetivo sustituta con recorte
Esta proporción puede reemplazar la probabilidad logarítmica que usamos en la función objetivo de la política. Esto nos da la parte izquierda de la nueva función objetivo: multiplicar la proporción por la ventaja.

Sin embargo, sin una restricción, si la acción tomada es mucho más probable en nuestra política actual que en la anterior, esto llevaría a un paso de gradiente de política significativo y, por lo tanto, a una actualización de política excesiva.
La parte recortada de la función objetivo sustituta con recorte
Por lo tanto, necesitamos limitar esta función objetivo penalizando los cambios que conducen a una proporción lejos de 1 (en el documento, la proporción solo puede variar de 0.8 a 1.2).
Al recortar la proporción, nos aseguramos de que no tengamos una actualización de política demasiado grande porque la política actual no puede ser demasiado diferente de la anterior.
Para hacer eso, tenemos dos soluciones:
- TRPO (Optimización de Política de Región Confiable) usa restricciones de divergencia KL fuera de la función objetivo para limitar la actualización de política. Pero este método es complicado de implementar y requiere más tiempo de computación.
- PPO recorta la proporción de probabilidad directamente en la función objetivo con su función objetivo sustituta con recorte.
Esta parte recortada es una versión donde rt(theta) está recortado entre [ 1 − ϵ , 1 + ϵ ] [1 – \epsilon, 1 + \epsilon] [ 1 − ϵ , 1 + ϵ ].
Con la función objetivo sustituta recortada, tenemos dos ratios de probabilidad, uno no recortado y otro recortado en un rango (entre [ 1 − ϵ , 1 + ϵ ] [1 – \epsilon, 1 + \epsilon] [ 1 − ϵ , 1 + ϵ ] , epsilon es un hiperparámetro que nos ayuda a definir este rango de recorte (en el papel ϵ = 0.2 \epsilon = 0.2 ϵ = 0 . 2 .).
Luego, tomamos el mínimo entre el objetivo recortado y no recortado, por lo que el objetivo final es un límite inferior (límite pesimista) del objetivo no recortado.
Tomar el mínimo entre el objetivo recortado y no recortado significa que seleccionaremos el objetivo recortado o no recortado según la proporción y la situación de ventaja.
Visualizar el Objetivo Sustituto Recortado
No te preocupes. Es normal si esto parece complejo de manejar en este momento. Pero vamos a ver cómo se ve esta Función Objetivo Sustituta Recortada, y esto te ayudará a visualizar mejor lo que está sucediendo.

Tenemos seis situaciones diferentes. Recuerda primero que tomamos el mínimo entre los objetivos recortados y no recortados.
Caso 1 y 2: la proporción está entre el rango
En las situaciones 1 y 2, el recorte no se aplica ya que la proporción está entre el rango [ 1 − ϵ , 1 + ϵ ] [1 – \epsilon, 1 + \epsilon] [ 1 − ϵ , 1 + ϵ ]
En la situación 1, tenemos una ventaja positiva: la acción es mejor que el promedio de todas las acciones en ese estado. Por lo tanto, debemos alentar a nuestra política actual a aumentar la probabilidad de tomar esa acción en ese estado.
Dado que la proporción está entre intervalos, podemos aumentar la probabilidad de nuestra política de tomar esa acción en ese estado.
En la situación 2, tenemos una ventaja negativa: la acción es peor que el promedio de todas las acciones en ese estado. Por lo tanto, debemos desalentar a nuestra política actual a tomar esa acción en ese estado.
Dado que la proporción está entre intervalos, podemos disminuir la probabilidad de que nuestra política tome esa acción en ese estado.
Caso 3 y 4: la proporción está por debajo del rango

Si la proporción de probabilidad es menor que [ 1 − ϵ ] [1 – \epsilon] [ 1 − ϵ ] , la probabilidad de tomar esa acción en ese estado es mucho menor que con la política anterior.
Si, como en la situación 3, la estimación de ventaja es positiva (A>0), entonces queremos aumentar la probabilidad de tomar esa acción en ese estado.
Pero si, como en la situación 4, la estimación de ventaja es negativa, no queremos disminuir aún más la probabilidad de tomar esa acción en ese estado. Por lo tanto, el gradiente es = 0 (ya que estamos en una línea plana), por lo que no actualizamos nuestros pesos.
Caso 5 y 6: la proporción está por encima del rango

Si la relación de probabilidad es mayor que [ 1 + ϵ ] , la probabilidad de tomar esa acción en ese estado en la política actual es mucho mayor que en la política anterior.
Si, como en la situación 5, la ventaja es positiva, no queremos ser demasiado codiciosos . Ya tenemos una mayor probabilidad de tomar esa acción en ese estado que en la política anterior. Por lo tanto, el gradiente es igual a 0 (ya que estamos en una línea plana), por lo que no actualizamos nuestros pesos.
Si, como en la situación 6, la ventaja es negativa, queremos disminuir la probabilidad de tomar esa acción en ese estado.
Entonces, si recapitulamos, solo actualizamos la política con la parte objetiva no recortada . Cuando el mínimo es la parte objetiva recortada, no actualizamos nuestros pesos de política ya que el gradiente será igual a 0.
Por lo tanto, actualizamos nuestra política solo si:
- Nuestra relación está en el rango [ 1 − ϵ , 1 + ϵ ]
- Nuestra relación está fuera del rango, pero la ventaja nos acerca al rango
- Si está por debajo de la relación pero la ventaja es > 0
- Si está por encima de la relación pero la ventaja es < 0
Te preguntarás por qué, cuando el mínimo es la relación recortada, el gradiente es 0. Cuando la relación está recortada, la derivada en este caso no será la derivada de r t ( θ ) ∗ A t , sino la derivada de ( 1 − ϵ ) ∗ A t o la derivada de ( 1 + ϵ ) ∗ A t , que ambas son iguales a 0.
En resumen, gracias a este objetivo sustituto recortado, restringimos el rango en el que la política actual puede variar en comparación con la anterior. Porque eliminamos el incentivo para que la relación de probabilidad se mueva fuera del intervalo, ya que el recorte tiene el efecto de establecer el gradiente. Si la relación es > 1 + ϵ o < 1 − ϵ , el gradiente será igual a 0.
La pérdida objetivo sustituta recortada final para el estilo PPO Actor-Critic se ve así, es una combinación de la función objetivo sustituta recortada, la función de pérdida de valor y la bonificación de entropía:
Eso fue bastante complejo. Tómate tu tiempo para comprender estas situaciones mirando la tabla y el gráfico. Debes entender por qué tiene sentido. Si quieres profundizar, el mejor recurso es el artículo “Hacia la entrega de una explicación coherente y autocontenida de la optimización de la política proximal” de Daniel Bick, especialmente la parte 3.4 .
Vamos a codificar nuestro Agente PPO
Ahora que hemos estudiado la teoría detrás de PPO, la mejor manera de entender cómo funciona es implementarlo desde cero.
Implementar una arquitectura desde cero es la mejor manera de entenderla, y es una buena práctica. Ya lo hemos hecho para un método basado en valores con Q-Learning y un método basado en políticas con Reinforce.
Entonces, para poder codificarlo, vamos a utilizar dos recursos:
- Un tutorial realizado por Costa Huang. Costa está detrás de CleanRL, una biblioteca de Aprendizaje Profundo por Reforzamiento que proporciona una implementación de un solo archivo de alta calidad con características amigables para la investigación.
- Además del tutorial, para profundizar, puedes leer los 13 detalles de implementación principales: https://iclr-blog-track.github.io/2022/03/25/ppo-implementation-details/
Luego, para probar su robustez, vamos a entrenarlo en 2 entornos clásicos diferentes:
- Cartpole-v1
- LunarLander-v2
Y finalmente, vamos a subir el modelo entrenado al Hub para evaluar y visualizar a su agente jugando.
LunarLander-v2 es el primer entorno que usaste cuando comenzaste este curso. En ese momento, no sabías cómo funcionaba, y ahora puedes programarlo desde cero y entrenarlo. ¡Qué increíble es eso 🤩!
via GIPHY
Comienza el tutorial aquí 👉 https://github.com/huggingface/deep-rl-class/blob/main/unit8/unit8.ipynb
¡Felicidades por terminar este capítulo! Había mucha información. Y felicitaciones por terminar el tutorial. 🥳, este fue uno de los más difíciles del curso.
No dudes en entrenar a tu agente en otros entornos. ¡La mejor manera de aprender es intentar cosas por ti mismo/a!
Quiero que pienses en tu progreso desde la primera Unidad. Con estas ocho unidades, has construido una base sólida en Aprendizaje Profundo por Reforzamiento. ¡Felicitaciones!
Pero esto no es el final, aunque la parte de fundamentos del curso haya terminado, esto no es el fin del viaje. Estamos trabajando en nuevos elementos:
- Agregar nuevos entornos y tutoriales.
- Una sección sobre multi-agentes (auto-juego, colaboración, competencia).
- Otra sobre RL fuera de línea y Transformadores de Decisiones.
- Artículos explicados de investigaciones.
- Y más por venir.
La mejor manera de mantenernos en contacto es registrarte en el curso para que te mantengamos actualizado/a 👉 http://eepurl.com/h1pElX
¡Y no olvides compartir con tus amigos que quieran aprender 🤗!
Finalmente, con tus comentarios, queremos mejorar y actualizar el curso de forma iterativa. Si tienes alguno, por favor completa este formulario 👉 https://forms.gle/3HgA7bEHwAmmLfwh9
¡Hasta la próxima!