AI y Machine Learning: cómo aprenderlos visualmente

Creé este tutorial como una pieza de nivel de entrada sobre Inteligencia Artificial.

Cualquier tema nuevo debe presentarse en un lenguaje que coincida con el nivel de habilidad del alumno en ese momento. Así que no esperes fórmulas matemáticas locas todavía.

En particular, veremos Machine Learning, también conocido como Deep Learning.

La profundidad de una red neuronal está determinada por el número de capas de entrada.

Los algoritmos de Machine Learning sopesan la probabilidad de un conjunto de datos en particular contra un patrón específico.

Pensando en rangos

Las neuronas en su cerebro definitivamente no son digitales, pero se parecen a la lógica binaria como en estado activado o desactivado. Pero en el software, usamos un rango de valores en su lugar.

El resultado de un ciclo de cálculo en una operación de IA es una estimación de precisión en el rango entre 0.0 - 1.0. En última instancia, se produce un valor de salida basado en qué tan bien los datos de entrada coinciden con un patrón específico con 1.0 siendo 100% coincidente (Raramente se alcanza eso, pero 0.95 - 0.97 es bueno).

Este patrón generalmente se entrena antes de que se puedan producir resultados significativos. Más sobre esto un poco más adelante en este tutorial. Pero primero, aquí está ML en su forma más básica.

Todo comienza con las redes neuronales, una imitación de software de la estructura física de las neuronas en un cerebro.

Estructura de red neuronal simple

Aprendizaje automático en su forma más básica: una red neuronal muy simple.

En este ejemplo minimalista se muestra 1 capa de entrada que consta de 3 nodos de entrada.

Por lo general, se proporciona un conjunto múltiple de entradas por capa. Cada entrada se recopila de algún tipo de fuente. Como una matriz de píxeles de una imagen utilizada para el reconocimiento facial, por ejemplo / o cualquier otro dato. Depende del propósito de lo que intente lograr con su algoritmo de IA.

Los valores de entrada y salida son pt flotantes. números entre 0.0 y 1.0.

Logísticamente, durante el funcionamiento de la red, los datos se alimentan de izquierda a derecha. Sin embargo ... La retropropagación a veces se usa para optimizar la red neuronal. Ahí es cuando viajamos por la red en reversa. Pero por ahora no necesitamos preocuparnos por eso.

Suma

La suma de varios nodos de entrada es exactamente lo que parece. Es la suma total de los pesos de cada nodo de la capa de entrada anterior. Después de calcular la suma, se pasa a la función de activación para su procesamiento.

Función de activación

La función de activación convierte la suma de los valores de entrada en un valor de salida.

Pero, ¿cómo funciona exactamente?

Necesitamos echar un vistazo a otro aspecto del aprendizaje automático.

¿Recuerdas esas ecuaciones matemáticas de la escuela secundaria? Parábolas: ¿alguien?

Fuente de la imagen: https://pl.wikipedia.org/wiki/Plik:Catenary-pm.svg

Una función de activación es literalmente solo una ecuación matemática. Entonces, para aquellos con experiencia en matemáticas, esto podría ser un poco más fácil de entender. Si no es así, sigue leyendo los diagramas visuales y el resto de este tutorial para que comience a asimilarse.

La razón por la que no podemos usar ecuaciones lineales simples se debe a sus limitaciones.

No son suficientes para la creación de redes neuronales útiles.

Las redes neuronales están diseñadas alrededor de ecuaciones más complejas. Por ejemplo, la función Sigmoide (también conocida como Logística) es bastante común. (Echaremos un vistazo a algunos de los diferentes en la sección a continuación).

Todos toman la forma de f (x) = ... y luego rompen el valor x de una manera única para esa función. Por qué esto es importante y por qué tenemos diferentes funciones de AF se hará más evidente un poco más tarde.

¿Qué sucede una vez que obtenemos nuestro resultado?

AF pasa el valor calculado al siguiente nodo y esencialmente como una entrada parcial en una de las funciones de activación en un nodo en el siguiente conjunto de entrada.

Puede pensar que toma un conjunto de entradas múltiples. Y pasando el valor calculado al siguiente nodo. Es la puerta de enlace de valor entre los conjuntos de entrada.

Diferentes tipos de funciones de activación

Al igual que hay diferentes tipos de ecuaciones matemáticas ... hay diferentes tipos de funciones de activación.

La forma exacta en que cruzan los números para llegar al valor de salida final está estrechamente relacionada con el entrenamiento de una red existente primero. Por lo tanto, aún no podemos profundizar tanto en el tema, porque en general, el sistema no se basa en algo tan simple como calcular y devolver un resultado numérico.

Pero lo que podemos hacer, para profundizar nuestra comprensión, hasta ahora, ¡es echar un vistazo a la representación visual de cada ecuación matemática detrás de las diferentes funciones de activación!

Este es un tutorial visual. Y para darle una idea básica de lo que enfrentará aquí es una tabla del conjunto clásico de ecuaciones matemáticas en las que se pueden basar muchas funciones de activación clásicas.

El AF más básico está representado por f (x) = x o la función de identidad.

Algunas fórmulas matemáticas básicas bien conocidas.

Hay varios otros. Pero son un poco más complejos.

Esencialmente, estas funciones se utilizan para determinar el valor del nodo resultante.

¿Cómo exactamente una función de activación determina su valor?

Bueno, eso es lo que es un AF. Toma una entrada en forma de un número y produce un valor de retorno entre 0.0–1.0 (a veces el rango es +/- infinito). Las fórmulas reales se describen arriba. Puede volver a escribir estas ecuaciones como funciones en Python, JavaScript o cualquier otro lenguaje de programación.

Si te gustan las matemáticas y tienes mucho tiempo libre, ¡te encantará escribir estas funciones en código! Pero a menudo no tienes que hacerlo. Y eso es porque ya existe A.I. las bibliotecas se encargan de eso por usted. De esta manera, puede concentrarse en construir su red neuronal y entrenarla para un propósito específico.

Cada nodo lleva un peso calculado

Entonces estas funciones de activación producen un valor.

Lo más importante a tener en cuenta en este momento: cada punto es un peso.

Este peso mide la probabilidad de que coincida un cierto patrón.

Pero son posibles varias capas de conjuntos de entrada, como se muestra en el siguiente ejemplo.

Nodos en una red neuronal un poco más avanzada conectados entre sí.

Cada nodo se comunica con cada nodo en la siguiente capa de entrada que forma esta autopista de comunicación cruzada.

El número de elementos en cada capa es arbitrario. No tiene que ser el mismo número que se muestra en el diagrama anterior. Dependiendo del problema que intentes resolver.

Se necesitará algo de intuición y creatividad para determinar la cantidad de nodos de entrada que desea usar en cada capa. Pero incluso resolver el mismo problema puede lograrse mediante diferentes estructuras de redes neuronales.

Debido a la naturaleza no lineal de los cálculos, este proceso es ambiguo.

Capas ocultas

Acabamos de discutir cómo una red neuronal puede tener múltiples capas de entrada. Pueden considerarse como filas verticales de nodos.

Todas las capas internas entre la primera fila de entrada y el nodo de salida a menudo se denominan capas ocultas. Eso tiene sentido porque aquí es donde se realiza la mayor parte del trabajo de procesamiento de IA. Básicamente es la caja misteriosa de IA.

Diferentes tipos de patrones de redes neuronales

A veces, ML puede parecerse mucho a crear un patrón de red para que coincida con los patrones.

Las redes neuronales vienen en diferentes formas y formas.

Los diferentes tipos de estructuras de redes neuronales son más aptos para resolver tipos particulares de problemas asociados con su estructura.

OK, pero ¿cómo escribimos el código?

Eso fue mucha teoría.

Pero, ¿cómo lo implementamos realmente en código?

Puede usar una biblioteca como Tensorflow.js para comenzar.

Pero eso no servirá de nada porque todavía hay mucho por cubrir.

OK, pero ¿cómo produce resultados significativos?

Hemos discutido la estructura de una red neuronal hasta este punto.

Hablamos sobre funciones de activación, entradas de datos y capas ocultas.

También hablamos sobre los pesos pasados ​​de aquí para allá en las conexiones simuladas.

Para que un algoritmo de aprendizaje automático no lineal produzca cualquier resultado sensible, primero debe ser entrenado en un conjunto de datos preexistentes.

Siempre comienza eligiendo datos para entrenar su algoritmo de IA.

Eso depende del problema que intentes resolver.

Si desea reconocer números en una imagen, comience con imágenes de dígitos.

Reconociendo números de una captura de pantalla

El ejemplo clásico de inteligencia artificial es enseñarle a una red neuronal a reconocer números entre 0 y 9. De la misma manera que puede entrenar un algoritmo de máquina para reconocer letras de la A a la Z o incluso partes de un rostro humano: un ojo o una boca en un La fotografía también representa un tipo particular de forma o patrón que es común a todos los humanos pero que puede parecer ligeramente diferente.

Recuerde que todo lo que estamos tratando aquí son patrones.

Cuando el algoritmo reconoce un patrón, nunca coincide al 100%. Pero cuanto más nos acerquemos a 1.0 (100%), más probable es que la forma que estamos buscando represente lo que fue entrenado para reconocer.

Si usáramos una fuente estándar, ni siquiera tendríamos que hacer ningún trabajo de IA. Simplemente podríamos escanear cada dígito para el patrón exacto de píxeles. Pero el punto clave de la IA es reconocer un patrón en la oscuridad.

Primero, necesitamos tener algún tipo de medio que se utilizará como un dato de entrenamiento. Cada dígito puede ser representado por una imagen:

Los mismos dígitos escritos varias veces producen un patrón ligeramente diferente. Imagen tomada de la demostración de JavaScript AI ubicada en http://myselph.de/neuralNet.html

Puede reconocer fácilmente cada dígito a simple vista. Pero un algoritmo de IA necesita ser entrenado para reconocer patrones similares porque, aunque son similares, todavía no son 100% idénticos.

Para lograr esto, podemos dividir el patrón primario en bloques más pequeños e implementar algo denominado extracción de características.

Extracción de características

Para identificar un dígito, el algoritmo implementa un sistema de extracción de características que divide los patrones comunes en contrapartes relevantes para construir el dígito / símbolo / letra / etc. completo

La esencia de un patrón sigue siendo la misma. Por ejemplo, 0 es principalmente un círculo; puede dividirlo en patrones más pequeños con un arco en cada uno de los lados:

Si solo podemos entrenar nuestro algoritmo para reconocer estos 4 patrones únicos y verificar su presencia dentro del área localizada de una imagen, podemos calcular la cantidad de certeza con la que se puede decir que podría ser un cero.

Es lo mismo para otros dígitos. El dígito 1, por ejemplo, es una sola barra vertical. O tal vez con una línea más pequeña en un ligero ángulo en la parte superior.

El número 2 es medio círculo en la parte superior, una línea diagonal y una línea horizontal.

El número 3 se puede dividir en dos patrones de semi-arco.

El número 4 puede considerarse como 3 líneas: vertical, horizontal y diagonal.

…y así.

¿Qué pasa si es un dígito escrito a mano? Todavía tiene las mismas propiedades de ese dígito: los mismos bordes, los mismos bucles.

¿Qué sucede si el dígito aparece en una señal de límite de velocidad en la calle desde un ángulo indirecto en una fotografía? Al igual que nuestra propia visión, la IA debería poder adaptarse a algún tipo de término de error.

¿Es este un cinco, tres u ocho?

Pruebe esta demostración de AI JavaScript que le permite dibujar algo en la pantalla y haga que el algoritmo previamente entrenado le diga lo que acaba de dibujar.

El algoritmo intentará darte la mejor coincidencia incluso si lo que dibujas no es realmente un número. Aún así, puede ver el intelecto artificial en el trabajo tratando de proporcionar la aproximación más cercana que pueda reunir.

¿Cómo se ve el conjunto entrenado?

Aquí hay un fragmento de los datos de entrenamiento del algoritmo. Es solo una lista de pesos almacenados en una matriz muy larga (miles de valores):

// Los pesos de la red neuronal (pesos unidad-unidad y sesgos de unidad) // el entrenamiento se realizó en Matlab con el conjunto de datos MNIST.
// estos datos son para una unidad 784-200-10, con no linealidad logística
// en el oculto y softmax en la capa de salida. La entrada es un
// [-1; 1] imagen de nivel de gris, fondo == 1, 28x28 píxeles linealizados
// en orden de columna (es decir, columna1 (:); columna2 (:); ...) salida i-ésima
// ser el máximo significa que la red piensa que la entrada codifica
// (i-1) los pesos a continuación mostraron una tasa de error de 1.92% en la prueba
// conjunto de datos (9808/10000 dígitos reconocidos correctamente).
dejar w12 = [[-0,00718674, 0,00941102, -0,0310175, -0,00121102, -0,00978546, -4.65943e-05, 0,0150367, 0,0101846, 0,0482145, 0,00291535, -0,00172736, 0,0234746, 0,0416268, 0,0315077, -0,00252011, 0,0163985, 0,00853601, 0,00836308 , 0.00692898, 0.0215552, 0.0540464, 0.0393167, 0.0668207, 0.0232665, 0.031598, 0.0143047, 0.0156885, -0.0269579, -0.00777022, 0.0397823, -0.00825727, 0.0212889, -0.00755215, 0.0353843, 0.03524, 29
/ * ... Miles de pesos más siguen ... * /

El código fuente completo no encajaría en este artículo. Pero los conjuntos suelen ser bastante largos, incluso para lo que parecen ser pruebas triviales.

Entrada de imagen de pintura en red neuronal

Este bit de código fue tomado de la función Recognize () escrita en JavaScript.

Fue tomado de la demostración en http://myselph.de

Puede consultar el código fuente completo aquí.

// para visualización / depuración: pintar la entrada a la red neuronal. if (document.getElementById ('preprocesamiento'). marcado == verdadero)
{
    ctx.clearRect (0, 0, canvas.width, canvas.height);
    ctx.drawImage (copyCtx.canvas, 0, 0);
    para (var y = 0; y <28; y ++) {
        para (var x = 0; x <28; x ++) {
           bloque var = ctx.getImageData (x * 10, y * 10, 10, 10);
           var newVal = 255 * (0.5 - nnInput [x * 28 + y] / 2);
           para (var i = 0; i <4 * 10 * 10; i + = 4) {
               block.data [i] = newVal;
               block.data [i + 1] = newVal;
               block.data [i + 2] = newVal;
               bloque.datos [i + 3] = 255;
           }
       ctx.putImageData (bloque, x * 10, y * 10);
       }
   }
}

Este código parcial "pega" la entrada de la imagen (un dibujo a mano alzada) que se dividió previamente en bloques de 10 x 10 que almacenan valores promedio de escala de grises para esa área de la imagen.

Luego lo comparará con el conjunto entrenado y después de analizar las sumas / y las comparaciones promedio contra él devolverán la probabilidad del resultado en términos de cuán cerca coincide su dibujo de lienzo HTML con un dígito en particular.

Ultimas palabras

La inteligencia artificial es un tema vasto. Hay diferentes tipos de patrones de aprendizaje automático y tutoriales que salen todos los días. ¡Este tutorial debería servir solo como una introducción para alguien que recién está comenzando!

Sígueme en Twitter para obsequios de libros gratis

Tome su copia del CSS Visual Dictionary incl. diagramas de todas las propiedades CSS.

En Twitter Tidal Wave es la cuenta que regala mis libros de forma gratuita.

Sígueme en @ js_tut donde publico tutoriales de JavaScript freemium.