Redes neuronales con Python

Redes neuronales con Python

JoaquĂ­n Amat Rodrigo
Mayo, 2021

Introducción


El Ă¡mbito de las redes neuronales y su hermano mayor, el deep learning, es complejo y amplio. Durante los Ăºltimos años, el interĂ©s y la aplicaciĂ³n de este tipo de modelos han experimentado tal expansiĂ³n que se ha convertido en una disciplina por sĂ­ misma. Si bien entender bien sus fundamentos requiere de una cantidad notable de tiempo y prĂ¡ctica, esto no significa que se necesiten adquirir todos ellos para empezar a sacarles partido; del mismo modo que no es necesario conocer el funcionamiento de todos los componentes de un smart phone (procesador, antena, circuitos...) para utilizarlo de forma productiva (hacer fotos, mandar email, navegar por internet...). En este documento se presenta una introducciĂ³n, mĂ¡s intuitiva que rigurosa, sobre los modelos de redes neuronales y de cĂ³mo crearlos con python.

En el ecosistema de python, existen mĂºltiples librerĂ­as que permiten crear modelos basados en redes neuronales. Conviene diferenciar entre dos casos de uso ya que, dependiendo de estos, son mĂ¡s adecuadas unas librerĂ­as u otras:

  • Modelos de redes simples (multi-perceptrĂ³n): estos modelos se caracterizan por tener arquitecturas relativamente sencillas por lo que los requerimientos computacionales no son elevados y no es necesario el uso el uso de GPUs. Dentro de este grupo destacan las implementaciones de Scikit-learn y H2O)

  • Deep learning: son modelos mĂ¡s complejos (redes convolucionales, redes recurrentes, LSTM...) cuyos requerimientos computacionales hacen necesario el uso de GPUs. Para este tipo de modelos se tiene que recurrir a frameworks especializados para como Tensorflow-Keras o Pytorch.

Los ejemplos de este documento se corresponden con el primer caso de uso, por lo que se utiliza la librerĂ­a Scikit-learn para crear los modelos.

Redes neuronales


Estructura de la red


Las redes neuronales son modelos creados al ordenar operaciones matemĂ¡ticas siguiendo una determinada estructura. La forma mĂ¡s comĂºn de representar la estructura de una red neuronal es mediante el uso de capas (layers), formadas a su vez por neuronas (unidades, units o neurons). Cada neurona, realiza una operaciĂ³n sencilla y estĂ¡ conectada a las neuronas de la capa anterior y de la capa siguiente mediante pesos, cuya funciĂ³n es regular la informaciĂ³n que se propaga de una neurona a otra.

RepresentaciĂ³n de una red neuronal feed-forward (single-layer perceptron). Fuente: Computer Age Statistical Inference 2016

La primera capa de la red neuronal (color verde) se conoce como capa de entrada o input layer y recibe los datos en bruto, es decir, el valor de los predictores. La capa intermedia (color azul), conocida como capa oculta o hidden layer, recibe los valores la capa de entrada, ponderados por los pesos (flechas grises). La Ăºltima capa, llamada output layer, combina los valores que salen de la capa intermedia para generar la predicciĂ³n.

Para facilitar la comprensiĂ³n de la estructura de las redes, es Ăºtil representar una red equivalente a un modelo de regresiĂ³n lineal.

$$y = w_1 x_1 + ... + w_d x_d + b$$
RepresentaciĂ³n de una red neuronal equivalente a un modelo lineal con 4 predictores. Fuente: COMS W4995 Applied Machine Learning

Cada neurona de la capa de entrada representa el valor de uno de los predictores. Las flechas representan los coeficientes de regresiĂ³n, que en tĂ©rminos de redes se llaman pesos, y la neurona de salida representa el valor predicho. Para que esta representaciĂ³n equivalga a la ecuaciĂ³n de un modelo lineal, faltan dos cosas:

  • El bias del modelo.

  • Las operaciones de multiplicaciĂ³n y suma que combinan el valor de los predictores con los pesos del modelo.

La capa intermedia de una red tiene un valor de bias, pero suele omitirse en las representaciones grĂ¡ficas. En cuanto a las operaciones matemĂ¡ticas, es el elemento clave que ocurre dentro de las neuronas y conviene verlo con detalle.

La neurona (unidad)


La neurona es la unidad funcional de los modelos de redes. Dentro de cada neurona, ocurren simplemente dos operaciones: la suma ponderada de sus entradas y la aplicaciĂ³n de una funciĂ³n de activaciĂ³n.

En la primera parte, se multiplica cada valor de entrada $x_i$ por su peso asociado $w_i$ y se suman junto con el bĂ­as. Este es el valor neto de entrada a la neurona. A continuaciĂ³n, este valor se pasa por una funciĂ³n, conocida como funciĂ³n de activaciĂ³n, que transforma el valor neto de entrada en un valor de salida.

Si bien el valor que llega a la neurona, multiplicaciĂ³n de los pesos por las entradas, siempre es una combinaciĂ³n lineal, gracias a la funciĂ³n de activaciĂ³n, se pueden generar salidas muy diversas. Es en la funciĂ³n de activaciĂ³n donde reside el potencial de los modelos de redes para aprender relaciones no lineales.

RepresentaciĂ³n de una neurona. Fuente: Deep Learning A Practitioner’s Approach by Josh Patterson and Adam Gibson

La anterior ha sido una explicaciĂ³n intuitiva del funcionamiento de una neurona. VĂ©ase ahora una definiciĂ³n mĂ¡s matemĂ¡tica.

El valor neto de entrada a una neurona es la suma de los valores que le llegan, ponderados por el peso de las conexiones, mĂ¡s el bias.

$$entrada = \sum^n_{i=1} x_i w_i + b$$

En lugar de utilizando el sumatorio, esta operaciĂ³n suele representarse como el producto matricial, donde $\textbf{X}$ representa el vector de los valores de entrada y $\textbf{W}$ el vector de pesos.

$$entrada = \textbf{X}\textbf{W} + b$$

A este valor se le aplica una funciĂ³n de activaciĂ³n ($g$) que lo transforma en lo que se conoce como valor de activaciĂ³n ($a$), que es lo que finalmente sale de la neurona.

$$a = g(entrada) = g(\textbf{X}\textbf{W} + b)$$

Para la capa de entrada, donde Ăºnicamente se quiere incorporar el valor de los predictores, la funciĂ³n de activaciĂ³n es la unidad, es decir, sale lo mismo que entra. En la capa de salida, la funciĂ³n de activaciĂ³n utilizada suele ser la identidad para problemas de regresiĂ³n y soft max para clasificaciĂ³n.

Función de activación


Las funciones de activaciĂ³n controlan en gran medida que informaciĂ³n se propaga desde una capa a la siguiente (forward propagation). Estas funciones convierten el valor neto de entrada a la neuronal, combinaciĂ³n de los input, pesos y bĂ­as, en un nuevo valor. Es gracias combinar funciones de activaciĂ³n no lineales con mĂºltiples capas (ver mĂ¡s adelante), que los modelos de redes son capaces de aprender relaciones no lineales.

La gran mayorĂ­a de funciones de activaciĂ³n convierten el valor de entrada neto de la neurona en un valor dentro del rango (0, 1) o (-1, 1). Cuando el valor de activaciĂ³n de una neurona (salida de su funciĂ³n de activaciĂ³n) es cero, se dice que la neurona estĂ¡ inactiva, ya que no pasa ningĂºn tipo de informaciĂ³n a las siguientes neuronas. A continuaciĂ³n, se describen las funciones de activaciĂ³n mĂ¡s empleadas.

Rectified linear unit (ReLU)

La funciĂ³n de activaciĂ³n ReLu aplica una transformaciĂ³n no lineal muy simple, activa la neurona solo si el input estĂ¡ por encima de cero. Mientras el valor de entrada estĂ¡ por debajo de cero, el valor de salida es cero, pero cuando es superior de cero, el valor de salida aumenta de forma lineal con el de entrada.

$$\operatorname{ReLU}(x) = \max(x, 0)$$

De esta forma, la funciĂ³n de activaciĂ³n retiene Ăºnicamente los valores positivos y descarta los negativos dĂ¡ndoles una activaciĂ³n de cero.

RepresentaciĂ³n funciĂ³n activaciĂ³n ReLU.

ReLU es con diferencia la funciĂ³n de activaciĂ³n mĂ¡s empleada, por sus buenos resultados en aplicaciones diversas. La razĂ³n de esto reside en el comportamiento de su derivada (gradiente), que es cero o constante, evitando asĂ­ un problema conocido como vanishing gradients que limita la capacidad de aprendizaje de los modelos de redes.



Sigmoide

La funciĂ³n sigmoide transforma valores en el rango de (-inf, +inf) a valores en el rango (0, 1).

$$\operatorname{sigmoid}(x) = \frac{1}{1 + \exp(-x)}$$
RepresentaciĂ³n funciĂ³n activaciĂ³n sigmoide.

Aunque la funciĂ³n de activaciĂ³n sigmoide se utilizĂ³ mucho en los inicios de los modelos de redes, en la actualidad, suele preferirse la funciĂ³n ReLU.

Un caso en el que la funciĂ³n de activaciĂ³n sigmoide sigue siendo la funciĂ³n utilizada por defecto es en las neuronas de la capa de salida de los modelos de clasificaciĂ³n binaria, ya que su salida puede interpretarse como probabilidades.

Tangente hiperbĂ³lica (Tanh)

La funciĂ³n de activaciĂ³n Tanh, se comporta de forma similar a la funciĂ³n sigmoide, pero su salida estĂ¡ acotada en el rango (-1, 1).

$$\operatorname{tanh}(x) = \frac{1 - \exp(-2x)}{1 + \exp(-2x)}$$



Sin las funciones de activaciĂ³n, las redes neuronales solo pueden aprender relaciones lineales.

Función de coste (loss function)


La funciĂ³n de coste ($l$), tambiĂ©n llamada funciĂ³n de pĂ©rdida, loss function o cost function, es la encargada de cuantificar la distancia entre el valor real y el valor predicho por la red, en otras palabras, mide cuĂ¡nto se equivoca la red al realizar predicciones. En la mayorĂ­a de casos, la funciĂ³n de coste devuelve valores positivos. Cuanto mĂ¡s prĂ³ximo a cero es el valor de coste, mejor son las predicciones de la red (menor error), siendo cero cuando las predicciones se corresponden exactamente con el valor real.

La funciĂ³n de coste puede calcularse para una Ăºnica observaciĂ³n o para un conjunto de datos (normalmente promediando el valor de todas las observaciones). El segundo caso, es el que se utiliza para dirigir el entrenamiento de los modelos.

Dependiendo del tipo de problema, regresiĂ³n o clasificaciĂ³n, es necesario utilizar una funciĂ³n de coste u otra. En problemas de regresiĂ³n, las mĂ¡s utilizadas son el error cuadrĂ¡tico medio y el error absoluto medio. En problemas de clasificaciĂ³n suele emplearse la funciĂ³n log loss, tambiĂ©n llamada logistic loss o cross-entropy loss.

Error cuadrĂ¡tico medio

El error cuadrĂ¡tico medio (mean squared error, MSE) es con diferencia la funciĂ³n de coste mĂ¡s utilizada en problemas de regresiĂ³n. Para una determinada observaciĂ³n $i$, el error cuadrĂ¡tico se calcula como la diferencia al cuadrado entre el valor predicho $\hat{y}$ y el valor real $y$.

$$l^{(i)}(\mathbf{w}, b) = \left(\hat{y}^{(i)} - y^{(i)}\right)^2$$

Las funciones de coste suelen escribirse con la notaciĂ³n $l(\mathbf{w}, b)$ para hacer referencia a que su valor depende de los pesos y bias del modelo, ya que son estos los que determinan el valor de las predicciones $y^{(i)}$.

Con frecuencia, esta funciĂ³n de coste se encuentra multiplicada por $\frac{1}{2}$, esto es simplemente por conveniencia matemĂ¡tica para simplificar el cĂ¡lculo de su derivada.

$$l^{(i)}(\mathbf{w}, b) = \frac{1}{2} \left(\hat{y}^{(i)} - y^{(i)}\right)^2$$

Para cuantificar el error que comete el modelo todo un conjunto de datos, por ejemplo los de entrenamiento, simplemente se promedia el error de todas las $N$ observaciones.

$$L(\mathbf{w}, b) =\frac{1}{n}\sum_{i=1}^n l^{(i)}(\mathbf{w}, b) = \frac{1}{n}\sum_{i=1}^n \left(\hat{y}^{(i)} - y^{(i)}\right)^2$$

Cuando un modelo se entrena utilizando el error cuadrĂ¡tico medio como funciĂ³n de coste, estĂ¡ aprendiendo a predecir la media de la variable respuesta.



Error medio absoluto

El error medio absoluto (mean absolute error, MAE) consiste en promediar el error absoluto de las predicciones.

$$L(\mathbf{w}, b) =\frac{1}{n}\sum_{i=1}^n |\hat{y}^{(i)} - y^{(i)}|$$

El error medio absoluto es mĂ¡s robusto frente a outliers que el error cuadrĂ¡tico medio. Esto significa que el entrenamiento del modelo se ve menos influenciado por datos anĂ³malos que pueda haber en el conjunto de entrenamiento. Cuando un modelo se entrena utilizando el error absoluto medio como funciĂ³n de coste, estĂ¡ aprendiendo a predecir la mediana de la variable respuesta.



Log loss, logistic loss o cross-entropy loss

En problemas de clasificaciĂ³n, la capa de salida utiliza como funciĂ³n de activaciĂ³n la funciĂ³n softmax. Gracias a esta funciĂ³n, la red devuelve una serie de valores que pueden interpretarse como la probabilidad de que la observaciĂ³n predicha pertenezca a cada una de las posibles clases.

Cuando la clasificaciĂ³n es de tipo binaria, donde la variable respuesta es 1 o 0, y $p = \operatorname{Pr}(y = 1)$, la funciĂ³n de coste log-likelihood se define como:

$$L_{\log}(y, p) = -\log \operatorname{Pr}(y|p) = -(y \log (p) + (1 - y) \log (1 - p))$$

Para problemas de clasificaciĂ³n con mĂ¡s de dos clases, esta fĂ³rmula se generaliza a:

$$L_{\log}(Y, P) = -\log \operatorname{Pr}(Y|P) = - \frac{1}{N} \sum_{i=0}^{N-1} \sum_{k=0}^{K-1} y_{i,k} \log p_{i,k}$$

En ambos casos, minimizar esta la funciĂ³n equivale a que la probabilidad predicha para la clase correcta tienda a 1, y a 0 en las demĂ¡s clases.

Dado que esta funciĂ³n se ha utilizado en campos diversos, se le conoce por nombres distintos: Log loss, logistic loss o cross-entropy loss, pero todos hacen referencia a lo mismo. Puede encontrarse una explicaciĂ³n mĂ¡s detallada de esta funciĂ³n de coste aquĂ­.

Múltiples capas


El modelo de red neuronal con una Ăºnica capa (single-layer perceptron), aunque supuso un gran avance en el campo del machine learning, solo es capaz de aprender patrones sencillos. Para superar esta limitaciĂ³n, los investigadores descubrieron que, combinando mĂºltiples capas ocultas, la red puede aprender relaciones mucho mĂ¡s complejas entre los predictores y la variable respuesta. A esta estructura se le conoce como perceptrĂ³n multicapa o multilayer perceptron (MLP), y puede considerarse como el primer modelo de deep learning.

La estructura de un perceptĂ³n multicapa consta de varias capas de neuronas ocultas. Cada neurona estĂ¡ conectada a todas las neuronas de la capa anterior y a las de la capa posterior. Aunque no es estrictamente necesario, todas las neuronas que forman parte de una misma capa suelen emplear la misma funciĂ³n de activaciĂ³n.

Combinando mĂºltiples capas ocultas y funciones de activaciĂ³n no lineales, los modelos de redes pueden aprender prĂ¡cticamente cualquier patrĂ³n. De hecho, estĂ¡ demostrado que, con suficientes neuronas, un MLP es un aproximador universal para cualquier funciĂ³n.