Un ejemplo básico de Aprendizaje por Refuerzo en Python
Supongamos que tenemos un agente que puede moverse hacia arriba, abajo, izquierda y derecha en un tablero de juego. El objetivo es llegar al punto final del tablero, obteniendo una recompensa de 10 puntos. En cada movimiento que realice el agente, recibirá una recompensa de -1 punto, y si se sale del tablero o choca con un obstáculo, recibirá una penalización de -5 puntos.
Para implementar esto en Python, podemos crear una matriz que represente el tablero, donde cada posición puede ser un obstáculo (O), vacía (V), el punto final (F) o la posición del agente (A).
import numpy as np
# matriz que representa el tablero
board = np.array([
['O', 'O', 'O', 'O', 'O'],
['O', 'V', 'V', 'F', 'O'],
['O', 'V', 'O', 'V', 'O'],
['O', 'V', 'V', 'V', 'O'],
['O', 'O', 'O', 'O', 'O'],
])
# posición inicial del agente
current_pos = (1, 1)
# función que mueve al agente en una dirección específica
def move_agent(action):
global current_pos
new_pos = None
if action == 'up':
new_pos = (current_pos[0] - 1, current_pos[1])
elif action == 'down':
new_pos = (current_pos[0] + 1, current_pos[1])
elif action == 'left':
new_pos = (current_pos[0], current_pos[1] - 1)
elif action == 'right':
new_pos = (current_pos[0], current_pos[1] + 1)
# si la nueva posición está dentro del tablero y no es un obstáculo
if new_pos[0] >= 0 and new_pos[0] < board.shape[0] and \
new_pos[1] >= 0 and new_pos[1] < board.shape[1] and \
board[new_pos] != 'O':
current_pos = new_pos
# si llega a la posición final, la recompensa es de 10 puntos
if board[new_pos] == 'F':
reward = 10
done = True
else:
# por cada movimiento, la recompensa es de -1 puntos
reward = -1
done = False
else:
# si se sale del tablero o choca con un obstáculo, la penalización es de -5 puntos
reward = -5
done = False
return current_pos, reward, done
Una vez que tenemos la matriz que representa el tablero y la función move_agent() que mueve al agente, podemos usar un bucle para que el agente explore el ambiente y aprenda la mejor estrategia para llegar al punto final:
# inicializamos la posición del agente
current_pos = (1, 1)
# inicializamos el puntaje y la función de valor (Q)
score = 0
Q = np.zeros((board.shape[0], board.shape[1], 4))
# definimos los hiperparámetros
alpha = 0.1
gamma = 0.9
epsilon = 0.1
# número de iteraciones o episodios
n_episodes = 1000
# bucle principal
for episode in range(n_episodes):
done = False
while not done:
# epsilon-greedy: elegimos una acción aleatoria con probabilidad epsilon y la mejor acción con probabilidad (1-epsilon)
if np.random.uniform() < epsilon:
action = np.random.choice(['up', 'down', 'left', 'right'])
else:
action = ['up', 'down', 'left', 'right'][np.argmax(Q[current_pos])]
# realizamos la acción y actualizamos el puntaje y la posición del agente
next_pos, reward, done = move_agent(action)
score += reward
# actualizamos la función de valor (Q)
Q[current_pos][['up', 'down', 'left', 'right'].index(action)] += \
alpha * (reward + gamma * np.max(Q[next_pos]) - Q[current_pos][['up', 'down', 'left', 'right'].index(action)])
# actualizamos la posición del agente
current_pos = next_pos
# si llega al punto final o se sale del tablero, se termina el episodio
if done:
current_pos = (1, 1)
# imprimimos el puntaje del episodio cada 100 episodios
if episode % 100 == 0:
print('Episodio {}: puntaje = {}'.format(episode, score))
# reseteamos el puntaje
score = 0