Herramientas de usuario

Herramientas del sitio


clase:iabd:pia:2eval:tema07.backpropagation_descenso_gradiente

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anterior Revisión previa
Próxima revisión
Revisión previa
clase:iabd:pia:2eval:tema07.backpropagation_descenso_gradiente [2023/04/20 11:29]
admin [Ejercicios]
clase:iabd:pia:2eval:tema07.backpropagation_descenso_gradiente [2024/02/28 15:38] (actual)
admin [Ejercicios]
Línea 658: Línea 658:
 Más información: Más información:
   * [[https://keras.io/api/optimizers/adam/|Adam]]   * [[https://keras.io/api/optimizers/adam/|Adam]]
 +  * {{ :clase:iabd:pia:2eval:the_math_behind_adam_optimizer.pdf |The Math Behind the Adam Optimizer}}
  
  
Línea 684: Línea 685:
 Más información: Más información:
   * [[https://keras.io/api/optimizers/Nadam/|Nadam]]   * [[https://keras.io/api/optimizers/Nadam/|Nadam]]
 +
 +
 +<note tip>
 +En nuestros proyectos, solemos necesitar mostrar por pantalla el optimizador que estamos usando y normalmente pasa ésto:
 +
 +<sxh python>
 +print(tf.keras.optimizers.Adam(learning_rate=0.001))
 +print(tf.keras.optimizers.Adamax(learning_rate=0.00000001))
 +</sxh>
 +
 +<sxh base>
 +<keras.optimizer_v2.adam.Adam object at 0x7fc4c0d16b60>
 +<keras.optimizer_v2.adamax.Adamax object at 0x7fc4c1db1810>
 +</sxh>
 +
 +Pero hay un truco para que se muestre de forma más amigable, que es sobre escribir la función ''__str__'' de la clase ''Optimizer'':
 +
 +<sxh python>
 +tf.keras.optimizers.Optimizer.__str__=lambda self: f'{self._name} lr=' + f'{self.learning_rate.numpy():.10f}'.rstrip('0')
 +</sxh>
 +
 +Y si volvemos a ejecutar de nuevo el código:
 +
 +<sxh python>
 +print(tf.keras.optimizers.Adam(learning_rate=0.001))
 +print(tf.keras.optimizers.Adamax(learning_rate=0.00000001))
 +</sxh>
 +
 +<sxh base>
 +Adam lr=0.001
 +Adamax lr=0.00000001
 +</sxh>
 +
 +
 +</note>
  
  
Línea 741: Línea 777:
   * [[https://vineetrawat9121996.medium.com/rmsprop-saviour-of-adagrad-de4e705427b4|RMSprop saviour of Adagrad]]: Lo que intenta mejorar RMSprop de Adagrad   * [[https://vineetrawat9121996.medium.com/rmsprop-saviour-of-adagrad-de4e705427b4|RMSprop saviour of Adagrad]]: Lo que intenta mejorar RMSprop de Adagrad
   * [[https://visharma1.medium.com/adagrad-and-adadelta-optimizer-in-depth-explanation-6d0ad2fdf22|Adagrad and Adadelta Optimizer: In-Depth Explanation]]   * [[https://visharma1.medium.com/adagrad-and-adadelta-optimizer-in-depth-explanation-6d0ad2fdf22|Adagrad and Adadelta Optimizer: In-Depth Explanation]]
-  * [[https://medium.com/geekculture/a-2021-guide-to-improving-cnns-optimizers-adam-vs-sgd-495848ac6008|A 2021 Guide to improving CNNs-Optimizers: Adam vs SGD]]+  * [[https://medium.com/geekculture/a-2021-guide-to-improving-cnns-optimizers-adam-vs-sgd-495848ac6008|A 2021 Guide to improving CNNs-Optimizers: Adam vs SGD]]: Las fórmulas de los optimizadores
  
 ===== Hardware entrenamiento ===== ===== Hardware entrenamiento =====
Línea 761: Línea 797:
  
  
-Usando el descenso de gradiente indica para cada parámetro si debe incrementar el valor del parámetro o decremenarlo.+Indica para cada parámetro: Si la función crece o decrece, el valor de su derivada (positiva o negativa) y por lo tanto si se debe incrementar el valor del parámetro o decremenarlo.
  
 ==== Ejercicio 2 ==== ==== Ejercicio 2 ====
Línea 779: Línea 815:
 <sxh python> <sxh python>
 #Código base de varios ejercicios. #Código base de varios ejercicios.
 + 
 import numpy as np import numpy as np
 import matplotlib.pyplot as plt import matplotlib.pyplot as plt
Línea 785: Línea 821:
 from matplotlib.ticker import MaxNLocator from matplotlib.ticker import MaxNLocator
 from matplotlib.ticker import MultipleLocator from matplotlib.ticker import MultipleLocator
 + 
 def sigmoid(z): def sigmoid(z):
     return 1/(1 + np.exp(-z))     return 1/(1 + np.exp(-z))
- +  
 def predict_formula(x,w,b): def predict_formula(x,w,b):
     return sigmoid(w*x+b)     return sigmoid(w*x+b)
- +  
 + 
 def loss_mae(y_true,y_pred): def loss_mae(y_true,y_pred):
     error=np.abs(np.subtract(y_true,y_pred))     error=np.abs(np.subtract(y_true,y_pred))
     mean_error=np.sum(error)/len(y_true)     mean_error=np.sum(error)/len(y_true)
- +  
     return mean_error     return mean_error
-  +   
-  +   
- +  
 def loss(x,y_true,w,b): def loss(x,y_true,w,b):
     y_pred=predict_formula(x,w,b)     y_pred=predict_formula(x,w,b)
-  +   
     return loss_mae(y_true,y_pred)     return loss_mae(y_true,y_pred)
- +  
 + 
 def plot_loss(x,y_true,perdida_original,valor_parametro_inicial,rango,perdidas,xlabel,axes): def plot_loss(x,y_true,perdida_original,valor_parametro_inicial,rango,perdidas,xlabel,axes):
     axes.set_ylim(ymin=0.0,ymax=0.7)     axes.set_ylim(ymin=0.0,ymax=0.7)
Línea 813: Línea 849:
     axes.set_xlabel(xlabel)     axes.set_xlabel(xlabel)
     axes.set_ylabel('loss')     axes.set_ylabel('loss')
 + 
     axes.vlines(x = valor_parametro_inicial, ymin = perdida_original, ymax = 0.7,colors = '#ff0000',linestyle="dashed")     axes.vlines(x = valor_parametro_inicial, ymin = perdida_original, ymax = 0.7,colors = '#ff0000',linestyle="dashed")
     axes.text(valor_parametro_inicial+0.1,0.72,f'{xlabel}={valor_parametro_inicial:0.2f}',c="#ff0000")     axes.text(valor_parametro_inicial+0.1,0.72,f'{xlabel}={valor_parametro_inicial:0.2f}',c="#ff0000")
- +  
 + 
     min_x=rango[np.argmin(perdidas)]     min_x=rango[np.argmin(perdidas)]
     min_y=np.min(perdidas)     min_y=np.min(perdidas)
     axes.vlines(x = min_x, ymin = 0, ymax = min_y,colors = '#00ff00',linestyle="dashed")     axes.vlines(x = min_x, ymin = 0, ymax = min_y,colors = '#00ff00',linestyle="dashed")
     axes.text(min_x+0.1,0.015,f'{min_x:0.2f}',c="#00ff00")     axes.text(min_x+0.1,0.015,f'{min_x:0.2f}',c="#00ff00")
- +  
-    +     
 def plot_simple_metrics(axes,history,title): def plot_simple_metrics(axes,history,title):
 + 
     axes.plot(history,linestyle="dotted",label=f"loss :{history[-1]:.2f}",c="#003B80")       axes.plot(history,linestyle="dotted",label=f"loss :{history[-1]:.2f}",c="#003B80")  
 + 
     axes.set_xlabel('Nº Épocas', fontsize=13,color="#003B80"     axes.set_xlabel('Nº Épocas', fontsize=13,color="#003B80"
     axes.xaxis.set_major_locator(MaxNLocator(integer=True))     axes.xaxis.set_major_locator(MaxNLocator(integer=True))
 + 
     axes.set_ylabel('Métricas', fontsize=13,color="#003B80")     axes.set_ylabel('Métricas', fontsize=13,color="#003B80")
     axes.set_ylim(ymin=0,ymax=1.1)     axes.set_ylim(ymin=0,ymax=1.1)
     axes.yaxis.set_major_locator(MultipleLocator(0.1))     axes.yaxis.set_major_locator(MultipleLocator(0.1))
 + 
     axes.set_title(title)     axes.set_title(title)
     axes.set_facecolor("#F0F7FF")     axes.set_facecolor("#F0F7FF")
     axes.grid(visible=True, which='major', axis='both',color="#FFFFFF",linewidth=2)     axes.grid(visible=True, which='major', axis='both',color="#FFFFFF",linewidth=2)
     axes.legend()     axes.legend()
- +  
 + 
 def plot_losses(x,y_true,w_inicial,b_inicial,subfigure): def plot_losses(x,y_true,w_inicial,b_inicial,subfigure):
     perdida_original=loss(x,y_true,w_inicial,b_inicial)     perdida_original=loss(x,y_true,w_inicial,b_inicial)
- +  
 +    kk=subfigure
     subfigure.suptitle(f'loss={perdida_original:0.2f}',c="#ff0000")     subfigure.suptitle(f'loss={perdida_original:0.2f}',c="#ff0000")
 +
     axes_w=subfigure.add_subplot(1,2,1)     axes_w=subfigure.add_subplot(1,2,1)
     axes_b=subfigure.add_subplot(1,2,2)        axes_b=subfigure.add_subplot(1,2,2)   
- +  
-    rango=np.linspace(-4,4,400)+    rango=np.linspace(-5,5,400)
     perdidas_w=[]     perdidas_w=[]
     perdidas_b=[]     perdidas_b=[]
 + 
     for parametro in rango:     for parametro in rango:
         perdidas_w.append(loss(x,y_true,parametro,b_inicial))         perdidas_w.append(loss(x,y_true,parametro,b_inicial))
         perdidas_b.append(loss(x,y_true,w_inicial,parametro))         perdidas_b.append(loss(x,y_true,w_inicial,parametro))
- +  
 + 
     plot_loss(x,y_true,perdida_original,w_inicial,rango,perdidas_w,"w",axes_w)     plot_loss(x,y_true,perdida_original,w_inicial,rango,perdidas_w,"w",axes_w)
     plot_loss(x,y_true,perdida_original,b_inicial,rango,perdidas_b,"b",axes_b)     plot_loss(x,y_true,perdida_original,b_inicial,rango,perdidas_b,"b",axes_b)
 + 
     return perdida_original     return perdida_original
 + 
 +def plot_evolucion_parametros(axes,ws,bs):
 +    axes.plot(ws,linestyle="solid",label="w",c="#6ABF40")  
 +    axes.plot(bs,linestyle="solid",label="b",c="#BF9140"    
 + 
 +    axes.set_xlabel('Nº Épocas', fontsize=13,color="#003B80"
 +    axes.xaxis.set_major_locator(MaxNLocator(integer=True))
 + 
 +    axes.set_ylabel('Valor de los parámetros', fontsize=13,color="#003B80")
 +    axes.set_ylim(ymin=-5,ymax=5)
 +    axes.yaxis.set_major_locator(MultipleLocator(1))
 + 
 +    axes.set_title("Evolución de los parámetros en cada época")
 +    axes.set_facecolor("#F0F7FF")
 +    axes.grid(visible=True, which='major', axis='both',color="#FFFFFF",linewidth=2)
 +    axes.legend()
 + 
  
  
 def plot_parametros(x,y_true,parametros): def plot_parametros(x,y_true,parametros):
-    figure=plt.figure(figsize=(8,3.5*len(parametros)),layout='constrained')+    figure=plt.figure(figsize=(8,3.5*(len(parametros)+1)),layout='constrained')
     figure.suptitle("$y=\\frac{1}{1 + e^{-( w \\cdot x+b  )}}$")     figure.suptitle("$y=\\frac{1}{1 + e^{-( w \\cdot x+b  )}}$")
     subfigures = figure.subfigures(nrows=len(parametros)+1, ncols=1)     subfigures = figure.subfigures(nrows=len(parametros)+1, ncols=1)
  
 +    ws=[]
 +    bs=[]
     history=[]     history=[]
     for index,(w,b) in enumerate(parametros):     for index,(w,b) in enumerate(parametros):
-        if (len(parametros)>1): +        subfigure=subfigures[index] 
-            subfigure=subfigures[index] + 
-        else: +
-            subfigure=subfigures +
         loss=plot_losses(x,y_true,w,b,subfigure)         loss=plot_losses(x,y_true,w,b,subfigure)
 +        ws.append(w)
 +        bs.append(b)
         history.append(loss)         history.append(loss)
 + 
     axes=subfigures[-1].add_subplot(1,2,1)     axes=subfigures[-1].add_subplot(1,2,1)
     plot_simple_metrics(axes,history,"loss")     plot_simple_metrics(axes,history,"loss")
- +    axes=subfigures[-1].add_subplot(1,2,2)  
 +    plot_evolucion_parametros(axes,ws,bs) 
 + 
 def descenso_gradiente(x,y_true,learning_rate,w,b): def descenso_gradiente(x,y_true,learning_rate,w,b):
     h=0.000003     h=0.000003
- +  
     gradiente_w =(loss(x,y_true,w+h,b)-loss(x,y_true,w,b))/h     gradiente_w =(loss(x,y_true,w+h,b)-loss(x,y_true,w,b))/h
     gradiente_b =(loss(x,y_true,w,b+h)-loss(x,y_true,w,b))/h     gradiente_b =(loss(x,y_true,w,b+h)-loss(x,y_true,w,b))/h
 + 
     w=w-learning_rate*gradiente_w     w=w-learning_rate*gradiente_w
     b=b-learning_rate*gradiente_b     b=b-learning_rate*gradiente_b
     return w,b     return w,b
- +  
 + 
 def plot_descenso_gradiente(x,y_true,w_inicial,b_inicial,learning_rate,epochs): def plot_descenso_gradiente(x,y_true,w_inicial,b_inicial,learning_rate,epochs):
     figure=plt.figure(figsize=(8,3.5*epochs),layout='constrained')     figure=plt.figure(figsize=(8,3.5*epochs),layout='constrained')
     figure.suptitle("$y=\\frac{1}{1 + e^{-( w \\cdot x+b  )}}$")     figure.suptitle("$y=\\frac{1}{1 + e^{-( w \\cdot x+b  )}}$")
 + 
     subfigures = figure.subfigures(nrows=epochs+1, ncols=1)     subfigures = figure.subfigures(nrows=epochs+1, ncols=1)
     w=w_inicial     w=w_inicial
     b=b_inicial     b=b_inicial
 +  
 +    ws=[] 
 +    bs=[]
     history=[]     history=[]
     for epoch in range(epochs):     for epoch in range(epochs):
Línea 908: Línea 966:
         else:         else:
             subfigure=subfigures             subfigure=subfigures
 + 
         loss=plot_losses(x,y_true,w,b,subfigure)         loss=plot_losses(x,y_true,w,b,subfigure)
 +        ws.append(w)
 +        bs.append(b)
         history.append(loss)         history.append(loss)
         w,b=descenso_gradiente(x,y_true,learning_rate,w,b)         w,b=descenso_gradiente(x,y_true,learning_rate,w,b)
 + 
     axes=subfigures[-1].add_subplot(1,2,1)     axes=subfigures[-1].add_subplot(1,2,1)
     plot_simple_metrics(axes,history,"loss")     plot_simple_metrics(axes,history,"loss")
 +    axes=subfigures[-1].add_subplot(1,2,2)    
 +    plot_evolucion_parametros(axes,ws,bs)
 </sxh> </sxh>
  
Línea 932: Línea 994:
 x=iris.data[0:99,2] x=iris.data[0:99,2]
 y_true=iris.target[0:99] y_true=iris.target[0:99]
 +</sxh>
  
 +<sxh python>
 parametros=[(-0.3,0.1)] parametros=[(-0.3,0.1)]
 plot_parametros(x,y_true,parametros) plot_parametros(x,y_true,parametros)
Línea 1025: Línea 1089:
   * Función de activación de las capas ocultas: ''selu''   * Función de activación de las capas ocultas: ''selu''
  
-Prueba únicamente con **20 épocas** con todas las combinaciones de lo siguiente:+Prueba únicamente con **épocas** con todas las combinaciones de lo siguiente:
  
   * Optimizadores   * Optimizadores
Línea 1038: Línea 1102:
     * 0.01     * 0.01
     * 0.001     * 0.001
 +    * 0.0005
  
  
Línea 1046: Línea 1111:
  
 ==== Ejercicio 6.B ==== ==== Ejercicio 6.B ====
-Siguiendo con el ejercicio anterior, entrena ahora la red con 500 épocas pero ahora solo con los optimizadores/tasas de aprendizaje que seleccionaste en el ejercicio anterior+Siguiendo con el ejercicio anterior, entrena ahora la red con 300 épocas pero ahora solo con los optimizadores/tasas de aprendizaje que seleccionaste en el ejercicio anterior
  
  
 ==== Ejercicio 6.C ==== ==== Ejercicio 6.C ====
-Repite el ejercicio anterior pero ahora con **TODAS** las combinaciones de optimizadores y tasas de aprendizaje. ¿Fue adecuada la selección que hiciste inicialmente?+Repite el ejercicio anterior pero ahora con **TODAS** las combinaciones de optimizadores y tasas de aprendizaje.  
 + 
 +¿Fue adecuada la selección que hiciste en el ejercicio anterior?
  
  
clase/iabd/pia/2eval/tema07.backpropagation_descenso_gradiente.1681982993.txt.gz · Última modificación: 2023/04/20 11:29 por admin