Bueno, esta es mi entrada al desafío final del curso.
Usé is_slippery=False para que el entorno sea determinístico y el agente pueda aprender un camino consistente.
Código:
import numpy as np
import gymnasium as gym
# Configurar el entorno
env = gym.make("FrozenLake-v1", is_slippery=False)
# Inicializar la tabla Q
n_estados = env.observation_space.n
n_acciones = env.action_space.n
Q = np.zeros((n_estados, n_acciones))
# Hiperparámetros
alpha = 0.8 # tasa de aprendizaje
gamma = 0.95 # factor de descuento
epsilon = 1.0 # exploración inicial
epsilon_decay = 0.001 # cuánto baja epsilon por episodio
epsilon_min = 0.01 # mínimo de exploración
episodios = 2000
# Entrenamiento
for episodio in range(episodios):
estado, _ = env.reset()
done = False
while not done:
# Política epsilon-greedy
if np.random.uniform(0, 1) < epsilon:
accion = env.action_space.sample() # explorar
else:
accion = np.argmax(Q[estado]) # explotar
nuevo_estado, recompensa, done, truncated, _ = env.step(accion)
# Actualizar tabla Q
Q[estado, accion] = Q[estado, accion] + alpha * (
recompensa + gamma * np.max(Q[nuevo_estado]) - Q[estado, accion]
)
estado = nuevo_estado
# Bajar epsilon gradualmente
epsilon = max(epsilon_min, epsilon - epsilon_decay)
print("Entrenamiento completado")
print(f"Epsilon final: {epsilon:.3f}")
# Evaluación
exitosos = 0
episodios_eval = 100
for _ in range(episodios_eval):
estado, _ = env.reset()
done = False
while not done:
accion = np.argmax(Q[estado]) # solo lo mejor aprendido
estado, recompensa, done, truncated, _ = env.step(accion)
if recompensa == 1:
exitosos += 1
print(f"\nEpisodios exitosos: {exitosos}/{episodios_eval}")
print(f"Tasa de éxito: {exitosos}%")
# Mostrar tabla Q final
print("\nTabla Q aprendida:")
print(Q)
Output:
Entrenamiento completado
Epsilon final: 0.010
Episodios exitosos: 100/100
Tasa de éxito: 100%
Tabla Q aprendida:
[[0.73509189 0.77378094 0.77378094 0.73509189]
[0.73509189 0. 0.81450625 0.77378079]
[0.77378094 0.857375 0.77377869 0.81450625]
[0.81450617 0. 0.74369728 0.76198497]
[0.77378094 0.81450625 0. 0.73509189]
[0. 0. 0. 0. ]
[0. 0.9025 0. 0.81450625]
[0. 0. 0. 0. ]
[0.81450625 0. 0.857375 0.77378094]
[0.81450625 0.9025 0.9025 0. ]
[0.857375 0.95 0. 0.857375 ]
[0. 0. 0. 0. ]
[0. 0. 0. 0. ]
[0. 0.9025 0.95 0.857375 ]
[0.9025 0.95 1. 0.9025 ]
[0. 0. 0. 0. ]]
El agente arranca con epsilon=1.0, explorando completamente al azar, y lo va bajando gradualmente hasta 0.01, momento en que ya confía casi exclusivamente en lo que aprendió. Después de 2000 episodios de entrenamiento, la evaluación dio 100/100 episodios exitosos.
La tabla Q resultante también refleja lo aprendido. Los estados correspondientes a agujeros tienen todos sus valores en cero porque el agente nunca puede tomar una acción desde ahí. El estado 14, que es el paso previo a la meta, muestra un valor de 1.0 para la acción de 'derecha', lo cual muestra que el agente aprendió con certeza absoluta cuál es el movimiento correcto en ese punto.