Un Tutorial de Aprendizaje Profundo: De Perceptrones a Redes Profundas Parte 2

Máquina de Boltzmann Restringidas

El siguiente paso lógico es mirar las máquinas de Boltzmann restringidas (MBR), una red neuronal generativa que puede aprender una distribución de probabilidad sobre su propio conjunto de entradas.
In machine learning, Restricted Botlzmann Machines are composed of visible and hidden units.
Dichos mecanismos están compuestos de una capa de sesgo (bias) oculta y visible. A diferencia de las redes feedforward, las conexiones entre las capas visibles y ocultas son no-dirigidas (los valores se pueden propagar tanto en direcciones visible-a-oculto y oculto-a-visible) y completamente conectadas (cada unidad de una capa está conectada a cada unidad en la siguiente capa, si permitimos que cualquier unidad en cualquier capa se conecte a cualquier otra capa, entonces tendríamos un Boltzmann (en lugar de una máquina de Boltzmann restringida).
El estándar MBR tiene binario oculto y unidades visibles: es decir, la activación de la unidad es 0 o 1 bajo una distribución de Bernoulli, pero hay variantes con otras no-linealidades.
Mientras que los investigadores han tenido conocimiento sobre las MBR desde hace algún tiempo, la reciente introducción del algoritmo de entrenamiento no supervisado de la divergencia contrastiva, ha renovado el interés.

La Divergencia Contrastiva

El algoritmo de un solo paso de la divergencia contrastiva (CD-1) funciona así:
  1. Fase positiva:
    • Una muestra de entrada v se sujeta a la capa de entrada.
    • v se propaga a la capa oculta de una manera similar como a las redes feedforward. El resultado de las activaciones de la capa oculta es h.
  2. Fase negativa:
    • Propagar h de regreso a la capa visible con resultado v’ (las conexiones entre las capas visibles y ocultas son no-dirigidas y por lo tanto permiten el movimiento en ambas direcciones).
    • Propagar la nueva v’ de vuelta a la capa oculta con resultado de activaciones h’.
  3. Actualización de peso:
    weight update
    Donde a es la tasa de aprendizaje y vv’hh’, y w son vectores.
La intuición detrás del algoritmo es que la fase positiva (h dada v) refleja la representación interna de la red de datos de la vida real. Mientras tanto, la fase negativa representa un intento de recrear los datos, basados en esta representación interna (v’ dada h). El objetivo principal es que los datos generados sean lo más cercano posible a la de la vida real y esto se refleja en la fórmula actualización peso.
En otras palabras, la red tiene una percepción de cómo los datos de entrada pueden ser representados, por lo que trata de reproducir los datos basándose en esta percepción. Si su reproducción no es lo suficientemente cercana a la realidad, hace un ajuste y lo intenta de nuevo.

Volviendo a la Gripe

Para demostrar la divergencia contrastiva, usaremos el mismo conjunto de datos de síntomas que utilizamos anteriormente. La red de prueba es una MBR con seis unidades visibles y dos unidades ocultas. Vamos a entrenar la red, utilizando la divergencia contrastiva con los síntomas v sujetos a la capa visible. Durante las pruebas, los síntomas se presentan de nuevo a la capa visible; luego los datos se propagan a la capa oculta. Las unidades ocultas representan el estado enfermo / sano, una arquitectura muy similar a la autoencoder (propagación de datos de la capa visible a la oculta).
Después de varios cientos de iteraciones, se observa el mismo resultado que con autoencoders: una de las unidades ocultas tiene un valor mayor de activación cuando se presenta alguna de las muestras de “enfermos”, mientras que el otro está siempre más activo para las muestras de “sanos”.
Puedes ver este ejemplo en acción en el método testContrastiveDivergence.

Redes Profundas

Hemos demostrado ahora que las capas ocultas de autoencoders y las MBR actúan como detectores de características eficaces; pero es raro que podamos utilizar estas funciones directamente. De hecho, el conjunto de datos anterior, es más una excepción que una regla. En su lugar, tenemos que encontrar la manera de utilizar estas características detectadas, indirectamente.
Por suerte, se descubrió que estas estructuras pueden ser apiladas para formar redes profundas. Estas redes pueden ser entrenadas codiciosamente, una capa a la vez, para ayudar a superar la desaparición de gradientes y problemas de sobreajuste asociados con la clásica propagación hacia atrás.
Las estructuras resultantes son a menudo bastante potentes, produciendo resultados impresionantes. Tomemos, por ejemplo, la famosa “cat” paper de Google, en el que utilizan una clase especial de autoencoders profundos para “aprender” la detección del rostro humano y de gatos, basado en datos no marcados.
Miremos más de cerca.

Autoencoders Apilados

Como su nombre lo indica, esta red consiste en múltiples autoencoders apilados.
Stacked Autoencoders have a series of inputs, outputs, and hidden layers that contribute to machine learning outcomes.
La capa oculta de autoencoder t actúa como una capa de entrada a autoencoder t + 1. La capa de entrada del primer autoencoder es la capa de entrada para toda la red. El procedimiento de entrenamiento de greedy layer-wise funciona así:
  1. Entrena al primer autoencoder (t=1, o las conexiones de color rojo en la figura anterior, pero con una capa de salida adicional) de forma individual utilizando el método de propagación hacia atrás con todos los datos de entrenamiento disponibles.
  2. Entrena al segundo autoencoder t=2 (conexiones verdes). Dado que la capa de entrada para t=2 es la capa oculta de t=1, ya no estamos interesados en la capa de salida de t=1 y la quitamos de la red. El entrenamiento comienza sujetando una muestra de entrada a la capa de entrada de t=1, que se propaga hacia adelante a la capa de salida de t=2. A continuación, los pesos (entrada-oculta y oculta-salida) de t=2 se actualizan mediante propagación hacia atrás. t=2 utiliza todas las muestras de entrenamiento, similar a t=1.
  3. Repite el procedimiento anterior para todas las capas (es decir, elimina la capa de salida del autoencoder anterior, sustitúyela por otra autoencoder, y entrénala con propagación hacia atrás).
  4. Pasos 1-3 se llaman pre-entrenamiento y dejan los pesos inicializados correctamente. Sin embargo, no hay mapeo entre los datos de entrada y las etiquetas de salida. Por ejemplo, si la red está entrenada para reconocer imágenes de dígitos escritos a mano, todavía no es posible mapear las unidades del último detector de características (es decir, la capa oculta del último autoencoder) al tipo de dígitos de la imagen. En ese caso, la solución más común es añadir una o más capas enteramente conectadas con la última capa (conexiones azules). Toda la red ahora se puede ver como un perceptrón de múltiples capas y es entrenado utilizando propagación hacia atrás (este paso también se denomina ajuste fino).
Entonces, los autoencoders apilados tratan de proporcionar un método de pre-entrenamiento eficaz para inicializar los pesos de una red, dejándote con un complejo perceptrón multicapa, que está listo para entrenar (o hacer ajuste fino).

Las Redes de Creencias Profundas

Al igual que con autoencoders, también podemos apilar máquinas de Boltzmann, para crear una clase conocida como redes de creencias profundas (DBN).
Deep belief networks are comprised of a stack of Boltzmann machines.
En este caso, la capa oculta de la MBR t actúa como una capa visible de MBR t + 1. La capa de entrada de la primera MBR es la capa de entrada para toda la red, y la greedy layer-wise de pre-entrenamiento funciona así:
  1. Capacita la primera MBR t=1, utilizando divergencia contrastiva con todas las muestras de entrenamiento.
  2. Capacita la segunda MBR t=2. Puesto que la capa visible para t=2 es la capa oculta de t=1, la formación comienza por sujetar la muestra de entrada a la capa visible de t=1, la cual se propaga hacia adelante a la capa oculta de t=1. Estos datos sirven, posteriormente, para iniciar el entrenamiento de divergencia contrastiva para t=2.
  3. Repite el procedimiento anterior para todas las capas.
  4. Al igual que en los autoencoders apiladas, después de pre-entrenar, la red se puede ampliar mediante la conexión de una o más capas completamente conectadas a la capa oculta final MBR. Esto forma un perceptrón de múltiples capas que puede ser afinado mediante propagación hacia atrás.
Este procedimiento es similar al de autoencoders apilados, pero con los autoencoders siendo reemplazados por MBR, y la propagación hacia atrás es reemplazada con el algoritmo de divergencia contrastiva.
(Nota: para más información sobre la construcción y entrenamiento de autoencoders apilados o redes de creencias profundas, visita el código de ejemplo aquí.)

Redes Convolucionales

Como arquitectura final de aprendizaje profundo, vamos a echar un vistazo a las redes convolucionales, una clase particularmente interesante y especial de las redes feedforward, que están muy bien adaptadas al reconocimiento de imágenes.
Convolutional networks are a special class of deep learning feedforward networks.Image via DeepLearning.net
Antes de examinar la estructura real de las redes convolucionales, en primer lugar definiremos un filtro de imagen o una región cuadrada con pesos asociados. Un filtro se aplica a través de una imagen de entrada completa, y a menudo aplicarás varios filtros. Por ejemplo, podrías aplicar cuatro filtros de 6x6 a una imagen de entrada dada. Luego, el píxel de salida con coordenadas 1,1 es la suma ponderada de un cuadrado de 6x6 píxeles de entrada, con la esquina superior izquierda de 1,1 y los pesos del filtro (que también es un cuadrado 6x6). Pixel de salida de 2,1 es el resultado del cuadrado de entrada, con la esquina superior izquierda de 2,1 y así sucesivamente.
Con esto revisado, estas redes se definen por las siguientes propiedades:
  • Las capas convolucionales aplican una serie de filtros a la entrada. Por ejemplo, la primera capa de convolución de la imagen podría tener cuatro filtros de 6x6. El resultado de un filtro aplicado a través de la imagen, se denomina mapa de características (FM) y la cantidad de mapas de función es igual al número de filtros. Si la capa anterior también es convolucional, los filtros se aplican en todas las FM con diferentes pesos, por lo que cada FM de entrada está conectado a cada FM de salida. La intuición detrás de los pesos compartidos a través de la imagen es que, se detectarán las características independientemente de su ubicación, mientras que la multiplicidad de filtros permite a cada uno de ellos detectar un conjunto diferente de características.
  • Las capas submuestreo reducen el tamaño de la entrada. Por ejemplo, si la entrada consiste de una imagen 32x32, y la capa tiene una región de submuestreo de 2x2, el valor de salida sería una imagen de 16x16, lo que significa que 4 pixeles (cada cuadrado de 2x2) de la imagen de entrada se combinan en un píxel de una sola salida. Existen múltiples maneras de submuestra, pero los más populares son el pooling máximopooling promedio, y pooling estocástico.
  • La última capa de submuestreo (o convolucional) suele estar relacionada con una o más capas totalmente conectadas, la última de las cuales representa los datos de objetivo.
  • El entrenamiento se realiza usando propagación hacia atrás modificada, la cual toma en cuenta las capas de submuestreo y actualiza los pesos de filtro convolucional, basándose en todos los valores a los que se aplica dicho filtro.
Se pueden ver varios ejemplos de redes convolucionales entrenadas (con propagación hacia atrás) en el conjunto de datos MNIST (imágenes en escala de grises de cartas escritas a mano) aquí, específicamente en los métodos testLeNet* (recomendaría testLeNetTiny2, ya que logra una baja tasa de error de alrededor del 2% en un período de tiempo relativamente corto). También hay una agradable visualización JavaScript de una red similar aquí.

Implementación

Ahora que hemos revisado las variantes de la red neural más comunes, me gustaría escribir un poco sobre los desafíos planteados durante la ejecución de estas estructuras profundas de aprendizaje.
En términos generales, mi objetivo en la creación de una biblioteca de aprendizaje profundo era (y sigue siendo) construir un marco basado en una red neuronal, que cumpliera con los siguientes criterios:
  • Una arquitectura común capaz de representar diversos modelos (todas las variantes en las redes neuronales que hemos visto anteriormente, por ejemplo).
  • La capacidad de utilizar diversos algoritmos de entrenamiento (de propagación hacia atrás, divergencia contrastiva, etc.).
  • Rendimiento decente.
Para satisfacer estos requisitos, tomé un enfoque escalonado (o modular) para el diseño de software.

Estructura

Empecemos con lo básico:
  • NeuralNetworkImpl es la clase base para todos los modelos de redes neuronales.
  • Cada red contiene un conjunto de capas.
  • Cada capa tiene una lista de conexiones, donde una conexión es una relación entre dos capas, de tal manera que la red es un gráfico acíclico dirigido.
Esta estructura es lo suficientemente ágil para ser utilizada para las clásicas redes feedforward, así como para MBR y arquitecturas más complejas como ImageNet.
También permite que una capa sea parte de más de una red. Por ejemplo, las capas en una red de creencia profunda también son capas en sus correspondientes MBR.
Además, esta arquitectura permite a un DBN ser visto como una lista de MBR apilados durante la fase de pre-entrenamiento, y como una red feedforward durante la fase de ajuste fino, que es intuitivamente agradable, al igual que programáticamente conveniente.

Propagación de Datos

El siguiente módulo se encarga de la propagación de datos a través de la red, un proceso de dos pasos:
  1. Determina el orden de las capas. Por ejemplo, para conseguir los resultados de un perceptrón de múltiples capas, los datos son “sujetados” a la capa de entrada (por lo tanto, esta es la primera capa que se calcula) y propagados hasta el final a la capa de salida. Para actualizar los pesos durante la propagación hacia atrás, el error de salida tiene que ser propagado a través de cada capa en orden de anchura, a partir de la capa de salida. Esto se consigue utilizando diferentes implementaciones de LayerOrderStrategy, que se aprovecha de la estructura gráfica de la red, empleando diferentes métodos de gráfico de recorrido. Algunos ejemplos incluyen la estrategia de anchura y la ubicación de una capa específica. El orden es en realidad determinado por las conexiones entre las capas, por lo que las estrategias regresan una lista ordenada de conexiones.
  2. Calcula el valor de activación. Cada capa tiene una Calculadora de Conexión asociada, que toma su lista de conexiones (de la etapa anterior) y los valores de entrada (de otras capas) y calcula la activación resultante. Por ejemplo, en una simple red feedforward sigmoidal, la calculadora de conexión de la capa oculta toma los valores de las capas de entrada y sesgo (bias) (que son, respectivamente, los datos de entrada y una serie de 1s) y los pesos entre las unidades (en los casos de capas completamente conectadas, los pesos son, en realidad, almacenados en una conexión FullyConnected como un Matrix), calcula la suma ponderada, y alimenta el resultado a la función sigmoide. Las calculadoras de conexión implementan una variedad de transferencia (por ejemplo, suma ponderada, convolucional) y la funciones de (por ejemplo, logistic y tanh para perceptrón multicapa, binario para RMB) activación. La mayoría de ellos se pueden ejecutar en una GPU usando Aparapi y se puede usar con el entrenamiento mini-batch.

Computación GPU con Aparapi

Como mencioné anteriormente, una de las razones por las que las redes neuronales han hecho un resurgimiento en los últimos años, es que sus métodos de entrenamiento son muy propicios para el paralelismo, lo que le permite acelerar el entrenamiento de manera significativa, con el uso de un GPGPU. En este caso, decidí trabajar con la biblioteca Aparapi para añadir soporte GPU.
Aparapi impone algunas restricciones importantes sobre las calculadoras de conexión:
  • Sólo se permiten matrices unidimensionales (y variables) de los tipos de datos primitivos.
  • Sólo los miembros del método de la clase Aparapi Kernel, tienen permitido ser llamados desde el código ejecutable GPU.
Así, la mayoría de los datos (pesos, entrada, y las matrices de salida) se almacenan en las instancias Matrix, que utilizan matrices de flotador unidimensionales, internamente. Todas las calculadoras de conexión Aparapi utilizan ya sea AparapiWeightedSum (para capas completamente conectadas y funciones de entrada de suma ponderada), AparapiSubsampling2D (para capas de submuestreo), o AparapiConv2D (para capas convolucionales). Algunas de estas limitaciones se pueden superar con la introducción de la Arquitectura del Sistema heterogéneo (HSA). Aparapi también permite ejecutar el mismo código en ambos CPU y GPU.

Entrenamiento

El módulo de entrenamiento implementa diversos algoritmos de entrenamiento. Se basa en los dos módulos anteriores. Por ejemplo, BackPropagationTrainer (todos los entrenadores están utilizando el Trainer de la clase base) utiliza la calculadora capa feedforward para la fase feedforward y una calculadora especial de capa de anchura, para propagar el error y la actualización los pesos.
Mi último trabajo es el de apoyo de Java 8 y algunas otras mejoras, que están disponibles en esta rama y pronto se fusionaran con maestro.

Conclusión

El objetivo de este tutorial de aprendizaje profundo de Java era darle una breve introducción al campo de los algoritmos de aprendizaje profundo, comenzando con la unidad más básica de la composición (el perceptrón) y avanzando a través de diversas arquitecturas eficaces y populares, como la de máquina Boltzmann restringida.
Las ideas detrás de las redes neuronales han existido desde hace mucho tiempo; pero hoy en día, no se puede poner un pie en la comunidad de aprendizaje automático sin escuchar acerca de las redes profundas o alguna otra opinión sobre el aprendizaje profundo. La moda no se debe confundir con justificación, pero con los avances de la computación GPGPU y el impresionante progreso realizado por investigadores como Geoffrey Hinton, Yoshua Bengio, Yann LeCun y Andrew Ng, el campo sin duda muestra gran promesa. No hay mejor momento para familiarizarse e involucrarse como el actual.

Apéndice: Recursos

Si estás interesado en aprender más, encontré los siguientes recursos, muy útiles, durante mi trabajo:
Artículo vía Toptal

Déjame tus dudas y comentarios: Conversion Conversion Emoticon Emoticon

Entradas Populares