Saltar al contenido
Aprendizaje por Refuerzo con Python

Introducción al Aprendizaje por Refuerzo

Introducción

Aprendizaje por Refuerzo

El aprendizaje por refuerzo es una rama del aprendizaje automático que se enfoca en cómo un agente inteligente puede aprender a tomar decisiones óptimas a través de la interacción con su entorno. En este paradigma, el agente recibe recompensas positivas o negativas según las decisiones que toma, con el objetivo de maximizar su recompensa total a largo plazo.

A diferencia del aprendizaje supervisado o no supervisado, en el aprendizaje por refuerzo el agente no recibe una etiqueta o una salida correcta. En cambio, aprende a través de la experiencia y la retroalimentación. Por ejemplo, un robot que navega por un laberinto puede recibir una recompensa positiva por llegar al final y una recompensa negativa por chocar con las paredes.

Una de las características más importantes del aprendizaje por refuerzo es la capacidad de aprender de forma autónoma. El agente toma decisiones por sí mismo y aprende de sus errores y aciertos. Además, el aprendizaje por refuerzo se puede aplicar en diferentes ámbitos, como robótica, juegos, finanzas, entre otros.

Resumen

Aprendizaje por Refuerzo

El Aprendizaje por Refuerzo es un tipo de aprendizaje automático en el que un agente aprende a tomar decisiones a través de la interacción con un ambiente. El agente realiza una serie de acciones en el ambiente y recibe una recompensa o penalización según el resultado de esas acciones. El objetivo del agente es maximizar la recompensa total obtenida a lo largo del tiempo.

En el Aprendizaje por Refuerzo, el agente no recibe ejemplos etiquetados previamente como en el aprendizaje supervisado, sino que aprende mediante la retroalimentación que le proporciona el ambiente. El ambiente proporciona una señal de recompensa al agente, quien debe aprender a asociar sus acciones con los resultados obtenidos.

El Aprendizaje por Refuerzo se utiliza en una amplia variedad de aplicaciones, tales como juegos de mesa, robots, sistemas de control automático, entre otros. Es una técnica poderosa que permite a los agentes aprender a tomar decisiones en situaciones complejas y dinámicas. Para implementar el Aprendizaje por Refuerzo en Python, se puede utilizar la librería OpenAI Gym, la cual proporciona un conjunto de ambientes para que los agentes puedan interactuar y aprender.

Aplicación teórica

Ejemplo Práctico de Introducción al Aprendizaje por Refuerzo

Supongamos una computadora que juega un juego de ajedrez contra un ser humano. Inicialmente, la computadora no conoce ninguna estrategia para ganar, por lo que su primer movimiento es completamente aleatorio. Después de cada movimiento de la computadora, el ser humano tiene la oportunidad de responder al movimiento.

El objetivo de la computadora es ganar el juego, pero al comienzo no sabe cómo hacerlo. Así que su tarea es aprender de sus errores y ajustar su estrategia para maximizar sus posibilidades de ganar. Aquí es donde entra en juego el aprendizaje por refuerzo.

Cada vez que la computadora hace un movimiento, recibe retroalimentación:

  • Si su movimiento fue bueno, el ser humano no tendrá muchas oportunidades para responder de manera efectiva, y la computadora recibe una recompensa.
  • Si su movimiento fue malo, el ser humano tendrá muchas opciones para responder y la computadora recibirá una penalización.

Con el tiempo, la computadora aprende cuáles movimientos son buenos y cuáles son malos, y comienza a ajustar su estrategia en consecuencia. Eventualmente, aprende a jugar bien y a ganar contra los jugadores humanos. Esto se logró mediante el aprendizaje por refuerzo, ya que la computadora ajustó su comportamiento en función de la retroalimentación que recibió.

Aplicación práctica

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