Depois de explorar o exemplo de Q-Leaning e enteder a mecânica, as variáveis e estruturas
quebrei em funções, parametrizei e fiz uma tabela comparativa no final com parâmetros variados pra medir quão bem sucedido foi com aquelas parâmetros.
- primeiro fiz uma lista de 5 lista de parâmetros
- tenho ainda uma versão com mais listas de parametros variados mas ficou grande pra por aqui
import numpy as np
import gymnasium as gym
import pandas as pd
def avaliar_agente(ambiente, q_table, num_tests=1000):
"""
Avalia o agente utilizando apenas explotação.
"""
sucessos = 0
for _ in range(num_tests):
state, info = ambiente.reset()
done = False
while not done:
action = np.argmax(q_table[state])
state, reward, done, truncated, info = ambiente.step(action)
if done and reward == 1:
sucessos += 1
taxa_sucesso = (sucessos / num_tests) * 100
return sucessos, taxa_sucesso
def treinamento_Q_learning(alpha=0.8, gamma=0.95, epsilon=1.0, num_episodes=20000, num_tests=1000, epsilon_decay=0.999, epsilon_min=0.01):
"""
Treina um agente usando Q-Learning e retorna métricas de teste.
se não passar nenhum parametroida padrão será usado
"""
ambiente = gym.make("FrozenLake-v1", is_slippery=True )
q_table = np.zeros( (ambiente.observation_space.n, ambiente.action_space.n) )
epsilon_atual = epsilon
recompensas_treinamento = []
# Treinamento
for episode in range(num_episodes):
state, info = ambiente.reset()
done = False
recompensa_total = 0
while not done:
# Exploração
if np.random.rand() < epsilon_atual:
action = ambiente.action_space.sample()
# Explotação
else:
action = np.argmax(q_table[state])
new_state, reward, done, truncated, info = ambiente.step(action)
best_next_action = np.max(q_table[new_state])
q_table[state, action] += alpha * (reward + gamma * best_next_action - q_table[state, action])
state = new_state
recompensa_total += reward
epsilon_atual = max( epsilon_atual * epsilon_decay, epsilon_min )
recompensas_treinamento.append(recompensa_total)
# Avaliação
sucessos, taxa_sucesso = avaliar_agente( ambiente, q_table, num_tests )
return {
"alpha": alpha,
"gamma": gamma,
"epsilon": epsilon,
"episodios": num_episodes,
"sucessos": sucessos,
"taxa_sucesso": taxa_sucesso,
"q_table": q_table,
"recompensas": recompensas_treinamento
}
def executar_experimentos(lista_parametros, num_episodes=20000, num_tests=1000, epsilon_decay=0.999, epsilon_min=0.01):
'''
Permite o teste com vários hiperparâmetros novos para comparação.
se não passar nenhum parametroida padrão será usado
'''
resultados = []
for parametros in lista_parametros:
resultado = treinamento_Q_learning(
alpha=parametros["alpha"],
gamma=parametros["gamma"],
epsilon=parametros["epsilon"],
num_episodes=num_episodes,
num_tests=num_tests,
epsilon_decay=epsilon_decay,
epsilon_min=epsilon_min
)
resultados.append({
"alpha": resultado["alpha"],
"gamma": resultado["gamma"],
"epsilon": resultado["epsilon"],
"sucessos": resultado["sucessos"],
"taxa_sucesso": round(resultado["taxa_sucesso"], 2)
})
return pd.DataFrame(resultados)
lista_parametros = [
{"alpha": 0.10, "gamma": 0.90, "epsilon": 1.00},
{"alpha": 0.30, "gamma": 0.95, "epsilon": 1.00},
{"alpha": 0.50, "gamma": 0.95, "epsilon": 1.00},
{"alpha": 0.80, "gamma": 0.95, "epsilon": 1.00},
{"alpha": 0.95, "gamma": 0.99, "epsilon": 1.00},
]
#
#alpha # Taxa de aprendizado: o quanto o agente aprende de novas informações
#gamma # Fator de desconto: quão importante são as recompensas futuras em comparação com as imediatas
#epsilon # Probabilidade inicial de explorar ações aleatórias
#epsilon_decay = 0.999 # Reduz gradualmente a exploração conforme o agente aprende
#epsilon_min = 0.01 # Limite mínimo de exploração para garantir que o agente ainda explore um pouco
#num_episodes = 20000 # Número total de tentativas de aprendizado (episódios)
resultado_final = executar_experimentos( lista_parametros, num_episodes=20000, num_tests=1000, epsilon_decay= 0.999, epsilon_min=0.01 )
print(resultado_final)