Descenso de gradiente con impulso desde cero

Descenso de gradiente es un algoritmo de optimización que sigue el gradiente negativo de una función objetivo para localizar el mínimo de la función.

Un problema con el descenso de gradiente es que puede rebotar alrededor del espacio de búsqueda en problemas de optimización que tienen grandes cantidades de curvatura o gradientes ruidosos, y puede atascarse en puntos planos en el espacio de búsqueda que no tienen gradiente.

Impulso es una extensión del algoritmo de optimización del descenso de gradientes que permite que la búsqueda genere inercia en una dirección en el espacio de búsqueda y supere las oscilaciones de gradientes ruidosos y la costa a través de puntos planos del espacio de búsqueda.

En este tutorial, descubrirá el descenso de gradiente con el algoritmo de impulso.


Recomendado: ¿Qué es el Big data?.


Después de completar este tutorial, sabrá:

  • El descenso de gradiente es un algoritmo de optimización que utiliza el gradiente de la función objetivo para navegar por el espacio de búsqueda.
  • El descenso de gradiente se puede acelerar utilizando el impulso de actualizaciones pasadas a la posición de búsqueda.
  • Cómo implementar la optimización del descenso de gradientes con impulso y desarrollar una intuición para su comportamiento.

Empecemos.

Descenso de gradiente con impulso desde cero

Descenso de gradiente con impulso desde cero
Foto de Chris Barnes, algunos derechos reservados.

Descripción general del tutorial

Este tutorial se divide en tres partes; son:

  1. Descenso de gradiente
  2. Impulso
  3. Descenso de gradiente con impulso
    1. Problema de prueba unidimensional
    2. Optimización del descenso de gradientes
    3. Visualización de la optimización del descenso de gradientes
    4. Optimización del descenso de gradientes con impulso
    5. Visualización de la optimización del descenso de gradientes con Momentum

Descenso de gradiente

El descenso de gradientes es un algoritmo de optimización.

Técnicamente se le conoce como un algoritmo de optimización de primer orden, ya que hace uso explícito de la derivada de primer orden de la función objetivo objetivo.

Los métodos de primer orden se basan en la información del gradiente para ayudar a dirigir la búsqueda de un mínimo …

– Página 69, Algoritmos de optimización, 2019.

La derivada de primer orden, o simplemente la “derivado, ”Es la tasa de cambio o pendiente de la función objetivo en un punto específico, p. para una entrada específica.

Si la función de destino toma múltiples variables de entrada, se la denomina función multivariante y las variables de entrada se pueden considerar como un vector. A su vez, la derivada de una función objetivo multivariante también puede tomarse como un vector y se denomina generalmente “gradiente”.

  • Degradado: Derivada de primer orden para una función objetivo multivariante.

La derivada o el gradiente apunta en la dirección del ascenso más pronunciado de la función objetivo para una entrada específica.

El descenso de gradiente se refiere a un algoritmo de optimización de minimización que sigue el negativo del gradiente cuesta abajo de la función objetivo para localizar el mínimo de la función.

El algoritmo de descenso de gradiente requiere una función objetivo que se está optimizando y la función derivada para la función objetivo. La función objetivo F() devuelve una puntuación para un conjunto dado de entradas y la función derivada F'() da la derivada de la función objetivo para un conjunto dado de entradas.

El algoritmo de descenso de gradiente requiere un punto de partida (X) en el problema, como un punto seleccionado al azar en el espacio de entrada.

Luego se calcula la derivada y se da un paso en el espacio de entrada que se espera que resulte en un movimiento cuesta abajo en la función objetivo, asumiendo que estamos minimizando la función objetivo.

Un movimiento cuesta abajo se realiza calculando primero qué tan lejos moverse en el espacio de entrada, calculado como el tamaño del paso (llamado alfa o el tasa de aprendizaje) multiplicado por el gradiente. Esto luego se resta del punto actual, asegurando que nos movemos contra el gradiente o hacia abajo de la función de destino.

  • x = x – tamaño_paso * f ‘(x)

Cuanto más pronunciada sea la función objetivo en un punto dado, mayor será la magnitud del gradiente y, a su vez, mayor será el paso dado en el espacio de búsqueda. El tamaño del paso realizado se escala mediante un hiperparámetro de tamaño de paso.

  • Numero de pie (alfa): Hiperparámetro que controla qué tan lejos moverse en el espacio de búsqueda contra el gradiente en cada iteración del algoritmo, también llamado tasa de aprendizaje.

Si el tamaño del paso es demasiado pequeño, el movimiento en el espacio de búsqueda será pequeño y la búsqueda llevará mucho tiempo. Si el tamaño del paso es demasiado grande, la búsqueda puede rebotar en el espacio de búsqueda y omitir los óptimos.

Ahora que estamos familiarizados con el algoritmo de optimización del descenso de gradientes, echemos un vistazo al impulso.

Impulso

Momentum es una extensión del algoritmo de optimización del descenso de gradientes, a menudo denominado descenso de gradiente con impulso.

Está diseñado para acelerar el proceso de optimización, p. Ej. disminuir el número de evaluaciones de funciones requeridas para alcanzar los óptimos, o para mejorar la capacidad del algoritmo de optimización, p. resultar en un mejor resultado final.

Un problema con el algoritmo de descenso de gradiente es que la progresión de la búsqueda puede rebotar alrededor del espacio de búsqueda según el gradiente. Por ejemplo, la búsqueda puede progresar cuesta abajo hacia los mínimos, pero durante esta progresión, puede moverse en otra dirección, incluso cuesta arriba, dependiendo de la pendiente de puntos específicos (conjuntos de parámetros) encontrados durante la búsqueda.

Esto puede ralentizar el progreso de la búsqueda, especialmente para aquellos problemas de optimización en los que la tendencia o forma más amplia del espacio de búsqueda es más útil que los gradientes específicos en el camino.

Un enfoque para este problema es agregar el historial a la ecuación de actualización de parámetros en función del gradiente encontrado en las actualizaciones anteriores.

Este cambio se basa en la metáfora del impulso de la física donde la aceleración en una dirección se puede acumular a partir de actualizaciones pasadas.

El nombre de momento se deriva de una analogía física, en la que el gradiente negativo es una fuerza que mueve una partícula a través del espacio de parámetros, de acuerdo con las leyes del movimiento de Newton.

– Página 296, Deep Learning, 2016.

Momentum implica agregar un hiperparámetro adicional que controla la cantidad de historial (momentum) para incluir en la ecuación de actualización, es decir, el paso a un nuevo punto en el espacio de búsqueda. El valor del hiperparámetro se define en el rango de 0,0 a 1,0 y, a menudo, tiene un valor cercano a 1,0, como 0,8, 0,9 o 0,99. Un impulso de 0.0 es lo mismo que un descenso de gradiente sin impulso.

Primero, dividamos la ecuación de actualización del descenso del gradiente en dos partes: el cálculo del cambio a la posición y la actualización de la posición anterior a la nueva.

El cambio en los parámetros se calcula como el gradiente para el punto escalado por el tamaño del paso.

  • change_x = step_size * f ‘(x)

La nueva posición se calcula simplemente restando el cambio del punto actual

El impulso implica mantener el cambio de posición y utilizarlo en el cálculo posterior del cambio de posición.

Si pensamos en actualizaciones a lo largo del tiempo, entonces la actualización en la iteración actual o en el momento

  • change_x

La actualización de la posición se realiza como antes.

  • x

El cambio en la posición acumula magnitud y dirección de cambios sobre las iteraciones de la búsqueda, proporcional al tamaño del hiperparámetro de impulso.

Por ejemplo, un gran impulso (por ejemplo, 0,9) significará que la actualización está fuertemente influenciada por la actualización anterior, mientras que un impulso modesto (0,2) significará muy poca influencia.

El algoritmo de impulso acumula un promedio móvil de gradientes pasados ​​que decae exponencialmente y continúa moviéndose en su dirección.

– Página 296, Deep Learning, 2016.

Momentum tiene el efecto de amortiguar el cambio en el gradiente y, a su vez, el tamaño del paso con cada nuevo punto en el espacio de búsqueda.

El impulso puede aumentar la velocidad cuando la superficie de costo es muy no esférica porque amortigua el tamaño de los pasos a lo largo de las direcciones de alta curvatura, lo que produce una mayor tasa de aprendizaje efectivo a lo largo de las direcciones de baja curvatura.

– Página 21, Redes neuronales: trucos del oficio, 2012.

Momentum es más útil en problemas de optimización donde la función objetivo tiene una gran cantidad de curvatura (por ejemplo, cambia mucho), lo que significa que el gradiente puede cambiar mucho en regiones relativamente pequeñas del espacio de búsqueda.

El método de impulso está diseñado para acelerar el aprendizaje, especialmente frente a altas curvaturas, gradientes pequeños pero consistentes o gradientes ruidosos.

– Página 296, Deep Learning, 2016.

También es útil cuando se estima el gradiente, como a partir de una simulación, y puede ser ruidoso, p. Ej. cuando el gradiente tiene una gran varianza.

Por último, el impulso es útil cuando el espacio de búsqueda es plano o casi plano, p. Ej. gradiente cero. El impulso permite que la búsqueda progrese en la misma dirección que antes del punto plano y cruzar la región plana.

Ahora que estamos familiarizados con lo que es el impulso, veamos un ejemplo trabajado.

Descenso de gradiente con impulso

En esta sección, primero implementaremos el algoritmo de optimización del descenso de gradientes, luego lo actualizaremos para usar el impulso y comparar los resultados.

Problema de prueba unidimensional

Primero, definamos una función de optimización.

Usaremos una función unidimensional simple que eleva al cuadrado la entrada y define el rango de entradas válidas de -1.0 a 1.0.

los objetivo() función a continuación implementa esta función.

Luego, podemos muestrear todas las entradas en el rango y calcular el valor de la función objetivo para cada una.

Finalmente, podemos crear una gráfica de línea de las entradas (eje x) versus los valores de la función objetivo (eje y) para obtener una intuición de la forma de la función objetivo que buscaremos.

El siguiente ejemplo une esto y proporciona un ejemplo de cómo trazar la función de prueba unidimensional.

La ejecución del ejemplo crea un gráfico de líneas de las entradas de la función (eje x) y la salida calculada de la función (eje y).

Podemos ver la familiar forma de U llamada parábola.

Gráfico de línea de función unidimensional simple

Gráfico de línea de función unidimensional simple

Optimización del descenso de gradientes

A continuación, podemos aplicar el algoritmo de descenso de gradiente al problema.

Primero, necesitamos una función que calcule la derivada de la función objetivo.

La derivada de x ^ 2 es x * 2 y la derivado() La función implementa esto a continuación.

Podemos definir una función que implemente el algoritmo de optimización del descenso de gradientes.

El procedimiento implica comenzar con un punto seleccionado al azar en el espacio de búsqueda, luego calcular el gradiente, actualizar la posición en el espacio de búsqueda, evaluar la nueva posición e informar el progreso. Luego, este proceso se repite durante un número fijo de iteraciones. A continuación, la función devuelve el punto final y su evaluación.

La función descenso de gradiente() a continuación implementa esto y toma el nombre de las funciones objetivo y de gradiente, así como los límites de las entradas a la función objetivo, el número de iteraciones y el tamaño del paso, luego devuelve la solución y su evaluación al final de la búsqueda.

Luego, podemos definir los límites de la función objetivo, el tamaño del paso y el número de iteraciones del algoritmo.

Usaremos un tamaño de paso de 0.1 y 30 iteraciones, ambas encontradas después de un poco de experimentación.

La semilla para el generador de números pseudoaleatorios es fija para que siempre obtengamos la misma secuencia de números aleatorios y, en este caso, asegura que obtengamos el mismo punto de partida para la búsqueda cada vez que se ejecuta el código (por ejemplo, algo interesante lejos de el optima).

Al unir esto, el ejemplo completo de aplicación de la búsqueda de cuadrícula a nuestra función de prueba unidimensional se enumera a continuación.

La ejecución del ejemplo comienza con un punto aleatorio en el espacio de búsqueda, luego aplica el algoritmo de descenso de gradiente, informando el rendimiento a lo largo del camino.

Nota: Sus resultados pueden variar dada la naturaleza estocástica del algoritmo o procedimiento de evaluación, o las diferencias en la precisión numérica. Considere ejecutar el ejemplo varias veces y compare el resultado promedio.

En este caso, podemos ver que el algoritmo encuentra una buena solución después de aproximadamente 27 iteraciones, con una evaluación de función de aproximadamente 0.0.

Tenga en cuenta que el óptimo para esta función está en f (0.0) = 0.0.

Es de esperar que el descenso de gradiente con impulso acelere el procedimiento de optimización y encuentre una solución evaluada de manera similar en menos iteraciones.

Visualización de la optimización del descenso de gradientes

A continuación, podemos visualizar el progreso de la búsqueda en un gráfico de la función objetivo.

Primero, podemos actualizar el descenso de gradiente() función para almacenar todas las soluciones y su puntuación encontradas durante la optimización como listas y devolverlas al final de la búsqueda en lugar de la mejor solución encontrada.

La función se puede llamar y podemos obtener las listas de las soluciones y las puntuaciones encontradas durante la búsqueda.

Podemos crear una gráfica lineal de la función objetivo, como antes.

Finalmente, podemos trazar cada solución encontrada como un punto rojo y conectar los puntos con una línea para que podamos ver cómo la búsqueda se movió cuesta abajo.

Al unir todo esto, el ejemplo completo de trazar el resultado de la búsqueda de descenso de gradiente en la función de prueba unidimensional se enumera a continuación.

Running the example performs the gradient descent search on the objective function as before, except in this case, each point found during the search is plotted.

Nota: Your results may vary given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.

In this case, we can see that the search started more than halfway up the right part of the function and stepped downhill to the bottom of the basin.

We can see that in the parts of the objective function with the larger curve, the derivative (gradient) is larger, and in turn, larger steps are taken. Similarly, the gradient is smaller as we get closer to the optima, and in turn, smaller steps are taken.

This highlights that the step size is used as a scale factor on the magnitude of the gradient (curvature) of the objective function.

Plot of the Progress of Gradient Descent on a One Dimensional Objective Function

Plot of the Progress of Gradient Descent on a One Dimensional Objective Function

Gradient Descent Optimization With Momentum

Next, we can update the gradient descent optimization algorithm to use momentum.

This can be achieved by updating the gradient_descent() function to take a “momentum” argument that defines the amount of momentum used during the search.

The change made to the solution must be remembered from the previous iteration of the loop, with an initial value of 0.0.

We can then break the update procedure down into first calculating the gradient, then calculating the change to the solution, calculating the position of the new solution, then saving the change for the next iteration.

The updated version of the gradient_descent() function with these changes is listed below.

We can then choose a momentum value and pass it to the gradient_descent() function.

After a little trial and error, a momentum value of 0.3 was found to be effective on this problem, given the fixed step size of 0.1.

Tying this together, the complete example of gradient descent optimization with momentum is listed below.

Running the example starts with a random point in the search space, then applies the gradient descent algorithm with momentum, reporting performance along the way.

Nota: Your results may vary given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.

In this case, we can see that the algorithm finds a good solution after about 13 iterations, with a function evaluation of about 0.0.

As expected, this is faster (fewer iterations) than gradient descent without momentum, using the same starting point and step size that took 27 iterations.

Visualization of Gradient Descent Optimization With Momentum

Finally, we can visualize the progress of the gradient descent optimization algorithm with momentum.

The complete example is listed below.

Running the example performs the gradient descent search with momentum on the objective function as before, except in this case, each point found during the search is plotted.

Nota: Your results may vary given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.

In this case, if we compare the plot to the plot created previously for the performance of gradient descent (without momentum), we can see that the search indeed reaches the optima in fewer steps, noted with fewer distinct red dots on the path to the bottom of the basin.

Plot of the Progress of Gradient Descent With Momentum on a One Dimensional Objective Function

Plot of the Progress of Gradient Descent With Momentum on a One Dimensional Objective Function

As an extension, try different values for momentum, such as 0.8, and review the resulting plot.
Let me know what you discover in the comments below.

Further Reading

This section provides more resources on the topic if you are looking to go deeper.

Books

APIs

Articles

Resumen

In this tutorial, you discovered the gradient descent with momentum algorithm.

Specifically, you learned:

  • Gradient descent is an optimization algorithm that uses the gradient of the objective function to navigate the search space.
  • Gradient descent can be accelerated by using momentum from past updates to the search position.
  • How to implement gradient descent optimization with momentum and develop an intuition for its behavior.

Do you have any questions?
Ask your questions in the comments below and I will do my best to answer.