PROPÓSITO: La siguiente unidad tiene como propósito principal la implementación de los algoritmos de aprendizaje profundo.
Las redes neuronales artificiales son un modelo computacional vagamente inspirado en el comportamiento observado en su homólogo biológico. Consiste en un conjunto de unidades, llamadas neuronas artificiales, conectadas entre sí para transmitirse señales. La información de entrada atraviesa la red neuronal (donde se somete a diversas operaciones) produciendo unos valores de salida. Cada neurona está conectada con otras a través de unos enlaces.
En estos enlaces el valor de salida de la neurona anterior es multiplicado por un valor de peso. Estos pesos en los enlaces pueden incrementar o inhibir el estado de activación de las neuronas adyacentes. Del mismo modo, a la salida de la neurona, puede existir una función limitadora o umbral, que modifica el valor resultado o impone un límite que no se debe sobrepasar antes de propagarse a otra neurona. Esta función se conoce como función de activación.
Estos sistemas aprenden y se forman a sí mismos, en lugar de ser programados de forma explícita, y sobresalen en áreas donde la detección de soluciones o características es difícil de expresar con la programación convencional. Para realizar este aprendizaje automático, normalmente, se intenta minimizar una función de pérdida que evalúa la red en su total. Los valores de los pesos de las neuronas se van actualizando buscando reducir el valor de la función de pérdida. Este proceso se realiza mediante la propagación hacia atrás.
El objetivo de la red neuronal es resolver los problemas de la misma manera que el cerebro humano, aunque las redes neuronales son más abstractas. Las redes neuronales actuales suelen contener desde unos miles a unos pocos millones de unidades neuronales.
En el campo de las Redes Neuronales, el perceptrón, creado por Frank Rosenblatt, se refiere a:
la neurona artificial o unidad básica de inferencia en forma de discriminador lineal, a partir de lo cual se desarrolla un algoritmo capaz de generar un criterio para seleccionar un sub-grupo a partir de un grupo de componentes más grande.
La limitación de este algoritmo es que si dibujamos en un gráfico estos elementos, se deben poder separar con un hiperplano únicamente los elementos "deseados" discriminándolos (separándolos) de los "no deseados". Sin embargo, El perceptrón puede utilizarse con otros tipos de perceptrones o de neurona artificial, para formar una red neuronal artificial más compleja. Una implementación de este código puede encontrarse aquí
En el campo de las Redes Neuronales, el perceptrón, creado por Frank Rosenblatt, se refiere a:
la neurona artificial o unidad básica de inferencia en forma de discriminador lineal, a partir de lo cual se desarrolla un algoritmo capaz de generar un criterio para seleccionar un sub-grupo a partir de un grupo de componentes más grande.
La limitación de este algoritmo es que si dibujamos en un gráfico estos elementos, se deben poder separar con un hiperplano únicamente los elementos "deseados" discriminándolos (separándolos) de los "no deseados". Sin embargo, El perceptrón puede utilizarse con otros tipos de perceptrones o de neurona artificial, para formar una red neuronal artificial más compleja.
Entrenamiento
Siendo X cada uno de los patrones de entrenamiento y d(x) su clase asociada con valores de (1,-1), el proceso de aprendizaje tiene los siguientes pasos.
Dar valores aleatorios a los pesos w_i y al umbral θ.
Seleccionar un vector de entrada X ̅=x_1, x_2, x_3,…, x_n del conjunto de ejemplos de entrenamiento.
Calcular la diferencia entre la salida deseada y la real. (d^p- y^p) y aplicar Δ_p w_j= γ (d^p- y^p)x_j
Modificar los pesos. w_j= w_j+ Δ_p w_j
Si no se ha cumplido el criterio de terminación, retornar a 2.
Aprendizaje profundo (en inglés, deep learning) es un conjunto de algoritmos de aprendizaje automático (en inglés, machine learning) que intenta modelar abstracciones de alto nivel en datos usando arquitecturas computacionales que admiten transformaciones no lineales múltiples e iterativas de datos expresados en forma matricial o tensorial. El aprendizaje profundo es parte de un conjunto más amplio de métodos de aprendizaje automático basados en asimilar representaciones de datos. Una observación (por ejemplo, una imagen) puede ser representada en algunas formas (por ejemplo, un vector de píxeles), pero algunas representaciones hacen más fácil aprender tareas de interés (por ejemplo, "¿es esta imagen una cara humana?") sobre la base de ejemplos, y la investigación en esta área intenta definir qué representaciones son mejores y cómo crear modelos para reconocer estas representaciones.
Varias arquitecturas de aprendizaje profundo, como redes neuronales profundas, redes neuronales profundas convolucionales, y redes de creencia profundas, han sido aplicadas a campos como visión por computador, reconocimiento automático del habla, y reconocimiento de señales de audio y música, y han mostrado producir resultados de vanguardia en varias tareas.
Pytorch: Es una biblioteca de aprendizaje automático3 de código abierto basada en la biblioteca de Torch, utilizado para aplicaciones que implementan cosas como visión artificial y procesamiento de lenguajes naturales, principalmente desarrollado por el Laboratorio de Investigación de Inteligencia Artificial4 de Facebook (FAIR). Es un software libre y de código abierto liberado bajo la Licencia Modificada de BSD. A pesar de que la interfaz de Python está más pulida y es el foco principal del desarrollo, PyTorch también tiene una interfaz en C++.
Tensorflow: Es una biblioteca de código abierto para aprendizaje automático a través de un rango de tareas, y desarrollado por Google para satisfacer sus necesidades de sistemas capaces de construir y entrenar redes neuronales para detectar y descifrar patrones y correlaciones, análogos al aprendizaje y razonamiento usados por los humanos. Actualmente es utilizado tanto en la investigación como en los productos de Google frecuentemente reemplazando el rol de su predecesor de código cerrado, DistBelief. TensorFlow fue originalmente desarrollado por el equipo de Google Brain para uso interno en Google antes de ser publicado bajo la licencia de código abierto Apache 2.0 el 9 de noviembre de 2015.
Keras: Es una biblioteca de Redes Neuronales de Código Abierto escrita en Python. Es capaz de ejecutarse sobre TensorFlow, Microsoft Cognitive Toolkit o Theano. Está especialmente diseñada para posibilitar la experimentación en más o menos poco tiempo con redes de Aprendizaje Profundo. Sus fuertes se centran en ser amigable para el usuario, modular y extensible.
Deep Dream
Segmentación de objetos
Generación de rostros
Rostros a partir de dibujos
Interpretación semantica
Sustitución de rostros
Llevando el perceptrón multicapa a profundidad
Esta fue considerada la primera arquitectura de Deep Learning. Consiste en incluir un modelo con muchas capas con muchas neuronas. Esto hace que las capas sean más densas y la complejidad se aumente. Con esta configuración, es posible implementar problemas de clasificación, regresión y clustering.
Las redes neuronales convolucionales (Convolutional Neural Nets - 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”. Aquí, las “neuronas” corresponden a campos receptivos de una manera muy similar a las neuronas en la corteza visual primaria (V1) de un cerebro biológico. Este tipo de red es una variación de un perceptrón multicapa, sin embargo, debido a que su aplicación es realizada en matrices bidimensionales, son muy efectivas para tareas de visión artificial, como en la clasificación y segmentación de imágenes, entre otras aplicaciones.
Corteza visual
Cómo estan construidas y cómo funcionan
Las redes neuronales convolucionales consisten en múltiples capas de filtros convolucionales de una o más dimensiones. Después de cada capa, por lo general se añade una función para realizar un mapeo causal no-lineal. Como cualquier red empleada para clasificación, al principio estas redes tienen una fase de extracción de características, compuesta de neuronas convolucionales , luego hay una reducción por muestreo y al final tendremos neuronas de perceptrón mas sencillas para realizar la clasificación final sobre las características extraídas. La fase de extracción de características se asemeja al proceso estimulante en las células de la corteza visual. Esta fase se compone de capas alternas de neuronas convolucionales y neuronas de reducción de muestreo. Según progresan los datos a lo largo de esta fase, se disminuye su dimensionalidad, siendo las neuronas en capas lejanas mucho menos sensibles a perturbaciones en los datos de entrada, pero al mismo tiempo siendo estas activadas por características cada vez más complejas. Por esto, 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.
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 y se irán ajustando mediante backpropagation. 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)
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).
Subsampling con Maxpooling
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.
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.
Flujo convolucional compuesto
Y al finalizar...... Conectar con un MLP
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», y con ello aplanamos (y conectamos) una nueva capa oculta de neuronas tipo feedforward. Entonces, a esta nueva red 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 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]. También, 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, segun este ejemplo.
Efecto de las funciones de activación
Revisemos los siguientes ejemplos en Keras y pytorch: ejemplo 1 (keras), ejemplo 1 (pytorch), ejemplo 2 (keras) . También es importante conocer y utilizar el concepto de generadores para escalar daos en este tipo de modelos. Por ello, tenemos este ejemplo 3 (keras).
Una serie de tiempo es una secuencia de datos u observaciones, medidos en determinados momentos y ordenados cronológicamente. Visualmente, es una curva que evoluciona en el tiempo. Una serie de tiempo es un conjunto de observaciones sobre los valores que toma una variable (cuantitativa) a través del tiempo. Por tanto, una serie de tiempo es una forma estructurada de representar datos. Los datos se pueden comportar de diferentes maneras a través del tiempo: puede que se presente una tendencia, estacionalidad o simplemente no presenten una forma definida. Representar los datos del negocio como series de tiempo suele ayudar a las empresas a visualizar la actividad del negocio. A su vez, usualmente las series de tiempo se utilizan para predecir el comportamiento futuro de la variable medida. A modo de ejemplo, el siguiente gráfico presenta la serie de tiempo de las ventas de un producto. A simple vista, se aprecia una cierta estacionalidad. Durante los meses de verano (Diciembre-Febrero) baja la venta, mientras sube en invierno.
Para fines prácticos me limitaré a explicar en este post únicamente la convolución, debido a que es el más utilizado, sin embargo, el procedimiento es casi el mismo. Retomando, la convolución discreta en 1D de dos señales x y h, veamos como se realiza el proceso que se indica en la operación de convolución.
Reflexión: Se refleja h(k), obteniendo así h[−k]
Desplazamiento: Ahora h(−k) se desplaza en un instante de tiempo n0, resultando en h[n0−k]
Multiplicación: Esta vez se multiplican las señales x[k] y h[n0−k], obteniendo una secuencia de valores.
Suma: Finalmente se suman los valores de la secuencia anterior, siendo esta sumatoria el resultado de la convolución (la señal de salida y[n]) en el instante en el que n=n0.
Uno de los componentes fundamentales para lograr estos objetivos son los enormes datasets con imágenes que alimentan a los algoritmos, sin embargo, estos muchas veces son limitados o escasos. Data augmentation o Aumento de datos es una técnica que nos permite aumentar nuestro set de datos de entrenamiento para mejorar la precisión, la generalización, y controlar el overfitting. Una idea para el aumento de datos es usar transformaciones de imágenes. A continuación, analicemos el notebook de Transformaciones. Para encontrar un implementación prácitica en cuanto al uso de tranformaciones de imaǵenes y manejo de volúmenes a gran escala, analizaremos el siguiente notebook.