Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

0
respostas

[Projeto] Mão na massa: Q Learning e Frozenlake

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)