"""
*********************************
Hilario Iglesias Martinez.
*********************************
clasedeterceroamiercoles.py
--------------------------------
Función de partida:
f(x)=3*x+5*x**2/7
**********************************************
Derivada:f'(x) = 3 + (10/7)*x
***********************************************
El descenso de gradiente es un algoritmo iterativo
que utiliza la derivada (o el gradiente)
de la función objetivo en un punto específico
para determinar la dirección, y el tamaño del
paso que debes tomar para moverte hacia una región
de menor valor de la función. La derivada de
la función objetivo se calcula en cada iteración,
y se utiliza para ajustar los parámetros,
con el objetivo de acercarte al mínimo de la función.
En resumen, el descenso de gradiente es una técnica
fundamental en el campo de la optimización y el aprendizaje
automático, ya que permite encontrar valores óptimos para los
parámetros de una función de manera iterativa utilizando
información sobre la pendiente de la función en diferentes puntos.
-----------------------------------------------
Aquí hay una descripción, paso a paso, del proceso del descenso de gradiente:
Inicialización: Comienza con un valor inicial para
los parámetros de la función que deseas optimizar.
Cálculo del Gradiente:
Calcula la derivada (gradiente) de la función en el punto actual.
Actualización de Parámetros:
Ajusta los parámetros en la dirección opuesta al gradiente
multiplicado por una tasa de aprendizaje.
La tasa de aprendizaje controla el tamaño de
los pasos que tomas en cada iteración.
Repetición: Repite los pasos 2 y 3 para un
número predeterminado de iteraciones, o
hasta que se alcance cierto criterio de convergencia.
Convergencia:
El algoritmo converge cuando los cambios
en los parámetros se vuelven muy pequeños,
indicando que se ha llegado a una región
cercana al mínimo (o máximo) de la función.
*************************************************
Programa realizado sobre paltaforma Linux:
Ubuntu 20.04.6 LTS.
Editado en Sublime Text.
-----------------------------------------
Ejecución en consola Linux:
python3 clasedeterceroamiercoles.py
*******************************************************
"""
#Importamos los modulos necesarios para el programa.
import numpy as np
import matplotlib.pyplot as plt
#Declaramos las funciones para luego llamarlas.
def FuncionParabola(x):
return 3*x+(5*x**2)/7
def FuncionDerivadaParabola(x):
return 10*x/7+3
#Aqui se declaran los parametros iniciales para el recorrido del gradiente.
Punto_x_Inicial=50
TasaAprendizaje=0.04
Iteraciones=1000
#Para situar la gráfica debemos planificar el espacio en puntos referente ejes x,y.
ValoresDe_x=np.linspace(-50,50,3000)
ValoresDe_y=FuncionParabola(ValoresDe_x)
#Inicializamos la lista para almacenar los valores de x,y.
Almacenar_x=[Punto_x_Inicial]
Almacenar_y=[FuncionParabola(Punto_x_Inicial)]
#Debemos abrir un bucle for para el cálculo de las iteraciones.
for _ in range(Iteraciones):
NuevoValor_x=Almacenar_x[-1]-(TasaAprendizaje*FuncionDerivadaParabola(Almacenar_x[-1]))
Almacenar_x=np.append(Almacenar_x,NuevoValor_x)
Almacenar_y=np.append(Almacenar_y,FuncionParabola(NuevoValor_x))
#Calculamos los valores de menor gradiente para x,y.
MinimoValorDeIndice_x = np.argmin(Almacenar_y)
MinimoValorDe_x = Almacenar_x[MinimoValorDeIndice_x]
MinimoValorDe_y=FuncionParabola(MinimoValorDe_x)
print("********************************************************")
print("El mínimo valor de x, es:",MinimoValorDe_x)#Imprimimos el mínimo valor para x.
print("El mínimo valor de y, es:",MinimoValorDe_y)
print("*******************************************************")
plt.figure(figsize=(10,6))
#Vamos a generar la GRAFICA de la parábola, llamando a los Valores de x, Valores de y.
plt.plot(ValoresDe_x,ValoresDe_y, label='Parabola de f(x)=3*x+5*x**2/7 ')
#Generamos los puntos del descenso de gradiente sobre la parabola.
plt.scatter(Almacenar_x,Almacenar_y, color='red',label='Situación de los Puntos de descenso de gradiente')
#Señalamos el punto mínimo de otro color.
plt.scatter(MinimoValorDe_x,FuncionParabola(MinimoValorDe_x),color='green',label='Punto Mínimo valor x,y' )
plt.scatter(Punto_x_Inicial,FuncionParabola(Punto_x_Inicial),color='black',label='Punto Inicial')
#Colocamos etiquetas a los ejes x,y.
plt.xlabel('Eje x')
plt.ylabel('Eje y, valores f(x)=3*x+5*x**2/7')
plt.grid(True)
#Dimensionamos el grid para referenciar valores.
y_ticks = np.arange(0, 150, 10)#Valor, inicial, final, de 10 en 10.
plt.legend()
#************************************************************
# Agregando etiquetas para el punto mínimo y el punto inicial
plt.annotate(f'Mínimo: ({MinimoValorDe_x:.2f}, {MinimoValorDe_y:.2f})',
xy=(MinimoValorDe_x, MinimoValorDe_y), xycoords='data',
xytext=(-40, 40), textcoords='offset points',
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"))
plt.annotate(f'Inicial: ({Punto_x_Inicial}, {FuncionParabola(Punto_x_Inicial):.2f})',
xy=(Punto_x_Inicial, FuncionParabola(Punto_x_Inicial)), xycoords='data',
xytext=(-50, -40), textcoords='offset points',
arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=-.2"))
#*************************************************************
plt.show()#Mostrar la gráfica completa con la leyenda.
"""
********************************************************
El mínimo valor de x, es: -2.099999993279536
El mínimo valor de y, es: -3.150000000000001
*******************************************************
"""