0
respostas

[Projeto] Mão na massa: identificando objetos com MobileNetV2

Fique um pouco em dúvida com relação ao título, não seria algo relacionado a aprendizado por reforço com FrozenLake e Q-Learning, não de MobileNetV2? de todo modo segue à baixo o que eu desenvolvi e o link das evidências.

!pip install gymnasium
import numpy as np
import gymnasium as gym
import random
import matplotlib.pyplot as plt

# 1. Configuração do ambiente
env = gym.make("FrozenLake-v1", is_slippery=True)

# 2. Inicialização da Q-table e hiperparâmetros
num_states = env.observation_space.n
num_actions = env.action_space.n

q_table = np.zeros((num_states, num_actions))

alpha = 0.8
gamma = 0.95
epsilon = 1.0
epsilon_min = 0.01
epsilon_decay = 0.995

num_episodes = 2000
max_steps = 100

recompensas_por_episodio = []

# 3. Treinamento com Q-Learning
for episodio in range(num_episodes):
    state, _ = env.reset()
    done = False
    recompensa_total = 0

    for passo in range(max_steps):
        if random.uniform(0, 1) < epsilon:
            action = env.action_space.sample()
        else:
            action = np.argmax(q_table[state])

        next_state, reward, terminated, truncated, _ = env.step(action)
        done = terminated or truncated

        q_table[state, action] = q_table[state, action] + alpha * (
            reward + gamma * np.max(q_table[next_state]) - q_table[state, action]
        )

        state = next_state
        recompensa_total += reward

        if done:
            break

    epsilon = max(epsilon_min, epsilon * epsilon_decay)
    recompensas_por_episodio.append(recompensa_total)

# 4. Exibindo a Q-table
print("Q-table aprendida:")
print(q_table)

# 5. Avaliação
num_testes = 100
sucessos = 0

for episodio in range(num_testes):
    state, _ = env.reset()
    done = False

    for passo in range(max_steps):
        action = np.argmax(q_table[state])
        next_state, reward, terminated, truncated, _ = env.step(action)
        done = terminated or truncated
        state = next_state

        if done:
            sucessos += reward
            break

print(f"\nSucessos em {num_testes} episódios de teste: {int(sucessos)}")
print(f"Taxa de sucesso: {sucessos / num_testes:.2%}")

# 6. Gráfico de evolução
plt.figure(figsize=(10, 5))
plt.plot(np.convolve(recompensas_por_episodio, np.ones(100)/100, mode='valid'))
plt.title("Evolução do aprendizado do agente")
plt.xlabel("Episódios")
plt.ylabel("Recompensa média (janela de 100 episódios)")
plt.grid(True)
plt.show()

Com essa prática, foi possível entender na prática como funciona o aprendizado por reforço em um ambiente simples.

def treinar_agente(alpha, gamma, epsilon_inicial, num_episodes=2000, max_steps=100):
    env = gym.make("FrozenLake-v1", is_slippery=True)
    num_states = env.observation_space.n
    num_actions = env.action_space.n
    
    q_table = np.zeros((num_states, num_actions))
    
    epsilon = epsilon_inicial
    epsilon_min = 0.01
    epsilon_decay = 0.995

    for episodio in range(num_episodes):
        state, _ = env.reset()
        
        for passo in range(max_steps):
            if random.uniform(0, 1) < epsilon:
                action = env.action_space.sample()
            else:
                action = np.argmax(q_table[state])

            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated

            q_table[state, action] = q_table[state, action] + alpha * (
                reward + gamma * np.max(q_table[next_state]) - q_table[state, action]
            )

            state = next_state

            if done:
                break

        epsilon = max(epsilon_min, epsilon * epsilon_decay)

    # Avaliação
    sucessos = 0
    testes = 100

    for _ in range(testes):
        state, _ = env.reset()
        for _ in range(max_steps):
            action = np.argmax(q_table[state])
            next_state, reward, terminated, truncated, _ = env.step(action)
            done = terminated or truncated
            state = next_state
            if done:
                sucessos += reward
                break

    taxa_sucesso = sucessos / testes
    return taxa_sucesso

Testando combinações:

parametros = [
    {"alpha": 0.1, "gamma": 0.9, "epsilon": 1.0},
    {"alpha": 0.5, "gamma": 0.95, "epsilon": 1.0},
    {"alpha": 0.8, "gamma": 0.99, "epsilon": 1.0},
    {"alpha": 0.8, "gamma": 0.95, "epsilon": 0.5},
]

for p in parametros:
    resultado = treinar_agente(p["alpha"], p["gamma"], p["epsilon"])
    print(f"alpha={p['alpha']}, gamma={p['gamma']}, epsilon={p['epsilon']} -> taxa de sucesso: {resultado:.2%}")

https://github.com/Moquiuti/fundamentos-ia-investigando-algoritmos-abordagens-machine-learning/blob/main/treinando_um_agente_com_Q_Learning_no_FrozenLake.ipynb