Existen varias funciones de pérdida (loss) que se usan comúnmente en redes.
Mean Squared Error, su formulación es:
$$ \text{MSE} = \frac{\sum_{i=1}^{m} (\hat{y}_i - y_i)^2}{m} $$Entropía cruzada binaria o Binary Cross Entropy:
$$ \text{CE} = - \sum_{i=1}^{m} y_i log(\hat{y}_i) + (1-y_i) log(1-\hat{y}_i) $$Entropía cruzada categórica o Categorical Cross Entropy:
$$ \text{CE} = - \sum_{c=1}^{C} y_c log(\hat{y}_c)$$La primera cantidad que es útil para rastrear durante el entrenamiento es la pérdida, ya que se evalúa en los lotes individuales durante la fase hacia adelante del algoritmo de aprendizaje. El gráfico de pérdida muestra cómo va evoulcionando el aprendizaje.
La segunda cantidad importante a seguir durante el entrenamiento de un clasificador es la precisión de validación / entrenamiento. Esta gráfica puede dar información valiosa sobre la cantidad de sobreajuste en el modelo.
La forma más simple de actualización es cambiar los parámetros a lo largo de la dirección negativa del gradiente
x += - learning_rate * dx
Se introduce la variable $v$ o velocidad, inicializada a 0, y la constante $mu$ que respresenta un factor de fricción, normalmente inicializada a $0.9$.
v = mu * v - learning_rate * dx # integrate velocity x += v # integrate position
Nesterov Momentum es una versión ligeramente diferente de la actualización con momento que recientemente ha ido ganando popularidad. Goza de mayores garantías teóricas de convergencia para las funciones convexas y, en la práctica, también funciona un poco mejor que el momento estándar.
La idea detrás del momento de Nesterov es que cuando el punto actual está en alguna posición $x$, podemos calcular el gradiente no en ese punto sino en el que obtendremos después de aplicar el momento.
x_ahead = x + mu * v v = mu * v - learning_rate * dx_ahead x += v
Reducir la tasa de aprendizaje por algún factor cada pocas épocas. Los valores típicos pueden reducir la velocidad de aprendizaje a la mitad cada 5 épocas, o 0.1 cada 20 épocas. Estos números dependen en gran medida del tipo de problema y del modelo. Una heurística que se puede ver en la práctica es observar el error de validación mientras se entrena con una velocidad de aprendizaje fija, y reducir la velocidad de aprendizaje en una constante (por ejemplo, 0.5) cada vez que el error de validación deje de mejorar.
Se trata de ir rebajando la tasa de aprendizaje de forma exponencial. $\alpha_{0}$ y $k$ son hiperparámetros.
$\alpha = \alpha_0 e^{-kt} $
$\alpha_{0}$ y $k$ son hiperparámetros.
$\alpha = \frac{\alpha_0}{1 + kt} $
Observa que la variable caché
tiene un tamaño igual al tamaño del gradiente y realiza un seguimiento de la suma por parámetro de los gradientes cuadrados. Esto se usa para normalizar el paso de actualización de parámetros, de forma elemental. Hay que tener en cuenta que los pesos que reciben altos gradientes tendrán una tasa de aprendizaje efectiva reducida, mientras que los pesos que reciben actualizaciones pequeñas o poco frecuentes tendrán una tasa de aprendizaje efectiva mayor. Curiosamente, la operación de la raíz cuadrada resulta ser muy importante y, sin ella, el algoritmo funcionaría mucho peor. El término de suavizado eps (generalmente establecido en un rango de 1e-4 a 1e-8) evita la división por cero. Un inconveniente de Adagrad es que, en el caso del Aprendizaje Profundo, la tasa de aprendizaje monotónica decreciente generalmente resulta demasiado agresiva y deja de aprender demasiado pronto.
cache += dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)
La actualización RMSProp ajusta el método de Adagrad de una manera muy simple en un intento por reducir la agresividad de la tasa de aprendizaje monótonamente decreciente.
cache = decay_rate * cache + (1 - decay_rate) * dx**2
x += - learning_rate * dx / (np.sqrt(cache) + eps)
Se parece a la actualización RMSProp pero con impulso. Este mecanismo de actualización (simplificado) tiene el siguiente aspecto:
m = beta1*m + (1-beta1)*dx
v = beta2*v + (1-beta2)*(dx**2)
x += - learning_rate * m / (np.sqrt(v) + eps)