Introducción al descenso del gradiente

El descenso del gradiente es un algoritmo de optimización utilizado en el aprendizaje automático y la inteligencia artificial. Su objetivo principal es encontrar los parámetros de un modelo que minimicen una función de coste o de error. Utiliza la derivación en funciones y se ajusta iterativamente en la dirección opuesta al gradiente, buscando el valor mínimo de la función de coste de manera eficiente.

Imaginemos que un ciego está parado en la cima de una montaña y su objetivo es descender hasta la base de la montaña lo más rápido posible. A pesar de su discapacidad visual, puede utilizar un bastón guía para “sentir” la inclinación del terreno a su alrededor.

La montaña representa una función de coste que queremos minimizar, y la velocidad a la que el ciego desciende se relaciona con la pendiente de la montaña en ese punto. El ciego quiere encontrar el camino que lo lleve a la base de la montaña de la manera más rápida, lo que equivale a encontrar el mínimo de la función de coste.

El descenso del gradiente es como si el ciego tomara pequeños pasos en la dirección en la que siente que la pendiente es más pronunciada. A medida que da estos pasos, se acerca gradualmente al punto más bajo de la montaña, que representa el mínimo de la función de coste. Este proceso continúa hasta que encuentra una superficie más plana, indicando que ha alcanzado el mínimo.

Como funciona el descenso del gradiente

Funciones de una sola variable

Mediante la derivación tradicional:

Si f'(x) = 0 y existe f''(x), entonces:

  • f''(x) > 0 => mínimo relativo en x.
  • f''(x) < 0 => máximo relativo en x.

Si tenemos la función f(x)=2x^2+4x

Su derivada es:

f'(x) =4x+4

Igualamos la derivada a cero y la solución de la ecuación es cuyo valor crítico es:

x = -1

Realizamos la segunda derivada

f ‘ ‘(x)=4x

Como el valor de la segunda derivada es mayor que 0 entonces tenemos un mínimo en el punto x=-1

Mediante la aproximación:

Empezamos en un punto x0, y nos movemos una distancia positiva determinada por el ratio α en la dirección opuesta a la dirección de la derivada entonces nuestro nuevo punto será:

x1 = x0 – α dy/dx

Si α es demasiado pequeño, nos aproximamos muy lentamente al mínimo y se necesitan mas pasos, y si es muy alta se converge antes pero con el riesgo de perder ese valor.

import numpy as np
import matplotlib.pyplot as plt
#Definimos una funcion de dos variables
def funcion(x):
    y = 2*x**2+4*x
    return y
def getDerivada(x):
    dx = 4*x + 4   
    return dx
res = 100
#Creamos dos vectores que genere 100 valores desde -10 a 10
X=np.linspace(-10,10,res)
def descensoGradiente(x,ratio): 
   #punto inicial  
   plt.plot(x,funcion(x),"o",c="blue")
   #Lo repetimos mil veces
   for _ in range(1000): 
        #Gradiente de la funcion
        dx = getDerivada(x)
        #Al punto x le restamos el gradiente
        x = x - ratio * dx
        plt.plot(x,funcion(x),"o",c="blue")
   return x
#tasa de aprendizaje
ratio=0.01
#Punto Inicial
x=10
#Dibujamos el camino
plt.plot(X,funcion(X),c="red") 
x=descensoGradiente(x,ratio)
print("EL valor aproximado del minimo de la funcion es:", x)
plt.show()
descenso del gradiente - BigDataJavierHeras

Funciones de dos variables

Mediante el gradiente

Si tenemos la función:

f(x,y) = 2*x**2 + 2*y**2 + 4*x+ 4*y

Sabemos que sus derivadas son:

df /dx = 4x +4

df /dy = 4y + 4

Luego su vector gradiente es:

gradiente f(x,y) = (4x +4, 4y+y)

Los puntos críticos son las soluciones del sistema de ecuaciones:

4x+4 = 0

4y+4 = 0

Que tiene un solo valor en el punto P(-1,-1)

Realizamos las segundas derivadas:

Funciones para encontrar el descenso del gradiente mediante las derivadas parciales

Su matriz hessiana es:

La matriz hessiana para el descenso del gradiente

Como del determinante de la matriz hessiana es mayor que cero entonces tenemos un mínimo en el punto P(-1,-1)

Mediante la aproximación:

Empezamos en un punto P(x0,y0), y nos movemos una distancia positiva determinada por el ratio α en la dirección opuesta a la dirección gradiente entonces nuestro nuevo punto será:

Descenso del gradiente Buscando el valor mínimo.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
#Definimos una funcion cuadratica 
def funcionCuadratica(x,y):
    Z = 2*x**2  + 2*y**2 + 4*x+ 4*y
    return Z
def getGradiente(x,y):
    dx = 4*x + 4
    dy = 4*y + 4
    return dx,dy
def descensoGradiente(x,y,ratio):    
    #punto inicial
    ax.plot3D(x,y,funcionCuadratica(x,y),"o",c="blue")
    #Lo repetimos mil veces
    for _ in range(1000): 
        #Gradiente de la funcion
        dx,dy= getGradiente(x,y)
        #Al punto x,y le restamos el gradiente
        x = x - ratio * dx
        y = y - ratio * dy
        #Camino de puntos que encuentran el minimo de la funcion
        ax.plot3D(x,y,funcionCuadratica(x,y),"o",c="blue")  
    return x,y
fig = plt.figure()
ax = plt.axes(projection='3d')
res = 100
#Creamos dos vectores que genere 100 valores desde -10 a 10
X=np.linspace(-10,10,res)
Y=np.linspace(-10,10,res)
#Creamos una cuadricula rectangular a partir de una matriz de valores xy
_X, _Y = np.meshgrid(X, Y)
_Z = 2*_X**2  + 2*_Y**2 + 4*_X+ 4*_Y
ax.plot_surface(_X,_Y,_Z, color="red")  
#tasa de aprendizaje
ratio=0.001
#Punto Inicial
x=10
y=2
x,y=descensoGradiente(x,y,ratio)
print(x,y)
plt.show()
Descenso del gradiente buscando el valor mínimo.