1
resposta

Mão na massa: identificando objetos com MobileNetV2

import numpy as np
import gymnasium as gym

Inicializar o ambiente FrozenLake

O agente precisa atravessar um lago congelado sem cair nos buracos

env = gym.make("FrozenLake-v1", is_slippery=True)

Definir os hiperparâmetros do Q-Learning

alpha = 0.8 # Taxa de aprendizado: o quanto o agente aprende de novas informações
gamma = 0.95 # Fator de desconto: quão importante são as recompensas futuras em comparação com as imediatas
epsilon = 1.0 # 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)

Criar a tabela Q (Q-table) com zeros

As linhas representam os estados e as colunas representam as ações

q_table = np.zeros((env.observation_space.n, env.action_space.n))

Iniciar o treinamento do agente

for episode in range(num_episodes):
# Reiniciar o ambiente a cada episódio
state, _ = env.reset()
done = False

while not done:
    # Escolher uma ação usando a estratégia epsilon-greedy
    # Com probabilidade 'epsilon', escolhemos uma ação aleatória (exploração)
    # Caso contrário, escolhemos a melhor ação conhecida até o momento (exploração)
    if np.random.rand() < epsilon:
        action = env.action_space.sample()  # Explorar uma ação aleatória
    else:
        action = np.argmax(q_table[state])  # Explorar a ação com maior valor na Q-table

    # Executar a ação escolhida no ambiente
    next_state, reward, done, truncated, _ = env.step(action)

    # Atualizar a Q-table com a fórmula de aprendizado por reforço
    # Q(s, a) = Q(s, a) + alpha * (recompensa + desconto * max(Q(s', a')) - Q(s, a))
    best_next_action = np.max(q_table[next_state])  # Melhor ação no próximo estado
    q_table[state, action] += alpha * (reward + gamma * best_next_action - q_table[state, action])

    # Avançar para o próximo estado
    state = next_state

# Reduzir a taxa de exploração gradualmente, sem ultrapassar o mínimo definido
if epsilon > epsilon_min:
    epsilon *= epsilon_decay

Avaliar o desempenho do agente treinado

Aqui, testamos 1000 episódios para verificar quantas vezes ele atravessa o lago com sucesso

successes = 0
for episode in range(1000):
state, _ = env.reset()
done = False
while not done:
# O agente agora só escolhe a melhor ação aprendida (sem exploração aleatória)
action = np.argmax(q_table[state])
state, reward, done, truncated, _ = env.step(action)
if done and reward == 1.0:
successes += 1 # Contabilizar os sucessos

Exibir o resultado final

print(f"O agente conseguiu atravessar o lago com sucesso em {successes} de 1000 episódios.")

1 resposta

Olá, Ronaldo. Como vai?

É excelente ver sua dedicação em compartilhar o código desta atividade! Notei que, apesar de o título do seu post mencionar o MobileNetV2 (que é focado em visão computacional), o código que você postou é um exemplo brilhante de Aprendizado por Reforço utilizando o algoritmo Q-Learning no ambiente FrozenLake.

Essa é uma técnica fundamental em IA, e seu código está muito bem estruturado. Para ajudar outros alunos que lerem seu tópico, preparei uma breve explicação sobre os pontos principais que você implementou:

A Q-Table: Você criou uma matriz de zeros que funciona como a "memória" do agente. Com o tempo, essa tabela deixa de ser composta por zeros e passa a guardar valores que indicam qual ação é mais vantajosa em cada quadrado do gelo.

Equilíbrio entre Exploração e Explotação: O uso do epsilon e do epsilon_decay é crucial. No começo, o agente não sabe nada e precisa "chutar" caminhos (exploração). Conforme os episódios passam, ele começa a usar o que aprendeu (explotação) para chegar ao objetivo.

Fórmula de Atualização: A linha onde você calcula o q_table[state, action] é o coração do algoritmo. Ela ajusta o valor atual baseado na recompensa recebida e no potencial de ganho futuro no próximo estado.

Apenas uma pequena observação técnica: no seu código, o comentário menciona que o agente atravessa o lago sem cair nos buracos. Com o parâmetro is_slippery=True, o gelo é escorregadio, o que torna o desafio muito mais difícil, pois o agente pode tentar ir para a direita e acabar escorregando para baixo. Isso torna a taxa de sucesso menor, mas o aprendizado muito mais robusto!

Se quiser testar como o agente se comporta em um ambiente "perfeito", você pode alterar para is_slippery=False e verá a taxa de sucesso subir para quase 100% após o treinamento.

Parabéns pelo post e pelo progresso no curso!

Espero que possa ter lhe ajudado!