[ Foro de Python ]

Algoritmo de Backpropagation (función lógica)

17-Apr-2023 23:08
Caio Lorenzo Iriarte Salles
0 Respuestas

Tengo el siguiente código en Python:

import numpy as np


#     Funciones lógicas
def net1(vec):
   return int(vec[0] and not vec[1] and vec[2] and not vec[3])


def net2(vec):
   return int(vec[0] and not vec[1] and not vec[2] and not vec[3])


def net3(vec):
   return int(vec[0] and not vec[2] and vec[3])


def net4(vec):
   return int(not vec[0] and not vec[1] and vec[2])


def net5(vec):
   return int(vec[1] and vec[2] and vec[3])


def logic_fcn(vec):
   return (net1(vec) or net2(vec) or net3(vec) or net4(vec) or net5(vec))


def sigmoid(z):
   return 1/(1 + np.exp(-z))





def forward(vec, p, s, pf):
   t0 = sigmoid(s[0] + np.sum(vec*p[0]))
   t1 = sigmoid(s[1] + np.sum(vec*p[1]))
   t2 = sigmoid(s[2] + np.sum(vec*p[2]))
   t3 = sigmoid(s[3] + np.sum(vec*p[3]))
   t4 = sigmoid(s[4] + np.sum(vec*p[4]))
   
   return sigmoid(s[5] + np.dot(np.array([t0,t1,t2,t3,t4]),pf))
   #   (-10) -> 0 || (10) -> 1



def evaluate(inputs,labels):
   itera = len(inputs)
   aciertos = 0
   
   #   s: sesgo (tamaño: 6), p: pesos (tamaño 5 x (vectores de 4)), pf: pesos de función final (vector de 5 elementos)
   p, s, pf = fit(inputs,labels)
   
   print("PARTE A -----------------------------------------------------\n")
   for it in range(itera):
       res = forward(inputs[it], p, s, pf)
       correcto = (abs(res - labels[it]) <= 0.1)
       print("Valor referencia: ",labels[it],", valor forward: ",res)
       
       if(correcto):
           print(" correcto\n")
           aciertos = aciertos + 1
       else:
           print(" incorrecto\n")
   
   print("TASA DE ACIERTOS: ",(aciertos/16)*100,"%\n")
   return 0




#   Devuelve el vector de perdida del algoritmo de backpropagation
def perdida(vec_z, vec_ob):
   z_sig = np.zeros(len(vec_z))
   
   for i in range(len(vec_z)):
       z_sig[i] = sigmoid(vec_z[i])
       
   vec_perdida = z_sig - vec_ob
   return vec_perdida




#   Funcion de backpropagation (A3)
def fit(inputs, labels):
   
   # Inicialización de los vectores de pesos y sesgo:
   s = np.array(np.random.uniform(low=-40,high=40,size=6))
   p = np.array(np.random.uniform(low=-40,high=40,size=(5,4)))
   pf = np.array(np.random.uniform(low=10,high=30,size=5))
   learning_rate = 0.2
   
   
   #   Vectores solución de términos:
   vec_t1 = [net1(inputs[0]),net1(inputs[1]),net1(inputs[2]),net1(inputs[3]),net1(inputs[4]),net1(inputs[5]),net1(inputs[6]),net1(inputs[7]),
             net1(inputs[8]),net1(inputs[9]),net1(inputs[10]),net1(inputs[11]),net1(inputs[12]),net1(inputs[13]),net1(inputs[14]),net1(inputs[15])]
   vec_t2 = [net2(inputs[0]),net2(inputs[1]),net2(inputs[2]),net2(inputs[3]),net2(inputs[4]),net2(inputs[5]),net2(inputs[6]),net2(inputs[7]),
             net2(inputs[8]),net2(inputs[9]),net2(inputs[10]),net2(inputs[11]),net2(inputs[12]),net2(inputs[13]),net2(inputs[14]),net2(inputs[15])]
   vec_t3 = [net3(inputs[0]),net3(inputs[1]),net3(inputs[2]),net3(inputs[3]),net3(inputs[4]),net3(inputs[5]),net3(inputs[6]),net3(inputs[7]),
             net3(inputs[8]),net3(inputs[9]),net3(inputs[10]),net3(inputs[11]),net3(inputs[12]),net3(inputs[13]),net3(inputs[14]),net3(inputs[15])]
   vec_t4 = [net4(inputs[0]),net4(inputs[1]),net4(inputs[2]),net4(inputs[3]),net4(inputs[4]),net4(inputs[5]),net4(inputs[6]),net4(inputs[7]),
             net4(inputs[8]),net4(inputs[9]),net4(inputs[10]),net4(inputs[11]),net4(inputs[12]),net4(inputs[13]),net4(inputs[14]),net4(inputs[15])]
   vec_t5 =  [net5(inputs[0]),net5(inputs[1]),net5(inputs[2]),net5(inputs[3]),net5(inputs[4]),net5(inputs[5]),net5(inputs[6]),net5(inputs[7]),
             net5(inputs[8]),net5(inputs[9]),net5(inputs[10]),net5(inputs[11]),net5(inputs[12]),net5(inputs[13]),net5(inputs[14]),net5(inputs[15])]
   
   t1_ajustado = False
   t2_ajustado = False
   t3_ajustado = False
   t4_ajustado = False
   t5_ajustado = False
   f_ajustada = False
   vec_unos = np.ones(16)
   
   #   Ajuste de términos
   while(not t1_ajustado or not t2_ajustado or not t3_ajustado or not t4_ajustado or not t5_ajustado):
       if(not t1_ajustado):
           z_t1 = p[0]@(inputs.T) + np.multiply(vec_unos,s[0])
           t1_perdida = perdida(z_t1,vec_t1)
           max_t1 = np.max(np.abs(t1_perdida))
           
           if(max_t1 > 0.1):
               p[0] = p[0] - learning_rate*(t1_perdida@inputs)
               s[0] = s[0] - learning_rate*(t1_perdida@(vec_unos.T))
           else:
               t1_ajustado = True
           
       if(not t2_ajustado):
           z_t2 = p[1]@(inputs.T) + np.multiply(vec_unos,s[1])
           t2_perdida = perdida(z_t2,vec_t2)
           max_t2 = np.max(np.abs(t2_perdida))
           
           if(max_t2 > 0.1):
               p[1] = p[1] - learning_rate*(t2_perdida@inputs)
               s[1] = s[1] - learning_rate*(t2_perdida@(vec_unos.T))
           else:
               t2_ajustado = True
               
       if(not t3_ajustado):
           z_t3 = p[2]@(inputs.T) + np.multiply(vec_unos,s[2])
           t3_perdida = perdida(z_t3,vec_t3)
           max_t3 = np.max(np.abs(t3_perdida))
           
           if(max_t3 > 0.1):
               p[2] = p[2] - learning_rate*(t3_perdida@inputs)
               s[2] = s[2] - learning_rate*(t3_perdida@(vec_unos.T))
           else:
               t3_ajustado = True
               
       if(not t4_ajustado):
           z_t4 = p[3]@(inputs.T) + np.multiply(vec_unos,s[3])
           t4_perdida = perdida(z_t4,vec_t4)
           max_t4 = np.max(np.abs(t4_perdida))
           
           if(max_t4 > 0.1):
               p[3] = p[3] - learning_rate*(t4_perdida@inputs)
               s[3] = s[3] - learning_rate*(t4_perdida@(vec_unos.T))
           else:
               t4_ajustado = True
               
       if(not t5_ajustado):
           z_t5 = p[4]@(inputs.T) + np.multiply(vec_unos,s[4])
           t5_perdida = perdida(z_t5,vec_t5)
           max_t5 = np.max(np.abs(t5_perdida))
           
           if(max_t5 > 0.1):
               p[4] = p[4] - learning_rate*(t5_perdida@inputs)
               s[4] = s[4] - learning_rate*(t5_perdida@(vec_unos.T))
           else:
               t5_ajustado = True
               
   print(p)
   
   t1_pesos = p[0]@(inputs.T) + np.multiply(vec_unos,s[0])
   t2_pesos = p[1]@(inputs.T) + np.multiply(vec_unos,s[1])
   t3_pesos = p[2]@(inputs.T) + np.multiply(vec_unos,s[2])
   t4_pesos = p[3]@(inputs.T) + np.multiply(vec_unos,s[3])
   t5_pesos = p[4]@(inputs.T) + np.multiply(vec_unos,s[4])
   in_final = np.array([t1_pesos,t2_pesos,t3_pesos,t4_pesos,t5_pesos])
   learning_rate = 0.055
   
   
   #   Ajuste de función final
   while(not f_ajustada):
       z_final = pf@in_final + np.multiply(vec_unos,s[5])
       # print(z_final)
       func_perdida = perdida(z_final,labels)
       max_final = np.max(np.abs(func_perdida))
       
       if(max_final > 0.1):
           pf = pf - learning_rate*(func_perdida@(in_final.T))
           s[5] = s[5] - learning_rate*(func_perdida@(vec_unos.T))
           print(pf)
           print(s[5])
       else:
           f_ajustada = True
   

   
   # Devolución de los vectores de pesos y sesgo
   return p, s, pf





if __name__ == "__main__":
   inputs = np.array([np.asarray([0,0,0,0]),np.asarray([0,0,0,1]),np.asarray([0,0,1,0]),np.asarray([0,0,1,1]),np.asarray([0,1,0,0]),np.asarray([0,1,0,1]),np.asarray([0,1,1,0]),
             np.asarray([0,1,1,1]),np.asarray([1,0,0,0]),np.asarray([1,0,0,1]),np.asarray([1,0,1,0]),np.asarray([1,0,1,1]),np.asarray([1,1,0,0]),np.asarray([1,1,0,1]),
             np.asarray([1,1,1,0]),np.asarray([1,1,1,1])])
   
   #   Dan como resultado true (1) o false (0) (labels)
   labels = np.array([logic_fcn(inputs[0]),logic_fcn(inputs[1]),logic_fcn(inputs[2]),logic_fcn(inputs[3]),logic_fcn(inputs[4]),logic_fcn(inputs[5]),logic_fcn(inputs[6]),logic_fcn(inputs[7]),
             logic_fcn(inputs[8]),logic_fcn(inputs[9]),logic_fcn(inputs[10]),logic_fcn(inputs[11]),logic_fcn(inputs[12]),logic_fcn(inputs[13]),logic_fcn(inputs[14]),logic_fcn(inputs[15])])
   
   
   evaluate(inputs,labels)



El problema del código arriba es que no consigo que la función 'fit' realice el ajuste óptimo de pesos y sesgos, debido a que no se ajustan los pesos finales de la función final (se queda parado el programa en el último 'while'). Por ello, pido por aquí algo de ayuda al respecto, para que me funcione el programa. Gracias




(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)