Saltar al contenido principal

Aprendizaje por Refuerzo con Gimnasio: Guía práctica

Comprende los fundamentos del Aprendizaje por Refuerzo (RL) y explora el paquete de software Gymnasium para construir y probar algoritmos de RL utilizando Python.
Actualizado 26 dic 2024  · 30 min de lectura

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

Mejora tus conocimientos de Python para convertirte en un científico del aprendizaje automático.
Empieza a Aprender Gratis

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 de N_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 y CartPole-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 y torch 2.5.1. Sin embargo, Gimnasio funciona mejor con torch 1.13.0 y numpy 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

Eleva tus habilidades de aprendizaje automático al nivel de producción.

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.


Photo of Arun Nanda
Author
Arun Nanda
LinkedIn

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.

Temas

¡Aprende más sobre el aprendizaje por refuerzo con estos cursos!

curso

Reinforcement Learning with Gymnasium in Python

4 hr
4K
Start your reinforcement learning journey! Learn how agents can learn to solve environments through interactions.
Ver detallesRight Arrow
Comienza El Curso
Ver másRight Arrow
Relacionado

tutorial

Introducción al Q-Learning: Tutorial para principiantes

Conozca el algoritmo de aprendizaje por refuerzo sin modelos más popular con un tutorial de Python.
Abid Ali Awan's photo

Abid Ali Awan

16 min

tutorial

¿Qué es el Refuerzo?

El refuerzo mejora el rendimiento del aprendizaje automático corrigiendo secuencialmente los errores y combinando los aprendices débiles en predictores fuertes.
Vinod Chugani's photo

Vinod Chugani

11 min

tutorial

Comprender la regresión logística en el tutorial de Python

Aprende sobre la regresión logística, sus propiedades básicas, y construye un modelo de machine learning sobre una aplicación del mundo real en Python.
Avinash Navlani's photo

Avinash Navlani

10 min

tutorial

Ajuste fino de GPT-3 mediante la API OpenAI y Python

Libere todo el potencial de GPT-3 mediante el ajuste fino. Aprenda a utilizar la API de OpenAI y Python para mejorar este modelo de red neuronal avanzado para su caso de uso específico.
Zoumana Keita 's photo

Zoumana Keita

12 min

tutorial

Tutorial del Optimizador Adam: Intuición e implementación en Python

Comprender y aplicar el optimizador Adam en Python. Aprende la intuición, las matemáticas y las aplicaciones prácticas del aprendizaje automático con PyTorch
Bex Tuychiev's photo

Bex Tuychiev

14 min

tutorial

Guía completa para el aumento de datos

Aprende sobre técnicas, aplicaciones y herramientas de aumento de datos con un tutorial de TensorFlow y Keras.
Abid Ali Awan's photo

Abid Ali Awan

15 min

See MoreSee More