¿Entrenar de cero o a partir de una política anterior?
Cuando empiezas a encadenar varias fases de entrenamiento, tarde o temprano aparece esta duda: ¿tiene sentido reutilizar una política anterior o es mejor entrenar desde cero?
Pues depende de qué haya cambiado entre una fase y la siguiente. Y no siempre merece la pena forzar la reutilización de una política solo porque ya existe.
Entrenar a partir de una política anterior significa usar una red que ya ha aprendido algo útil como punto de partida para un nuevo entrenamiento. La política no empieza desde pesos aleatorios, sino desde un comportamiento que ya funciona más o menos. Eso suele hacer que el entrenamiento sea más rápido y más estable, sobre todo cuando el nuevo objetivo es una extensión clara del anterior.
Por ejemplo, si una política ya sabe mantener el equilibrio, tiene bastante sentido reutilizarla cuando el siguiente objetivo es empezar a moverse sin caerse. Empezar desde cero obligaría a la red a aprender equilibrio y movimiento a la vez, lo que normalmente hace el entrenamiento más lento y más caótico.
Ahora bien, esto solo funciona si el problema sigue siendo compatible. Y aquí es donde empiezan los matices importantes.
Compatibilidad
Para poder cargar una política anterior, el tamaño del vector de observaciones y del vector de acciones tiene que ser el mismo. La red está construida esperando un número concreto de entradas, y si ese número cambia, la política deja de ser compatible. No es una decisión conceptual, es simplemente cómo funcionan las redes neuronales.
Esto se vuelve especialmente relevante cuando, al avanzar de fase, aparecen nuevas observaciones que antes no eran necesarias. Añadir nuevas observaciones cambia el problema que la política está resolviendo. En ese caso, cargar directamente una política entrenada con un vector de observaciones más pequeño no tiene sentido.
Estrategias entrenando de cero
Supongamos que de una fase a otra hemos agregado observaciones nuevas para poder realizar el entrenamiento. En este caso, no podremos reutilizar la politica obtenida en el entrenamiento de la fase anterior.
Llegados a este hay varias opciones, y ninguna es la correcta en todos los casos. Una estrategia que suele funcionar bien es entrenar primero desde cero una política base usando ya el vector de observaciones nuevo, pero con un objetivo simple, como el equilibrio. De esta forma la red aprende a interpretar las nuevas observaciones en un entorno controlado. A partir de ahí, sí tiene sentido reutilizar esa política para fases posteriores más complejas.
Otra opción es entrenar directamente el objetivo final desde cero con el nuevo vector de observaciones. Esto también funciona, pero suele ser más difícil de depurar, porque estás mezclando demasiadas cosas a la vez: nuevas observaciones, nuevos objetivos y una política sin ningún conocimiento previo.
Es importante recalcar que entrenar desde cero no significa volver al punto inicial del proyecto. Aunque los pesos de la red se reinicien, el diseño del entorno, las recompensas y las observaciones suele ser mucho mejor gracias a lo aprendido en fases anteriores. No se pierde todo lo anterior, aunque la política sí sea nueva.
Ejemplo práctico
Supongamos que en el proyecto se ha completado una primera fase de entrenamiento utilizando un vector de observaciones muy básico y unas recompensas orientadas al objetivo de la Fase 1, obteniendo una política que parece funcionar correctamente.
Al avanzar a la Fase 2, estas observaciones resultan insuficientes para el nuevo objetivo, por lo que es necesario añadir nuevas componentes al vector de observación. Esto hace que la política entrenada en la fase anterior deje de ser compatible y no pueda reutilizarse directamente.
Con el nuevo vector de observaciones ampliado, se diseñan de nuevo las recompensas para resolver primero el objetivo de la Fase 1 y se lanza un entrenamiento desde cero. El resultado es una política compatible con el nuevo espacio de observaciones.
Una vez obtenida esta política base, ya es posible reutilizarla para entrenar el objetivo de la Fase 2. Para ello se ajustan las recompensas al nuevo objetivo y se lanza un nuevo entrenamiento cargando la política entrenada en el paso anterior.
Reanudar el entrenamiento con --resume
--resumeDurante las primeras pruebas cometí el error de modificar las recompensas y reanudar el entrenamiento usando --resume, esperando que la política se adaptase automáticamente al nuevo objetivo.
Esto dió lugar a comportamientos extraños, aún haciendo cambios importantes en las recompensas apenas parecían tener efecto. Por las malas descubrí que --resume no significa seguir entrenando a partir de una política, sino continuar exactamente el mismo entrenamiento.
Al reanudar un entrenamiento se cargan no solo los pesos de la red, sino también el estado interno del optimizador (por ejemplo, la información acumulada sobre gradientes y direcciones de mejora). Si las recompensas, el objetivo o el significado de las observaciones han cambiado, el problema que se está resolviendo ya no es el mismo, pero el optimizador sigue actuando como si lo fuera.
Por este motivo, reanudar un entrenamiento cuando se modifican las recompensas, los objetivos o las observaciones no es una buena idea. El uso correcto de --resume se limita a casos en los que el entrenamiento se ha interrumpido y se desea continuar exactamente el mismo experimento, sin cambios.
Si lo que se quiere es reutilizar una política para entrenar un objetivo distinto, lo correcto no es reanudar un entrenamiento, sino cargar los pesos de la política y lanzar un entrenamiento nuevo.
Advertencia sobre --load_run y --checkpoint
--load_run y --checkpointUna confusión que me hizo dar vueltas en círculos durante días fue pensar que las opciones --load_run y --checkpoint permitían cargar únicamente una política entrenada previamente para iniciar un nuevo entrenamiento por fases.
Al menos en RSL-RL, esto no es así. Estas opciones solo tienen efecto cuando se utilizan junto con --resume, y en ese caso el comportamiento es equivalente a reanudar el entrenamiento completo. Es decir, además de los pesos de la red, se cargan también el estado del optimizador y otros datos internos del checkpoint.
Por tanto, --load_run y --checkpoint no sirven por sí solos para un entrenamiento por fases, y su uso conduce a los mismos problemas que --resume cuando el objetivo del entrenamiento ha cambiado.
Last updated