¿Qué es una política en el aprendizaje por refuerzo? (RL 4)

| | ,

1. Introducción

En este cuarto artículo de la serie RL, vamos a hablar del concepto de política en el aprendizaje por refuerzo, de su definición matemática y de los tipos de políticas que se pueden utilizar. Además, utilizaremos las librerías PyTorch y Stable Baselines de Python, de uso común en aplicaciones de aprendizaje por refuerzo, para ver algunos ejemplos de políticas en la práctica.

2. Definición de una política

Una política (policy), en el contexto del aprendizaje por refuerzo, es el conjunto de reglas o estrategias que utiliza un agente para decidir qué acciones llevar a cabo.

En algunas traducciones del inglés, verás que también se refieren a las políticas con el nombre de directivas. Es más, ya que la política viene a ser como el cerebro del agente, a menudo se sustituye la palabra “política” por la de “agente”, como por ejemplo en la siguiente frase: “la política está intentando maximizar la recompensa”.

Ahora que tenemos claro el concepto, vamos a ver qué tipos de políticas se suelen utilizar.

3. Tipos de políticas en el aprendizaje por refuerzo

En general, las políticas pueden ser de uno de los dos tipos siguientes:

  • Políticas deterministas, en las cuales la acción llevada a cabo por el agente en cualquier estado vendrá siempre dada de forma determinista como la salida de la política. Por si no tienes del todo claro el significado de determinista, quiere decir que, dadas unas entradas concretas, es posible calcular o predecir un resultado también concreto. Estas políticas se suelen denotar mediante la letra µ, de tal forma que la siguiente ecuación significa que “una acción α en un momento temporal concreto t, viene dada por la política µ del estado s en ese momento”:
\begin{aligned}
α_t = µ(s_t)
\end{aligned}
  • Políticas estocásticas, que vienen dadas por distribuciones de probabilidad condicionada y se denotan con el símbolo π. En este caso, la probabilidad de llevar a cabo una acción α en un momento temporal concreto t, estando en el estado s, viene dada por:
\begin{aligned}
α_t \sim π(·|s_t)
\end{aligned}

En una política determinista, está clara la acción a llevar a cabo en un momento dado y para un estado concreto. Por el contrario, en una política estocástica, las acciones a llevar a cabo no están completamente determinadas, sino que tienen una probabilidad asociada.

Además, en el aprendizaje por refuerzo profundo (deep reinforcement learning), se habla también de políticas parametrizadas, que son aquellas que tienen como salida una función que depende de un conjunto de parámetros, los cuales podemos ajustar mediante algún algoritmo de optimización. Por ejemplo, una política parametrizada podría depender de los pesos de una red neuronal.

Normalmente, denotamos los parámetros de una política con la letra “θ” o con la letra “Φ”, y añadimos dicha letra como subíndice del símbolo que denota a la política en sí (“µ” o “π”), para que quede clara la conexión entre política y parámetros:

\begin{aligned}
α_t = µ_θ(s_t)
\end{aligned}
\begin{aligned}
α_t \sim π_θ(·|s_t)
\end{aligned}

Políticas deterministas

Fíjate en el siguiente fragmento de código, que crea una política determinista muy sencilla para un espacio de acciones continuo, utilizando el paquete torch.nn de PyTorch:

pi_net = nn.Sequential(
              nn.Linear(obs_dim, 64),
              nn.Tanh(),
              nn.Linear(64, 64),
              nn.Tanh(),
              nn.Linear(64, act_dim)
            )

Este código construye un perceptrón multicapa (MLP) con dos capas ocultas de tamaño 64 y funciones de activación de tipo tanh. Si el objeto obs es un vector de Numpy que contiene un lote de observaciones, se puede utilizar el objeto pi_net anterior para obtener un lote de acciones, tal y como puedes ver a continuación:

obs_tensor = torch.as_tensor(obs, dtype=torch.float32)
actions = pi_net(obs_tensor)

Políticas estocásticas

Los dos tipos de políticas estocásticas más comunes en el aprendizaje por refuerzo son las categóricas y las gaussianas diagonales. Mientras que las políticas categóricas se usan en espacios de acciones discretos, las gaussianas diagonales se utilizan en espacios de acciones continuos.

Hay dos cálculos claves a la hora de utilizar y entrenar agentes con políticas estocásticas:

  • La toma de muestras de acciones de la política.
  • El cálculo de log-likelihood (el logaritmo natural de la función de probabilidad) para acciones concretas:
\begin{aligned}
log π_θ (α|s)
\end{aligned}

Si quieres ver más detalles acerca de cómo llevar a cabo estos dos cálculos, tanto en el caso de las políticas categóricas como en el de las gaussianas, puedes visitar este enlace.

4. Políticas disponibles en Stable Baselines

El paquete Stable Baselines, igual que su predecesor Stable Baselines3, cuenta con un conjunto de políticas predeterminadas que se pueden utilizar con la mayoría de los espacios de acciones en el aprendizaje por refuerzo:

MlpPolicyImplementa el algoritmo actor-crítico, utilizando un MLP (2 capas de 64)
MlpLstmPolicyImplementa el algoritmo actor-crítico, utilizando redes LSTM con extracción de características mediante MLP
MlpLnLstmPolicyImplementa el algoritmo actor-crítico, utilizando una capa LSTM normalizada con una extracción de características MLP
CnnPolicyImplementa el algoritmo actor-crítico, utilizando una CNN
CnnLstmPolicyImplementa el algoritmo actor-crítico, utilizando LSTM con una extracción de características de CNN
CnnLnLstmPolicyImplementa el algoritmo actor-crítico, utilizando una capa de LSTM normalizados con una extracción de características de CNN

Además, es posible personalizar estas políticas mediante el parámetro policy_kwargs para la clase del modelo que se quiera utilizar, o bien crear una nueva política directamente desde cero.

5. Ejemplo práctico

Fíjate en el siguiente ejemplo, tomado de la documentación oficial de Stable Baselines:

import gym

from stable_baselines import DQN
from stable_baselines.common.evaluation import evaluate_policy

# Create environment
env = gym.make('LunarLander-v2')

# Instantiate the agent
model = DQN('MlpPolicy', env, learning_rate=1e-3, prioritized_replay=True, verbose=1)
# Train the agent
model.learn(total_timesteps=int(2e5))
# Save the agent
model.save("dqn_lunar")
del model  # delete trained model to demonstrate loading

# Load the trained agent
model = DQN.load("dqn_lunar")

# Evaluate the agent
mean_reward, std_reward = evaluate_policy(model, model.get_env(), n_eval_episodes=10)

# Enjoy trained agent
obs = env.reset()
for i in range(1000):
    action, _states = model.predict(obs)
    obs, rewards, dones, info = env.step(action)
    env.render()

Hemos importado la librería Gym de OpenAI y las clases DQN y evaluate_policy del paquete Stable Baselines. Después, hemos creado el entorno “LunarLander-v2”, uno de los que vienen ya predefinidos la librería Gym. A continuación, hemos instanciado el agente basado en el algoritmo DQN, definiendo una política de tipo “MlpPolicy” y una serie de parámetros adicionales. La línea 12 del código es la que nos permite entrenarlo y, a partir de la línea 20 del código, simplemente evaluamos al agente y generamos una serie de acciones y estados sucesivos para verlo en acción.

¿Qué te parece? Ya ves que con paquetes como Gym y Stable Baselines, no puede ser más sencillo definir, entrenar y generar resultados en aplicaciones de aprendizaje por refuerzo.

Si te has perdido los anteriores artículos de esta serie, puedes echarles un vistazo desde estos links:

Anterior

Espacio de acciones en el aprendizaje por refuerzo (RL 3)

Python: ventajas y desventajas

Siguiente

Deja un comentario