Clase 3: Feed Forward Networks
Son redes neuronales que se caracterizan por tener una arquitectura en la que la información fluye en una sola dirección, desde las entradas hasta las salidas. En general todas las neuronas de una capa están conectadas a todas las neuronas de la siguiente capa, sin ciclos ni conexiones recurrentes.
Una red neuronal feedforward con al menos una capa oculta y un número finito de neuronas, usando funciones de activación no lineales (como sigmoide, tanh o ReLU), puede aproximar cualquier función continua definida en un conjunto compacto (acotado y cerrado) de \(\mathbb{R}^n\) a cualquier nivel de precisión, siempre que se utilicen suficientes neuronas y se ajusten adecuadamente los pesos y sesgos.
Importante
Este tipo de Redes tiene distintos nombres que son usados de manera intercambiable:
De ahora en adelante utilizaremos las siguiente notación para referirnos a una Red Neuronal Feed Forward:
\[h_\theta(X) = \sigma_s(Z)\]
Logits
Definiremos \(Z=\phi_L(X) W_{L+1} + b_{L+1}^T\) como Logits y corresponden a las activaciones de la última capa antes de aplicar la función de activación de salida \(\sigma_s(.)\).
Son las configuraciones externas que no se aprenden durante el entrenamiento, sino que se definen antes de entrenar el modelo y controlan su comportamiento y rendimiento.
🤓 Hiperparámetros de una Red Neuronal
En el aprendizaje supervisado se abordan principalmente dos tipos de problemas: clasificación y regresión. Según el tipo de problema, la hipótesis debe adoptar una forma distinta en la capa de salida.
⚠️ Dimensión de Salida
Está definida por el número de valores a predecir para cada observación. Denominaremos \(k\) como la dimensión de salida.
Para una red de dos capas:
\[\phi_0(X) = X\] \[\phi_1(X) = \sigma_1(W_1 \cdot \phi_0(X) + \bar{b_1}^T)\] \[\phi_2(X) = \sigma_2(W_2 \cdot \phi_1(X) + \bar{b_2}^T)\]
Donde \(W_1 \in \mathbb{R}^{n \times d_1}\) y \(W_2 \in \mathbb{R}^{d_1 \times k}\) y \(b_1 \in \mathbb{R}^{d_1}\) y \(b_2 \in \mathbb{R}^{k}\).
✅ Activación de la Salida
Según el tipo de problema, la capa de salida puede necesitar una función de activación particular que ajuste los resultados al formato correcto. En este sentido, \(\sigma_2\) estará determinada por la naturaleza del problema a resolver.
Clasificación Binaria
El approach más común utiliza \(k=1\) con una Sigmoide para calcular la probabilidad de la clase 1. Otros approach utilizan \(k=2\) para calcular la probabilidad de ambas clases (Activando con Softmax).
Clasificación Multiclase
Utiliza \(k=C\) donde C es el número de clases a clasificar. Se usa una función Softmax para transformar el output en una distribución de probabilidades.
Clasificación Multilabel
Se requiere un \(k=C\) donde C es el número de clases a clasificar. Se usa una función Sigmoide para transformar cada clase en probabilidades.
Regresión Simple
Se requiere un \(k=1\). Típicamente no requiere de funciones adicionales aunque a veces se agregan funciones para acotar la salida.
Regresión Multiple
Se requiere un \(k=V\) con V el número de valores a predecir. Se deben tener las mismas consideraciones para acotar la salida.
👀 Muy Importante
En la mayoría de las implementaciones en Código la activación de la salida va embebida en la Loss Function. Por lo tanto, no es necesario aplicar una función de activación explícita en la capa de salida. Aunque sí deben aplicarse al momento de la Predicción del modelo.
🤓 Convención para Código
En Pytorch, nunca aplicaremos una función de activación a la capa de salida.
Cuidado
Otros frameworks como Tensorflow, Keras, etc. utilizan una convención distinta y aplican funciones de activación a la capa de salida.
¿Puedo aplicar distintas Funciones de Activación a cada Neurona?
Puedo, pero no se hace. Complicaría muchísimo la implementación.
Definición
\[\sigma(z) = \frac{1}{1 + e^{-z}}\]
Propiedades
Definición
\[S_i(z) = \frac{e^{z_i}}{\sum_{j=1}^k e^{z_j}}\]
Propiedades
Definición
\[Tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}\]
Propiedades
Redes Recurrentes
(RNNs).Definición
\[ReLU(z) = max(0, z)\]
Propiedades
Redes Convolucionales
(CNNs).Son las encargadas de medir el error entre la predicción del modelo y el valor real. En general, se busca minimizar la Loss Function durante el entrenamiento del modelo.
Clasificación Binaria: Binary Cross Entropy
\[BCE(Z) = - \frac{1}{m}\left[y^T log(\sigma(Z)) + (1-y)^T log(1-\sigma(Z))\right]\]
Donde \(Z\) corresponden a los Logits del Modelo.
En Pytorch esta función se llama BCEWithLogitsLoss
.
🤓 Logits
Se refiere a las activaciones finales del modelo antes de aplicar la función de activación.
👊 Clasificación Multilabel: BCEWithLogitsLoss
En Pytorch se suele utilizar BCEWithLogitsLoss
ya que combina una sigmoide a cada activación de la salida.
Clasificación Multiclase: CrossEntropy
\[CE(Z)= \frac{1}{m}Tr(Y^T \hat{Y})\]
Donde \(Tr(.)\) es la traza de una matriz e \(Y \in \{0,1\}^{m \times k}\) es la codificación One-Hot de las etiquetas y \(\hat{Y} = Softmax(Z)\), donde \(Z\) son los Logits del modelo.
🤓 Traza (\(Tr(.)\))
Corresponde a la suma de los elementos de la diagonal principal de una matriz.
Derivada
\[\frac{\partial CE(X)}{\partial Z} = \frac{1}{m}\left(Softmax(Z) - Y\right)\]
En Pytorch se suele utilizar CrossEntropyLoss
ya que combina aplica una función Softmax a la capa de salida además de ser una clase numericamente más estable.
Regresión: Mean Squared Error (MSELoss)
\[MSE(Z) = \frac{1}{m}||Z - \bar{y}||^2\]
Donde \(||.||\) corresponde a la norma Euclideana e \(\bar{y} \in \mathbb{R}^{m \times 1}\).
Derivada
\[\frac{\partial MSE(Z)}{\partial Z} = \frac{2}{m}(Z - \bar{y})\]
Regresión: Mean Absolute Error (L1Loss)
\[L1Loss(Z) = \frac{1}{m}|Z - \bar{y}|\]
Donde \(||.||\) corresponde a la norma Euclideana y \(\bar{y} \in \mathbb{R}^{m \times 1}\).
Derivada
\[\frac{\partial L1Loss(Z)}{\partial Z} = \frac{1}{m}sign(Z-\bar{y})\]
\[\operatorname{sign}(z) = \begin{cases} +1 & \text{si z > 0},\\[2mm] 0 & \text{si z = 0},\\[1mm] -1 & \text{si z < 0} \end{cases}\]
Gradient Descent corresponde al algoritmo de Optimización más popular, pero no necesariamente el más eficiente. Distintas variantes han ido apareciendo para ir mejorando eventuales deficiencias de la proposición inicial.
Epochs
Corresponden a la cantidad de iteraciones que se realizan a la Update Rule para que el modelo se optimize.
Standard Gradient Descent
\[\theta := \theta - \frac{\alpha}{m}\nabla_\theta L\]
Importante
Los minibatches
permiten estimar el gradiente con un subconjunto de datos, manteniendo la dirección correcta para actualizar los parámetros de manera más eficiente. Se realiza en un subconjunto de \(B\) datos donde \(B << m\).
\[\theta := \theta - \frac{\alpha}{B}\nabla_\theta L\]
👀 Importante
minibatches
para utilizar todos los datos.step
.minibatches
han sido utilizados, se dice que se ha completado una epoch
.minibatch
de tamaño 32, 64 o 128.minibatch
si no tiene el tamaño completo para evitar problemas de estabilidad de graientes.Pros
Contras
\[\theta_{t+1} = \theta_t - \alpha v_{t + 1}\] \[v_{t+1} = \beta v_{t} + (1-\beta) \nabla_\theta L(\theta_{t+1})\]
donde \(0<\beta<1\), pero normalmente \(\beta=0.9\).
☝️ Intuición
\[\begin{align} v_{t+1}&=(1-\beta)\nabla_\theta L(\theta_{t}) + \beta v_t \\ v_{t+1}&=(1-\beta)\nabla_\theta L(\theta_{t}) + \beta \left[(1-\beta) \nabla_\theta L(\theta_{t-1}) + \beta v_{t-1}\right] \\ v_{t+1}&=(1-\beta)\nabla_\theta L(\theta_{t}) + \beta (1-\beta) \nabla_\theta L(\theta_{t-1}) + \beta^2 (1-\beta) \nabla_\theta L(\theta_{t-2})... \\ \end{align}\]
\[\theta_{t+1} = \theta_t - \alpha u_{t + 1}\] \[v_{t + 1} = \beta v_t + (1-\beta) \nabla_\theta f(\theta_{t+1} + \beta v_t)\]
donde \(0<\beta<1\), pero normalmente \(\beta=0.9\).
☝️ Intuición
El método de Nesterov “mira hacia adelante” en la dirección del momentum antes de calcular el gradiente, lo que le da una corrección más precisa y evita en parte el sobrepaso de mínimos. En este caso \(\theta_{t+1} + \beta v_t\) es el punto “futuro” para calcular el gradiente.
☝️ Intuición
☝️ Intuición
¿Qué tal, si el learning rate se va adaptando en el tiempo y deja de ser estática?
\[r_{t+1} = r_t + \nabla_\theta f(\theta_t)^2\] \[\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{r_{t+1}}}\nabla_\theta f(\theta_t)\]
Efecto
Pros
Contras
☝️ Intuición
\[s_{t+1} = \beta r_t + (1-\beta) \nabla_\theta f(\theta_t)^2\] \[\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{s_{t+1}}}\nabla_\theta f(\theta_t)\]
Pros
Contras
☝️ Intuición
Se mantiene el Exponential Moving average para: Los gradientes (como utilizando momentum), los gradientes al cuadrado (como RMSprop).
\[v_{t+1} = \beta_1 v_t + (1-\beta_1) \nabla_\theta f(\theta_t)\] \[s_{t+1} = \beta_2 s_t + (1-\beta_2) \nabla_\theta f(\theta_t)^2\] \[\theta_{t+1} = \theta_t - \frac{\alpha}{\sqrt{s'_{t+1}}} v'_{t+1}\]
\[v'_{t+1} = \frac{v_{t+1}}{1-\beta_1^{t+1}}\] \[s'_{t+1} = \frac{v_{t+1}}{1-\beta_2^{t+1}}\]
Pros
Contras