Aprendizaje Profundo | Aprende Machine Learning https://aprendemachinelearning.com en Español Tue, 17 Oct 2023 07:26:38 +0000 en-US hourly 1 https://wordpress.org/?v=6.4.3 https://aprendemachinelearning.com/wp-content/uploads/2017/11/cropped-icon_red_neuronal-1-32x32.png Aprendizaje Profundo | Aprende Machine Learning https://aprendemachinelearning.com 32 32 134671790 ¿Cómo funcionan los Transformers? en Español https://aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/ https://aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/#comments Tue, 08 Nov 2022 08:54:00 +0000 https://www.aprendemachinelearning.com/?p=7771 El Machine Learning cambió para siempre con la llegada en 2017 de un paper llamado Attention is all you need en donde se presentaba una nueva arquitectura para NLP: Los Transformers

The post ¿Cómo funcionan los Transformers? en Español first appeared on Aprende Machine Learning.

]]>
Imagen creada por el Autor utilizando el modelo de text-to-img StableDiffusion

Los Transformers aparecieron como una novedosa arquitectura de Deep Learning para NLP en un paper de 2017 “Attention is all you need” que presentaba unos ingeniosos métodos para poder realizar traducción de un idioma a otro superando a las redes seq-2-seq LSTM de aquel entonces. Pero lo que no sabíamos es que este “nuevo modelo” podría ser utilizado en más campos como el de Visión Artificial, Redes Generativas, Aprendizaje por Refuerzo, Time Series y en todos ellos batir todos los records! Su impacto es tan grande que se han transformado en la nueva piedra angular del Machine Learning.

En este artículo repasaremos las piezas fundamentales que componen al Transformer y cómo una a una colaboran para conseguir tan buenos resultados. Los Transformers y su mecanismo de atención posibilitaron la aparición de los grandes modelos generadores de texto GPT2, GPT3 y BERT que ahora podían ser entrenados aprovechando el paralelismo que se alcanza mediante el uso de GPUs.

Agenda

  • ¿Qué son los transformers?
  • Arquitectura
    • General
    • Embeddings
    • Positional Encoding
    • Encoder
      • Mecanismo de Atención
      • Add & Normalisation Layer
      • Feedforward Network
    • Decoder
    • Salida del Modelo
  • Aplicaciones de los Transformers
    • BERT
    • GPT-2
    • GPT-3
  • Resumen

¿Qué son los transformers en Machine Learning?

En el paper original de 2017 “Attention is all you need” aparece el diagrama con la novedosa arquitectura del Transformer, que todos deberíamos tatuarnos en un brazo. Esta arquitectura surge como una solución a problemas de aprendizaje supervisado en Procesamiento del Lenguaje Natural, obteniendo grandes ventajas frente a los modelos utilizados en ese entonces. El transformer permitía realizar la traducción de un idioma a otro con la gran ventaja de poder entrenar al modelo en paralelo; lo que aumentaba drásticamente la velocidad y reducción del coste; y utilizando como potenciador el mecanismo de atención, que hasta ese momento no había sido explotado del todo. Veremos que en su arquitectura utiliza diversas piezas ya existentes pero que no estaban combinadas de esta manera. Además el nombre de “Todo lo que necesitas es Atención” es a la vez un tributo a los Beatles y una “bofetada” a los modelos NLP centrados en Redes Recurrentes que en ese entonces estaban intentando combinarlos con atención. De esta sutil forma les estaban diciendo… “tiren esas redes recurrentes a la basura”, porque el mecanismo de atención NO es un complemento… es EL protagonista!

All you need is Love Attention

The Beatles

Con el tiempo, esta arquitectura resultó ser flexible y se pudo utilizar para tareas más allá del NLP, además de para la generación de texto, clasificación, resumen de contenidos también pudo traspasar esa frontera y ser aplicado en Visión Artificial, Generación de Audio, Predicción de Series Temporales y Aprendizaje por Refuerzo.

La Arquitectura Encoder-Decoder del Transformer

Veamos primero la gran foto de los Transformers.

Visión General

Estás viendo el dibujo que deberías de llevar en tu próxima camiseta:

La Arquitectura de los Transformers

La primera impresión puede ser algo intimidante, pero vayamos poco a poco. Si pensamos en el modelo como una caja negra, sería simplemente:

Entrada -> Transformer -> Salida

Vemos que con una entrada de texto “Hola” obtenemos la salida “Hello”.

Si hacemos un poco de zoom en esa caja, veremos dos componentes principales: Encoders y Decoders.

La entrada pasará por una serie de Encoders que se encadenan uno tras otro y luego envían su salida a otra serie de Decoders hasta emitir la Salida final. En el paper original, se utilizan 6 encoders y 6 decoders. Notaremos un recuadro llamado “Target” donde estamos pasando el Output Deseado al modelo para entrenar; pero obviamente que no lo pasaremos al momento de la inferencia; al menos no completo (más adelante en el artículo).

Observamos ahora con mayor detalle cómo está compuesto un Encoder y un Decoder y veremos que son bastante parecidos por dentro.

En su interior tanto Encoder como decoder cuentan con un componente de Atención (o dos) y una red neuronal “normal” como salidas.

Para comenzar a evaluar con mayor detalle las partes del Transformer, primero deberemos generar un Embedding de la entrada y luego entrar al Encoder. Así que veamos eso primero.

Embeddings

El uso de embeddings existía en NLP desde antes de los Transformers, puede que estés familiarizado con modelos como el word-2-vec y puede que ya hayas visto las proyecciones creadas con miles de palabras donde los embeddings logran agrupar palabras de manera automática en un espacio multidimensional. Entonces conceptos como “hombre y mujer”, distanciado de “perro y gato” veremos nombres de países juntos y profesiones ó deportes también agrupados en ese espacio. Primero convertimos las palabras a tokens, es decir a un valor numérico asociado, porque recordemos que las redes neuronales únicamente pueden procesar números y no cadenas de texto.

Ejemplo de Word Embeddings y una proyección en 3D.

Entonces convertimos una palabra a un número, ese número a un vector de embeddings de 512 dimensiones (podría ser de otro valor, pero el propuesto en el paper fue este).

Entonces:

  1. Palabra -> Token(*)
  2. Token -> Vector n-dimensional

(*) NOTA: una palabra podría convertirse en más de un token

La parte novedosa que introduce el paper de los transformers, es el “Positional Encoding” a esos embeddings…

Positional Encoding

Una vez que tenemos los embeddings, estaremos todos de acuerdo que el orden en que pasemos las palabras al modelo, será importante. De hecho podríamos alterar totalmente el significado de una oración si mezclamos el orden de sus palabras o hasta podría carecer totalmente de significado.

La casa es verde != verde casa la es

Entonces necesitamos pasar al modelo los tokens pudiendo especificar de alguna manera su posición.

Aquí, de paso comentaremos dos novedades de los Transformers: la solución a este posicionamiento pero también esto permite el poder enviar en simultáneo TODOS los tokens al modelo, algo que anteriormente no se podía hacer, por lo que se pasaba “palabra por palabra” una después de la otra, resultando en una menor velocidad.

Para resolver el posicionamiento, se agrega una valor secuencial al embedding que se asume que la red podrá interpretar. Si aparece el token “perro” como segunda palabra ó como décima, mantendrá en esencia el mismo vector (calculado anteriormente en el embedding) pero con un ligero valor adicional que lo distinguirá y que será el que le de la pista a la red neuronal de interpretar su posición en la oración.

En el paper se propone una función sinusoidal sobre el vector de 512 dimensiones del embedding. Entonces ese vector de embeddings del token “perro” será distinto si la palabra aparece primera, segunda, tercera.

Y ahora sí, podemos dar entrada al Encoder de los Transformers.

Encoder

El Encoder está compuesto por la capa de “Self attention” y esta conectada a una red feed forward. Entre las entradas y salidas se aplica la Skip Connection (ó ResNet) y un Norm Layer.

El mecanismo de Atención, es una de las implementaciones novedosas que propone el paper. Veremos que logra procesar en paralelo, manteniendo la ventaja de entreno mediante GPU.

El Encoder tiene como objetivo procesar la secuencia de los tokens de entrada y ser a su vez la entrada del mecanismo de atención del Decoder. No olvides que realmente se encadenan varios Encoders con varios Decoders (no se utilizan sólo uno en la práctica).

El -dichoso- mecanismo de Atención

Primero que nada, ¿Para qué queremos un mecanismo de Atención? El mecanismo de atención nos ayuda a crear y dar fuerza a las relaciones entre palabras en una oración. Si tenemos el siguiente enunciado:

El perro estaba en el salón, durmiendo tranquilo.

Nosotros comprendemos fácilmente que la palabra “tranquilo” se refiere al perro y no al “salón”. Pero a la red neuronal que comienza “en blanco”, sin saber nada de las estructuras del lenguaje (español, pero podría ser cualquier idioma), y que además ve la misma frase como valores numéricos:

5 186 233 7 5 1433 567 721

NOTA: no olvides que cada token, por ej. el nº5 corresponde a un embedding de n-dimensiones de 512 valores. Por simplificar usamos el 5 como reemplazo de “El”, por no escribir sus 512 componentes.

¿Cómo podrá entender que ese último token “721” está afectando a la segunda palabra “186”?
Por eso surgen los mecanismos de atención; para lograr dar más -o menos- importancia a una palabra en relación a las otras de la oración.

La solución que presentan los Transformers en cuanto a la atención, es la construcción de un “Diccionario Blando” (Soft Dictionary). ¿Qué es esto de un diccionario blando?
En programación, es probable que conozcas el uso de diccionarios de tipo “clave-valor” un típico “hashmap” en donde ante una entrada, obtengo un valor dict[“perro”]=0.78.
Para el “diccionario de atenciones” podría ser que si pedimos la atención de “tranquilo vs perro” de la oración, nos devuelva un 1 indicando mucha atención, pero si le pedimos “tranquilo vs salón” nos devuelva un -1.

Pero… eso no es todo. Nuestro Diccionario es “Suave/Blando”, esto quiere decir que no se va a saber “de memoria” el resultado de una clave. Si alteramos un poco la oración, el diccionario tradicional fallaría:

El perro estaba durmiendo en un salón tranquilo.

Ahora la clave de atención para “tranquilo vs salón” deberá pasar de -1 a ser cercana a 1.

Para poder calcular la atención, se utilizan 3 matrices llamadas “Query-Key-Value” que van a operar siguiendo una fórmula que nos devuelve un “score” o puntaje de atención.

  • En la matriz Q de Query tendremos los tokens (su embedding) que estamos evaluando.
  • En la matriz K de Key tendremos los tokens nuevamente, como claves del diccionario.
  • En la matriz V de Value tendremos todos los tokens (su embedding) “de salida”.

El resultado de la atención será aplicar la siguiente fórmula:

Si nos olvidamos del Softmax y el “multihead” (se definirá a continuación), podemos simplificar la fórmula diciendo que:
La atención será multiplicación matricial Q por la transpuesta de K; a eso le llamamos “factor”; y ese factor multiplicado por V.

¿Y eso qué significa? ¿Por qué estamos operando de esa manera? Si recuerdas, tanto Q como K son los valores de los Embeddings, es decir, cada token es un vector n-dimensional. Al hacer el producto vectorial obtenemos matemáticamente la “Similitud” entre los vectores. Entonces si el embedding estuviera funcionando bien, la similitud entre “nieve” y “blanco” deberían estar más cercanas que “nieve” y “negro”. Entonces cuando dos palabras sean similares, tendremos un valor positivo y mayor que si son opuestos, donde obtendríamos un valor negativo (dirección contraria). Este factor se multiplica por la matriz de Valor conformando el Score final de atención para cada relación entre pares de <<palabras>> que estamos evaluando.

Como estamos trabajando con matrices, seguimos aprovechando la capacidad de calcular todo a la vez y poder hacerlo acelerado por GPU.

Más de una atención: Multi-Head Attention

…hay más en el paper, porque el tipo de atención que vamos a calcular se llama “Multi-head Attention“. ¿Qué son esas “Multi-cabezas”??? Lo que se hace es que en vez de calcular la atención de todos los tokens de la oración una vez con las 512 dimensiones (provenientes del embedding), subdividiremos esos valores en grupos y de cada uno, calcular su atención. En el paper proponen “8 heads” con lo que entonces calcularemos “8 atenciones de a 64 valores del embeddings” por cada token! Esto a mi modo de entender es algo bastante arbitrario pero por arte de “magia matemática” funciona… Luego de calcular esas 8 cabezas, (esas 8 atenciones) haremos un promedio de los valores de cada atención entre tokens.

Si volvemos al ejemplo para la clave de “tranquilo vs perro” calcularemos 8 atenciones y al promediarlas deberíamos obtener un valor cercano a 1 (para la 1er oración).

Cuando terminemos de entrenar el modelo Transformer completo, podríamos intentar analizar y entender esas matrices de atención creadas y tratar de comprenderlas. Algunos estudios muestran que la “multi-atención” logra representar relaciones como la de “artículo-sustantivo” ó “adjetivo-sustantivo”, “verbo sustantivo” lo cual me sigue pareciendo algo increíble.

3 tipos de atención: Propia, Cruzada y Enmascarada

Prometo que esto ya es lo último que nos queda comprender sobre los mecanismos de atención… A todo lo anterior, hay que sumar que tenemos 3 tipos distintos de atención

  1. Self Attention
  2. Cross Attention
  3. Masked Attention

Su comportamiento es igual que al descripto anteriormente pero con alguna particularidad:

Self Attention se refiere que crearemos los valores y las matrices de Q-K-V a partir de las propias entradas de los tokens de entrada.

En la Atención Cruzada, vemos cómo utilizamos como entradas en el Decoder los valores obtenidos en el Encoder. Esto es lo que hará que con sólo el valor (Value) del Output pueda modelar la salida de atención buscada, esto es importante porque al final es lo que condicionará mayormente la “traducción” que está haciendo internamente el Decoder!

Y la llamada “Masked attention” se refiere a que enmascaramos parte triangular superior de la matriz de atención al calcularla para no caer en “data-leakage”, es decir, para no “adelantar información futura” que el Output no podría tener en su momento. Esto puede resultar confuso, intentaré aclararlo un poco más. En el Encoder, cuando tenemos los valores de entrada y hacemos “self-attention” dijimos que calculamos la atención de “todos contra todos” porque todos los tokens de entrada son conocidos desde el principio. Si recordamos la frase anterior:

El perro estaba en el salón, durmiendo tranquilo.

Aquí podemos calcular tanto la atención para la clave “perro-tranquilo” y también la de “tranquilo-perro”

Sin embargo -si suponemos que estamos traduciendo al inglés- en el output tendremos

“The dog was in the living room, sleeping peacefully”

PERO hay un detalle; para poder generar el output al momento de la inferencia, generaremos de a una palabra por vez, entonces iremos produciendo el siguiente output:

T1 – The
T2 – The dog
T3 – The dog was
T4 – The dog was in …

Esto quiere decir que vamos generando los tokens de a uno a la vez por lo que al principio no podríamos conocer la relación entre “dog-peacefully” pues esta relación aún no existe!

Entonces diferenciemos esto:

-> Al momento de entrenar el modelo pasamos el output deseado COMPLETO a las matrices de QKV de “Masked Attention” para entrenar en paralelo; al estar enmascarado, es como si estuviésemos simulando la secuencia “The, The dog, The dog was…”

-> Al momento de inferencia REALMENTE tendremos uno a uno los tokens como una secuencia temporal, realmente, iremos agregando de a una palabra del output a la cadena de salida a la vez.

Al enmascarar la matriz Q*K en su diagonal superior, prevenimos obtener valores “futuros” en la relación de atención entre sus tokens.

Short residual skip Connections y Layer Normalization

Al utilizar Skip Connections permitimos mantener el valor de origen del input a través de las deep neural networks evitando que sus pesos se desvanezcan con el paso del tiempo. Esta técnica fue utilizada en las famosas ResNets para clasificación de imágenes y se convirtieron en bloques de construcción para redes profundas. También es sumamente importante la Normalización en RRNN. Previene que el rango de valores entre capas cambie “demasiado bruscamente” logrando hacer que el modelo entrene más rápido y con mayor capacidad de generalización.

Feed Forward Network

La salida final del Encoder la dará una Red Neuronal “normal”, también llamada MLP ó capa densa. Se agregarán dos capas con Dropout y una función de activación no lineal.

Decoder

Ahora que conocemos los componentes del Encoder, podemos ver que con esos mismos bloques podemos crear el Decoder.

Al momento de entrenar, estaremos pasando el Input “hola amigos” y Output “hello friends” (su traducción) al mismo tiempo al modelo.

Tradicionalmente, usamos la salida únicamente para “validar” el modelo y ajustar los pesos de la red neuronal (durante el backpropagation). Sin embargo en el Transformer estamos usando la salida “hello friends” como parte del aprendizaje que realiza el modelo.

Entonces, el output “hello friends” es también la “entrada” del decoder hacia embeddings, posicionamiento y finalmente ingreso a la Masked Self Attention que comentamos antes (para los valores de Q,K,V).

De aquí, y pasando por la Skip Connection y Normalización (en la gráfica “Add & Norm) entramos al segundo mecanismo de Atención Cruzada que contiene para las matrices Query y Key” la salida del Encoder y como Value la salida de la Masked Attention.

Nuevamente Suma y Normalización, entrada a la Feed Forward del Decoder.

RECORDAR: “N encoder y N decoders”

No olvidemos que si bien estamos viendo en mayor detalle “un encoder” y “un decoder”, la arquitectura completa del Transformer implica la creación de (en el paper original) 6 encoders encadenados que enlazan con otros 6 decoders.

Salida final del Modelo

La salida final del modelo pasa por una última capa Lineal y aplicar Softmax. El Softmax, por si no lo recuerdas nos dará un valor de entre 0 y 1 para cada una de las posibles palabras (tokens) de salida. Entonces si nuestro “lenguaje” total es de 50.000 posibles tokens (incluyendo signos de puntuación, admiración, interrogación), encontraremos a uno de ellos con valor más alto, que será la predicción.

Si yo te dijera “en casa de herrero cuchillo de …” y vos tuvieras que predecir la próxima palabra, de entre todas las posibles en el castellano seguramente elegirías “palo” con probabilidad 0,999. Ahí acabas de aplicar Softmax intuitivamente en tu cabeza, y descartaste al resto de 49.999 palabras restantes.

Repaso de la arquitectura

Repasemos los puntos fuertes de la arquitectura de los Transformers:

  • La arquitectura de Transformers utiliza Encoders y Decoders
  • El Transformer permite entrenar en paralelo y aprovechar el GPU
  • Utiliza un mecanismo de atención que cruza en memoria “todos contra todos los tokens” y obtiene un score. Los modelos anteriores como LSTM no podían memorizar textos largos ni correr en paralelo.
  • El mecanismo de atención puede ser de Self Attention en el Encoder, Cross Attention ó Masked Attention en el Decoder. Su funcionamiento es igual en todos los casos, pero cambian los vectores que utilizamos como entradas para Q,K,V.
  • Se utiliza El Input pero también la Salida (el Output del dataset) para entrenar al modelo.

Aplicaciones de los Transformers

Los Transformers se convirtieron en el modelo “de facto” para todo tipo de tareas de NLP, incluyendo Traducción de idiomas (como vimos), clasificación de texto, resumen de textos y Question-Answering. Sólo basta con modificar los datasets que utilizamos para entrenar al modelo y la “salida final del modelo”, manteniendo al resto de arquitectura.

A raíz de poder entrenar mediante GPU, reducción de tiempo y dinero, surgieron varios modelos para NLP que fueron entrenados con datasets cada vez más grandes, con la creencia de que cuantas más palabras, más acertado sería el modelo, llevándolos al límite. Ahora, parece que hemos alcanzado un tope de acuracy, en el cual no vale la pena seguir extendiendo el vocabulario.

Vemos 3 de estos grandes modelos de NLP y sus características

BERT – 2018

BERT (Bidirectional Encoder Representations from Transformers) aparece en 2018, desarrollado por Google y utiliza sólo la parte del Encoder de los Transformers. Este modelo fue entrenado con todos los artículos de la Wikipedia en Inglés que contiene más de 2500 millones de palabras. Esto permitió generar un modelo “pro-entrenado” en inglés muy poderoso que podía ser utilizado para múltiples tareas de NLP. Además, al ser Open Source, permitió la colaboración y extensión por parte de la comunidad científica. El poder utilizar un modelo pre-entrenado tan grande, preciso y potente, permite justamente “reutilizar” ese conocimiento sin necesidad de tener que entrenar nuevamente un modelo de NLP, con el coste y tiempo (e impacto medioambiental) que puede conllevar.

Además BERT contenía algunas novedades, por ejemplo, en vez de utilizar un “Embeddings único y estático”, implementó un mecanismo en donde la misma palabra (token) podría devolver un vector distinto (de “embeddings”) de acuerdo al contexto de la oración de esa palabra.

Cuando salió BERT, batió muchos de los records existentes en datasets como SQuAD, GLUE y MultiNLI.

GPT-2 – 2019

GPT es un modelo de generación de texto creado por Open AI en 2019 y que contiene 1500 millones de parámetros en la configuración de su red neuronal profunda.

Al ser entrenado para generar “siguiente palabra”, pasa a convertirse en un problema de tipo “no supervisado”. Su re-entreno fue realizado usando BooksCorpus, un dataset que contiene más de 7,000 libros de ficción no publicados de diversos géneros.

Este modelo generó polémica en su momento debido a que empezaba a crear textos similares a lo que podía escribir una persona, con lo cual antes de ser lanzado, se temió por su mal uso para generar contenido falso en internet. Había sido anunciado en febrero y recién fue accesible al público, de manera parcial en Agosto. Los modelos de tipo GPT utilizan únicamente la parte de “Decoder” del Transformer.

Ejercicio Práctico: Crea tu propio chatbot con GPT-2 en Español!

GPT-3 – 2020

Lanzado en 2020, la red de GPT-3 tiene 175.000 millones de parámetros. Entrenado con textos de internet que contienen más de 500.000 millones de tokens.

En GPT-3, la generación de textos por la IA puede alcanzar un nivel literario que pasa inadvertido por los humanos, el modelo es capaz de mantener la coherencia en textos largos y debido a su gran conocimiento del mundo, crear un contexto y párrafos muy reales.

Otra de las novedades que trajo GPT3 es que lograba realizar tareas “inesperadas” de manera correcta, sin haber sido entrenado para ello. Por ejemplo, puede realizar Question-Answer, crear diálogos ó hasta escribir código en Python, Java o traducir idiomas. A este tipo de aprendizaje “no buscado” le llamamos “One Shot Learning”.

El Codigo de GPT-3 aún no ha sido liberado, hasta la fecha.

Más allá del NLP

Al comportarse tan bien para tareas de NLP, se comenzó a utilizar esta arquitectura adaptada para Clasificación de imágenes en Computer Vision y también logró superar en muchos casos a las Redes Convolucionales! A este nuevo modelo se le conoce como Vision Transformer o “Vit”.

También podemos utilizar Transformers para pronóstico de Series Temporales (Time Series). Este caso de uso tiene mucha lógica si lo pensamos, porque al final es muy parecido a “predecir la próxima palabra”, pero en su lugar “predecir la próxima venta”, ó stock…

Los Transformers están siendo utilizados en modelos generativos de música o como parte de los modelos de difusión text-to-image como Dall-E2 y Stable Diffusion.

Por último, los Transformers también están siendo utilizados en Aprendizaje por Refuerzo, donde también tienen sentido, pues la fórmula principal de este tipo de problemas también contiene una variable temporal/secuencial.

Y en todos estos campos, recién está empezando la revolución! No digo que será el Transformer quien reemplace al resto de Arquitecturas y modelos de Machine Learning existentes, pero está siendo un buen motivo para cuestionarlos, replantearlos y mejorar!

Resumen

Los Transformers aparecieron en un paper de 2017 implementando un eficiente mecanismo de atención como punto clave para resolver problemas de traducción en el campo del Procesamiento del Lenguaje Natural. Como bien sabemos, el lenguaje escrito conlleva implícitamente un orden temporal, secuencial que hasta aquel entonces era una de las barreras para no poder crear modelos extensos, pues impedía el aprovechamiento de GPU. La nueva arquitectura rompía esa barrera utilizando unos sencillos trucos: utilizar todos los token al mismo tiempo (en vez de uno en uno) y enmascarar la multiplicación matricial para impedir el data leakage en el caso del decoder.

Además, resolvió el Posicionamiento de los token y aprovechó técnicas ya existentes como el uso de Skip Connections y Normalization Layers.

Todo ello posibilitó la creación de los grandes modelos actuales, BERT, GPT y la aparición de muchísimos modelos disponibles “pre-entrenados” que pueden ser descargados y reutilizados para fine-tuning por cualquier persona.

Como si esto fuera poco, los Transformers tienen la flexibilidad suficiente para traspasar el área de NLP y contribuir al resto de áreas del Machine Learning obteniendo resultados impresionantes.

Habrá que agradecer a Ashish VaswaniNoam ShazeerNiki ParmarJakob UszkoreitLlion JonesAidan N. GomezLukasz KaiserIllia Polosukhin por su obra maestra.

Material Extra

Enlaces a más info sobre Transformers!

Suscripción al Blog

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

El libro del Blog

Si te gustan los contenidos del blog y quieres darme tu apoyo, puedes comprar el libro en papel, ó en digital (también lo puede descargar gratis!).

The post ¿Cómo funcionan los Transformers? en Español first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/como-funcionan-los-transformers-espanol-nlp-gpt-bert/feed/ 1 7771
Modelos de Detección de Objetos https://aprendemachinelearning.com/modelos-de-deteccion-de-objetos/ https://aprendemachinelearning.com/modelos-de-deteccion-de-objetos/#respond Fri, 21 Aug 2020 08:00:00 +0000 https://www.aprendemachinelearning.com/?p=6747 Luego de haber hecho un ejercicio Práctico de Detección de objetos en imágenes por medio de redes neuronales, veremos la teoría que hay detrás de estos algoritmos. Para comprender el artículo doy por sentado que ya tienes conocimiento de cómo funcionan las redes neuronales y...

The post Modelos de Detección de Objetos first appeared on Aprende Machine Learning.

]]>
Luego de haber hecho un ejercicio Práctico de Detección de objetos en imágenes por medio de redes neuronales, veremos la teoría que hay detrás de estos algoritmos.

Para comprender el artículo doy por sentado que ya tienes conocimiento de cómo funcionan las redes neuronales y de la teoría de Clasificación de imágenes. Si no, te recomiendo que leas primero esos artículos.

Agenda

  • Introducción: ¿Qué es la detección de imágenes?
  • Primera intuición de detección a partir de la clasificación con CNN
  • R-CNN: búsqueda selectiva
    • ¿Cómo funciona R-Cnn?
  • Problemas y mejoras: fast y faster r-cnn
  • Detección Rápida: YOLO
    • ¿Cómo funciona YOLO?
    • Arquitectura de la red Darknet
  • Otras alternativas
    • 2016 – Single Shot Detection
    • 2018 – RetinaNet
    • 2019 – Google Spinet
    • 2020 – Facebook saca del horno DETR
  • Resumen

Introducción: ¿Qué es la detección de imágenes?

Podemos tener la errónea intuición de que la detección de imágenes sea una tarea sencilla, pero veremos que realmente no lo es y de hecho es un gran problema a resolver. Nosotros los humanos podemos ver una foto y reconocer inmediatamente cualquier objeto que contenga de un vistazo rápido, si hay objetos pequeños o grandes, si la foto es oscura ó hasta algo borrosa. Imaginemos un niño escondido detrás de un árbol donde apenas sobresale un poco su cabeza ó un pie.

Para la detección de imágenes mediante Algoritmos de Machine Learning esto implica una red neuronal convolucional que detecte una cantidad limitada (ó específica) de objetos, no pudiendo detectar objetos que antes no hubiera visto, ó si están en tamaños que logra discernir y todas las dificultades de posibles “focos”, rotación del objeto, sombras y poder determinar en qué posición -dentro de la imagen- se encuentra.

Si es difícil con 1 objeto… imagínate con muchos!.

¿En qué consiste la detección de objetos?

Un algoritmo de Machine Learning de detección, para considerarse como tal deberá:

  • Detectar multiples objetos.
  • dar la posición X e Y del objeto en la imagen (o su centro) y dibujar un rectángulo a su alrededor.
  • Otra alternativa es la segmentación de imágenes (no profundizaremos en este artículo).
  • Detectar “a tiempo”… o puede que no sirva el resultado. Esta es una característica que debemos tener en cuenta si por ejemplo queremos hacer detección en tiempo real sobre video.

Nueva Salida

Entonces para entrenar nuestra máquina de manera supervisada deberemos indicar la clase del objeto (por ejemplo perro ó gato) y además la posición dentro de la imagen, X, Y el ancho y alto del objeto.

Y por si esto fuera poco, podrían ser múltiples objetos en la misma imagen, con lo cual para detectar 2 perros en una foto, necesitamos como salida 10 neuronas.

Este es un gran cambio, pues en clasificación de imágenes veníamos acostumbrados a devolver un array con por ejemplo Perro = [1 0] y Gato = [0 1].

La nueva salida deberá contener adicionalmente la posición (por ej. 54,45) y dimensión (por ej. 100,100) de cada clase, resultando en algo mínimo como

  • [1 0 100 100 54 45] pudiendo detectar sólo 1 objeto ó
  • [1 0 100 100 54 45 0 1 200 200 30 25] para 2 objetos.

Primera intuición: detección a partir de la clasificación

Podemos partir de este punto: tenemos una red CNN entrenada para detectar perros y gatos y supongamos que tiene una muy buena taza de aciertos. A esta red le pasamos una imagen nueva y nos devuelve “perro” ó “gato”. Agregaremos una tercera salida “otros” por si le pasamos la foto de algo que no sepa reconocer .

Entre las redes CNN pre-entregadas más conocidas están Alexnet, Resnet, y VGG

Si a nuestra red pre-entrenada, le pasamos una imagen con 2 perros será incapaz de detectarlos, puede que no detecte ni siquiera a uno.

Si le pasamos una imagen con perros y gatos, tampoco los podrá identificar y mucho menos localizar.

Entonces lo que el “sentido común de ingenieros” nos dice es: “vamos a iterar”. Es decir, iteremos un “área reducida” dentro de la foto de izquierda a derecha y de arriba abajo y le aplicamos la CNN pre-entrenada para ver si detecta algo.

Al ir iterando, lograremos detectar los 2 animales de la foto.

La foto original
El resultado deseado
Comenzamos a iterar…
Perro detectado
Otro tamaño de bounding-box…
iteramos de izq-der, arriba abajo…
Gato detectado!

Sin embargo esta solución trae consigo múltiples inconvenientes:

  1. ¿De qué tamaño será la ventana deslizante? y de hecho, podría ser de diversos tamaños.
  2. ¿Cuántos píxeles nos moveremos hacia izquierda (y luego hacia abajo)?
  3. Dependiendo de esos factores, el tiempo de cómputo podría ser muy largo, pues para cada movimiento implica realizar una clasificación individual con la CNN.
  4. Si detectamos algún objeto dentro de la ventana, ¿quiere decir que tengo los valores x e y? No necesariamente.
  5. Si nos movemos apenas pixeles con la ventana, podemos estar detectando al “mismo perro” múltiples veces
  6. Surge una problemática de poder distinguir entre animales si estos se encuentran muy cercanos.
Podemos tener dos cajas que detectan al mismo perro.
Esta detección es correcta, 2 perros: pero podría ocurrir…
…detectar por error a 2 perros dentro de una misma caja

De los puntos 5 y 6 surge la necesidad de crear una nueva métrica específica para la detección de imágenes en donde podamos evaluar al mismo tiempo si la clase de objeto es correcta y si la posición del “bounding box” (X,Y, alto y ancho) es buena. Esa métrica será “mAP“.

A raíz de estos puntos, surgen estrategias para intentar solventarlos. Veamos algunas.

R-CNN: búsqueda selectiva

En 2014 surgen las “Region Based Convolutional Neural Networks” con la siguiente propuesta: primero determinar “regiones de interés” dentro de la imagen (esto es conocido como “selective search”) y luego realizar clasificación de imágenes sobre esas áreas usando una red pre-entrenada.

Esto implica un primer algoritmo sobre la imágen que pueda determinar las áreas de interés que pueden llegar a ser 2000 regiones de diversos tamaños (si había más, se descartan). Luego pasar esas regiones por la CNN y mediante un clasificador binario validar si eran de clases correctas y eliminar las de poca confianza. Finalmente un regresor se encargaría de ajustar correctamente la posición de la localización.

La selección de las regiones podría ser por ejemplo “áreas contiguas con un mismo tono de color” ó detección de líneas que delimiten áreas, ó cambios bruscos en contraste y brillo. Son pasadas “rápidas” sobre una imagen, similar a como lo hace un editor de imágenes.

Fuente:  https://arxiv.org/abs/1311.2524

Para evitar el solapamiento del mismo objeto en diversas áreas se utiliza el concepto de IoU ó “Intersection over Union”.

IoU: nos da un porcentaje de acierto del área de predicción frente a la bounding-box real que queríamos detectar.

El IoU en conjunto con “Non-Máximum-Supression” ayudan a seleccionar las áreas del objeto que queremos localizar.

NMS: nos permite quedarnos de entre muchas cajas que detectaron al mismo objeto y se superponen, con la que mejor se ajusta al resultado. Nos quedamos con la mejor y eliminamos al resto.

A pesar de todas estas mejoras, la detección de objetos sobre una sola imagen podía tomar unas 25 segundos. Y el entrenamiento de la propia red es muy lento.

Mejoras sobre R-CNN: fast y faster R-cnn

Surgen otros 2 algoritmos: fast R-CNN y luego faster R-CNN para intentar mejorar el tiempo de detección.

Fast R-CNN mejora el algoritmo inicial haciendo reutilización de algunos recursos como el de las features extraídas por la CNN agilizando el entreno y detección de las imágenes. Esta nueva red tiene mejoras también en el IOU y en la función de Loss para mejorar el posicionamiento de la “caja delimitante”. Sin embargo no ofrece un aumento dramático de velocidad en el entrenamiento y detección.

Faster R-CNN logra una mejora en velocidad al integrar el algoritmo de “región proposal” sobre la propia CNN. Además aparece el concepto de usar “anchor” fijos, es decir, ciertos tamaños pre calculados para la detección de objetos específicos de la red. Por ejemplo, podemos definir 3 tamaños de ventana en 3 escalas distintas de tamaños, es decir un total de 9 anclas.

Faster-R-CNN. Fuente https://arxiv.org/abs/1506.01497

Mask R-CNN

No entraré en detalle, esta red, intenta hacer uso de las R-CNN pero en vez de detectar el “bounding box” de cada objeto, intentará hacer segmentación de imagen, definiendo la superficie de cada objeto.

Fuente: https://arxiv.org/abs/1703.06870

Detección Rápida: YOLO

En 2016 crean YOLO, una red que quiere decir “You Only Look Once“. Esta red hace una única pasada a la red convolucional y detecta todos los objetos para los que ha sido entrenada para clasificar. Al ser un “sólo cálculo” y sin necesidad de iterar, logra velocidades nunca antes alcanzadas con ordenadores que no tienen que ser tan potentes. Esto permite detección sobre video en tiempo real de cientos de objetos en simultáneo y hasta su ejecución en dispositivos móviles.

¿Cómo funciona YOLO ?

Yolo es una solución que reutiliza varias técnicas que vimos anteriormente con un “twist-plot” final.

Yolo define una grilla de tamaño fijo sobre la imagen de 13×13. Sobre esas celdas intentará detectar objetos valiéndose de anchors fijos, por ejemplo de 3 anclas con 3 tamaños distintos (9 predicciones por cada celda). Hace uso de IoU y Non-Max-supression. También tiene asociada una red de regresión al final para las posiciones de los bounding-boxes.

Yolo utiliza una grilla fija, en este caso de 13×13
Aqui vemos ejemplo de 5 anclas de distintos tamaños

La “grandiosidad” de YOLO consiste en su red CNN. Antes vimos que R-CNN utilizaba algún algoritmo adicional para seleccionar las regiones de interés sobre las que realiza las predicciones. En cambio YOLO, utiliza la misma Red CNN de clasificación con un “truco” por el cual no necesita iterar la grilla de 13×13, si no que la propia red se comporta como si hiciera un especie de “offset” que le permite hacer la detección en simultáneo de las 169 casillas.

YOLO utiliza una red CNN llamada Darknet, aunque también puede ser entrenada con cualquier otra red Convolucional. Al mismo tiempo de entrenarse se crea la red con este <<offset>> que comentaba.

Este video te ayudará comprender el funcionamiento de YOLO, explicado nada más y nada menos que por Andrew Ng.

Además Yolo utiliza las neuronas de tipo convolucional al final de la cadena sin necesidad de hacer la transformación a una red “tradicional”.

Gracias a estos retoques, logra la sorprendente capacidad de casi 60 FPS (cuadros por segundo) en ordenadores normales. Se le critica que si bien es rápida, suele tener menor porcentaje de aciertos frente a las R-CNN.

Pero con el paso del tiempo fueron evolucionando las versiones YoloV2, V3 y recientemente V4 que están enfocadas a mejorar esa precisión de las bounding boxes, a la vez que mantienen su rapidez.

Resultados de YOLOv3 sobre el Dataset COCO.

Arquitectura de la Red

La arquitectura se basa en una red convolucional GoogleNet y consta de 24 capas convolucionales. El autor la bautizó como Darknet. Embebe en su salida tanto la parte que clasifica las imágenes como la de posicionamiento y tamaño de los objetos.

Por ejemplo par el CocoDataset que debe detectar 80 objetos diferentes, tendremos como salida:

Tamaño de grillaCantidad AnclasCantidad de clases Ccore, X, Y, Alto, Ancho
13 * 13* 3 * (80 +* 5)

Para este ejemplo nos dará un array de 43.095 datos siendo el máximo de objetos que puede detectar y localizar 13x13x3 = 507 objetos de 80 clases en la misma foto en una sola pasada. (Realmente hará 13x13x3 x3 tamaños = 1521 predicciones). Sorprendente!.

Crea tu propia red de detección de objetos YOLO siguiendo este ejercicio explicado paso a paso y con todo el código Python en una Jupyter Notebook usando Keras y Tensorflow

Otras Alternativas para Detección

Comentaremos brevemente otras técnicas que surgieron y que también se pueden utilizar.

SSD – Single Shot Detector

Tiene una estructura piramidal en su CNN en la que las capas van disminuyendo gradualmente. Esto le permite poder detectar objetos grandes y pequeños. No utiliza una grilla predefinida, pero cuenta con “anclas” de distintas proporciones que se van escalando a medida que descendemos por la pirámide (mapa de features más pequeños, con anclas proporcionalmente más grandes).

RetinaNet (2018)

RetinaNet también se basa en una estructura de CNN piramidal mejorada para reconocer objetos de diversos tamaños en una sola pasada. Innova con una nueva función de pérdida llamada <<Focal Loss>>.

Google: Spinet (dic 2019)

Google Spinet rompe con la estructura piramidal y propone una arquitectura novedosa llamada “scale-permuted” en la que se alternan diversos tamaños en las convoluciones.

Facebook: DETR (junio 2020)

Facebook propone una “End to End object detection with Transformers“. Es decir, utilizar la más novedosa y efectiva técnica de redes neuronales utilizada en NLP pero aplicada a la detección de imágenes! Muy ingenioso!

Resumen

La tarea de Detección de objetos en imágenes fue impulsora de mejora tanto en redes neuronales convolucionales como en la arquitectura general utilizada poniendo a prueba el valor real del deeplearning, entrelazando redes con funciones específicas.

Los logros obtenidos son enormes, de gran aplicación y como vemos sigue siendo un campo en desarrollo, en donde grandes como Google y Facebook siguen innovando con nuevas propuestas, aún con un mundo bajo Pandemia.

Las aplicaciones que tiene la detección de imágenes van desde seguridad, conducción de coches autónomos hasta salud y poder dar visión -al fin- a los robots 😉

Si te suscribes salvas un gatito (o no)

Recibe los próximos artículos sobre Machine Learning, estrategias, teoría y código Python en tu casilla de correo!

NOTA: algunos usuarios reportaron que el email de confirmación y/o posteriores a la suscripción entraron en su carpeta de SPAM. Te sugiero que revises y recomiendo que agregues nuestro remitente info @ aprendemachinelearning.com a tus contactos para evitar problemas. Gracias!

Aún no realizaste el ejercicio práctico de detección de objetos con Python, Keras y Tensorflow? Anímate!

El libro del Blog

Si te gustan los contenidos del blog puedes comprar el libro en papel ó en

formato digital (el precio lo pones tú!)…

The post Modelos de Detección de Objetos first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/modelos-de-deteccion-de-objetos/feed/ 0 6747
¿Cómo funcionan las Convolutional Neural Networks? Visión por Ordenador https://aprendemachinelearning.com/como-funcionan-las-convolutional-neural-networks-vision-por-ordenador/ https://aprendemachinelearning.com/como-funcionan-las-convolutional-neural-networks-vision-por-ordenador/#comments Thu, 29 Nov 2018 09:00:00 +0000 https://www.aprendemachinelearning.com/?p=6209 En este artículo intentaré explicar la teoría relativa a las Redes Neuronales Convolucionales (en inglés CNN) que son el algoritmo utilizado en Aprendizaje Automático para dar la capacidad de “ver” al ordenador. Gracias a esto, desde apenas 1998, podemos clasificar imágenes, detectar diversos tipos de...

The post ¿Cómo funcionan las Convolutional Neural Networks? Visión por Ordenador first appeared on Aprende Machine Learning.

]]>
En este artículo intentaré explicar la teoría relativa a las Redes Neuronales Convolucionales (en inglés CNN) que son el algoritmo utilizado en Aprendizaje Automático para dar la capacidad de “ver” al ordenador. Gracias a esto, desde apenas 1998, podemos clasificar imágenes, detectar diversos tipos de tumores automáticamente, enseñar a conducir a los coches autónomos y un sinfín de otras aplicaciones.

El tema es bastante complejo/complicado e intentaré explicarlo lo más claro posible. En este artículo doy por sentado que tienes conocimientos básicos de cómo funciona una red neuronal artificial multicapa feedforward (fully connected). Si no es así te recomiendo que antes leas sobre ello:

¿Qúe es una CNN? ¿Cómo puede ver una red neuronal? ¿Cómo clasifica imagenes y distingue un perro de un gato?

La CNN es un tipo de Red Neuronal Artificial con aprendizaje supervisado que procesa sus capas imitando al cortex visual del ojo humano para identificar distintas características en las entradas que en definitiva hacen que pueda identificar objetos y “ver”. Para ello, la CNN contiene varias capas ocultas especializadas y con una jerarquía: esto quiere decir que las primeras capas pueden detectar lineas, curvas y se van especializando hasta llegar a capas más profundas que reconocen formas complejas como un rostro o la silueta de un animal.

Necesitaremos…

Recodemos que la red neuronal deberá aprender por sí sola a reconocer una diversidad de objetos dentro de imágenes y para ello necesitaremos una gran cantidad de imágenes -lease más de 10.000 imágenes de gatos, otras 10.000 de perros,…- para que la red pueda captar sus características únicas -de cada objeto- y a su vez, poder generalizarlo -esto es que pueda reconocer como gato tanto a un felino negro, uno blanco, un gato de frente, un gato de perfil, gato saltando, etc.-

Pixeles y neuronas

Para comenzar, la red toma como entrada los pixeles de una imagen. Si tenemos una imagen con apenas 28×28 pixeles de alto y ancho, eso equivale a  784 neuronas. Y eso es si sólo tenemos 1 color (escala de grises). Si tuviéramos una imagen a color, necesitaríamos 3 canales (red, green, blue) y entonces usaríamos 28x28x3 = 2352 neuronas de entrada. Esa es nuestra capa de entrada. Para continuar con el ejemplo, supondremos que utilizamos la imagen con 1 sólo color.

No Olvides: Pre-procesamiento

Antes de alimentar la red, recuerda que como entrada nos conviene normalizar los valores. Los colores de los pixeles tienen valores que van de 0 a 255, haremos una transformación de cada pixel: “valor/255” y nos quedará siempre un valor entre 0 y 1.

Convoluciones

Ahora comienza el “procesado distintivo” de las CNN. Es decir, haremos las llamadas “convoluciones”: Estas consisten en tomar “grupos de pixeles cercanos” de la imagen de entrada e ir operando matemáticamente (producto escalar) contra una pequeña matriz que se llama kernel. Ese kernel supongamos de tamaño 3×3 pixels “recorre” todas las neuronas de entrada (de izquierda-derecha, de arriba-abajo) y genera una nueva matriz de salida, que en definitiva será nuestra nueva capa de neuronas ocultas. NOTA: si la imagen fuera a color, el kernel realmente sería de 3x3x3 es decir: un filtro con 3 kernels de 3×3; luego  esos 3 filtros se suman (y se le suma una unidad bias) y conformarán 1 salida (cómo si fuera 1 solo canal).

El kernel tomará inicialmente valores aleatorios(1) y se irán ajustando mediante backpropagation. (1)Una mejora es hacer que siga una distribución normal siguiendo simetrías, pero sus valores son aleatorios.

Filtro: conjunto de kernels

UN DETALLE: en realidad, no aplicaremos 1 sólo kernel, si no que tendremos muchos kernel (su conjunto se llama filtros). Por ejemplo en esta primer convolución podríamos tener 32 filtros, con lo cual realmente obtendremos 32 matrices de salida (este conjunto se conoce como “feature mapping”), cada una de 28x28x1 dando un total del 25.088 neuronas para nuestra PRIMER CAPA OCULTA de neuronas. ¿No les parecen muchas para una imagen cuadrada de apenas 28 pixeles? Imaginen cuántas más serían si tomáramos una imagen de entrada de 224x224x3 (que aún es considerado un tamaño pequeño)…

Aquí vemos al kernel realizando el producto matricial con la imagen de entrada y desplazando de a 1 pixel de izquierda a derecha y de arriba-abajo y va generando una nueva matriz que compone al mapa de features

A medida que vamos desplazando el kernel y vamos obteniendo una “nueva imagen” filtrada por el kernel. En esta primer convolución y siguiendo con el ejemplo anterior, es como si obtuviéramos 32 “imágenes filtradas nuevas”. Estas imágenes nuevas lo que están “dibujando” son ciertas características de la imagen original. Esto ayudará en el futuro a poder distinguir un objeto de otro (por ej. gato ó perro).

La imagen realiza una convolución con un kernel y aplica la función de activación, en este caso ReLu

La función de Activación

La función de activación más utilizada para este tipo de redes neuronales es la llamada ReLu por Rectifier Linear Unit  y consiste en f(x)=max(0,x).

Subsampling

Ahora viene un paso en el que reduciremos la cantidad de neuronas antes de hacer una nueva convolución. ¿Por qué? Como vimos, a partir de nuestra imagen blanco y negro de 28x28px tenemos una primer capa de entrada de 784 neuronas y luego de la primer convolución obtenemos una capa oculta de 25.088 neuronas -que realmente son nuestros 32 mapas de características de 28×28-

Si hiciéramos una nueva convolución a partir de esta capa, el número de neuronas de la próxima capa se iría por las nubes (y ello implica mayor procesamiento)! Para reducir el tamaño de la próxima capa de neuronas haremos un proceso de subsampling en el que reduciremos el tamaño de nuestras imágenes filtradas pero en donde deberán prevalecer las características más importantes que detectó cada filtro. Hay diversos tipos de subsampling, yo comentaré el “más usado”: Max-Pooling

Subsampling con Max-Pooling

Vamos a intentar explicarlo con un ejemplo: supongamos que haremos Max-pooling de tamaño 2×2. Esto quiere decir que recorreremos cada una de nuestras 32 imágenes de características obtenidas anteriormente de 28x28px de izquierda-derecha, arriba-abajo PERO en vez de tomar de a 1 pixel, tomaremos de “2×2” (2 de alto por 2 de ancho = 4 pixeles) e iremos preservando el valor “más alto” de entre esos 4 pixeles (por eso lo de “Max”). En este caso, usando 2×2, la imagen resultante es reducida “a la mitad”y quedará de 14×14 pixeles. Luego de este proceso de subsamplig nos quedarán  32 imágenes de 14×14, pasando de haber tenido 25.088 neuronas a  6272, son bastantes menos y -en teoría- siguen almacenando la información más importante para detectar características deseadas.

¿Ya terminamos? NO: ahora más convoluciones!!

Muy bien, pues esa ha sido una primer convolución: consiste de una entrada, un conjunto de filtros, generamos un mapa de características y hacemos un subsampling. Con lo cual, en el ejemplo de imágenes de 1 sólo color tendremos:

1)Entrada: Imagen 2)Aplico Kernel 3)Obtengo Feature Mapping 4)Aplico Max-Pooling 5)Obtengo “Salida” de la Convolución
28x28x1 32 filtros de 3×3 28x28x32 de 2×2 14x14x32

La primer convolución es capaz de detectar características primitivas como lineas ó curvas. A medida que hagamos más capas con las convoluciones, los mapas de características serán capaces de reconocer formas más complejas, y el conjunto total de capas de convoluciones podrá “ver”.

Pues ahora deberemos hacer una Segunda convolución que será:

1)Entrada: Imagen 2)Aplico Kernel 3)Obtengo Feature Mapping 4)Aplico Max-Pooling 5)Obtengo “Salida” de la Convolución
14x14x32 64 filtros de 3×3 14x14x64 de 2×2 7x7x64

La 3er convolución comenzará en tamaño 7×7 pixels y luego del max-pooling quedará en 3×3 con lo cual podríamos hacer sólo 1 convolución más. En este ejemplo empezamos con una imagen de 28x28px e hicimos 3 convoluciones. Si la imagen inicial hubiese sido mayor (de 224x224px) aún hubiéramos podido seguir haciendo convoluciones.

1)Entrada: Imagen 2)Aplico Kernel 3)Obtengo Feature Mapping 4)Aplico Max-Pooling 5)Obtengo “Salida” de la Convolución
7x7x64 128 filtros de 3×3 7x7x128 de 2×2 3x3x128

Llegamos a la última convolución y nos queda el desenlace…

Conectar con una red neuronal “tradicional”.

Para terminar, tomaremos la última capa oculta a la que hicimos subsampling, que se dice que es “tridimensional” por tomar la forma -en nuestro ejemplo- 3x3x128 (alto,ancho,mapas) y la “aplanamos”, esto es que deja de ser tridimensional, y pasa a ser una capa de neuronas “tradicionales”, de las que ya conocíamos. Por ejemplo, podríamos aplanar (y conectar) a una nueva capa oculta de 100 neuronas feedforward.

Entonces, a esta nueva capa oculta “tradicional”, le aplicamos una función llamada Softmax que conecta contra la capa de salida final que tendrá la cantidad de neuronas correspondientes con las clases que estamos clasificando. Si clasificamos perros y gatos, serán 2 neuronas. Si es el dataset Mnist numérico serán 10 neuronas de salida. Si clasificamos coches, aviones ó barcos serán 3, etc.

Las salidas al momento del entrenamiento tendrán el formato conocido como “one-hot-encoding” en el que para perros y gatos sera: [1,0] y [0,1], para coches, aviones ó barcos será [1,0,0]; [0,1,0];[0,0,1].

Y la función de Softmax se encarga de pasar a probabilidad (entre 0 y 1) a las neuronas de salida. Por ejemplo una salida [0,2 0,8] nos indica 20% probabilidades de que sea perro y 80% de que sea gato.

¿Y cómo aprendió la CNN a “ver”?: Backpropagation

El proceso es similar al de las redes tradicionales en las que tenemos una entrada y una salida esperada (por eso aprendizaje supervisado) y mediante el backpropagation mejoramos el valor de los pesos de las interconexiones entre capas de neuronas y a medida que iteramos esos pesos se ajustan hasta ser óptimos. PERO…

En el caso de la CNN, deberemos ajustar el valor de los pesos de los distintos kernels. Esto es una gran ventaja al momento del aprendizaje pues como vimos cada kernel es de un tamaño reducido, en nuestro ejemplo en la primer convolución es de tamaño de 3×3, eso son sólo 9 parámetros que debemos ajustar en 32 filtros dan un total de 288 parámetros. En comparación con los pesos entre dos capas de neuronas “tradicionales”: una de 748 y otra de  6272 en donde están TODAS interconectarlas con TODAS y eso equivaldría a tener que entrenar y ajustar más de 4,5 millones de pesos (repito: sólo para 1 capa).

Comparativa entre una red neuronal “tradicional” y una CNN

Dejaré un cuadro resumen para intentar aclarar más las diferencias entre las redes Fully connected y las Convolutional Neural Networks.

  Red “tradicional” Feedforward multicapa Red Neuronal Convolucional CNN
Datos de entrada en la Capa Inicial Las características que analizamos. Por ejemplo: ancho, alto, grosor, etc. Pixeles de una imagen. Si es color, serán 3 capas para rojo,verde,azul
Capas ocultas elegimos una cantidad de neuronas para las capas ocultas. Tenemos de tipo:
* Convolución (con un tamaño de kernel y una cantidad de filtros)
* Subsampling
Capa de Salida La cantidad de neuronas que queremos clasificar. Para “comprar” ó “alquilar” serán 2 neuronas. Debemos “aplanar” la última convolución con una (ó más) capas de neuronas ocultas “tradicionales” y hacer una salida mediante SoftMax a la capa de salida que clasifica “perro” y “gato” serán 2 neuronas.
Aprendizaje Supervisado Supervisado
Interconexiones Entre capas, todas las neuronas de una capa con la siguiente. Son muchas menos conexiones necesarias, pues realmente los pesos que ajustamos serán los de los filtros/kernels que usamos.
Significado de la cantidad de capas ocultas Realmente es algo desconocido y no representa algo en sí mismo. Las capas ocultas son mapas de detección de características de la imagen y tienen jerarquía: primeras capas detectan lineas, luego curvas y formas cada vez más elaboradas.
Backpropagation Se utiliza para ajustar los pesos de todas las interconexiones de las capas Se utiliza para ajustar los pesos de los kernels.

Arquitectura básica

Resumiendo: podemos decir que los elementos que usamos para crear CNNs son:

  • Entrada: Serán los pixeles de la imagen. Serán alto, ancho y profundidad será 1 sólo color o 3 para Red,Green,Blue.
  • Capa De Convolución: procesará la salida de neuronas que están conectadas en “regiones locales” de entrada (es decir pixeles cercanos), calculando el producto escalar entre sus pesos (valor de pixel) y una pequeña región a la que están conectados en el volumen de entrada. Aquí usaremos por ejemplo 32 filtros o la cantidad que decidamos y ese será el volumen de salida.
  • “CAPA RELU” aplicará la función de activación en los elementos de la matriz.
  • POOL ó SUBSAMPLING: Hará una reducción en las dimensiones alto y ancho, pero se mantiene la profundidad.
  • CAPA “TRADICIONAL” red de neuronas feedforward que conectará con la última capa de subsampling y finalizará con la cantidad de neuronas que queremos clasificar.

Pon en práctica YA MISMO la teoría y aprende a clasificar imágenes en Python mediante este ejercicio!!

Finalizando…

Se me quedan en el tintero muchísimas cosas más que explicar… pero creo que lo iré completando con el tiempo o crearé un nuevo artículo con mayor detalle/más técnico. Temas y definiciones como padding, stride, evitar overfitting, image-aumentation, dropout… o por nombrar algunas redes famosas ResNet, AlexNet, GoogLeNet and DenseNet, al mismísimo Yann LeCun… todo eso.. se queda fuera de este texto.

Este artículo pretende ser un punto inicial para seguir investigando y aprendiendo sobre las CNN. Al final dejo enlace a varios artículos para ampliar información sobre CNN.

También puedes pasar a un nuevo nivel y hacer Detección de Objetos en Python!

Conclusiones

Hemos visto cómo este algoritmo utiliza variantes de una red neuronal tradicional y las combina con el comportamiento biológico del ojo humano, para lograr aprender a ver. Recuerda que puedes hacer un ejercicio propuesto para clasificar más de 70.000 imágenes deportivas con Python en tu ordenador!

Suscripción al Blog

Recibe nuevos artículos sobre Machine Learning, redes neuronales y código Python cada 15 días 

Más recursos sobre CNN (en Inglés)


El libro del Blog (en desarrollo)

Puedes colaborar comprando el libro ó lo puedes descargar gratuitamente. Aún está en borrador, pero apreciaré mucho tu ayuda! Contiene Extras descargares como el “Lego Dataset” utilizado en el artículo de Detección de Objetos.

The post ¿Cómo funcionan las Convolutional Neural Networks? Visión por Ordenador first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/como-funcionan-las-convolutional-neural-networks-vision-por-ordenador/feed/ 28 6209
Clasificación de Imágenes en Python https://aprendemachinelearning.com/clasificacion-de-imagenes-en-python/ https://aprendemachinelearning.com/clasificacion-de-imagenes-en-python/#comments Thu, 08 Nov 2018 07:30:00 +0000 https://www.aprendemachinelearning.com/?p=5910 Crearemos una Convolutional Neural Network con Keras y Tensorflow en Python para reconocimiento de Imágenes. En este artículo iremos directo al grano: veremos el código que crea la red neuronal para visión por computador. En un próximo artículo explicaré bien los conceptos utilizados, pero esta...

The post Clasificación de Imágenes en Python first appeared on Aprende Machine Learning.

]]>
Crearemos una Convolutional Neural Network con Keras y Tensorflow en Python para reconocimiento de Imágenes.

En este artículo iremos directo al grano: veremos el código que crea la red neuronal para visión por computador. En un próximo artículo explicaré bien los conceptos utilizados, pero esta vez haremos un aprendizaje Top-down 😉

Ejercicio Propuesto: Clasificar imágenes de deportes

Para el ejercicio se me ocurrió crear “mi propio set MNIST” con imágenes de deportes. Para ello, seleccioné los 10 deportes más populares del mundo -según la sabiduría de internet- : Fútbol, Basket, Golf, Futbol Americano, Tenis, Fórmula 1, Ciclismo, Boxeo, Beisball y Natación (enumerados sin orden particular entre ellos).

Obtuve entre 5000 y 9000 imágenes de cada deporte, a partir de videos de Youtube (usando a FFMpeg!). Las imágenes están en tamaño <<diminuto>> de 21×28 pixeles en color y son un total de 77.000. Si bien el tamaño en pixeles puede parecer pequeño ES SUFICIENTE para que nuestra red neuronal pueda distinguirlas!!! (¿increíble, no?).

Entonces el objetivo es que nuestra máquina: “red neuronal convolucional” aprenda a clasificar -por sí sóla-, dada una nueva imagen, de qué deporte se trata.

Ejemplo de imágenes de los deportes más populares del mundo

Dividiremos el set de datos en 80-20 para entrenamiento y para test. A su vez, el conjunto de entrenamiento también lo subdividiremos en otro 80-20 para Entrenamiento y Validación en cada iteración (EPOCH) de aprendizaje.

Una muestra de las imágenes del Dataset que he titulado sportsMNIST. Contiene más de 70.000 imágenes de los 10 deportes más populares del mundo.

Requerimientos para realizar el Ejercicio

Necesitaremos por supuesto tener Python 3.6 y como lo haremos en una Notebook Jupyter, recomiendo tener instalada una suite como Anaconda, que nos facilitará las tareas.

Además instalar Keras y Tensorflow como backend. Puedes seguir este artículo en donde se explica como instalar todo el ambiente de desarrollo rápidamente.

Necesitarás descargar el archivo zip con las imágenes (están comprimidas) y decomprimirlas en el mismo directorio en donde ejecutarás la Notebook con el código. Al descomprimir, se crearán 10 subdirectorios con las imágenes: uno por cada deporte

Al código Python sin más!

Por más que no entiendas del todo el código sigue adelante, intentaré explicar brevemente qué hacemos paso a paso y en un próximo artículo se explicará cada parte de las CNN (Convolutional Neural Networks). También dejaré al final varios enlaces con información adicional que te ayudarán.

Esto es lo que haremos hoy:

  1. Importar librerías
  2. Cargar las 70.000 imágenes (en memoria!)
  3. Crear dinámicamente las etiquetas de resultado.
  4. Dividir en sets de Entrenamiento, Validación y Test
    • algo de preprocesamiento de datos
  5. Crear el modelo de la CNN
  6. Ejecutar nuestra máquina de aprendizaje (Entrenar la red)
  7. Revisar los resultados obtenidos

Empecemos a programar!:

1- Importar librerías

Cargaremos las libs que utilizaremos para el ejercicio.

import numpy as np
import os
import re
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import keras
from keras.utils import to_categorical
from keras.models import Sequential,Input,Model
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.layers.normalization import BatchNormalization
from keras.layers.advanced_activations import LeakyReLU

2-Cargar las imágenes

Recuerda tener DESCOMPRIMIDAS las imágenes!!! Y ejecutar el código en el MISMO directorio donde descomprimiste el directorio llamado “sportimages” (contiene 10 subdirectorios: uno por cada deporte).

Este proceso plt.imread(filepath)  cargará a memoria en un array las 77mil imágenes, por lo que puede tomar varios minutos y consumirá algo de memoria RAM de tu ordenador.

dirname = os.path.join(os.getcwd(), 'sportimages')
imgpath = dirname + os.sep 

images = []
directories = []
dircount = []
prevRoot=''
cant=0

print("leyendo imagenes de ",imgpath)

for root, dirnames, filenames in os.walk(imgpath):
    for filename in filenames:
        if re.search("\.(jpg|jpeg|png|bmp|tiff)$", filename):
            cant=cant+1
            filepath = os.path.join(root, filename)
            image = plt.imread(filepath)
            images.append(image)
            b = "Leyendo..." + str(cant)
            print (b, end="\r")
            if prevRoot !=root:
                print(root, cant)
                prevRoot=root
                directories.append(root)
                dircount.append(cant)
                cant=0
dircount.append(cant)

dircount = dircount[1:]
dircount[0]=dircount[0]+1
print('Directorios leidos:',len(directories))
print("Imagenes en cada directorio", dircount)
print('suma Total de imagenes en subdirs:',sum(dircount))
leyendo imagenes de /Users/xxx/proyecto_python/sportimages/
Directorios leidos: 10
Imagenes en cada directorio [9769, 8823, 8937, 5172, 7533, 7752, 7617, 9348, 5053, 7124]
suma Total de imagenes en subdirs: 77128

3- Crear etiquetas y clases

Crearemos las etiquetas en labels , es decir, le daremos valores de 0 al 9 a cada deporte. Esto lo hacemos para poder usar el algoritmo supervisado e indicar que cuando cargamos una imagen de futbol en la red, ya sabemos que corresponde con la “etiqueta 6”. Y con esa información, entrada y salida esperada, la red al entrenar, ajustará los pesos de las neuronas.

Luego convertimos las etiquetas y las imágenes en numpy array con np.array()

labels=[]
indice=0
for cantidad in dircount:
    for i in range(cantidad):
        labels.append(indice)
    indice=indice+1
print("Cantidad etiquetas creadas: ",len(labels))

deportes=[]
indice=0
for directorio in directories:
    name = directorio.split(os.sep)
    print(indice , name[len(name)-1])
    deportes.append(name[len(name)-1])
    indice=indice+1

y = np.array(labels)
X = np.array(images, dtype=np.uint8) #convierto de lista a numpy

# Find the unique numbers from the train labels
classes = np.unique(y)
nClasses = len(classes)
print('Total number of outputs : ', nClasses)
print('Output classes : ', classes)
Cantidad etiquetas creadas: 77128
0 golf
1 basket
2 tenis
3 natacion
4 ciclismo
5 beisball
6 futbol
7 americano
8 f1
9 boxeo
Total number of outputs : 10
Output classes : [0 1 2 3 4 5 6 7 8 9]

4-Creamos sets de Entrenamiento y Test, Validación y Preprocesar

Nótese la “forma” (shape) de los arrays: veremos que son de 21×28 y por 3 pues el 3 se refiere a los 3 canales de colores que tiene cada imagen: RGB (red, green, blue) que tiene valores de 0 a 255.

Preprocesamos el valor de los pixeles y lo normalizamos para que tengan un valor entre 0 y 1, por eso dividimos en 255.

Ademas haremos el “One-Hot encoding” con to_categorical()  que se refiere a convertir las etiquetas (nuestras clases) por ejemplo de fútbol un 6 a una salida de tipo (0 0 0 0 0 0 1 0 0 0) Esto es porque así funcionan mejor las redes neuronales para clasificar y se corresponde con una capa de salida de la red neuronal de 10 neuronas.
NOTA: por si no lo entendiste, se pone un 1 en la “sexta posición” del array y el resto en ceros, PERO no te olvides que empieza a contar incluyendo el cero!!! por eso la “etiqueta 6” queda realmente en la séptima posición.

Por último en este bloque, subdividimos los datos en 80-20 para test y entrenamiento con train_test_split()  y nuevamente en 80-20 el de training para obtener un subconjunto de validación.

#Mezclar todo y crear los grupos de entrenamiento y testing
train_X,test_X,train_Y,test_Y = train_test_split(X,y,test_size=0.2)
print('Training data shape : ', train_X.shape, train_Y.shape)
print('Testing data shape : ', test_X.shape, test_Y.shape)

train_X = train_X.astype('float32')
test_X = test_X.astype('float32')
train_X = train_X / 255.
test_X = test_X / 255.

# Change the labels from categorical to one-hot encoding
train_Y_one_hot = to_categorical(train_Y)
test_Y_one_hot = to_categorical(test_Y)

# Display the change for category label using one-hot encoding
print('Original label:', train_Y[0])
print('After conversion to one-hot:', train_Y_one_hot[0])

train_X,valid_X,train_label,valid_label = train_test_split(train_X, train_Y_one_hot, test_size=0.2, random_state=13)

print(train_X.shape,valid_X.shape,train_label.shape,valid_label.shape)
Training data shape : (61702, 21, 28, 3) (61702,)
Testing data shape : (15426, 21, 28, 3) (15426,)
Original label: 0
After conversion to one-hot: [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
(49361, 21, 28, 3) (12341, 21, 28, 3) (49361, 10) (12341, 10)

5 – Creamos la red (Aquí la Magia)

Ahora sí que nos apoyamos en Keras para crear la Convolutional Neural Network. En un futuro artículo explicaré mejor lo que se está haciendo. Por ahora “confíen” en mi:

  • Declaramos 3 “constantes”:
    • El valor inicial del learning rate INIT_LR
    • cantidad de epochs  y
    • tamaño batch de imágenes a procesar batch_size  (cargan en memoria).
  • Crearemos una primer capa de neuronas  “Convolucional de 2 Dimensiones” Conv2D() , donde entrarán nuestras imágenes de 21x28x3.
  • Aplicaremos 32 filtros (kernel) de tamaño 3×3 (no te preocupes si aún no entiendes esto!) que detectan ciertas características de la imagen (ejemplo: lineas verticales).
  • Utilizaremos La función LeakyReLU como activación de las neuronas.
  • Haremos un MaxPooling (de 2×2) que reduce la imagen que entra de 21×28 a la mitad,(11×14) manteniendo las características “únicas” que detectó cada kernel.
  • Para evitar el overfitting, añadimos una técnica llamada Dropout
  • “Aplanamos” Flatten()  los 32 filtros y creamos una capa de 32 neuronas “tradicionales” Dense()
  • Y finalizamos la capa de salida con 10 neuronas con activación Softmax, para que se corresponda con el “hot encoding” que hicimos antes.
  • Luego compilamos nuestra red sport_model.compile()  y le asignamos un optimizador (en este caso de llama Adagrad).
INIT_LR = 1e-3
epochs = 6
batch_size = 64

sport_model = Sequential()
sport_model.add(Conv2D(32, kernel_size=(3, 3),activation='linear',padding='same',input_shape=(21,28,3)))
sport_model.add(LeakyReLU(alpha=0.1))
sport_model.add(MaxPooling2D((2, 2),padding='same'))
sport_model.add(Dropout(0.5))

sport_model.add(Flatten())
sport_model.add(Dense(32, activation='linear'))
sport_model.add(LeakyReLU(alpha=0.1))
sport_model.add(Dropout(0.5)) 
sport_model.add(Dense(nClasses, activation='softmax'))

sport_model.summary()

sport_model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adagrad(lr=INIT_LR, decay=INIT_LR / 100),metrics=['accuracy'])

6-Entrenamos la CNN

Llegó el momento!!! con esta linea sport_model.fit()  iniciaremos el entrenamiento y validación de nuestra máquina! Pensemos que introduciremos miles de imágenes, pixeles, arrays, colores… filtros y la red se irá regulando sola, “aprendiendo” los mejores pesos para las más de 150.000 interconexiones para distinguir los 10 deportes. Esto tomará tiempo en un ordenador como mi Macbook Pro (del 2016) unos 4 minutos… puede parecer mucho o muy poco… según se lo mire. NOTA: podemos ejecutar este mismo código pero utilizando GPU (en tu ordenador o en la nube) y los mismos cálculos tomaría apenas 40 segundos.

Por último guardamos la red YA ENTRENADA sport_model.save()  en un formato de archivo h5py ya que nos permitirá poder utilizarla en el futuro SIN necesidad de volver a entrenar (y ahorrarnos los 4 minutos de impaciencia! ó incluso si contamos con GPU, ahorrarnos esa espera).

sport_train_dropout = sport_model.fit(train_X, train_label, batch_size=batch_size,epochs=epochs,verbose=1,validation_data=(valid_X, valid_label))

# guardamos la red, para reutilizarla en el futuro, sin tener que volver a entrenar
sport_model.save("sports_mnist.h5py")
Train on 49361 samples, validate on 12341 samples
Epoch 1/6
49361/49361 [==============================] – 40s 814us/step – loss: 1.5198 – acc: 0.4897 – val_loss: 1.0611 – val_acc: 0.7136
Epoch 2/6
49361/49361 [==============================] – 38s 775us/step – loss: 1.2002 – acc: 0.6063 – val_loss: 0.8987 – val_acc: 0.7717
Epoch 3/6
49361/49361 [==============================] – 43s 864us/step – loss: 1.0886 – acc: 0.6469 – val_loss: 0.8078 – val_acc: 0.7977
Epoch 4/6
49361/49361 [==============================] – 41s 832us/step – loss: 1.0166 – acc: 0.6720 – val_loss: 0.7512 – val_acc: 0.8180
Epoch 5/6
49361/49361 [==============================] – 36s 725us/step – loss: 0.9647 – acc: 0.6894 – val_loss: 0.7033 – val_acc: 0.8323
Epoch 6/6
49361/49361 [==============================] – 40s 802us/step – loss: 0.9258 – acc: 0.7032 – val_loss: 0.6717 – val_acc: 0.8379

Vemos que tras 6 iteraciones completas al set de entrenamiento, logramos un valor de precisión del 70% y en el set de validación alcanza un 83%. ¿Será esto suficiente para distinguir las imágenes deportivas?

7-Resultados obtenidos

Ya con nuestra red entrenada, es la hora de la verdad: ponerla a prueba con el set de imágenes para Test que separamos al principio y que son muestras que nunca fueron “vistas” por la máquina.

test_eval = sport_model.evaluate(test_X, test_Y_one_hot, verbose=1)

print('Test loss:', test_eval[0])
print('Test accuracy:', test_eval[1])
15426/15426 [==============================] – 5s 310us/step
Test loss: 0.6687967825782881
Test accuracy: 0.8409179307662388

En el conjunto de Testing vemos que alcanza una precisión del 84% reconociendo las imágenes de deportes. Ahora podríamos hacer un análisis más profundo, para mejorar la red, revisando los fallos que tuvimos… pero lo dejaremos para otra ocasión (BONUS: en la Jupyter Notebook verás más información con esto!) Spoiler Alert: La clase que peor detecta, son las de Fórmula 1.

Puedes probar con esta imagen de Basketball y de Fútbol a clasificarlas. En mi caso, fueron clasificadas con éxito.

En mis pruebas, a veces confundía esta imagen de Fútbol con Golf… ¿Será por el verde del campo?

Conclusiones y promesa futura!

Creamos una red neuronal “novedosa”: una red convolucional, que aplica filtros a las imágenes y es capaz de distinguir distintos deportes con un tamaño 21×28 pixels a color en tan sólo 4 minutos de entrenamiento.

Esta vez fuimos a la inversa que en otras ocasiones y antes de conocer la teoría de las redes específicas para reconocimiento de imágenes (las CNN) les he propuesto que hagamos un ejercicio práctico. Aunque pueda parecer contra-intuitivo, muchas veces este método de aprendizaje (en humanos!) funciona mejor, pues vuelve algo más dinámica la teoría. Espero que les hayan quedado algunos de los conceptos y los terminaremos de asentar en un próximo artículo (ya puedes leerlo!)

Suscripción al Blog

Recibe el próximo artículo con más teoría, prácticas y material para seguir aprendiendo Machine Learning! 

Los recursos y… Más recursos

Y mientras escribo el próximo artículo para el blog en español…

Ya disponible: ¿Qué son las Convolutional Neural Networks y cómo funcionan? La Teoría que faltaba 🙂

…les dejo varios enlaces (que seguramente utilizaré como inspiración) con más información sobre las Convolutional Neural Networks:

Y por último MIS artículos sobre Redes Neuronales (en Español! ejem-ejem!)

Otros:


El libro del Blog (en desarrollo)

Puedes colaborar comprando el libro ó lo puedes descargar gratuitamente. Aún está en borrador, pero apreciaré mucho tu ayuda! Contiene Extras descargares como el “Lego Dataset” utilizado en el artículo de Detección de Objetos.

The post Clasificación de Imágenes en Python first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/clasificacion-de-imagenes-en-python/feed/ 92 5910
Breve Historia de las Redes Neuronales Artificiales https://aprendemachinelearning.com/breve-historia-de-las-redes-neuronales-artificiales/ https://aprendemachinelearning.com/breve-historia-de-las-redes-neuronales-artificiales/#comments Wed, 12 Sep 2018 07:00:00 +0000 https://www.aprendemachinelearning.com/?p=5917 Arquitecturas y Aplicaciones de las Redes Neuronales más usadas. Vamos a hacer un repaso por las diversas estructuras inventadas, mejoradas y utilizadas a lo largo de la historia para crear redes neuronales y sacar el mayor potencial al Deep Learning para resolver toda clase de...

The post Breve Historia de las Redes Neuronales Artificiales first appeared on Aprende Machine Learning.

]]>
Arquitecturas y Aplicaciones de las Redes Neuronales más usadas.

Vamos a hacer un repaso por las diversas estructuras inventadas, mejoradas y utilizadas a lo largo de la historia para crear redes neuronales y sacar el mayor potencial al Deep Learning para resolver toda clase de problemas de regresión y clasificación.

Evolución de las Redes Neuronales en Ciencias de la Computación

Vamos a revisar las siguientes redes/arquitecturas:

  • 1958 – Perceptron
  • 1965 – Multilayer Perceptron
  • 1980’s
    • Neuronas Sigmoidales
    • Redes Feedforward
    • Backpropagation
  • 1989 – Convolutional neural networks (CNN) / Recurent neural networks (RNN)
  • 1997 – Long short term memory (LSTM)
  • 2006 – Deep Belief Networks (DBN): Nace deep learning
    • Restricted Boltzmann Machine
    • Encoder / Decoder = Auto-encoder
  • 2014 – Generative Adversarial Networks (GAN)

Si bien esta lista no es exhaustiva y no se abarcan todos los modelos creados desde los años 50, he recopilado las que fueron -a mi parecer- las redes y tecnologías más importantes desarrolladas para llegar al punto en que estamos hoy: el Aprendizaje Profundo.

El inicio de todo: la neurona artificial

1958 – Perceptron

Entre las décadas de 1950 y 1960 el científico Frank Rosenblatt, inspirado en el trabajo de Warren McCulloch y Walter Pitts creó el Perceptron, la unidad desde donde nacería y se potenciarían las redes neuronales artificiales.

Un perceptron toma varias entradas binarias x1, x2, etc y produce una sóla salida binaria. Para calcular la salida, Rosenblatt introduce el concepto de “pesos” w1, w2, etc, un número real que expresa la importancia de la respectiva entrada con la salida. La salida de la neurona será 1 o 0 si la suma de la multiplicación de pesos por entradas es mayor o menor a un determinado umbral.

Sus principales usos son decisiones binarias sencillas, o para crear funciones lógicas como OR, AND.

1965 – Multilayer Perceptron

Como se imaginarán, el multilayer perceptron es una “amplicación” del percepción de una única neurona a más de una. Además aparece el concepto de capas de entrada, oculta y salida. Pero con valores de entrada y salida binarios. No olvidemos que tanto el valor de los pesos como el de umbral de cada neurona lo asignaba manualmente el científico. Cuantos más perceptrones en las capas, mucho más difícil conseguir los pesos para obtener salidas deseadas.

Los 1980s: aprendizaje automático

Neuronas Sigmoides

Para poder lograr que las redes de neuronas aprendieran solas fue necesario introducir un nuevo tipo de neuronas. Las llamadas Neuronas Sigmoides son similares al perceptron, pero permiten que las entradas, en vez de ser ceros o unos, puedan tener valores reales como 0,5 ó 0,377 ó lo que sea. También aparecen las neuronas “bias” que siempre suman 1 en las diversas capas para resolver ciertas situaciones. Ahora las salidas en vez de ser 0 ó 1, será d(w . x + b) donde d será la función sigmoide definida como d(z) = 1/( 1 +e-z). Esta es la primer función de activación!

Imagen de la Curva Logística Normalizada de Wikipedia

Con esta nueva fórmula, se puede lograr que pequeñas alteraciones en valores de los pesos (deltas) produzcan pequeñas alteraciones en la salida. Por lo tanto, podemos ir ajustando muy de a poco los pesos de las conexiones e ir obteniendo las salidas deseadas.

Redes Feedforward

Se les llama así a las redes en que las salidas de una capa son utilizadas como entradas en la próxima capa. Esto quiere decir que no hay loops “hacia atrás”. Siempre se “alimenta” de valores hacia adelante. Hay redes que veremos más adelante en las que sí que existen esos loops (Recurrent Neural Networks).

Además existe el concepto de “fully connected Feedforward Networks” y se refiere a que todas las neuronas de entrada, están conectadas con todas las neuronas de la siguiente capa.

1986 – Backpropagation

Gracias al algoritmo de backpropagation se hizo posible entrenar redes neuronales de multiples capas de manera supervisada. Al calcular el error obtenido en la salida e ir propagando hacia las capas anteriores se van haciendo ajustes pequeños (minimizando costo) en cada iteración para lograr que la red aprenda consiguiendo que la red pueda -por ejemplo- clasificar las entradas correctamente.

Nuevo Artículo: Pronóstico de Series Temporales con Redes Neuronales

1989 – Convolutional Neural Network

Las Convolutional Neural Networks son redes multilayered que toman su inspiración del cortex visual de los animales. Esta arquitectura es útil en varias aplicaciones, principalmente procesamiento de imágenes. La primera CNN fue creada por Yann LeCun y estaba enfocada en el reconocimiento de letras manuscritas.

La arquitectura constaba de varias capas que implementaban la extracción de características y luego clasificar. La imagen se divide en campos receptivos que alimentan una capa convolutional que extrae features de la imagen de entrada (Por ejemplo, detectar lineas verticales, vértices, etc). El siguiente paso es pooling que reduce la dimensionalidad de las features extraídas manteniendo la información más importante. Luego se hace una nueva convolución y otro pooling que alimenta una red feedforward multicapa. La salida final de la red es un grupo de nodos que clasifican el resultado, por ejemplo un nodo para cada número del 0 al 9 (es decir, 10 nodos, se “activan” de a uno).

Nuevo artículo: ¿Qué son y cómo funcionan las Convolutional Neural Networks?

Esta arquitectura usando capas profundas y la clasificación de salida abrieron un mundo nuevo de posibilidades en las redes neuronales. Las CNN se usan también en reconocimiento de video y tareas de Procesamiento del Lenguaje natural. ¿Quieres hacer tu propia CNN en Python?

1997 Long Short Term Memory / Recurrent Neural Network

Aqui vemos que la red LSTM tiene neuronas ocultas con loops hacia atrás (en azul). Esto permite que almacene información en celdas de memoria.

Las Long short term memory son un tipo de Recurrent neural network. Esta arquitectura permite conexiones “hacia atrás” entre las capas. Esto las hace buenas para procesar datos de tipo “time series” (datos históricos). En 1997 se crearon las LSTM que consisten en unas celdas de memoria que permiten a la red recordar valores por períodos cortos o largos.

Una celda de memoria contiene compuertas que administran como la información fluye dentro o fuera. La puerta de entrada controla cuando puede entran nueva información en la memoria. La puerta de “olvido” controla cuanto tiempo existe y se retiene esa información. La puerta de salida controla cuando la información en la celda es usada como salida de la celda. La celda contiene pesos que controlan cada compuerta. El algoritmo de entrenamiento -conocido como backpropagation-through-time optimiza estos pesos basado en el error de resultado.

Las LSTM se han aplicado en reconocimiento de voz, de escritura, text-to-speech y otras tareas.

Se alcanza el Deep Learning

2006 – Deep Belief Networks (DBN)

La Deep Belief Network utiliza un Autoencoder con Restricted Boltzmann Machines para preentrenar a las neuronas de la red y obtener un mejor resultado final.

Antes de las DBN en 2006 los modelos con “profundidad” (decenas o cientos de capas) eran considerados demasiado difíciles de entrenar (incluso con backpropagation) y el uso de las redes neuronales artificiales quedó estancado. Con la creación de una DBN que logro obtener un mejor resultado en el MNIST, se devolvió el entusiasmo en poder lograr el aprendizaje profundo en redes neuronales. Hoy en día las DBN no se utilizan demasiado, pero fueron un gran hito en la historia en el desarrollo del deep learning y permitieron seguir la exploración para mejorar las redes existentes CNN, LSTM, etc.

Las Deep Belief Networks, demostraron que utilizar pesos aleatorios al inicializar las redes son una mala idea: por ejemplo al utilizar Backpropagation con Descenso por gradiente muchas veces se caía en mínimos locales, sin lograr optimizar los pesos. Mejor será utilizar una asignación de pesos inteligente mediante un preentrenamiento de las capas de la red -en inglés “pretrain”-. Se basa en el uso de la utilización de Restricted Boltzmann Machines y Autoencoders para pre-entrenar la red de manera no supervisada. Ojo! luego de pre-entrenar y asignar esos pesos iniciales, deberemos entrenar la red por de forma habitual, supervisada (por ejemplo con backpropagation).

Se cree que ese preentrenamiento es una de las causas de la gran mejora en las redes neuronales y permitir el deep learning: pues para asignar los valores se evalúa capa a capa, de a una, y no “sufre” de cierto sesgo que causa el backpropagation, al entrenar a todas las capas en simultáneo.

2014 – Generative Adversarial Networks

Las GAN, entrenan dos redes neuronales en simultáneo. La red de Generación y la red de Discriminación. A medida que la máquina aprende, comienza a crear muestras que son indistinguibles de los datos reales.

Estas redes pueden aprender a crear muestras, de manera similar a los datos con las que las alimentamos.

La idea detrás de GAN es la de tener dos modelos de redes neuronales compitiendo. Uno, llamado Generador, toma inicialmente “datos basura” como entrada y genera muestras. El otro modelo, llamado Discriminador, recibe a la vez muestras del Generador y del conjunto de entrenamiento (real) y deberá ser capaz de diferenciar entre las dos fuentes. Estas dos redes juegan una partida continua donde el Generador aprende a producir muestras más realistas y el Discriminador aprende a distinguir entre datos reales y muestras artificiales. Estas redes son entrenadas simultáneamente para finalmente lograr que los datos generados no puedan detectarse de datos reales.

Sus aplicaciones principales son la de generación de imágenes realistas, pero también la de mejorar imágenes ya existentes, o generar textos (captions) en imágenes, o generar textos siguiendo un estilo determinado y hasta desarrollo de moléculas para industria farmacéutica.

Conclusión, repaso y Nuevos descubrimientos

Hemos recorrido estos primeros -casi- 80 años de avances en las redes neuronales en la historia de la inteligencia artificial. Se suele dividir en 3 etapas, del 40 al 70 en donde se pasó del asombro de estos nuevos modelos hasta el escepticismo, el retorno de un invierno de 10 años cuando en los ochentas surgen mejoras en mecanismos y maneras de entrenar las redes (backpropagation) y se alcanza una meseta en la que no se puede alcanzar la “profundidad” de aprendizaje seguramente también por falta de poder de cómputo. Y una tercer etapa a partir de 2006 en la que se logra superar esa barrera y aprovechando el poder de las GPU y nuevas ideas se logra entrenar cientos de capas jerárquicas que conforman y potencian el Deep Learning y dan una capacidad casi ilimitada a estas redes.

Como último comentario, me gustaría decir que recientemente (feb 2018) hay nuevos estudios de las neuronas humanas biológicas en las que se está redescubriendo su funcionamiento y se está produciendo una nueva revolución, pues parece que es totalmente distinto a lo que hasta hoy conocíamos. Esto puede ser el principio de una nueva etapa totalmente nueva y seguramente mejor del Aprendizaje Profundo, el Machine Learning y la Inteligencia Artificial.

Suscripción al Blog

Recibe nuevos artículos sobre Machine Learning, redes neuronales y código Python cada 15 días 

Más recursos /  Seguir leyendo.

The post Breve Historia de las Redes Neuronales Artificiales first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/breve-historia-de-las-redes-neuronales-artificiales/feed/ 6 5917
Aprendizaje Profundo: una Guía rápida https://aprendemachinelearning.com/aprendizaje-profundo-una-guia-rapida/ https://aprendemachinelearning.com/aprendizaje-profundo-una-guia-rapida/#comments Tue, 14 Nov 2017 10:00:42 +0000 https://www.aprendemachinelearning.com/?p=5338 Explicando Deep Learning y Redes Neuronales -sin código- Intentaré explicar brevemente en qué consiste el Deep Learning ó Aprendizaje Profundo utilizado en Machine Learning describiendo sus componentes básicos. Conocimientos Previos Daré por sentado que el lector ya conoce la definición de Machine Learning y sus principales...

The post Aprendizaje Profundo: una Guía rápida first appeared on Aprende Machine Learning.

]]>
Explicando Deep Learning y Redes Neuronales -sin código-

Intentaré explicar brevemente en qué consiste el Deep Learning ó Aprendizaje Profundo utilizado en Machine Learning describiendo sus componentes básicos.

Conocimientos Previos

Daré por sentado que el lector ya conoce la definición de Machine Learning y sus principales aplicaciones en el mundo real y el panorama de algoritmos utilizados con mayor frecuencia. Nos centraremos en Aprendizaje Profundo aplicando Redes Neuronales Artificiales.

Entonces, ¿cómo funciona el Deep Learning? Mejor un Ejemplo

El Aprendizaje Profundo es un método del Machine Learning que nos permite entrenar una Inteligencia Artificial para obtener una predicción dado un conjunto de entradas. Esta inteligencia logrará un nivel de cognición por jerarquías. Se puede utilizar Aprendizaje Supervisado o No Supervisado.

Explicaré como funciona el Deep Learning mediante un ejemplo hipotético de predicción sobre quién ganará el próximo mundial de futbol. Utilizaremos aprendizaje supervisado mediante algoritmos de Redes Neuronales Artificiales.

Para lograr las predicciones de los partidos de fútbol usaremos como ejemplo las siguientes entradas:

  •  Cantidad de Partidos Ganados
  •  Cantidad de Partidos Empatados
  •  Cantidad de Partidos Perdidos
  • Cantidad de Goles a Favor
  • Cantidad de Goles en Contra
  • “Racha Ganadora” del equipo (cant. max de partidos ganados seguidos sobre el total jugado)

Y podríamos tener muchísimas entradas más, por ejemplo la puntuación media de los jugadores del equipo, o el score que da la FIFA al equipo. Como en cada partido tenemos a 2 rivales, deberemos estos 6 datos de entrada por cada equipo, es decir, 6 entradas del equipo 1 y otras 6 del equipo 2 dando un total de 12 entradas.

La predicción de salida será el resultado del partido: Local, Empate o Visitante.

Creamos una Red Neuronal

En la programación “tradicional” escribiríamos código en donde indicamos reglas por ejemplo “si goles  de equipo 1 mayor a goles de equipo 2 entonces probabilidad de Local aumenta”. Es decir que deberíamos programar artesanalmente unas reglas de inteligencia bastante extensa e inter-relacionar las 12 variables. Para evitar todo ese enredo y hacer que nuestro código sea escalaba y flexible a cambios recurrimos a las Redes Neuronales de Machine Learning para indicar una arquitectura de interconexiones y dejar que este modelo aprenda por sí mismo (y descubra él mismo relaciones de variables que nosotros desconocemos).

Lee aqui, sobre la historia de las Redes Neuronales

Vamos a crear una Red Neuronal con 12 valores de entrada (Input Layer) y con 3 neuronas de Salida (Output Layer). Las neuronas que tenemos en medio se llaman Hidden Layers y podemos tener muchas, cada una con una distinta cantidad de neuronas. Todas las neuronas estarán inter-conectadas unas con otras en las distintas capas como vemos en el dibujo. Las Neuronas son los círculos blancos.

  • La capa de entrada recibe los datos de entrada y los pasa a la primer capa oculta.
  • Las capas ocultas realizarán cálculos matemáticos con nuestras entradas. Uno de los desafíos al crear la Red Neuronal es decidir el número de capas ocultas y la cantidad de neuronas de cada capa.
  • La capa de Salida devuelve la predicción realizada. En nuestro caso de 3 resultados discretos las salidas podrán ser “1 0 0” para Local, “0 1 0” para Empate y “0 0 1” para Visitante.

La cantidad total de capas en la cadena le da “profundidad” al modelo. De aquí es que surge la terminología de Aprendizaje Profundo.

¿Cómo se calcula la predicción?

Cada conexión de nuestra red neuronal está asociada a un peso. Este peso dictamina la importancia que tendrá esa relación en la neurona al multiplicarse por el valor de entrada. Los valores iniciales de peso se asignan aleatoriamente (SPOILER: más adelante los pesos se ajustarán solos).

Imitando a las neuronas biológicas. cada Neurona tiene una Función de Activación. Esta función determinará si la suma de sus valores recibidos (previamente multiplicados por el peso de la conexión) supera un umbral que hace que la neurona se active y dispare un valor hacia la siguiente capa conectada. Hay diversas Funciones de Activación conocidas que se suelen utilizar en estas redes.

Cuando todas las capas finalizan de realizar sus cómputos, se llegará a la capa final con una predicción. Por Ejemplo si nuestro modelo nos devuelve 0.6 0.25 0.15 está prediciendo que ganará Local con 60% probabilidades, será Empate 25% o que gane Visitante 15%.

Entrenando Nuestra Red Neuronal

Entrenar nuestra IA puede llegar a ser la parte más difícil del Deep Learning. Necesitamos:

  1. Gran cantidad de valores en nuestro conjunto de Datos de Entrada
  2. Gran poder de cálculo computacional

Para nuestro ejemplo de “predicción de Partidos de Futbol para el próximo Mundial” deberemos crear una base de datos con todos los resultados históricos de los Equipos de Fútbol en mundiales, en partidos amistosos, en clasificatorios, los goles, las rachas a lo largo de los años, etc.

Para entrenar nuestra máquina, deberemos alimentarla con nuestro conjunto de datos de entrada y comparar el resultado (local, empate, visitante) contra la predicción obtenida. Como nuestro modelo fue inicializado con pesos aleatorios, y aún está sin entrenar, las salidas obtenidas seguramente serán erróneas.

Una vez que tenemos nuestro conjunto de datos, comenzaremos un proceso iterativo: usaremos una función para comparar cuan bueno/malo fue nuestro resultado contra el resultado real. Esta función es llamada “Función Coste“. Idealmente queremos que nuestro coste sea cero, es decir sin error(cuando el valor de la predicción es igual al resultado real del partido). A medida que entrena el modelo irá ajustando los pesos de inter-conexiones de las neuronas de manera automática hasta obtener buenas predicciones. A ese proceso de “ir y venir” por las capas de neuronas se le conoce como Back-Propagation. Más detalle a continuación.

¿Cómo reducimos la función coste -y mejoramos las predicciones-?

Para poder ajustar los pesos de las conexiones entre neuronas haciendo que el coste se aproxime a cero usaremos una técnica llamada Gradient Descent. Esta técnica permite encontrar el mínimo de una función. En nuestro caso, buscaremos el mínimo en la Función Coste.

Funciona cambiando los pesos en pequeños incrementos luego de cada iteración del conjunto de datos. Al calcular la derivada (o gradiente) de la Función Coste en un cierto conjunto de pesos, podremos ver en que dirección “descender” hacia el mínimo global. Aquí se puede ver un ejemplo de Descenso de Gradiente en  2 dimensiones, imaginen la dificultad de tener que encontrar un mínimo global en 12 dimensiones!

Para minimizar la función de coste necesitaremos iterar por el conjunto de datos cientos de miles de veces (ó más), por eso es tan necesario tener gran capacidad de cómputo en el ordenador/nube en la que entrenamos la red.

La actualización del valor de los pesos se realizará automáticamente usando el Descenso de Gradiente. Esta es parte de la magia del Aprendizaje Profundo “Automático”.

Una vez que finalizamos de entrenar nuestro Predictor de Partidos de Futbol del Mundial, sólo tendremos que alimentarlo con los partidos que se disputarán y podremos saber quién ganará Rusia 2018… Es un caso hipotético, pero es un ejercicio divertido para hacer.

¿Dónde puedo aprender más?

Hay muchos tipos de Redes Neuronales,  Convolutional Neural Networks (CNN) usadas para Vision por Computadora o las Recurrent Neural Networks RNN para Procesamiento Natural del Lenguaje. Puedes leer mi artículo con una sencilla implementación en Python con Keras, un artículo con un ejercicio en Python pero sin librerias. O un artículo sobre la historia de las Redes Neuronales. Si quieres aprender el aspecto técnico del Aprendizaje Profundo puedo sugerir tomar un curso online. Actualmente el más popular es el de Andrew Ng: Deep Learning Specialization. Se puede cursar gratuitamente o pagar para obtener la certificación. O para un conocimiento general de Machine Learning también puedo recomendar el curso estrella de Coursera. Un gran problema que surge al crear y entrenar Redes Neuronales es el Overfitting al dar demasiada complejidad a nuestra arquitectura de capas.

Si tienes dudas o preguntas sobre este tema puedo ayudarte, deja tus comentarios al finalizar este artículo.

Quieres preparar tu ambiente de desarrollo en Python?
Sigue este tutorial! Y crea tu primer red neuronal aquí

En Conclusión

  • El Aprendizaje Profundo utiliza Algoritmos de Redes Neuronales Artificiales que imitan el comportamiento biológico del cerebro.
  • Hay 3 tipos de Capas de Neuronas: de Entrada, Ocultas y de Salida.
  • Las conexiones entre neuronas llevan asociadas un peso, que denota la importancia del valor de entrada en esa relación.
  • Las neuronas aplican una Función de Activación para Estandarizar su valor de salida a la próxima capa de neuronas.
  • Para entrenar una red neuronal necesitaremos un gran conjunto de datos.
  • Iterar el conjunto de datos y comparar sus salidas producirá una Función Coste que indicará cuán alejado está nuestra predicción del valor real.
  • Luego de cada iteración del conjunto de datos de entrada, se ajustarán los pesos de las neuronas utilizando el Descenso de Gradiente para reducir el valor de Coste y acercar las predicciones a las salidas reales.

Si te gusta este artículo puedes ayudarme difundiendo en Redes Sociales el enlace para que más personas lo encuentren.

Y si vas a crear tu propia máquina, recuerda seguir los 7 pasos que comento en este artículo.

Para más actualizaciones te sugiero que te suscribas al blog o que me sigas en Twitter!

Nuevo! Ejercicio con Redes Neuronales: Pronóstico de Ventas

Entérate Primero – Suscripción

Anótate al blog y te notificará al publicarse el próximo post quincenal sobre Machine Learning. Súbete a la ola de Tecnología Disruptiva! 

GuardarGuardar

The post Aprendizaje Profundo: una Guía rápida first appeared on Aprende Machine Learning.

]]>
https://aprendemachinelearning.com/aprendizaje-profundo-una-guia-rapida/feed/ 11 5338