curso
Aprendizaje por Refuerzo con Gimnasio: Guía práctica
El aprendizaje por refuerzo (RL) es uno de los tres paradigmas principales del aprendizaje automático, siendo los otros dos el aprendizaje supervisado y el no supervisado. En la RL, un agente aprende a interactuar con su entorno para maximizar las recompensas acumuladas. Aprende la acción óptima en diferentes condiciones ambientales mediante ensayo y error. El Aprendizaje por Refuerzo con Retroalimentación Humana (RLHF) permite al agente modificar el comportamiento basándose en las aportaciones humanas en cada paso.
La RL resuelve problemas como los coches autoconducidos, el comercio automatizado, los jugadores informáticos en los videojuegos, los robots de entrenamiento, etc. Cuando se utilizan redes neuronales profundas para aplicar algoritmos de RL, se denomina Aprendizaje por Refuerzo Profundo.
En este tutorial, te mostraré cómo empezar a utilizar Gymnasium, una biblioteca Python de código abierto para desarrollar y comparar algoritmos de aprendizaje por refuerzo. Demostraré cómo configurarlo, explorar varios entornos de RL y utilizar Python para construir un agente sencillo que implemente un algoritmo de RL.
¿Qué es el Gimnasio?
Gymnasium es una biblioteca Python de código abierto diseñada para apoyar el desarrollo de algoritmos de RL. Para facilitar la investigación y el desarrollo en VR, Gymnasium proporciona:
- Una amplia variedad de entornos, desde juegos sencillos hasta problemas que imitan escenarios de la vida real.
- API racionalizadas y envoltorios para interactuar con los entornos.
- La posibilidad de crear entornos personalizados y aprovechar el marco de la API.
Los desarrolladores pueden construir algoritmos de RL y utilizar llamadas a la API para tareas como:
- Pasar al entorno la acción elegida por el agente.
- Conocer el estado del entorno y la recompensa tras cada acción.
- Entrenar el modelo.
- Comprobación del funcionamiento del modelo.
El Gimnasio de OpenAI contra el Gimnasio de Farama
OpenAI no ha dedicado recursos significativos al desarrollo de Gym porque no era una prioridad comercial para la empresa. Ta Fundación Farama se creó para normalizar y mantener a largo plazo las bibliotecas RL. Gymnasium es la bifurcación de la Fundación Farama del Gimnasio de OpenAI. Gimnasio 0.26.2 es un sustituto de Gimnasio 0.26.2. Con la bifurcación, Farama pretende añadir métodos funcionales (además de los basados en clases) para todas las llamadas a la API, admitir entornos vectoriales y mejorar las envolturas. El objetivo general es que el marco sea más limpio y eficaz.
Conviértete en un Científico ML
Montaje del gimnasio
Gymnasium necesita versiones específicas (no las últimas versiones) de varios programas dependientes como NumPy y PyTorch. Por tanto, te recomendamos que crees un nuevo entorno Conda o venv o un nuevo portátil para instalar, utilizar Gymnasium y ejecutar los programas de RL.
Puedes utilizar este cuaderno de DataLab para seguircon el tutorial.
Instalación del gimnasio
Para instalar Gymnasium en un servidor o máquina local, ejecuta
$ pip install gymnasium
Para instalarlo utilizando un bloc de notas como Colab de Google o DataLab de DataCamp, utiliza
!pip install gymnasium
El comando anterior instala Gymnasium y las versiones correctas de las dependencias.
Explorar los entornos del gimnasio
En noviembre de 2024, Gymnasium incluye más de 60 entornos incorporados. Para examinar los entornos incorporados disponibles, utiliza la función gym.envs.registry.all()
, como se muestra en el ejemplo siguiente :
import gymnasium as gym
for i in gym.envs.registry.keys():
print(i)
También puedes visitar la página de inicio del Gimnasio. La columna left tiene enlaces a todos los entornos. La página web de cada entorno incluye detalles sobre él, como acciones, estados, etc.
Los entornos están organizadosen categorías como Control Clásico, Box2D y más. A continuación, enumero algunos de los entornos comunes de cada grupo:
- Control clásico: Estos son los entornos canónicos utilizados en el desarrollo de la VR; son la base de muchos ejemplos de libros de texto. Proporcionan la mezcla adecuada de complejidad y sencillez para probar y comparar nuevos algoritmos de RL. Los entornos de control clásicos del Gimnasio incluyen
- Acrobot
- Poste de carro
- Coche de montaña Discreto
- Coche de montaña Continuo
- Péndulo
- Box2D: Box2D es un motor de física 2D para juegos. Los entornos basados en este motor incluyen juegos sencillos como:
- Lunar Lander
- Carreras de coches
- ToyText: Son entornos pequeños y sencillos que suelen utilizarse para depurar algoritmos de RL. Muchos de estos entornos se basan en el modelo de mundo en cuadrícula pequeña y en juegos de cartas sencillos. Algunos ejemplos son:
- Blackjack
- Taxi
- Lago Helado
- MuJoCo: La dinámica multiarticular con contacto (MuJoCo) es un motor de física de código abierto que simula entornos para aplicaciones como robótica, biomecánica, ML, etc. Los entornos MuJoCo en el Gimnasio incluyen:
- Hormiga
- Hopper
- Humanoid
- Nadador
- Y más
Además de los entornos incorporados, Gymnasium puede utilizarse con muchos entornos externos utilizando la misma API.
En este tutorial utilizaremos uno de los entornos canónicos de Control Clásico. Para importar un entorno concreto, utiliza el comando .make()
y pasa el nombre del entorno como argumento. Por ejemplo, para crear un nuevo entorno basado en CartPole (versión 1), utiliza el comando que aparece a continuación:
import gymnasium as gym
env = gym.make("CartPole-v1")
Comprender los conceptos del aprendizaje por refuerzo en el gimnasio
En pocas palabras, el Aprendizaje por Refuerzo consiste en un agente (como un robot) que interactúa con su entorno. Una política decide las acciones del agente. En función de las acciones del agente, el entorno le da una recompensa (o una penalización) en cada paso temporal. El agente utiliza la RL para averiguar la política óptima que maximiza las recompensas totales que gana el agente.
Componentes de un entorno de RL
Los siguientes son los componentes clave de un entorno de RL:
- Medio ambiente: El sistema, mundo o contexto externo. El agente interactúa con el entorno en una serie de pasos temporales. En cada paso temporal, en función de la acción del agente, el entorno:
- Da una recompensa (o penalización)
- Decide el siguiente estado
- Estado: Una representación matemática de la configuración actual del entorno.
- Por ejemplo, el estado de un entorno pendular puede incluir la posición y la velocidad angular del péndulo en cada paso de tiempo.
- Estado terminal: Un estado que no conduce a nuevos/otros estados.
- Agente: El algoritmo que observa el entorno y realiza diversas acciones basándose en esta observación. El objetivo del agente es maximizar sus recompensas.
- Por ejemplo, el agente decide con qué fuerza y en qué dirección empujar el péndulo.
- Observación: Una representación matemática de la visión que tiene el agente del entorno, adquirida, por ejemplo, mediante sensores.
- Acción: La decisión que toma el agente antes de pasar al siguiente paso. La acción afecta al siguiente estado del entorno y hace que el agente obtenga una recompensa.
- Recompensa: La retroalimentación del entorno al agente. Puede ser positivo o negativo, según la acción y el estado del entorno.
- Vuelve: La rentabilidad acumulada esperada en futuros periodos de tiempo. Las recompensas de pasos temporales futuros pueden descontarse utilizando un factor de descuento.
- Política: La estrategia del agente sobre qué acción realizar en distintos estados. Se suele representar como una matriz de probabilidad, P, que asigna estados a acciones.
- Dado un conjunto finito de m estados posibles y n acciones posibles, elemento Pmn de la matriz denota la probabilidad de tomar la acción an en el estado sm.
- Episodio: La serie de pasos temporales desde el estado inicial (aleatorio) hasta que el agente alcanza un estado terminal.
Espacio de observación y espacio de acción
La observación es la información que el agente recoge sobre el entorno. Un agente, por ejemplo, un robot, podría recoger información del entorno mediante sensores. Lo ideal sería que el agente pudiera observar el estado completo, que describe todos los aspectos del entorno. En la práctica, el agente utiliza sus observaciones como sustituto del estado. Así, las observaciones deciden las acciones del agente.
Un espacio es análogo a un conjunto matemático. El espacio de elementos X incluye todas las instancias posibles de X. El espacio de X también define la estructura (sintaxis y formato) de todos los elementos de tipo X. Cada entorno del Gimnasio tiene dos espacios, el espacio de acción, action_space
, y el espacio de observación, observation_space
. Tanto el espacio de acción como el de observación derivan de la superclase padre gymnasium.spaces.Space
.
Espacio de observación
El espacio de observación es el espacio que incluye todas las observaciones posibles. También define el formato en el que se almacenan las observaciones. El espacio de observación suele representarse como un objeto de datospe Box. Se trata de un ndarray que describe los parámetros de las observaciones. La casilla especifica los límites de cada dimensión. Puedes ver el espacio de observación de un entorno utilizando el método observation_space
:
print("observation space: ", env.observation_space)
En el caso del entorno CartPole-v1
, la salida tiene el aspecto del ejemplo siguiente :
observation space: Box([-4.8 -inf -0.41887903 -inf], [4.8 inf 0.41887903 inf], (4,), float32)
En este ejemplo, el espacio de observación CartPole-v1
tiene 4 dimensiones. Los 4 elementos de la matriz de observación son
- Posición del carro - varía entre -4,8 y +4,8
- Velocidad del carro - oscila entre - a +
- El ángulo del polo - varía entre -0,4189 y +0,4189
- La velocidad angular del polo - oscila entre - a +
Para ver un ejemplo de una matriz de observación individual, utiliza el comando .reset()
.
observation, info = env.reset()
print("observation: ", observation)
En el caso del entorno CartPole-v1
, la salida tiene el aspecto del ejemplo siguiente :
[ 0.03481963 -0.0277232 0.01703267 -0.04870504]
Los cuatro elementos de esta matriz corresponden a las cuatro magnitudes observadas (posición del carro, velocidad del carro, ángulo del poste, velocidad angular del poste ), como se ha explicado antes.
Espacio de acción
El espacio de acción incluye todas las acciones posibles que puede realizar el agente. El espacio de acción también define el formato en el que se representan las acciones. Puedes ver el espacio de acción de un entorno utilizando el método action_space
:
print("action space: ", env.action_space)
En el caso del entorno CartPole-v1
, la salida tiene el aspecto del ejemplo siguiente :
action space: Discrete(2)
En el caso del entorno CartPole-v1
, el espacio de acción es discreto. El agente puede realizar un total de dos acciones:
- 0: Empuja el carro hacia la izquierda
- 1: Empuja el carro hacia la derecha
Construir tu primer agente de RL con Gymnasium
En las secciones anteriores, hemos explorado los conceptos básicos de RL y Gimnasio. Esta sección te muestra cómo utilizar Gymnasium para construir un agente RL.
Crear y restablecer el entorno
El primer paso es crear una instancia del entorno. Para crear nuevos entornos, utiliza el método .make()
.
env = gym.make('CartPole-v1')
Las interacciones del agente modifican el estado del entorno. El método .reset()
restablece el entorno a un estado inicial. Por defecto, el entorno se inicializa con un estado aleatorio. Puedes utilizar un parámetro SEED
con el método .reset()
para inicializar el entorno al mismo estado cada vez que se ejecute el programa. El código siguiente muestra cómo hacerlo:
SEED = 1111
env.reset(seed=SEED)
El muestreo de acciones también implica aleatoriedad. Para controlar esta aleatoriedad y obtener una trayectoria de entrenamiento totalmente reproducible, podemos sembrar los generadores aleatorios de NumPy y PyTorch:
np.random.seed(SEED)
torch.manual_seed(SEED)
Acciones aleatorias frente a acciones inteligentes
En cada paso de un proceso de Markov, el agente puede elegir aleatoriamente una acción y explorar el entorno hasta llegar a un estado terminal. Eligiendo acciones al azar:
- Puede llevar mucho tiempo alcanzar el estado terminal.
- Las recompensas acumuladas son mucho menores de lo que podrían haber sido.
Entrenar al agente para que optimice la selección de acciones basándose en experiencias anteriores (de interacción con el entorno) es más eficaz para maximizar las recompensas a largo plazo.
El agente no entrenado comienza con acciones aleatorias basadas en una política inicializada aleatoriamente. Esta política suele representarse como una red neuronal. Durante el entrenamiento, el agente aprende la política óptima que maximiza las recompensas. En la RL, el proceso de entrenamiento también se denomina optimización de la política.
Existen varios métodos de optimización de la política. Las ecuaciones de Bellman describen cómo calcular el valor de las políticas de RL y determinar la política óptima. En este tutorial, utilizaremos una técnica sencilla llamada gradientes de política. Existen otros métodos, como la Optimización de la Política Próxima (OPP).
Implementación de un agente de gradiente de política simple
Para construir un agente de RL que utilice gradientes de política, creamos una red neuronal para aplicar la política, escribimos funciones para calcular los rendimientos y las pérdidas a partir de las recompensas escalonadas y las probabilidades de acción, y actualizamos iterativamente la política mediante técnicas estándar de retropropagación.
Configurar la red política
Utilizamos una red neuronal para aplicar la política. Como CartPole-v1
es un entorno sencillo, utilizamos una red neuronal con:
- Dimensiones de entrada iguales a la dimensionalidad del espacio de observación del entorno.
- Una sola capa oculta con 64 neuronas.
- Dimensiones de salida iguales a la dimensionalidad del espacio de acción del entorno.
Así pues, la función de la red política es asignar los estados observados a las acciones. Dada una observación de entrada, predice la acción correcta. El código siguiente implementa la red de políticas:
class PolicyNetwork(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim, dropout):
super().__init__()
self.layer1 = nn.Linear(input_dim, hidden_dim)
self.layer2 = nn.Linear(hidden_dim, output_dim)
self.dropout = nn.Dropout(dropout)
def forward(self, x):
x = self.layer1(x)
x = self.dropout(x)
x = F.relu(x)
x = self.layer2(x)
return x
La recogida de recompensas y el pase hacia delante
Como se ha dicho, en cada paso del proceso de Markov, el entorno da una recompensa basada en la acción y el estado del agente. El objetivo en RL es maximizar el rendimiento total.
- El rendimiento en cada paso temporal es la suma acumulada de las recompensas obtenidas desde el principio hasta ese paso.
- El rendimiento total en cada episodio se obtiene acumulando todas las recompensas escalonadas de ese episodio. Así, el rendimiento total es el rendimiento en el último paso temporal (cuando el agente alcanza un estado terminal).
En la práctica, al acumular recompensas, es habitual:
- Ajusta las recompensas futuras utilizando un factor de descuento.
- Normaliza el conjunto de retornos escalonados para garantizar un entrenamiento suave y estable.
El código siguiente muestra cómo hacerlo:
def calculate_stepwise_returns(rewards, discount_factor):
returns = []
R = 0
for r in reversed(rewards):
R = r + R * discount_factor
returns.insert(0, R)
returns = torch.tensor(returns)
normalized_returns = (returns - returns.mean()) / returns.std()
return normalized_returns
El paso hacia delante consiste en hacer funcionar al agente basándose en la política actual hasta que alcance un estado terminal y recoger las recompensas y probabilidades de acción escalonadas. Los pasos siguientes explican cómo aplicar el pase hacia delante:
- Restablece el entorno a un estado inicial.
- Inicializa los búferes para almacenar las probabilidades de acción, las recompensas y el rendimiento acumulado
- Utiliza la función
.step()
para ejecutar iterativamente el agente en el entorno hasta que termine: - Obtén la observación del estado del entorno.
- Obtén la acción prevista por la política en función de la observación.
- Utiliza la función
Softmax
para estimar la probabilidad de realizar la acción prevista. - Simula una distribución de probabilidad categórica basada en estas probabilidades estimadas.
- Muestrea esta distribución para obtener la acción del agente.
- Estima la probabilidad logarítmica de la acción muestreada a partir de la distribución simulada.
- Añade la probabilidad logarítmica de las acciones y las recompensas de cada paso a sus respectivos búferes.
- Estima los valores normalizados y descontados de los rendimientos en cada paso en función de las recompensas.
def forward_pass(env, policy, discount_factor):
log_prob_actions = []
rewards = []
done = False
episode_return = 0
policy.train()
observation, info = env.reset()
while not done:
observation = torch.FloatTensor(observation).unsqueeze(0)
action_pred = policy(observation)
action_prob = F.softmax(action_pred, dim = -1)
dist = distributions.Categorical(action_prob)
action = dist.sample()
log_prob_action = dist.log_prob(action)
observation, reward, terminated, truncated, info = env.step(action.item())
done = terminated or truncated
log_prob_actions.append(log_prob_action)
rewards.append(reward)
episode_return += reward
log_prob_actions = torch.cat(log_prob_actions)
stepwise_returns = calculate_stepwise_returns(rewards, discount_factor)
return episode_return, stepwise_returns, log_prob_actions
Actualizar la política en función de las recompensas
La pérdida representa la cantidad sobre la que aplicamos el descenso gradiente. El objetivo en RL es maximizar los beneficios. Por lo tanto, utilizamos el valor de rendimiento esperado como sustituto de la pérdida. El valor de rendimiento esperado se calcula como el producto de los rendimientos esperados escalonados y la probabilidad logarítmica de las acciones escalonadas. El código siguiente calcula la pérdida:
def calculate_loss(stepwise_returns, log_prob_actions):
loss = -(stepwise_returns * log_prob_actions).sum()
return loss
Para actualizar la política, ejecuta la retropropagación con respecto a la función de pérdida. El siguiente método update_policy()
invoca al método calculate_loss()
. A continuación, ejecuta la retropropagación sobre esta pérdida para actualizar los parámetros de la política, es decir, los pesos del modelo de la red política.
def update_policy(stepwise_returns, log_prob_actions, optimizer):
stepwise_returns = stepwise_returns.detach()
loss = calculate_loss(stepwise_returns, log_prob_actions)
optimizer.zero_grad()
loss.backward()
optimizer.step()
return loss.item()
La actualización de la política basada en el gradiente de los rendimientos se denomina método del gradiente de la política.
Formación de la política
Ahora tenemos todos los componentes necesarios para formar y evaluar la política. Ejecutamos el bucle de entrenamiento como se explica en los pasos siguientes:
Antes de empezar, declaramos los hiperparámetros, instanciamos una política y creamos un optimizador:
- Declara los hiperparámetros como constantes de Python:
MAX_EPOCHS
es el número máximo de iteraciones que estamos dispuestos a realizar para entrenar la política.DISCOUNT_FACTOR
decide la importancia relativa de las recompensas de los pasos temporales futuros. Un factor de descuento de 1 significa que todas las recompensas tienen la misma importancia, mientras que un valor de 0 significa que sólo es importante la recompensa del paso temporal actual.N_TRIALS
es el número de episodios sobre los que promediamos los rendimientos para evaluar el rendimiento del agente. Decidimos que el entrenamiento ha tenido éxito si el rendimiento medio deN_TRIALS
episodios está por encima del umbral .REWARD_THRESHOLD
: Si la política consigue un rendimiento superior al umbral, se considera que ha tenido éxito.DROPOUT
decide la fracción de los pesos que deben ponerse a cero aleatoriamente. La función de abandono pone a cero aleatoriamente una fracción de las ponderaciones del modelo. Esto reduce la dependencia de neuronas específicas y evita el sobreajuste, haciendo que la red sea más robusta.LEARNING_RATE
decide cuánto se pueden modificar los parámetros de la política en cada paso. La actualización de los parámetros en cada iteración es el producto del gradiente y la tasa de aprendizaje.- Define la política como una instancia de la clase
PolicyNetwork
(implementada anteriormente). - Crea un optimizador utilizando el algoritmo Adam y la tasa de aprendizaje.
Para entrenar la política, ejecutamos iterativamente los pasos de entrenamiento hasta que el rendimiento medio (sobre N_TRIALS
) sea mayor que el umbral de recompensa:
- Para cada episodio, ejecuta el paso adelante una vez. Recoge la probabilidad logarítmica de las acciones, los rendimientos escalonados y el rendimiento total de ese episodio. Acumula los rendimientos episódicos en una matriz.
- Calcula la pérdida utilizando las probabilidades logarítmicas y los retornos escalonados. Ejecuta la retropropagación sobre la pérdida. Utiliza el optimizador para actualizar los parámetros de la política.
- Comprueba si la rentabilidad media en
N_TRIALS
supera el umbral de recompensa .
El código siguiente implementa estos pasos:
def main():
MAX_EPOCHS = 500
DISCOUNT_FACTOR = 0.99
N_TRIALS = 25
REWARD_THRESHOLD = 475
PRINT_INTERVAL = 10
INPUT_DIM = env.observation_space.shape[0]
HIDDEN_DIM = 128
OUTPUT_DIM = env.action_space.n
DROPOUT = 0.5
episode_returns = []
policy = PolicyNetwork(INPUT_DIM, HIDDEN_DIM, OUTPUT_DIM, DROPOUT)
LEARNING_RATE = 0.01
optimizer = optim.Adam(policy.parameters(), lr = LEARNING_RATE)
for episode in range(1, MAX_EPOCHS+1):
episode_return, stepwise_returns, log_prob_actions = forward_pass(env, policy, DISCOUNT_FACTOR)
_ = update_policy(stepwise_returns, log_prob_actions, optimizer)
episode_returns.append(episode_return)
mean_episode_return = np.mean(episode_returns[-N_TRIALS:])
if episode % PRINT_INTERVAL == 0:
print(f'| Episode: {episode:3} | Mean Rewards: {mean_episode_return:5.1f} |')
if mean_episode_return >= REWARD_THRESHOLD:
print(f'Reached reward threshold in {episode} episodes')
break
Por último, invoca la función main()
para entrenar la política:
main()
Uuede utilizar este libro de trabajo DataLab para ejecutar directamente el algoritmo anterior y resolver el entorno CartPole utilizando RL.l algoritmo anterior directamente y resolver el entorno CartPole utilizando RL.
Técnicas Avanzadas en Gimnasio
Una vez demostrado cómo poner en práctica un algoritmo de RL, ahora hablaremos de algunas técnicas avanzadas que se utilizan habitualmente en la práctica.
Utilizar arquitecturas preconstruidas
Implementar algoritmos de RL desde cero es un proceso largo y difícil, sobre todo para entornos complejos y políticas de última generación.
Una alternativa más práctica es utilizar programascomo Líneas de Base Estables3. Viene con implementaciones probadas de algoritmos de RL. Incluye agentes preentrenados, guiones de entrenamiento, herramientas de evaluación y módulos para trazar gráficos y grabar vídeos.
Ray RLib es otra herramienta popular para RL. RLib está diseñado como una solución escalable, que facilita la implementación de algoritmos RL en sistemas multi-GPU. También admite RL multiagente, lo que abre nuevas posibilidades como:
- Aprendizaje multiagente independiente: Cada agente trata a los demás agentes como parte del entorno.
- Entrenamiento multiagente colaborativo: Un grupo de agentes comparten la misma política y funciones de valor y aprenden paralelamente de las experiencias de los demás.
- Formación adversaria: Los agentes (o grupos de agentes) compiten entre sí en entornos competitivos similares a un juego.
Tanto con RLib como con Stable Baselines3, puedes importar y utilizar entornos de OpenAI Gymnasium.
Entornos personalizados
Los entornos empaquetados con Gimnasio son la elección adecuada para probar nuevas estrategias de VR y políticas de formación. Sin embargo, para la mayoría de las aplicaciones prácticas, necesitas crear y utilizar un entorno que refleje fielmente el problema que quieres resolver. Puedes utilizar el Gimnasio para crear un entorno personalizado. La ventaja de utilizar los entornos personalizados de Gymnasium es que muchas herramientas externas como RLib y Stable Baselines3 ya están configuradas para trabajar con la estructura de la API de Gymnasium.
Para crear un entorno personalizado en Gimnasio, tienes que definir:
- El espacio de observación.
- Las condiciones terminales.
- El conjunto de acciones que el agente puede elegir.
- Cómo inicializar el entorno (cuando se llama a la función
reset()
) . - Cómo decide el entorno el siguiente estado dadas las acciones del agente (cuando se llama a la función
step()
) .
Para saber más, sigue la guíadel Gimnasio sobre la creación de entornos personalizados.
Buenas prácticas para utilizar el gimnasio
Experimenta con distintos entornos
El código de este tutorial muestra cómo aplicar el algoritmo de gradiente de política en el entorno CartPole. Se trata de un entorno sencillo con un espacio de acción discreto. Para comprender mejor la RL, te aconsejamos que apliques el mismo algoritmo de gradiente de política (y otrosritmos, como el PPO) en otros entornos .
Por ejemplo, el entorno Péndulo tiene un espacio de acción continuo. Consiste en una única entrada representada como variable continua: el par (magnitud y dirección del) aplicado al péndulo en cualquier estado dado. Este par puede tomar cualquier valor entre -2 y +2.
Experimentar con distintos algoritmos en diversos entornos te ayuda a comprender mejor los distintos tipos de soluciones de RL y sus retos.
Supervisar el progreso de la formación
Los entornos de RL suelen consistir en robots, péndulos, coches de montaña, videojuegos, etc. Visualizar las acciones del agente en el entorno permite comprender mejor e intuitivamente el rendimiento de la política.
En Gymnasium, el método env.render()
visualiza las interacciones del agente con el entorno. Muestra gráficamente el estado actual del entorno: las pantallas del juego, la posición del péndulo o del poste del carro, etc. La información visual de las acciones del agente y de las respuestas del entorno ayuda a controlar el rendimiento del agente y su progreso en el proceso de entrenamiento.
Hay cuatro modos de renderizado: "humano", "rgb_array", "ansi" y "rgb_array_list". Para visualizar el rendimiento del agente, utiliza el modo de renderizado "humano". El modo de renderizado se especifica cuando se inicializa el entorno. Por ejemplo:
env = gym.make(‘CartPole-v1’, render_mode=’human’)
Para realizar la renderización, implica al método .render()
después de cada acción realizada por el agente (mediante la llamada al método .step()
). El pseudocódigo siguiente ilustra cómo hacerlo:
while not done:
…
step, reward, terminated, truncated, info = env.step(action.item())
env.render()
…
Solución de errores comunes
Gymnasium facilita la interfaz con entornos RL complejos. Sin embargo, es un software continuamente actualizado con muchas dependencias. Por eso, es esencial estar atento a algunos tipos comunes de errores.
Desajustes de versión
- No coincide la versión del gimnasio: El paquete de software Gimnasio de Farama fue bifurcado de Gimnasio de OpenAI a partir de la versión 0.26.2. Se han producido algunos cambios de última hora entre las versiones anteriores de Gymnasium y las nuevas versiones de Gymnasium. Muchas implementaciones disponibles públicamente se basan en las versiones anteriores de Gym y puede que no funcionen directamente con la última versión. En estos casos, es necesario revertir la instalación a una versión anterior o adaptar el código para que funcione con la nueva versión.
- No coincide la versión del entorno: Muchos entornos de Gimnasio tienen versiones diferentes. Por ejemplo, hay dos entornos CartPole:
CartPole-v1
yCartPole-v0
. Aunque el comportamiento del entorno es el mismo en ambas versiones, algunos de los parámetros, como la duración del episodio, el umbral de recompensa, etc., pueden ser diferentes. Una política entrenada en una versión puede no funcionar tan bien en otra versión del mismo entorno. Tienes que actualizar los parámetros de entrenamiento y volver a entrenar la política para cada versión del entorno. - No coincide la versión de las dependencias: Gimnasio depende de dependencias como NumPy y PyTorch. En diciembre de 2024, las últimas versiones de estas dependencias son
numpy 2.1.3
ytorch 2.5.1
. Sin embargo, Gimnasio funciona mejor contorch 1.13.0
ynumpy 1.23.3
. Puedes encontrar problemas si instalas Gymnasium en un entorno con estas dependencias preinstaladas. Recomendamos instalar y trabajar con Gimnasio en un entorno Conda nuevo.
Problemas de convergencia
- Hiperparámetros: Al igual que otros algoritmos de aprendizaje automático, las políticas de RL son sensibles a hiperparámetros como la tasa de aprendizaje, el factor de descuento, etc. Recomendamos experimentar y ajustar los hiperparámetros manualmente o utilizando técnicas automatizadas como la búsqueda en cuadrícula y la búsqueda aleatoria.
- Exploración frente a explotación: Para algunas clases de políticas (como la PPO), el agente adopta una estrategia doble: explorar el entorno para descubrir nuevos caminos y adoptar un enfoque codicioso para maximizar las recompensas basándose en los caminos conocidos hasta el momento. Si explora demasiado, la política no converge. A la inversa, nunca intenta el camino óptimo si no explora lo suficiente. Por tanto, encontrar el equilibrio adecuado entre exploración y explotación es esencial. También es habitual dar prioridad a la exploración en los primeros episodios y a la explotación en los últimos durante el entrenamiento.
Inestabilidad del entrenamiento
- Grandes ritmos de aprendizaje: Si la tasa de aprendizaje es demasiado alta, los parámetros de la política sufren grandes actualizaciones en cada paso. Esto podría hacer que no se alcanzara el conjunto óptimo de valores. Una solución habitual es disminuir gradualmente la tasa de aprendizaje, garantizando actualizaciones más pequeñas y estables a medida que converge el entrenamiento.
- Exploración excesiva: Demasiada aleatoriedad (entropía) en la selección de acciones impide la convergencia y provoca grandes variaciones en la función de pérdida entre los pasos siguientes. Para tener un proceso de entrenamiento estable y convergente, equilibra la exploración con la explotación.
- Elección incorrecta del algoritmo: Los algoritmos simples, como el gradiente de la política, pueden conducir a un entrenamiento inestable en entornos complejos con grandes espacios de acción y de estado. En estos casos, recomendamos utilizar algoritmos más robustos, como PPO y Optimización de la Política de la Región de Confianza (TRPO). Estos algoritmos evitan grandes actualizaciones de la política en cada paso y pueden ser más estables.
- Aleatoriedad: Los algoritmos de RL son notoriamente sensibles a los estados iniciales y a la aleatoriedad inherente a la selección de acciones. Cuando una ejecución de entrenamiento es inestable, a veces puede estabilizarse utilizando una semilla aleatoria diferente o reinicializando la política.
Conclusión
En este tutorial, exploramos los principios básicos de la RL, hablamos de Gymnasium como paquete de software con una API limpia para interactuar con varios entornos de RL, y mostramos cómo escribir un programa Python para implementar un algoritmo sencillo de RL y aplicarlo en un entorno Gymnasium.
Tras comprender los conceptos básicos en este tutorial, te recomiendo que utilices los entornos de Gimnasio para aplicar los conceptos de RL a la resolución de problemas prácticos, como la optimización de rutas de taxi y las simulaciones de operaciones bursátiles.
Desarrolla habilidades de aprendizaje automático
Preguntas frecuentes
¿Cuál es el papel del Gimnasio en el aprendizaje por refuerzo?
Gymnasium viene con muchos entornos preconstruidos para probar y desarrollar algoritmos de RL. Normaliza la interfaz de estos entornos y de los nuevos entornos personalizados. Esto facilita la aplicación y evaluación de los algoritmos de RL.
¿Estás limitado a los entornos incorporados cuando utilizas OpenAI Gymnasium?
No. Además de más de 60 entornos preconstruidos, Gymnasium te permite crear nuevos entornos declarando sus espacios de estado y acción, y definiendo cómo debe responder el entorno a diversas acciones.
¿Cuál es la diferencia entre Gimnasio y Gimnasio?
En pocas palabras, Gymnasium, mantenido por la Fundación Farama, es la versión nueva y mejorada de Gym, que OpenAI ya no mantiene. Se espera que Gymnasium funcione como sustituto de Gym 0.26.2.
¿Cuál es la diferencia entre los métodos de VR basados en políticas y los basados en valores?
En los métodos basados en políticas, como los gradientes de políticas, el agente modifica directamente los parámetros de la política para encontrar qué política conduce al máximo rendimiento esperado.
En los métodos basados en valores, el agente se entrena en la función de valor. Aprender la función de valor óptima ayuda a deducir la política óptima.
¿Es la codificación manual de algoritmos la mejor y única forma de resolver problemas de RL?
Escribir código desde cero es la mejor manera de entender los distintos algoritmos de RL. Para uso en producción, existen herramientas como Stable Baselines3, RLib y CleanRL. Estas herramientas incluyen despliegues preconstruidos de algoritmos comunes de RL, que debes configurar y afinar en función del entorno.
Arun es un antiguo fundador de startups que disfruta construyendo cosas nuevas. Actualmente explora los fundamentos técnicos y matemáticos de la Inteligencia Artificial. Le encanta compartir lo que ha aprendido, así que escribe sobre ello.
Además de en DataCamp, puedes leer sus publicaciones en Medium, Airbyte y Vultr.
¡Aprende más sobre el aprendizaje por refuerzo con estos cursos!
curso
Deep Reinforcement Learning in Python
curso
Reinforcement Learning from Human Feedback (RLHF)
tutorial
Introducción al Q-Learning: Tutorial para principiantes
tutorial
¿Qué es el Refuerzo?
![Vinod Chugani's photo](https://media.datacamp.com/legacy/v1718937489/Vinod_Chugani_16d8c40269.png?w=48)
Vinod Chugani
11 min
tutorial
Comprender la regresión logística en el tutorial de Python
![Avinash Navlani's photo](https://media.datacamp.com/legacy/v1662144772/Avinash_Navlani_a73769a866.png?w=48)
Avinash Navlani
10 min
tutorial
Ajuste fino de GPT-3 mediante la API OpenAI y Python
tutorial
Tutorial del Optimizador Adam: Intuición e implementación en Python
tutorial