Otimização usando Gradient Descent em duas variáveis usando Python

curso
coursera
Algebra Linear
calculo
Machine Learning
Data Science
Deep Learning
Python
R
Algebra Linear
Anotações do módulo 2 do curso de Cálculo para aprendizado de máquina e ciência de dados
Author

Wellington Santos Souza

Published

Sunday, 04 August 2024

Método de Gradient Descent otimizando algumas funções em duas variáveis.

Vamos carregar os pacotes que utilizaremos aqui:

Code
import numpy as np
import matplotlib.pyplot as plt
from w2_tools import (plot_f_cont_and_surf, gradient_descent_two_variables, 
                      f_example_3, dfdx_example_3, dfdy_example_3, 
                      f_example_4, dfdx_example_4, dfdy_example_4)

Agora vamos explorar um exemplo simples de uma função em duas variáveis \(f(x,y)\) com um mínimo global.

Code
plot_f_cont_and_surf([0, 5], [0, 5], [74, 85], f_example_3, cmap='coolwarm', view={'azim':-60,'elev':28})
(<Figure size 960x480 with 2 Axes>,
 <Axes: xlabel='$x$', ylabel='$y$'>,
 <Axes3D: xlabel='$x$', ylabel='$y$', zlabel='$f$'>)

Para encontrarmos o mínimo, você podemos implementar a gradient descent a partir do ponto inicial \((x_0,y_0)\) e realizar etapas iteração por iteração usando as seguintes equações:

\[ x_1 = x_0 - \alpha \frac{\partial f}{\partial x}(x_0, y_0), \]

\[ y_1 = y_0 - \alpha \frac{\partial f}{\partial y}(x_0, y_0),\tag{1} \]

em que \(\alpha>0\) é uma taxa de aprendizado. O número de iterações também é um parâmetro. O método é implementado com o seguinte código:

Code
def gradient_descent(dfdx, dfdy, x, y, learning_rate = 0.1, num_iterations = 100):
    for iteration in range(num_iterations):
        x, y = x - learning_rate * dfdx(x, y), y - learning_rate * dfdy(x, y)
    return x, y

Agora, para otimizar a função, configuramos os parâmetros num_iterations, learning_rate, x_initial, y_initial e executar o gradient descent:

Code
num_iterations = 30; learning_rate = 0.25; x_initial = 0.5; y_initial = 0.6
print("Gradient descent result: x_min, y_min =", 
      gradient_descent(dfdx_example_3, dfdy_example_3, x_initial, y_initial, learning_rate, num_iterations)) 
Gradient descent result: x_min, y_min = (4.0, 4.0)

Pode ver a visualização executando o código a seguir. Observe que a descida de gradiente em duas variáveis executa etapas no plano, em uma direção oposta ao vetor de gradiente \(\begin{bmatrix}\frac{\partial f}{\partial x}(x_0, y_0) \\ \frac{\partial f}{\partial y}(x_0, y_0)\end{bmatrix}\) com a taxa de aprendizado \(\alpha\) como um fator de escala.

Code
num_iterations = 20; learning_rate = 0.25; x_initial = 0.5; y_initial = 0.6
num_iterations = 20; learning_rate = 0.5; x_initial = 0.5; y_initial = 0.6
num_iterations = 20; learning_rate = 0.15; x_initial = 0.5; y_initial = 0.6
num_iterations = 20; learning_rate = 0.15; x_initial = 3.5; y_initial = 3.6

gd_example_3 = gradient_descent_two_variables([0, 5], [0, 5], [74, 85], 
                                              f_example_3, dfdx_example_3, dfdy_example_3, 
                                              gradient_descent, num_iterations, learning_rate, 
                                              x_initial, y_initial, 
                                              [0.1, 0.1, 81.5], 2, [4, 1, 171], 
                                              cmap='coolwarm', view={'azim':-60,'elev':28})

Vamos dar uma olhada nessa outra função

Code
plot_f_cont_and_surf([0, 5], [0, 5], [6, 9.5], f_example_4, cmap='terrain', view={'azim':-63,'elev':21})
(<Figure size 960x480 with 2 Axes>,
 <Axes: xlabel='$x$', ylabel='$y$'>,
 <Axes3D: xlabel='$x$', ylabel='$y$', zlabel='$f$'>)

Podemos encontrar o mínimo global com:

Code
num_iterations = 100; learning_rate = 0.2; x_initial = 0.5; y_initial = 3

print("Gradient descent result: x_min, y_min =", 
      gradient_descent(dfdx_example_4, dfdy_example_4, x_initial, y_initial, learning_rate, num_iterations)) 
Gradient descent result: x_min, y_min = (0.5230322579358745, 0.5169891562802605)

Visualizando

Code
# Converges to the global minimum point.
num_iterations = 30; learning_rate = 0.2; x_initial = 0.5; y_initial = 3
# Converges to a local minimum point.
# num_iterations = 20; learning_rate = 0.2; x_initial = 2; y_initial = 3
# Converges to another local minimum point.
# num_iterations = 20; learning_rate = 0.2; x_initial = 4; y_initial = 0.5

gd_example_4 = gradient_descent_two_variables([0, 5], [0, 5], [6, 9.5], 
                                              f_example_4, dfdx_example_4, dfdy_example_4, 
                                              gradient_descent, num_iterations, learning_rate, 
                                              x_initial, y_initial, 
                                              [2, 2, 6], 0.5, [2, 1, 63], 
                                              cmap='terrain', view={'azim':-63,'elev':21})

Back to top