Iniciación a la programación de una Inteligencia Artificial

Después de los malos resultados que obtuvimos en una entrada anterior sobre pruebas de códigos libres de Inteligencia Artificial para la multimedia, hace poco comencé a estudiar programación de Inteligencias Artificiales y, aunque he comenzado por el tipo más común algo alejado de las películas americanas, me he llevado varias sorpresas que no esperaba. En primer lugar los lenguajes de programación más utilizados son realmente fáciles, como Python, o para pruebas se pueden utilizar el libre Octave y el comercial Matlab, todavía más fáciles si cabe. Y en el caso de la programación, tampoco es que sea necesario tener un Premio Nobel, puede estar al alcance incluso de un imberbe que no haya hecho pellas en matemáticas. Sí es cierto que detrás hay fórmulas que alguien tuvo que deducir, con una complejidad matemática menos accesible y además con el requisito, para el que las dedujo, de ser trasladables a códigos de programación, hoy día las Inteligencias Artificiales más comunes ya son más que conocidas en programación y prácticamente se trata de copiar y pegar estas fórmulas, las que serían la parte medular de una Inteligencia Artificial. Más que otra cosa, el programador debe conocer las distintas posibilidades para resolver un problema y saber analizar las variables y parámetros que manejará el código para que la Inteligencia Artificial funcione de forma eficiente, o al menos para que simplemente funcione.

Inteligencia Artificial

Inteligencia Artificial peliculera.

Tan sencillo es programar que explica el por qué hay tantos programadores de Inteligencias Artificiales, y además no son necesariamente informáticos. Esto presenta el problema de que los programas muy probablemente tengan grandes ineficiencias, y luego puede que haya una tendencia a convertir en abstracto, de rasgos humanos, o darle algún glamour a lo que no es para tanto, algo que cualquier informático sabe, o debería saber, más que de sobra. Tampoco es lo contrario, el típico «listo del pueblo» español que ha oído campanas a lo lejos o alguno le ha soplado que no sirven para tanto, como los perritos robots de 3.000 euros para que luego ni caguen en el suelo. En realidad la tecnología actual no está muy preparada aún para una Inteligencia Artificial de las películas americanas, lo que más se hace son Inteligencias Artificiales muy específicas para una tarea muy concreta, además los programadores deben simplificar el problema en lo posible o el algortimo no funcionará o será lento, por todo esto pueden parecer unas Inteligencias Artificiales algo distintas a lo esperado. Más que para otra cosa, las utilizan las grandes empresas para analizar datos de clientes, en gran parte algo parecido a las labores de un típico empleado agente comercial de ventas español, o también pueden ser útiles para optimizar el proceso productivo o el producto que manejen, es decir, en ninguno de estos casos no es nada glamouroso.

Sony Aibo

Sony Aibo, el perro que no le caga a los tontos españoles.

El tipo de Inteligencias más comunes se denominan más correctamente Machine Learning, o Aprendizaje Automático en español, en el sector se considera un error denominarlo Inteligencia Artificial. Consisten en códigos de programas capaces de aprender y mensurar a partir de unos datos o variables de las características de entrada, junto con variables de salida o con resultados conocidos para poder llevar a cabo el aprendizaje, para luego conseguir unos datos de salida válidos a partir de datos de entrada nuevos. Nada mejor que un ejemplo para conocer mejor de qué se trata, en este caso será inventado, predecir si un español es un tonto fascista español solo por la manera de andar, y con los datos de entrada o de aprendizaje inventados, ya que voluntarios tontos fascistas españoles no he podido encontrar. También podrían haberse elegido otros sistemas, como analizar la característica cara de malas pulgas o una peculiar sonrisa como para hacerse el listo del pueblo cuando escuchan algo que no les gusta o cuando hacen un sorteo en la tómbola de sus reducidos cerebros.

Octave

Octave versión 4.2.2 en Ubuntu Bionic 18.04 LTS

En la programación de Inteligencias Artificiales hasta con los lenguajes de programación de más alto nivel como Octave y Matlab, de más alto nivel que el habitual alto nivel y que bien se podrían calificar en una nueva categoría o denominarlos lenguajes de programación “de broma”, se pueden hacer funcionar con aceleración en tarjetas gráficas, en concreto en Matlab se puede usar algunas funciones que utilizan librerías CUDA, tampoco no hay que olvidar que Matlab es un software comercial de pago, con precios para el programa base de 125 € si es para uso personal no comercial, 2.000 € para uso personal profesional, o en las licencias empresariales hay que preguntar precios al comercial online aunque no serán baratas, mientras que Octave es un clon libre muy compatible con Matlab, solo que no tiene el mismo número de funciones matemáticas extra, o es más lento y no tendría opciones para un posible uso en producción como Matlab. En el caso de Octave las opciones de aceleración de funciones con la GPU pasarían por una librería libre basada en OpenCL que está muy verde, y otra basada en las CUDA de Nvidia pero que no cuenta con el apoyo de la comunidad de software libre, no lo aprovecha para que suponga una competencia dado el auge de las Inteligencias Artificiales, la única opción sería el uso de códigos externos, por ejemplo de C o C++. En cualquier caso estos lenguajes de programación son más utilizados para pruebas previas de un código, la mayor parte de programadores optan por otros, principalmente por el lenguaje de programación Python, que es también un lenguaje interpretado de muy alto nivel aunque no tanto como los anteriores, con varias opciones de librerías con aceleración en la GPU, unas más optimizadas que otras o según las operaciones matemáticas, en este y otros lenguajes por ejemplo el rendimiento depende de la forma en la que librería haga uso de la memoria de la tarjeta gráfica y del modelo de tarjeta. Pero nadie da duros a cuatro pesetas, en el caso de que se requiera maximizar la velocidad de ejecución probablemente no quede otra que programar con los lenguajes de programación más rápidos. En este caso utilizaremos Octave, con códigos compatibles con Matlab, aunque no tiene mucha importancia la elección del lenguaje de programación o será fácilmente trasladable por ejemplo al más utilizado Python, o al uso de librerías con aceleración en la GPU.

Esqueleto 3D

Esqueleto 3D

En primer lugar hay que analizar la mejor forma de afrontar el problema, suponemos que podemos conseguir todos los datos del movimiento de los huesos principales del esqueleto de personas que pasan por delante de una cámara de vídeo, como la longitud y el ángulo de cada hueso, esto se podría conseguir por ejemplo con un software de captura de movimientos. Aunque probablemente lo ideal sería que la misma Inteligencia Artificial pueda analizar el movimiento de los huesos, en este caso suponemos que queremos aprovechar un software ya probado o por simplificar el código de Inteligencia Artificial o Machine Learning. Ya sabemos que un palurdo fascista tiene unos andares característicos, podríamos denominarlo de superpollo, con piernas abiertas, brazos estirados, muchos taloneando o poniendo los pies como de punta, como si imitasen a un bufón medieval o algo parecido, otros movimientos característicos observables son las zancadas largas, el tronco estirado o la nuca hacia atrás. Ahora tendríamos que ponernos en la piel, solo un milisegundo y sin tocar… tampoco hay que pasarse, de un «listo del pueblo» o un simplón fascista español y descartar la información poco válida o simplificar la que se pueda deducir en otra o reducir en una nueva. En este caso inventado o que no tiene por qué coincidir con la realidad, descartaremos las piernas abiertas al ser poco rigurosa, pudiendo dar resultados ambiguos o falsos positivos en el caso de sobrepeso, o de los que van al gimnasio y también trabajan la parte de abajo, o el fascista puede apretar el culo hacia adentro, o no, si nota la presencia de machos por detrás. Los andares con pies de bufón medieval tampoco son lo suficientemente significativos. Al final, más por intuición que por otra cosa, por lo que puede que no sirva o haya que probar otras posibilidades, reducimos los movimientos de la parte superior del tronco al ángulo que forme una línea media que una la columna vertebral, y de la parte inferior solo nos quedaremos con el ángulo de la pierna al final de la zancada. También nos hubiera gustado quedarnos con el ángulo vertical de la nuca, aunque lo hemos descartado para simplificar al máximo el ejemplo.

Simplificando características Machine Learning

Simplificando características Machine Learning

En Octave podemos ejecutar comandos sueltos en la pestaña de comandos. Generaremos datos aleatorios de los 2 ángulos y los guardamos todos en un archivo de texto, luego añadiremos los inventados resultados positivos y negativos de tontos fascistas españoles según un criterio más o menos plausible, todos estos datos serán los que usaremos para el entrenamiento de la IA, será una matriz de 3 columnas, las 2 primeras para los ángulos y la tercera para el número que indica el resultado positivo o negativo. El número de filas de la matriz depende del número de individuos capturados, cuantos más mejor será el entrenamiento de la IA pero tardará más.

  • Comando para generar una matriz «A» de dimensión 100×3 con números aleatorios entre 0 y pi/4 para el ángulo «a» (pierna), entre 0 y pi/8 para «b» (columna), la tercera columna con los resultados son ceros que luego editaremos a mano ya que no tenemos palurdos fascistas voluntarios:

A=[rand(100,1)*pi/4, rand(100,1)*pi/8, zeros(100,1)]

  • Comando para guardar la matriz en un archivo de texto en el directorio actual, con valores numéricos en doble precisión, formato ASCII y en columnas separadas por un espacio tabulador:

save(‘MyMatrix.txt’, ‘A’, ‘-ascii’, ‘-double’, ‘-tabs’)

Este archivo o matriz lo podremos utilizar en el código para asignarlos a cualquier matriz con el comando load, por ejemplo: B = load(‘MyMatrix.txt’). Con el comando plot se pueden generar gráficas configurables, para ver todos los datos de entrada en conjunto o, posteriomente, verlos junto a la función que genere el código de aprendizaje, o también es posible generar gráficas de 3 dimensiones, por ejemplo si tuvieramos un sistema de aprendizaje del tipo  clasificación con 3 entradas, podríamos representarlas en un espacio tridimensional. Las gráficas aparecerán en una ventana aparte con algunos botones de opciones como la rotación o redimensión de la vista.

Machine Learning supervisado

Machine Learning supervisado

Ahora toca elegir la parte del código de Machine Learning para el aprendizaje. Hay varios tipos o sistemas de aprendizaje, divididos en supervisados y no supervisados, y dentro de los supervisados para problemas de regresión, con resultados dentro de unos márgenes dependientes de alguna función lineal o de cualquier orden, con resultados en tonos de grises; y para problemas de clasificación, de una respuesta sí o no, con resultados blanco o negro o una entre varias posibles respuestas fijas. Para cada tipo existen varios algoritmos de programación, con ventajas y desventajas. Podríamos haber escogido un sistema de aprendizaje para Regresión lineal que diera un resultado en porcentajes de palurdo, y luego decidir si por ejemplo a un individuo con un resultado del 60% es ya suficiente para calificarlo de palurdo fascista, aunque en este caso tendríamos que tener algún otro dato mensurable para que el sistema de entrenamiento conociera el porcentaje de palurdo de cada individuo y que fuese más o menos lineal, como un test de coeficiente intelectual o las calificaciones del colegio, o hacer una media ponderada entre varios de estos datos de salida, no de entrada. Este último aprendizaje a priori no sería del todo fiable, siempre cabría la posibilidad de una de las sorpresa españolas, un fascista mediocre, porque tampoco tienen mucho donde elegir, que según la Historia pueden ser los más peligrosos, el típico violento o antisocial de la clase que se viene muy arriba por leer un libro de Nietzsche y de la noche a la mañana se convierte en un «listo del pueblo», o al contrario, un fascista con malas notas por gastarse los dineros de los estudios yendo de putas, o por hacer pellas, como ya dicen los mierdecillas neonazis españoles en una de sus canciones, en la letra dicen algo parecido a que «en la escuela de las democracias la maestra solo enseña la Historia que ellos quieren», es decir, no quieren saber nada de los judeomasones como califican a todo lo que no les guste. O qué decir de las notas en matemáticas, a los españoles poco menos que les han inculcado que son cosas de judemasones, puede que incluso sea peor la geometría, junto a las cosas de los dineros o la ciencia en general, no hay que olvidar que el número cero no fue introducido en Europa hasta el siglo XIII por Fibonacci, muy famoso en el actual mundo de las finanzas, e igual fue debido porque a su conocida secuencia de números se le atribuyen propiedades mágicas más que otra cosa, ya que antes la Iglesia Católica consideraba el cero un número del Diablo, incluso en la Antigua Roma que tanto gusta a los más fascistas y neonazis españoles, tan sólo a unos pocos elegidos por la Iglesia les dio permiso para realizar algún cálculo que necesitase el cero, y en años recientes, según el diario de los comunistas, los actuales elegidos para usar los diabólicos números o los dineros seguirían siendo unos funcionarios escogidos de una organización del estado creada por el Opus Dei, que al parecer en democracias continua con las mismas rancias constumbres que siguen hasta los funcionarios que formarán parte de gobiernos socialistas. Para los datos que ya tenemos en el ejemplo es evidente que se trataría de un sistema supervisado de clasificación, para predecir un palurdo fascista, o un no palurdo o dudoso, y usaremos el algortimo más conocido denominado Regresión logística.

Gráfica con los datos de entrenamiento

Gráfica con los datos de entrenamiento

Para el código de aprendizaje de clasificación se usarán unas determinadas fórmulas con los cálculos basados en las matrices de los datos de aprendizaje, que no vienen al caso, en cualquier curso de Machine Learning las enseñan. Son algoritmos o pasos que van ajustando los parámetros de una función matemática al conjunto de datos de entrenamiento, siguiendo la dirección de unos mínimos de función o derivadas, aunque no hay que calcular ninguna derivada al estar deducida en el algoritmo genérico, y si el algortimo está bien implementado entonces encontrará los valores óptimos de la función. Solo apuntar que los cálculos matriciales se pueden programar en Octave de varias formas, con bucles for-to incluyendo los elementos de las matrices uno a uno, o con vectores, o directamente de una tacada con matrices, esta última sería la manera más rápida en Octave. Para los cálculos matriciales en Octave por ejemplo la matriz traspuesta de «A» será » A’ «, o la inversa también se puede incluir directamente en las fórmulas con el comando e instrucción de programación «inv(A)» o «pinv(A)». Aparte, es necesario conocer algunas particularidades de Octave en las operaciones algebraicas, como al multiplicar variables o vectores por matrices o en operaciones matemáticas con una matriz como variable, o también es fácil cometer errores con las dimensiones o en cálculos que mezclen matrices con variables unidimensionales o vectores.

Gráfica del resultado 1

Gráfica del resultado 1

Gráfica del resultado 2

Gráfica del resultado 2

Gráfica del resultado 3

Gráfica del resultado 3

Resultado 3 ampliado

Resultado 3 ampliado

Tras probar también una variante del algortimo con una variable configurable por el programador, se han generado tres gráficas muy diferentes con resultados casi idénticos, ligeramente mejor la primera con un 83% de aciertos, son las que mejor clasifican a palurdos fascistas y los no palurdos fascistas dependiendo de los dos ángulos de entrada. Estas gráficas están basadas cada una en una función matemática con parámetros constantes que son los que ha optimizado el código de entrenamiento, y con incógnitas donde sustituir nuevos valores de entrada, la fórmula o función será la que predice los nuevos resultados, en el caso de la regresión logística la función de predicción de resultados sería de la forma: y=1/(1+e^(C(n)*x(n))) [en comandos e instrucciones de Octave el número «e» elevado a una potencia sería «exp(j)»], la función ya concretada siempre dará un resultado numérico mayor o menor de 0.5 entre el 0 y el 1 numérico, resultados positivo o negativo, 1 ó 0 lógico, está basada en la función general que fue inventada o deducida para ser útil en este algoritmo de Machine Learning. Grosso modo la fórmula final es el cerebro de nuestra particular Inteligencia Artificial, o medio Inteligencia Artificial porque siendo un ejemplo así tan sencillo se ve un poco decepcionante. En este ejemplo quedan muchos palurdos y no palurdos del entrenamiento mal clasificados, pero en general se podría decir que no está tan mal para unos datos tan dispersos, posiblemente cercanos a la realidad, si bien, observando la gráfica 3, habría muchos falsos positivos con ángulos pequeños o en ángulos negativos, todos los que no entrasen dentro de esa especie de figura elíptica central (aparte los falsos negativos de la parte de la gráfica que va hacia la derecha, de mucha menos importancia por suponer la mayoría ángulos imposibles a efectos prácticos) serían clasificados como palurdos fascistas, de escogerse este tercer «cerebro» habría que tenerlo en cuenta a la hora de introducir los datos no entrenados. Contando solo los ejemplos entrenados se estima el porcentaje de acierto calculado en un 82%, es decir, puede ser el peor «cerebrito» según los números, pero si se tiene en cuenta que son ejemplos muy aleatorios o inventados igual en la práctica mejore sustancialmente al poder descartarse los ángulos imposibles, superando a las dos opciones anteriores. Estas gráficas de formas cerradas y/o irregulares son comunes en el algoritmo de Regresión Logística Regularizado, ya sea que aparezca o buscándolo para que abarque más datos de entrada del aprendizaje, si bien no siempre aseguran un mayor porcentaje de aciertos posterior. En este ejemplo, inventado, no sería de los más representativos, existiendo aplicaciones prácticas con resultados más concretos con similares funciones aparentemente simples, aun con muchas características de entrada, como por ejemplo la predicción de precio de una vivienda según sus características (numero de habitaciones, metros cuadrados, etc.) y basada en un histórico de ventas, o el ajuste de maquinaria basado en distintas medidas con sensores. Para este tipo de aprendizaje puede ser suficiente con una cantidad de resultados del orden de solo unos 10 ejemplos conocidos por cada características de entrada para conseguir resultados óptimizados en un código de aprendizaje Machine Learning, no requiriendo una excepcional potencia de proceso, salvo en el caso de una exagerada cantidad de variables de entrada o de ejemplos, o al procesar resultados prácticos si hubiera un número exagerado a predecir.

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.