¿Cómo le hago saber a AI que solo algunas acciones están disponibles durante estados específicos en el aprendizaje por refuerzo?

Supongo que está preguntando sobre “condiciones previas de acción”: cuando el conjunto de acciones es una función del estado del entorno actual. Hay dos formas de preguntar cómo incorporarlos: (1) desde una perspectiva de ingeniería de software, cómo asegurarse de que esta información por estado esté disponible; o (2) cómo incorporar esta información de conjunto de acciones por estado en algoritmos RL.

Comencemos con el primero. Hay al menos dos formas en las que podría realizar la ingeniería de software. Lo que podría estar haciendo ahora es hacer que su entorno proporcione al agente algo como un “Espacio de acción” por adelantado que el agente recibe una vez y usa para siempre. Esto es efectivamente lo que hace la colección de entornos Open AI’s Gym. Sin embargo, en lugar de proporcionar un solo espacio de acción, haga que proporcione una función de espacio de acción. Esta función recibiría una observación y luego devolvería un espacio de acción para esa observación. Si normalmente tiene un espacio de acción discreto definido por un conjunto de enteros, en algunas observaciones esta función puede devolver un espacio que incluye las acciones 1, 2, 3 y 4, y tal vez en otros devuelva un espacio que incluya solo 1, 3 y 4 (indicando que la acción 2 no está disponible).

La otra forma de hacerlo es proporcionar un espacio y una función “disponible”. El espacio es solo el espacio de acción completo habitual (por ejemplo, incluye las acciones 1, 2, 3, 4). La función disponible recibe tanto una observación como una acción y devuelve un valor booleano que indica si esa acción se puede seleccionar o no. En este enfoque, el agente puede simplemente seleccionar una acción y luego consultar si realmente puede usarla o no antes de ejecutarla, manejando cualquier lógica después del hecho. Este enfoque es un poco más engorroso, pero una razón por la que es posible que desee utilizarlo es si tiene un espacio de acción infinito (por ejemplo, continuo), es posible que no pueda enumerar todas las acciones disponibles por adelantado y, en su lugar, tenga que verificar cualquier acciones individualmente.

Para lo que vale, ambos enfoques para proporcionar información de condición previa de acción se utilizan en la biblioteca BURLAP RL.

Ahora consideremos el otro ángulo de cómo los algoritmos deberían incorporar la información de precondición, dado que se proporciona. Desearía poder darte una respuesta única, pero desafortunadamente, los enfoques dependen del algoritmo y, a veces, ¡hay más de una forma de hacerlo incluso para el mismo algoritmo! Sin embargo, describiré cómo podría hacerlo para dos clases comunes de algoritmos; métodos de función de acción y métodos de gradiente crítico / política del actor.

Consideremos primero cómo incorporarlo en métodos basados ​​en la función de acción (p. Ej., Q-learning, SARSA y sus variantes) con acciones discretas y cuando se sigue una política de exploración como épsilon codicioso. En el lado de selección de acciones, debe filtrar los valores Q al conjunto de las acciones disponibles en la observación actual. Luego, tome el argumento max de ese conjunto filtrado o seleccione al azar de ese conjunto filtrado. En el lado del aprendizaje, cuando actualiza el valor Q para una acción seleccionada, si está usando algo como Q-learning, cuando realiza el operador máximo de los valores Q para el siguiente estado, en su lugar aplique el operador máximo sobre el conjunto filtrado para las acciones disponibles en el siguiente estado. ¡Eso es!

Para los métodos de gradiente de crítico / política del actor, necesitará algo un poco diferente. Asumamos nuevamente un conjunto de acciones discretas. En estos métodos, está aprendiendo directamente una red de políticas que genera probabilidades de selección de acciones, en cuyo caso lo que realmente necesita hacer es incorporar de alguna manera en la red de políticas las condiciones previas de acción. Afortunadamente, para acciones discretas, hay una forma bastante directa de hacerlo. Para acciones discretas, comience con lo que normalmente haría y haga que la salida de la red genere una distribución de probabilidad sobre todas las acciones posibles (a menudo haciendo que tenga una capa de red softmax en la parte superior). Sin embargo, esta distribución de probabilidad ya no será la distribución final. En su lugar, le aplicaremos una capa más. Esta capa realizará una operación de “activación normalizada”. Lo que haremos primero será multiplicar la distribución de probabilidad por un vector de activación binario con una dimensionalidad igual al número de acciones. En el vector de compuerta, cada elemento es un 1 si esa acción está disponible en el estado actual, y 0 si no está disponible. La consecuencia de esta multiplicación es que solo tendrá valores distintos de cero para las acciones disponibles. Sin embargo, no hemos terminado, porque el resultado de nuestra red de políticas debe ser una distribución de probabilidad adecuada. Por lo tanto, queremos normalizar estos valores para que sumen uno. Podemos hacerlo dividiendo cada elemento por la suma de la salida cerrada. Es decir,

[matemáticas] \ pi = \ frac {\ hat {\ pi} \ times G} {sum (\ hat {\ pi} \ times G)} [/ math]

donde [math] \ hat {\ pi} [/ math] es la distribución de probabilidad previa que la red genera en todo el espacio de acción, [math] G [/ math] es el vector de activación binario que define qué acciones están disponibles, [math ] sum [/ math] suma todos los elementos de un vector y [math] \ times [/ math] realiza una multiplicación por elementos en dos vectores. Naturalmente, crearía G cada paso en función de las acciones disponibles y lo introduciría junto con la observación a la red de políticas.

¡Ahora el resultado final será una distribución de probabilidad sobre acciones que nunca selecciona acciones que no están disponibles en el estado actual y puede usar algoritmos de gradiente de crítico / política de actor sobre esta salida como lo haría normalmente!

Aquí está mi pensamiento sobre mi propia pregunta:

Digamos que hay una IA diseñada para aprender a jugar Super Mario. Y definimos una acción llamada “saltar” para saltar, que prácticamente presiona el botón A pronto y luego suelta el botón pronto. El resultado es un salto: salto corto.

Pero todos saben que no solo hay un salto corto en el juego, sino también un salto largo: para mostrarlo, AI tiene que seguir presionando el botón A, no soltar el botón A hasta que sea hora de dejar caer a Mario.

Como la distancia para saltar no es discreta, no creo que tenga sentido definir varias acciones de salto con diferentes distancias. En cambio, creo que tiene sentido definir una acción llamada “salto de mantenimiento”, mantenga presionado el botón A, y otra llamada “salto de liberación”, botón de liberación A. Para que la IA pueda elegir si caer en un determinado paso de tiempo, como humano

Entonces aquí surge una pregunta: como hay algunas otras acciones además de la acción de mantener / liberar el salto, cómo dejar que la IA simplemente elija “liberar el salto” o no hacer nada después de “presionar el salto” durante el entrenamiento.

En este diseño de acción, es fácil ver que sería terrible si la IA olvidara soltar el botón; esto llevaría a la IA a seguir saltando y luego a obtener un reconocimiento distorsionado del entorno al pensar “Oye, no estoy actuando, el el entorno solo me mantiene saltando. Siempre estoy saltando en el juego “.

Luego, en mi propio pensamiento, aparecen 2 formas de resolverlo:

Supongamos que estamos utilizando un gradiente de políticas para encontrar una política óptima con distribución de acciones, y tomamos una especie de red neuronal para entrenar con la entrada de píxeles sin procesar del juego.

1.utilizando “If then” para filtrar acciones incorrectas: es decir, después de presionar jump, grabarlo con una bandera, luego de obtener una distribución de todas las acciones en el siguiente paso de tiempo, sin importar qué acción se elija, simplemente haga:

si la acción elegida == “lanzar salto”:

lanzar salto

cambiar registro de bandera

más:

hacer nada

Pero el problema es que lo que realmente hizo la IA no influye en el entrenamiento, después de todo, solo elige alguna acción, diga C pero no “suelte el salto”. ¿Confundiría a la IA que C es buena durante el salto? Tengo una pérdida aquí.

2. Sin cambios en la elección de acciones, pero agregue una bandera numérica en la red

Es decir: después de presionar saltar, simplemente agregue una bandera como cierto valor unitario en una determinada capa oculta de la red neuronal.

El problema con esta solución es:

1) pérdida de tiempo, ya que la IA tiene que descubrir todas las demás acciones además del “lanzamiento de salto” no tiene sentido después de presionar el salto (solo por simplicidad, ignorando el efecto del botón de dirección durante el salto) después de una larga iteración de entrenamiento;

2) tiene que pensar qué valor numérico representa “salto presionado” o “no salto presionado”: ¿qué pasa si está bien, simplemente elija 0 y 1, no un efecto negativo en el cálculo del gradiente?

¿Hay alguna idea sobre esto, o crees que mi diseño sobre “acción de mantener / liberar” no tiene sentido?