Estás leyendo la publicación: Simulación de críquet manual con CNN y OpenCV: hacia la IA
Publicado originalmente en Hacia la IA, la empresa líder mundial en noticias y medios de IA y tecnología. Si está creando un producto o servicio relacionado con la IA, lo invitamos a considerar convertirse en patrocinador de la IA. En Hacia la IA, ayudamos a escalar las empresas emergentes de IA y tecnología. Permítanos ayudarlo a dar rienda suelta a su tecnología a las masas.
He querido trabajar en esto durante mucho tiempo. Mientras crecía, Hand Cricket era uno de mis juegos favoritos y siento que esta es mi forma de recordar esos momentos. Para aquellos de ustedes que no saben cómo funciona, aquí hay una breve descripción del juego:
- Hand Cricket es bastante similar al juego de piedra, papel o tijera. Verás cómo en unos minutos. En aras de la simplicidad, intentaré limitar las reglas a solo aquellas que son necesarias para jugar este juego.
- Necesitarás 2 jugadores para jugar este juego: un ‘bateador’ y un ‘jugador de bolos’.
- Aquí, tanto el bateador como el jugador de bolos eligen un símbolo al mismo tiempo, como piedra, papel o tijera. Cada símbolo está asociado con una cantidad específica de carreras/puntos.
- Hay un total de 7 gestos con las manos/símbolos involucrados en este juego
- El bateador y el lanzador son libres de elegir cualquier símbolo que deseen.
– Gol del lanzador: intenta elegir el mismo símbolo que el bateador
– Gol del bateador: prueba y elige un símbolo diferente del lanzador y anotar puntos/carreras
Ahora, así es como un bateador puede anotar carreras/puntos y cómo un jugador de bolos puede intentar detenerlo.
- Cada jugada en la que el bateador elige un número diferente al lanzador, obtiene tantos puntos como indique el número elegido.
- La única excepción a la regla anterior es el símbolo del puño cerrado (defensa). Este movimiento le dará al bateador tantos puntos como indique el símbolo elegido por el jugador de bolos.
- Si tanto el bateador como el jugador de bolos eligen el MISMO símbolo de mano, ¡se acabó el juego!
Aquí hay un escenario de muestra para que quede más claro:
– La ronda 1:
Símbolo del bateador = 4 ()
Símbolo del jugador de bolos = 2 ()
Puntaje del bateador = 4 carreras
– La ronda 2:
Símbolo del bateador = 5
Símbolo del jugador de bolos = 3
Puntuación del bateador = 9 carreras (4+5)
– Ronda 3:
Símbolo del bateador = 0 (defensa)
Símbolo del jugador de bolos = 1
Puntuación del bateador = 10 carreras (4+5+1)
– Ronda 4:
Símbolo del bateador = 0 (defensa)
Símbolo del jugador de bolos = 6
Puntuación del bateador = 16 carreras (4+5+1+6)
– Ronda 5:
Símbolo del bateador = 3
Símbolo del jugador de bolos = 3
Puntaje final del bateador = 16 carreras
. Eso fue agotador y bastante complicado, no gracias a mí. Por tu bien, espero que estés familiarizado con el juego de antemano.
Ahora que sabemos cómo funciona el juego, podemos sumergirnos en mi intento de replicar este juego. (Usaré Python para los fragmentos de código)
Este es un código bastante largo, así que tengan paciencia conmigo. El proceso se puede dividir en los siguientes pasos:
- Paso 1: recopilación y formato de datos
- Paso 2: Cargar los datos y procesarlos
- Paso 3: Diseño de la arquitectura del modelo CNN
- Paso 4: Entrenamiento del modelo CNN para contar los dedos
- Paso 5: Prueba del modelo en tiempo real para contar los dedos
- Paso 6: Modificación de las reglas de Hand Cricket
- Paso 7: Implementación del modelo CNN entrenado en tiempo real para simular Hand Cricket
El código en las siguientes secciones espera un nivel intermedio de competencia en python, OpenCV y CNN. Sugiero familiarizarse con un código más simple correspondiente a los temas antes mencionados antes de continuar con las secciones.
¡Empecemos!
Los datos requeridos para este proyecto deben ser imágenes que representen los números 0-6 (incluidos el 0 y el 6). Recopilé los datos y los subí a Kaggle: Símbolos de mano. He recopilado estos datos utilizando la biblioteca OpenCV de python. Aquí hay una lectura rápida de cómo lo hice: Recopilación de datos.
He recopilado un total de 28800 imágenes jpg de dimensiones 240×240 píxeles. De estas 28000, 20000 están almacenadas en la carpeta ‘tren’ y las 8800 imágenes restantes están en la carpeta ‘prueba’. ¿Por qué exactamente 28000 imágenes? ¿Por qué una proporción de tren a prueba de 20000:8800? ¿Por qué una imagen de tamaño 240×240? ¡Ninguna razón en particular! Seguí recopilando más y más datos mientras probaba simultáneamente cómo funciona el modelo en tiempo real. Estos números dieron como resultado un modelo lo suficientemente bueno, así que me quedé con ellos. De todos modos, ¡adelante!
Tanto la carpeta de entrenamiento como la de prueba contienen 8 carpetas más denominadas: ‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘ninguna’. Cada una de las carpetas de la carpeta de tren contiene 2500 imágenes y las de la carpeta de prueba contienen 1100 imágenes. ¿Confundido? yo tambien lo seria Aquí hay una mejor representación para hacerlo más fácil.
Establecí esta estructura con la esperanza de entrenar el modelo con los datos de la carpeta de entrenamiento y probarlo con los datos de la carpeta de prueba. Sin embargo, terminé usando todos los datos para entrenar el modelo, porque mi objetivo final es implementarlo en tiempo real y no informar la precisión lograda por el modelo. Si alguno de ustedes está interesado en averiguar la precisión, una estructura similar a la anterior podría resultar útil.
Algunos de ustedes pueden notar la carpeta llamada ‘ninguno’. Esta carpeta tiene imágenes sin símbolos de manos. Las imágenes de esta carpeta se utilizan para establecer un estado cuando el usuario no muestra ningún símbolo. Esencialmente contiene imágenes con un fondo aleatorio. En términos de aprendizaje automático, este es un problema de clasificación multiclase donde cada símbolo es una clase específica. Era necesario incluir una clase que indicara el estado del usuario para reconocer imágenes en tiempo real cuando el usuario no elegía un símbolo de mano.
El paso anterior nos haría almacenar los datos en el directorio de trabajo. Ahora tenemos que traerlo al entorno (almacenarlo en variables en el formato requerido).
Suponga que los datos se almacenan en una carpeta llamada ‘conjunto de datos’. Iteramos a través de esta carpeta y los archivos dentro de ella usando funciones de la biblioteca del sistema operativo de python. Cada imagen en cada carpeta se convierte en una matriz NumPy y se almacena en una lista llamada ‘images_as_numpyarr’. Se mantiene otra lista llamada ‘etiquetas’ que almacena el número representado por la imagen, en el mismo índice que la imagen almacenada en la lista images_as_numpyarr.
Para aquellos que estén familiarizados con el aprendizaje automático supervisado, la lista de etiquetas se utiliza para proporcionar supervisión al etiquetar los datos.
Entonces, imágenes_as_numpyarr[0] contendría los datos de píxeles de la imagen como una matriz NumPy y las etiquetas[0] contendría el número que se muestra en la imagen.
Entonces, si esta fue la primera imagen, images_as_numpyarr[0] almacenaría esta imagen como una matriz NumPy, y las etiquetas[0] almacenaría el número 3.
Las etiquetas del 0 al 6 indican el número que se muestra, mientras que la etiqueta 7 indica que no se muestra ningún número (el estado ‘ninguno’ mencionado en la sección anterior).
La lista de etiquetas etiquetaría la imagen de arriba como el número 7 (que indica la clase de la imagen) y la almacenaría en la lista.
Si se encontraran las siguientes imágenes, la lista de etiquetas sería:
etiquetas = [5, 4, 6, 7]
Estas etiquetas luego se han codificado utilizando la técnica One Hot Encoding en la línea 21.
Paso 3: Diseño de la arquitectura del modelo CNN
Ahora que tenemos los datos disponibles, necesitamos diseñar un modelo de CNN y alimentarlo con los datos. En lugar de construir una arquitectura desde cero, utilicé Transfer Learning para facilitar la construcción de un modelo efectivo. Aquí hay un artículo que lo explica en detalle: Transferencia de aprendizaje. En palabras simples, es el proceso de usar un modelo previamente entrenado (con pesos) y modificar las últimas capas para que se adapten a nuestras necesidades. Esta técnica ayuda a reducir el tiempo necesario para construir y compilar arquitecturas complejas.
Aquí, he usado una arquitectura liviana llamada MobileNet. Aquí está la arquitectura.
¿Complicado? Te siento. Por ahora, solo comprenda que MobileNet está preconstruido y preentrenado (lo que significa que el entrenamiento genera algunos pesos apropiados). Importaremos esta arquitectura, modificaremos las últimas capas (generalmente agregando nuevas capas) y entrenaremos el modelo en nuestros datos.
Aquí está el código. Importé la arquitectura MobileNet en la línea 8 y agregué algunas capas al final (líneas 9–13). Luego lo compilé usando el optimizador Adam con una tasa de aprendizaje de 0.0001. Intenté entrenar con diferentes parámetros y los del siguiente código demostraron ser lo suficientemente buenos.
Paso 4: Entrenamiento del modelo CNN para contar los dedos
Ahora que tenemos la arquitectura lista, pasamos las imágenes junto con las etiquetas como matrices NumPy (Línea 4).
La forma de images_as_numpyarr[0] es 240x240x3 (240×240 es el tamaño de la imagen y 3 indica el número de canales (RGB)) y el de las etiquetas[0] es 28800 × 8 (28800 es el número de imágenes y 8 es el número de clases diferentes posibles en la clasificación (0,1,2,3,4,5,6,7) (7 representa la clase ninguna)).
El modelo está entrenado para 2 épocas. Este proceso tomó entre 50 y 60 minutos en mi máquina. Este tiempo puede variar dependiendo de la potencia de procesamiento disponible para usted.
Luego, el modelo se guarda para verificar el progreso realizado y podemos cargar el modelo la próxima vez que trabajemos con esto, en lugar de entrenarlo nuevamente.
Paso 5: Prueba del modelo en tiempo real para contar los dedos
Nuestro modelo finalmente está listo para contar el número de dedos en tiempo real. Usando OpenCV podemos usar nuestra cámara web y hacer que nuestro modelo detecte la cantidad de dedos que se muestran.
Dibujamos un cuadrado en el lado derecho de la pantalla. En cada cuadro, extraeremos este cuadrado y lo pasaremos a nuestro modelo. Nuestro modelo luego devuelve una matriz de probabilidades. Dado que hay 8 clases posibles (0,1,2,3,4,5,6,7), cada valor en la matriz representa la probabilidad de que la imagen tenga una mano que represente el número x en el índice x (excepto 7 donde el el valor de probabilidad en el índice 7 representa la probabilidad de que no haya ninguna mano en la imagen). El valor de la matriz que tiene la máxima probabilidad es el valor que el modelo predice que se muestra en la imagen. Mostré este valor en la parte superior izquierda de la pantalla.
Paso 6: Mi adaptación de Hand Cricket
Ahora tenemos un modelo que es capaz de contar los dedos. Ahora pasamos a los tecnicismos del juego. Este proyecto fue creado para permitir que un solo humano juegue el juego con un bot. Si 2 jugadores humanos quisieran jugar al cricket de manos, podrían hacerlo en persona o mediante una videollamada. Entonces, el siguiente programa se puede usar para jugar solo contra un bot. Para facilitarlo aún más, el humano siempre actuará como bateador y el bot siempre será el jugador de bolos. El jugador de bolos elegirá al azar un número del 0 al 6 cada segundo. En el momento en que el bateador elige un número (señala un número con la mano en el área designada), el número se suma a su puntuación. Dado que la computadora elige un nuevo número en cada cuadro, es difícil mantenerse al día con el bot. Solo tenemos que elegir al azar un número, irregularmente par, y esperar que no coincida con el número elegido por el bot (el lanzador).
Paso 7: Implementación del modelo CNN entrenado en tiempo real para simular Hand Cricket
Si llegaron hasta aquí, felicítense porque tienen una gran dedicación para aprender. ( Estoy exhausto )
Esta es la última pieza de código que combina el modelo que cuenta los dedos (líneas 44 a 49) con las reglas del juego descritas en la sección introductoria (líneas 56 a 64).
Una vez más usamos OpenCV para acceder a la cámara web porque necesitamos implementar esto en tiempo real. Hay un espacio dedicado en la mitad derecha de la pantalla para el usuario (bateador). La puntuación actual y la puntuación más alta del usuario se muestran en la pantalla (líneas 67 a 80).
¡Aquí está el juego en acción! (Ignore los puntajes actuales y altos. Dado que cada segundo el modelo detecta un número elegido por mí (el bateador), digamos 5, se agregan 5 puntos a mi puntaje (puntaje del bateador). Entonces, cada segundo se agregarán 5 puntos a mi puntaje hasta que el bot también elige al azar 5, lo que significa Game Over para el bateador (yo). Cuando esto sucede, mi puntuación actual vuelve a 0 y mi juego comienza de nuevo)
Gracias por quedarte hasta el final. Puse mucho esfuerzo en este proyecto y espero que esta haya sido una experiencia de aprendizaje para usted también.
¡Hasta la proxima vez! ¡Ciao!
Hand Cricket Simulation usando CNN y OpenCV se publicó originalmente en Towards AI en Medium, donde las personas continúan la conversación destacando y respondiendo a esta historia.
Publicado a través de Hacia la IA