{ "cells": [ { "cell_type": "markdown", "id": "c3b22234", "metadata": {}, "source": [ "# Introduccion al Aprendizaje Reforzado\n", "## 1. Introducción\n", "En el aprendizaje reforzado los agentes aprenden a tomar decisiones a través de la interacción con un entorno dinámico, recibiendo recompensas o penalizaciones. El objetivo clave es la maximización de una señal de recompensa acumulada a largo plazo. Busca guiar el comportamiento del agente hacia decisiones óptimas basadas en la retroalimentación recibida del entorno.
\n", "En esta notebook, se pesentan ejemplos de funcionamiento de aprendizaje reforzado." ] }, { "cell_type": "markdown", "id": "ee9bf1fd", "metadata": {}, "source": [ "## 2. Ejemplos\n", "### 2.1. Raton y Queso\n", "Imaginarse que un ratón está en una celda de un laberinto de 3x3. El ratón debe llegar al queso que se encuentra en la celda inferior derecha (coordenada: posicion_raton=(x,y) a ingresar). El ratón puede moverse arriba, abajo, izquierda o derecha, y gana una recompensa cuando llega al queso. En este programa, se entrenará al ratón para llegar al queso." ] }, { "cell_type": "markdown", "id": "04205983", "metadata": {}, "source": [ "#### Inicio y preparación" ] }, { "cell_type": "code", "execution_count": 1, "id": "6ca5cb39", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import random\n", "\n", "# Parámetros del entorno\n", "filas = 3\n", "columnas = 3\n", "acciones = 4 # Arriba, Abajo, Izquierda, Derecha" ] }, { "cell_type": "markdown", "id": "2f0eb0ce", "metadata": {}, "source": [ "#### Funciones" ] }, { "cell_type": "code", "execution_count": 5, "id": "50683355", "metadata": {}, "outputs": [], "source": [ "# Definir las recompensas\n", "def definir_recompensas(posicion_queso):\n", " # Inicializar la matriz de recompensas\n", " recompensas = np.full((filas, columnas), -0.1) # Pequeña penalización por cada movimiento\n", " recompensas[posicion_queso] = 1 # Recompensa de 1 en la posición del queso\n", " return recompensas\n", "\n", "# Función para tomar una acción\n", "def tomar_accion(estado, accion):\n", " fila, columna = estado\n", "\n", " if accion == 0: # Arriba\n", " nueva_fila = max(fila - 1, 0) # Evitar salir del tablero\n", " nueva_columna = columna\n", " elif accion == 1: # Abajo\n", " nueva_fila = min(fila + 1, filas - 1)\n", " nueva_columna = columna\n", " elif accion == 2: # Izquierda\n", " nueva_fila = fila\n", " nueva_columna = max(columna - 1, 0)\n", " elif accion == 3: # Derecha\n", " nueva_fila = fila\n", " nueva_columna = min(columna + 1, columnas - 1)\n", "\n", " return (nueva_fila, nueva_columna)\n", "\n", "# Mostrar la acción en formato legible\n", "def mostrar_accion(accion):\n", " if accion == 0:\n", " return \"Arriba\"\n", " elif accion == 1:\n", " return \"Abajo\"\n", " elif accion == 2:\n", " return \"Izquierda\"\n", " else:\n", " return \"Derecha\"\n", "\n", "# Función para ejecutar un episodio\n", "def ejecutar_episodio(estado_inicial):\n", " estado = estado_inicial\n", " pasos = 0\n", " recorrido = []\n", " \n", " while estado != posicion_queso:\n", " accion = np.argmax(q_table[estado])\n", " nuevo_estado = tomar_accion(estado, accion)\n", " recompensa = recompensas[nuevo_estado]\n", " recorrido.append((estado, accion, nuevo_estado, recompensa))\n", " estado = nuevo_estado\n", " pasos += 1\n", " if pasos > 50: # Evitar bucles infinitos en caso de errores\n", " break\n", "\n", " return recorrido, pasos" ] }, { "cell_type": "markdown", "id": "a682f825", "metadata": {}, "source": [ "#### Programa principal" ] }, { "cell_type": "code", "execution_count": 6, "id": "155591e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Episodio 1: El ratón empieza en el estado (0, 0)\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón ha encontrado el queso en el estado (1, 2). ¡Recompensa +1!\n", "Episodio 1 terminado en 51 pasos.\n", "\n", "Episodio 5: El ratón empieza en el estado (0, 0)\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón ha encontrado el queso en el estado (1, 2). ¡Recompensa +1!\n", "Episodio 5 terminado en 51 pasos.\n", "\n", "Episodio 10: El ratón empieza en el estado (0, 0)\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Izquierda hacia (0, 0). Recompensa -0.1.\n", "El ratón ha encontrado el queso en el estado (1, 2). ¡Recompensa +1!\n", "Episodio 10 terminado en 51 pasos.\n", "\n", "Episodio 25: El ratón empieza en el estado (0, 0)\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón se mueve Arriba hacia (0, 0). Recompensa -0.1.\n", "El ratón ha encontrado el queso en el estado (1, 2). ¡Recompensa +1!\n", "Episodio 25 terminado en 51 pasos.\n", "\n", "Episodio 50: El ratón empieza en el estado (0, 0)\n", "El ratón se mueve Abajo hacia (1, 0). Recompensa -0.1.\n", "El ratón se mueve Derecha hacia (1, 1). Recompensa -0.1.\n", "El ratón se mueve Derecha hacia (1, 2). Recompensa 1.0.\n", "El ratón ha encontrado el queso en el estado (1, 2). ¡Recompensa +1!\n", "Episodio 50 terminado en 3 pasos.\n", "\n", "--- Probando la ruta aprendida ---\n", "Estado: (0, 0), Acción: Abajo, Nueva posición: (1, 0). Recompensa -0.1.\n", "Estado: (1, 0), Acción: Derecha, Nueva posición: (1, 1). Recompensa -0.1.\n", "Estado: (1, 1), Acción: Derecha, Nueva posición: (1, 2). Recompensa 1.0.\n", "¡El ratón llegó al queso en (1, 2) en 3 pasos!\n", "\n", "q_table:\n", "[[[-0.029404 0.27008942 -0.03447686 -0.03591 ]\n", " [-0.00865512 0.03062218 -0.030052 0.4247724 ]\n", " [-0.01 0.99361833 0. 0. ]]\n", "\n", " [[-0.0069391 -0.00328588 -0.0198 0.7264576 ]\n", " [ 0.00628597 0.00119338 -0.0108 1.10572651]\n", " [ 0.05287445 0.14810703 0.07834471 0. ]]\n", "\n", " [[ 0.30066543 -0.02862 -0.029404 -0.027404 ]\n", " [ 0.52289527 -0.01 -0.0108 -0.01 ]\n", " [ 0.89214688 0.05464058 0. 0. ]]]\n" ] } ], "source": [ "# Inicializar la tabla Q\n", "q_table = np.zeros((filas, columnas, acciones))\n", "\n", "# Parámetros del algoritmo Q-Learning\n", "alpha = 0.1 # Tasa de aprendizaje\n", "gamma = 0.8 # Factor de descuento\n", "epsilon = 0.1 # Tasa de exploración\n", "episodios = 100\n", "\n", "# Posición del queso (ajustable por parámetro)\n", "posicion_queso = (1, 2)\n", "recompensas = definir_recompensas(posicion_queso)\n", "\n", "# Entrenamiento del ratón\n", "for episodio in range(episodios):\n", " estado = (random.randint(0, filas - 1), random.randint(0, columnas - 1)) # Estado inicial aleatorio\n", " done = False\n", "\n", " while not done:\n", " if random.uniform(0, 1) < epsilon:\n", " accion = random.randint(0, 3) # Exploración\n", " else:\n", " accion = np.argmax(q_table[estado]) # Explotación\n", "\n", " nuevo_estado = tomar_accion(estado, accion)\n", " recompensa = recompensas[nuevo_estado]\n", "\n", " # Actualizar la tabla Q\n", " q_anterior = q_table[estado][accion]\n", " q_max_nuevo_estado = np.max(q_table[nuevo_estado])\n", " q_table[estado][accion] = q_anterior + alpha * (recompensa + gamma * q_max_nuevo_estado - q_anterior)\n", "\n", " # Moverse al nuevo estado\n", " estado = nuevo_estado\n", "\n", " # Si llegamos al queso, terminar el episodio\n", " if estado == posicion_queso:\n", " done = True\n", "\n", " # Mostrar progreso para episodios seleccionados\n", " if episodio in [0, 4, 9, 24, 49]:\n", " print(f\"\\nEpisodio {episodio + 1}: El ratón empieza en el estado (0, 0)\")\n", " recorrido, pasos = ejecutar_episodio(estado_inicial=(0, 0)) # Comenzar siempre desde (0, 0)\n", " for i, (estado, accion, nuevo_estado, recompensa) in enumerate(recorrido):\n", " print(f\"El ratón se mueve {mostrar_accion(accion)} hacia {nuevo_estado}. Recompensa {recompensa:.1f}.\")\n", " print(f\"El ratón ha encontrado el queso en el estado {posicion_queso}. ¡Recompensa +1!\")\n", " print(f\"Episodio {episodio + 1} terminado en {pasos} pasos.\")\n", "\n", "# Probar la ruta aprendida\n", "print(\"\\n--- Probando la ruta aprendida ---\")\n", "estado = (0, 0)\n", "pasos_totales = 0\n", "\n", "while estado != posicion_queso:\n", " accion = np.argmax(q_table[estado])\n", " nuevo_estado = tomar_accion(estado, accion)\n", " recompensa = recompensas[nuevo_estado]\n", " print(f\"Estado: {estado}, Acción: {mostrar_accion(accion)}, Nueva posición: {nuevo_estado}. Recompensa {recompensa:.1f}.\")\n", " estado = nuevo_estado\n", " pasos_totales += 1\n", "\n", "print(f\"¡El ratón llegó al queso en {posicion_queso} en {pasos_totales} pasos!\")\n", "print(\"\")\n", "print(\"q_table:\")\n", "print(q_table)" ] }, { "cell_type": "markdown", "id": "d65f2bdf", "metadata": {}, "source": [ "##### Resumen de la tabla Q:\n", "La tabla tiene 4 columnas: puntuación para \"arriba\", \"abajo\", \"izquierda\" y \"derecha\". La tabla tiene 3x3=9 filas: una por cada celda.\n", "Valores Q positivos: Indican que moverse en esa dirección desde esa casilla probablemente lleva a una mejor posición o más cerca del queso.\n", "Valores Q cercanos a 0 o negativos: Indican que moverse en esa dirección desde esa casilla es inútil, ya sea porque lleva fuera del tablero o porque no conduce hacia el queso.\n", "A medida que el ratón explora el tablero, la tabla Q se va llenando con valores que le indican cuáles acciones son mejores en cada estado. El objetivo es que, al final del entrenamiento, el ratón aprenda una estrategia (o política) que lo lleve al queso de la manera más eficiente posible en futuros intentos.." ] }, { "cell_type": "markdown", "id": "686c680b", "metadata": {}, "source": [ "### 2.2. Otro ejemplo:\n", "En este ejemplo, tenemos un entorno en el que el agente empieza en el estado inicial s_i, y debe elegir entre moverse a la izquierda o a la derecha. Si llega al estado de más a la izquierda, el episodio termina y el agente recibe una recompensa de -5. Por otro lado, si llega al estado de más a la derecha, el episodio termina y el agente recibe una recompensa de +5. El agente debe aprender a evitar el estado de -5 y moverse hacia el estado de +5. Si la política que aprende siempre termina en el estado con mayor recompensa, diremos que ha encontrado la política óptima (optimal policy). El código presente se basa en la notebook presentada en: notebook en google collab." ] }, { "attachments": { "imagen.png": { "image/png": "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dnV12bmcl1aoadvqUXBKQwREQAREQAREQASagUA+vRXXU82Qz2rmoV8LaETxgkULjFdX9EcYMmSIfbvwXW655ex3PMRbRd1d3T0W6eh0F9Lx81ulqyF5jfotAiIgAiIgAiIgAtUggN7CUj2QpuDrdwK6a0lX6OjsCPPnzw+DBw0OQ4cOTb03PvzwQ5sr9u9//3v46KOP7BjE9KhRo+ycESNGhEGDBllcYUkI8+bPM/G9aMEi+2bfggUL8safmqg2ioAIiIAIiIAIiECTE8DIOHfu3DB48ODQtrTN9JIbIBcvXmwayMP7778f5syZE+ix55uw6qqrhjFjxpi/s5/HduLhfJ+rf8jgIaGru8uMmp2drSVJWyu3JdxwCN6FCxcGfJdN/EaBwrrlllvCL3/5y/DSSy+FDz74wAqfb0TwSiutZMe9++67diwCGjHN92qrrRZ23333cMQRR4R11lnHbiYP+fx3cgfoHxEQAREQAREQARFoQQLDhw8391YCxknCrFmzwi9+8Yvw0EMPmWZ67733TEshiBHAyy+/vB3nRkqMkghovnfcccfwuc99Lmy99dYmrHNxL+oyTdZqmqrfCWgKjsKiIP7zP/8zTJkyJTzyyCNWeHvssUfYbbfdwrrrrhtWWWUV+1577bWtsD1wQ7z99tvhlVdesZbUY489ZuL73HPPNVG97777hqOPPjqMHz9e1uc+5PRDBERABERABESgvxBA4CKc777n7jB16tRw5ZVXmtFxyy23NC01bty4sMIKK5hxES3F/y6KEdSvv/56mD59enj55ZfDc889Fx5++OFw8cUXm+DmnAMOOCCcdNJJZq1etGhRH6t2KzBsSQGNOM43eA/xO3ny5HDPPfeYZRnR/POf/zxstulmYfGSxSaulyxZYgXlLap4QSGSR44cGTbYYAPbPGnSJPuePXu2ienLL7887L///mHjjTcO//Iv/xImTpwYP13/i4AIiIAIiIAIiEDLE7j22mut5/7FF180q/EVV1xhmgedhODtaP+4px9dRu+/99Kzf43V1whrrbVWHw708j/++OPhzjvvDD/4wQ/CT3/6UzNMnnfeeSaqWym0nIDGtxnXCsRve0fPzBkUFJ/vfve71ko64YQTwp///Oew8sormyXap6dzPxz3s3EXj3iBsS+tG8Et2AhyWmDETzrcSN///vetW4Lgvj3u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" } }, "cell_type": "markdown", "id": "83714300", "metadata": {}, "source": [ "![imagen.png](attachment:imagen.png)" ] }, { "cell_type": "code", "execution_count": 7, "id": "f606dc38", "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "id": "298a6564", "metadata": {}, "source": [ "#### Estado inicial" ] }, { "cell_type": "code", "execution_count": 8, "id": "0dd1ee4a", "metadata": {}, "outputs": [], "source": [ "state_rewards = [-5, 0, 0, 0, 0, 0, 5]\n", "final_state = [True, False, False, False, False, False, True]\n", "Q_values = [[0.0, 0.0], \n", " [0.0, 0.0],\n", " [0.0, 0.0],\n", " [0.0, 0.0],\n", " [0.0, 0.0],\n", " [0.0, 0.0],\n", " [0.0, 0.0]] # Q(s, a) matrix. [left, right]." ] }, { "cell_type": "markdown", "id": "541c2a4b", "metadata": {}, "source": [ "#### Funciones" ] }, { "cell_type": "code", "execution_count": 9, "id": "5d804281", "metadata": {}, "outputs": [], "source": [ "def select_epsilon_greedy_action(epsilon, state):\n", " \"\"\"Take random action with probability epsilon, else take best action.\"\"\"\n", " result = np.random.uniform()\n", " if result < epsilon:\n", " return np.random.randint(0, 2) # Random action (left or right).\n", " else:\n", " return np.argmax(Q_values[state]) # Greedy action for state." ] }, { "cell_type": "code", "execution_count": 10, "id": "189552ac", "metadata": {}, "outputs": [], "source": [ "def apply_action(state, action):\n", " \"\"\"Applies the selected action and get reward and next state.\n", " Action 0 means move to the left and action 1 means move to the right.\n", " \"\"\"\n", " if action == 0: # Mover a la izquierda\n", " next_state = state - 1\n", " else: # Mover a la derecha\n", " next_state = state + 1\n", " \n", " # Devuelve la recompensa y el siguiente estado\n", " reward = state_rewards[next_state]\n", " return reward, next_state" ] }, { "cell_type": "markdown", "id": "083ff731", "metadata": {}, "source": [ "#### Programa Principal" ] }, { "cell_type": "code", "execution_count": 11, "id": "4a49cf4e", "metadata": {}, "outputs": [], "source": [ "num_episodes = 1000\n", "epsilon = 0.2\n", "discount = 0.9 # Change to 1.0 if you want to simplify Q-value results.\n", "\n", "for episode in range(num_episodes+1):\n", " initial_state = 3 # State in the middle.\n", " state = initial_state\n", " while not final_state[state]: # Run until the end of the episode.\n", " # Select action.\n", " action = select_epsilon_greedy_action(epsilon, state)\n", " reward, next_state = apply_action(state, action)\n", " # Improve Q-values with Bellman Equation.\n", " if final_state[next_state]:\n", " Q_values[state][action] = reward\n", " else:\n", " Q_values[state][action] = reward + discount * max(Q_values[next_state])\n", " state = next_state" ] }, { "cell_type": "markdown", "id": "91544c38", "metadata": {}, "source": [ "#### Presentación de resultados:" ] }, { "cell_type": "code", "execution_count": 12, "id": "eaef41f3", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Final Q-values are:\n", "[[0.0, 0.0], [-5, 3.2805], [2.9524500000000002, 3.645], [3.2805, 4.05], [3.645, 4.5], [4.05, 5], [0.0, 0.0]]\n", "Best action for state 0 is left\n", "Best action for state 1 is right\n", "Best action for state 2 is right\n", "Best action for state 3 is right\n", "Best action for state 4 is right\n", "Best action for state 5 is right\n", "Best action for state 6 is left\n" ] } ], "source": [ "# Print Q-values to see if action right is always better than action left\n", "# except for states 0 and 6, which are terminal states and you cannot take\n", "# any action from them, so it does not matter.\n", "print('Final Q-values are:')\n", "print(Q_values)\n", "action_dict = {0:'left', 1:'right'}\n", "state = 0\n", "for state, Q_vals in enumerate(Q_values):\n", " print('Best action for state {} is {}'.format(state, action_dict[np.argmax(Q_vals)]))" ] }, { "cell_type": "markdown", "id": "773aad9f", "metadata": {}, "source": [ "#### Explicación del resultado:\n", "Interpretación de las Mejores Acciones:\n", "
* Estado 0: La mejor acción es \"izquierda\". Sin embargo, este estado es terminal, así que no tiene sentido realizar una acción desde aquí.\n", "
* Estado 1: La mejor acción es \"derecha\", con un valor Q de 3.2805. Esto indica que moverse a la derecha es preferible, ya que se espera que lleve a una mayor recompensa.\n", "
* Estado 2: También la mejor acción es \"derecha\", con un valor Q de 3.645. Similarmente, indica que avanzar a la derecha es ventajoso.\n", "
* Estado 3 y 4: La tendencia de la mejor acción continúa siendo \"derecha\", lo que sugiere que seguir hacia la derecha es el camino óptimo en estos estados.\n", "
* Estado 5: La mejor acción sigue siendo \"derecha\" (valor Q = 5), lo que significa que es el estado más favorable en el que se puede estar.\n", "
* Estado 6: La mejor acción es \"izquierda\". Al ser un estado terminal, no hay ninguna acción que pueda resultar en un cambio." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.10" } }, "nbformat": 4, "nbformat_minor": 5 }