Crear un bot para participar en la mini copa AI 2018 basada en una red neuronal recurrente


Inicialmente, no tenía planes para un artículo, especialmente sobre hablar en una conferencia. Pero hubo una conferencia. Y después de hablar sobre ello, los televidentes me hicieron preguntas sobre la implementación de algunos problemas técnicos. Y así resultó palabra por palabra: un artículo.


Grabación en vivo debajo del enlace .


Descargo de responsabilidad: este artículo es un intento de responder algunas de estas preguntas. Me alegrará si surgen nuevas preguntas, respondiendo que habrá una oportunidad de aprender algo nuevo yo mismo. Y sí, este artículo no es en modo alguno un intento de sentir el tintineo de las tuberías de cobre.


Y comencemos desde el comienzo de esta historia. Primavera de 2018, mail.ru anunció un concurso de programación basado en el juego Agairo . La esencia de la competencia es la creación de un juego bot.


Reglas de competencia en este enlace . Pero para ser breve y describir las reglas con tus propias palabras, debes crear un bot para jugar en Agairo. En un momento, un juego popular de Internet (en el sentido de que se lanza desde el navegador), cuya esencia es comerse a tus hermanos menores y escapar de los más grandes. Usted controla una rueda de color en un espacio bidimensional limitado. Para crear la jugabilidad en este espacio, además de tu círculo, hay otros círculos controlados en consecuencia por otros jugadores. Hay alimentos (puntos de colores) para el crecimiento, se introducen obstáculos adicionales en forma de "virus", una colisión con la que se crea una división de su círculo en pequeños, lo que complica parcialmente el proceso del juego, ya que los pequeños comen los más grandes y los más grandes son más seguros.


Daré una imagen de una variante del juego para competiciones


Además, por jugador no nos referimos al desarrollador del bot, sino al propio bot.


Los organizadores de la competencia en general conservaron el concepto original del juego, pero agregaron una serie de innovaciones. La principal de las cuales es la restricción de la revisión del bot y la introducción de una ley física simple llamada inercia. La física ha pasado por la física durante mucho tiempo, por lo que la inercia está asociada no solo con nosotros, sino también con cantidades tales como masa, velocidad y aceleración. No necesitamos nada más del mundo de la física.


Espero que la parte literaria haya prestado suficiente atención y es hora de pasar al componente técnico de la competencia y participar en él.


Descargo de responsabilidad 2: estoy bastante seguro de que lo que se describe a continuación podría hacerse más delgado, más elegante e inteligente, pero cómo sucedió, sucedió.


Así que escriba la receta y los ingredientes principales, no todos son nuevos, pero puede agregar los suyos a su gusto.


Tarea: Crea un bot que pueda jugar Agairo solo.
La idea principal: utilizar redes neuronales (en adelante denominadas red neuronal, red neuronal (NN)) como elemento de control del bot.
Principales herramientas de producción: Microsoft Visual Studio y c # con una transición suave a c ++.


Entonces, lo más importante para el autor es elegir o comprender a su lector, para quien escribo, sabe qué son las redes neuronales, los algoritmos genéticos y cómo describir todo esto en detalle.


Eso es todo, elegí a mi lector, mi lector sabe todo esto, pero no tan bien como para usarlo en la práctica.


Por lo tanto, mientras escribo este artículo, recordaré formas simples como una neurona y una función de activación.


Para la visualización, usaré imágenes dibujadas a mano, que deben leerse como: si ve algún error allí, escriba, vuelva a dibujar los correctos.



Entonces, todo está listo para ser enviado a la ruta de la construcción del software del bot. Comencemos:


Tomamos el ciclo, o más bien, los organizadores de la competencia lo prepararon para nosotros como un ejemplo de un simple bot. Vamos más allá, descargue el archivo para el participante del concurso desde el repositorio utilizando este enlace . Los organizadores prometieron que el servidor del concurso vivirá y, una vez completado, podremos verificar estas palabras. Abrimos el archivo y elegimos un lenguaje de programación que nos sea comprensible.


La documentación de la competencia también describe la tecnología de comunicación del cliente (lea nuestro bot) y el servidor de un centro de datos que vive en algún lugar en las profundidades. En resumen, la comunicación pasa por la línea de la consola, escribiendo y leyendo comandos desde ella.


La palabra mágica Serialización debería mencionarse aquí: empaqueta sus datos en un formato que el serializador entiende y la capacidad de volver a leer estos datos en el programa utilizando el serializador. Hay muchos serializadores, el formato secuencial más simple para escribir en el archivo txt también es un serializador, pero simple. Lo que necesitamos saber sobre los serializadores es que existen y son casi transparentes en términos de API. Los organizadores probablemente entendieron esto y, por lo tanto, el ejemplo de su bot contiene todas las instrucciones necesarias para trabajar con el serializador. En nuestro caso, fue JSON .


Para el bot después del serializador, el mundo del juego parece una serie de datos recibidos al comienzo del ciclo mencionado. Los datos sobre el mundo del juego están limitados por el servidor de acuerdo con el radio de la vista igual a los 4 radios del bot, recuerde que el bot es un círculo. Y el círculo alrededor del círculo es el borde externo de la revisión, aunque el círculo externo está ligeramente sesgado hacia el movimiento del bot en relación con el centro del bot, pero esto puede descuidarse en nuestro caso.



Y entonces tenemos un Ciclo, la medida del Ciclo es Tick, cuántos ciclos han pasado, se han ejecutado tantos ticks. Lo más probable es que ya no recordaremos este Tick, pero introducirá una serie de limitaciones y simplificaciones importantes: el tiempo de cálculo está limitado no solo por un solo Tick, el tiempo de una iteración del ciclo, sino también por el tiempo de cálculo total, al exceder el cual el servidor del juego desconectará su bot de la administración. Marque y es hora de dar comandos al bot. Lo consideraremos un tiempo cuántico de juego, Tick es una cantidad de tiempo indivisible en el mundo del juego. Las ventajas se derivan de esto. Dado que la marca es igual a 1 de forma predeterminada, es más fácil calcular velocidades, aceleraciones y otros valores. En todas las fórmulas, multiplicamos por 1, en lugar de utilizar algún tipo de tiempo de curva t = 0.0015 segundos en ellas. Los errores en estas operaciones también son mínimos.


Todo lo anterior es algo similar a una película, parece que la imagen en la pantalla es animada y conmovedora, pero de hecho, se nos muestran 25 fotogramas diferentes por segundo, y nuestro cerebro solo considera que es una frecuencia suficiente para una percepción completa de la dinámica del video. Entonces el bot ve el mundo a intervalos de tiempo. Tick ​​es un marco del mundo del juego.


La red neuronal también funcionará de acuerdo con las garrapatas.


La imagen comienza a despejarse desde el costado del bot:


El servidor envía los datos procesados ​​sobre el mundo al bot-> Tick Start-> el bot recibe los datos -> los procesa-> envía los comandos de administración del bot al servidor-> El servidor lee los datos-> End of the Tick y luego en un círculo o bucle casi infinito, 45000 ticks en el final El juego es una figura bastante sustancial.


Nota importante: puede omitir Tick y no obtendrá nada por ello. Hay casos de servidores donde cada Tick necesita decirle algo al servidor, para que el servidor no sospeche que el bot está bloqueado en el programa de control.


El autor decidió no tocar mucho el servidor, pero necesito decir algunas palabras al respecto. Hay un modelo del mundo del juego en el servidor y, de acuerdo con él, realiza cálculos y acciones. El programa del servidor incluye los siguientes bloques:


  • cálculo de colisiones de bots (procesamiento de colisiones con los límites del mundo del juego, quién se comió a quién, bot bot o comida de bot, o una colisión con un virus, etc.)
  • cálculo de la física del bot (movimiento del bot, cambios en la velocidad del bot de acuerdo con los comandos del bot o colisiones que ocurrieron)
  • cálculos relacionados con dividir bots o combinarlos, si es posible, agregando alimentos y otras funciones para mantener el mundo del juego.
  • y, por supuesto, enviar y recibir datos a bots en ticks de juegos.

Tal servidor se llama un "comando". Es decir, todas las acciones ocurren en el lado del servidor, lo que elimina los problemas con la sincronización de datos. El cliente (lea el bot) solo recibe una imagen del mundo preparada, al igual que sus otros rivales, aquí se logra la igualdad de las posiciones de los bots, no hay prioridades ni colas. Una vez más, se produce un cambio en las coordenadas del bot en el servidor, por ejemplo, el bot da un comando para cambiar y solo en el siguiente Tick aprende sus nuevas coordenadas, que no siempre coinciden con el equipo, como una opción un obstáculo en forma de un muro del mundo del juego.


foto del sitio de los organizadores



Descubrimos la lectura de datos con el bot y el servidor de administración, ahora echemos un vistazo a las profundidades del dispositivo bot.


Como el lector probablemente ya entendió, habrá pocas palabras y mucho trabajo, o viceversa.
El bot está controlado por una red neuronal. Corto y espacioso, pero no del todo claro cómo.


La elección de una red neuronal y la técnica para su implementación.


Por el momento, decidimos que la red neuronal para nosotros es una caja negra que tiene una entrada y una salida.


La entrada y la salida para nosotros serán matrices unidimensionales con una dimensión de N = 16 para la entrada y una dimensión de M = 4 para la salida.



Dado que la naturaleza de la red neuronal artificial se copia aproximadamente de la red neuronal natural, sería bueno para nosotros acercar la estructura de los datos de entrada a los naturales. En la naturaleza, varios sensores son responsables de esto. Así que quédate con los sensores de bot.


La siguiente opción se seleccionó experimentalmente (la imagen se simplifica a 8 sensores y una red neuronal 4x3, pero esto es solo para confundir a mi lector):



El campo de visión del bot se divide en sectores iguales (posiblemente incluso desiguales). Cada sector proporciona una señal a una de las entradas de la red neuronal. En consecuencia, si dividimos el área alrededor del bot en 16 sectores (360/12 = 22.5 grados de visión general del sector), obtenemos 16 entradas de la red neuronal. Típicamente, una señal que va de -1 a 1 se aplica a la entrada de una red neuronal, por lo tanto, será necesario normalizar las señales de entrada.


El racionamiento es, simplificado, dividiendo la señal total por su valor máximo posible. Por supuesto, es posible hacer una normalización dinámica, es decir, buscar el máximo cada vez y llevar el valor de la señal a su norma, pero estableceremos el valor máximo en forma de una constante igual al número máximo de objetos en un sector y no lo cambiaremos en el proceso de trabajo en el bot.


Las señales pueden ser positivas o negativas, estamos de acuerdo en que el valor de la señal de 0 a 1 es un motivo positivo para nuestro bot (comida, comida en forma de bot más pequeño), un valor de señal negativa de -1 a 0 es un motivo negativo para el bot (pared mundo de juego, otro bot más grande).


dibujo



Una señal de un sector es una cantidad normalizada que consiste en la suma de señales individuales. Cada señal individual, como se ha dicho, tiene un signo y una magnitud. La magnitud de la señal se define como una función proporcional de la distancia. La distancia mínima es el límite circular del bot definitorio; la distancia máxima es el límite de la visibilidad del bot. En consecuencia, si recibimos una señal positiva de, por ejemplo, alimentos que acaban de ingresar al sector a una distancia máxima, entonces la señal será débil y aumentará si el bot se acerca a los alimentos.


Los sensores en forma de sectores fueron los más adecuados para este caso, pero puede haber simplemente antenas de sonda, aquí la fantasía está de su lado. Por supuesto, el autor probó varias opciones para dividirse en sectores de 4 sectores a 72, pero la práctica ha demostrado que la red neuronal está entrenada con bastante éxito en 16 sectores y está lista para controlar el bot incluso con cuatro sectores. Aquí se manifiesta la flexibilidad de la naturaleza misma de la red neuronal.


Finalmente, se pronunció la palabra entrenamiento de redes neuronales . Pero por ahora, decidimos que la red neuronal es un cuadro negro con entrada y salida, y dado que clasificamos los datos de entrada, queda por decir algunas palabras sobre los datos o señales de salida de este cuadro, qué hacer con él y cómo procesarlo.


Establecemos la dimensión de la señal de salida en 4. Este número es una manifestación del dualismo de coordenadas cartesianas y polares. El autor no se olvidó de la naturaleza del conocimiento de su lector y, por lo tanto, le recuerda con su dibujo del conocimiento una vez bien adquirido.



Entonces, los desarrolladores del servidor usaron lógicamente las coordenadas polares para simular el mundo del juego, y para los bots y sus desarrolladores proporcionaron cortésmente las coordenadas cartesianas. Por lo tanto, el autor tuvo que elegir un lado en este sistema de coordenadas. Para una red neuronal, un sistema de coordenadas polares que contiene solo la magnitud (longitud de lectura) del vector y el ángulo de su desviación es más comprensible. Después de todo, también comprende las palabras "girar a la derecha" en lugar de moverse dos pasos a lo largo de la ordenada y tres pasos a lo largo de la abscisa.


Por lo tanto, 4 señales de salida, estas son 2 señales sobre aumentar o disminuir el ángulo del vector de velocidad del bot, y 2 más están aumentando o disminuyendo la magnitud del vector de velocidad.
Pero dado que el servidor del juego pidió dar comandos para administrar el bot en coordenadas cartesianas, un par de fórmulas para traducir de coordenadas polares a coordenadas cartesianas y toda esta desgracia llegaron a su lugar (este es un pseudocódigo similar a c #).


float rotate1 = outputs[0]; float rotate2 = outputs[1]; float speed1 = outputs[2]; float speed2 = outputs[3]; if (rotate1 > 0.65 && rotate2 < 0.65) angle = angle + 35 * PI / 180; if (rotate1 < 0.65f && rotate2 > 0.65) angle = angle - 35 * PI / 180; if (speed1 > 0.65 && speed2 < 0.65) speed = speed + 2; if (speed1 < 0.65 && speed2 > 0.65) speed = speed - 2; dx = speed * Cos(angle); dy = speed * Sin(angle); 

Las señales están en su lugar, como un bot. Parece que le dieron señales de entrada, pero a la salida, algo no vale la pena: se para o se mueve al azar.


Entonces vino a abrir la caja negra y mirar adentro.


Continuará


Pero antes de la nueva serie teaser:


El bot morado en la red neuronal juega en Local Runner contra los bots estándar que los organizadores cosieron por defecto.


Source: https://habr.com/ru/post/es417311/


All Articles