Anuncio

Colapsar
No hay ningún anuncio todavía.

Minicurso perceptrón, redes neuronales artificiales

Colapsar
X
 
  • Filtro
  • Hora
  • Mostrar
Borrar todo
nuevos mensajes

  • Minicurso perceptrón, redes neuronales artificiales

    Acabo de ver un curso en youtube que explica, con matemáticas sencillas, como construir un perceptrón, básicamente una red neuronal artificial que recoge datos de entrada y elabora respuestas de salida.
    Creo que sólo con las matemáticas de bachillerato es entendible.

    https://www.youtube.com/playlist?lis...wWiF8a_52dQ3JQ

    Si miráis en su listas de reproducción, también hay vídeos divulgativos, y unos vídeos de mecánica clásica (para explicar posteriormente la mecánica cuántica) también fácilmente entendible.

    PD: no sabía muy bien donde ubicar el hilo por ser tan variados los vídeos a los que me refiero....

    - - - Actualizado - - -

    He intentado hacer el ejercicio que propone al final en el último vídeo. Ya acabé la red, el problema me surge que no "aprende" si no que "memoriza" el resultado.
    Sii queréis echar un vistazo, os paso los códigos de la red:

    Neuronas por capa: 3 5 5 4
    Objetivo: resolución de ecuación de segundo grado ax^+bx+c=0, 3 variables entrada a b c, 4 variables de salida, 2 por cada solución: y_1 + y_2 i, y_3 + y_4 i.

    Función, que a partir de las entradas, calcula la salida:
    Código:
    function RNA(x) # resolviendo la ecuación ax^+bx+c=0, introducir: x=[a b c]
     v_min=-10^2; # Valores maximo y minimo que puede tomar las entradas y salidas
     V_max=10^2;
      
     printf("%fx^2 + %fx + %f = 0 \n", x(1), x(2), x(3));
     s_1=scale(x, v_min, V_max, 0, 1); # se reescalan las variables de entrada de [v_min,V_max] -> [0,1]
     
     load("w"); # se carga el archivo con los pesos y los umbrales
     
     s_2=neuron(s_1*w_1 + u_2);     # se procesan las salidas de cada neurona
     s_3=neuron(s_2*w_2 + u_3);
     s_4=neuron(s_3*w_3 + u_4);   
     
     y=scale(s_4, 0, 1, v_min, V_max); # se vuelven a reescalar los valores de salida de [0,1] -> [v_min,V_max]
                                      # array de 4 dimensiones, 2 posibles resultados de la ecuacion dados en forma compleja: (y1 + y2i, y3 + y4i)
     if((y(1)+y(2)*i)==(y(3)+y(4)*i)) #se imprime el resultado por pantalla
       printf("x = %f + %f i\n \n", y(1), y(2));
     else
       printf("x_1 = %f + %f i,  x_2 = %f + %f i \n \n", y(1), y(2), y(3), y(4));
     endif
    endfunction
    
    
    
    
    function s=neuron(a)
     s=sigmoid(a); #funcionamiento de neurona
    endfunction
    
    
    
    function y=sigmoid(x) # función sigmoide
        y=1./(1+e.^(-x));
    endfunction
    
    
    
    function y=scale(x, x_0, x_1, y_0, y_1) # escalado basado en función lineal
        y = ((y_1-y_0)/(x_1 - x_0))*(x - x_0) + y_0;
    endfunction
    Función de entrenamiento:
    Código:
    function train()
     v_min=-10^2; # Valores maximo y minimo que puede tomar las entradas y salidas
     V_max=10^2;
     h=0.1; # razon de aprendizaje
     n=500; # numero de veces de practica
     l=1; # identificador de la solucion
    
     load("w"); # se carga el archivo con los pesos y los umbrales 
     load("solutions"); # se cargan las soluciones
     if((v(l,1)+v(l,2)*i)==(v(l,3)+v(l,4)*i)) # se imprimen las soluciones por pantalla
       printf("solucion: x = %f + %f i\n \n", v(l,1), v(l,2));
     else
       printf("soluciones: x_1 = %f + %f i,  x_2 = %f + %f i \n \n", v(l,1), v(l,2), v(l,3), v(l,4));
     endif
     
     v(l,:)=scale(v(l,:), v_min, V_max, 0, 1); # se reescalan los resultados de [v_min,V_max] -> [0,1]
     
     for k=1:n
      [s_1, s_2, s_3, s_4]=RNA_ap(x(l,:)); # La red neuronal calcula los resultados y pasa las variables
     
      d_4=s_4.*(1-s_4).*(s_4-v(l,:)); # Calculamos los deltas
      d_3=s_3.*(1-s_3).*(w_3*d_4')';
      d_2=s_2.*(1-s_2).*(w_2*d_3')';
     
      # Calculamos las derivadas parciales del error con respecto a los pesos y umbrales
      for i=1:length(s_1)
       for j=1:length(d_2)
        Dw_1(i,j)=s_1(i)*d_2(j);
       end
      end
      for i=1:length(s_2)
       for j=1:length(d_3)
        Dw_2(i,j)=s_2(i)*d_3(j);
       end
      end
      for i=1:length(s_3)
       for j=1:length(d_4)
        Dw_3(i,j)=s_3(i)*d_4(j);
       end
      end
      Du_2=d_2;
      Du_3=d_3;
      Du_4=d_4;
     
       w_1=w_1-h*Dw_1; # aplicamos el descenso del gradiente
       w_2=w_2-h*Dw_2;
       w_3=w_3-h*Dw_3;
       u_2=u_2-h*Du_2;
       u_3=u_3-h*Du_3;
       u_4=u_4-h*Du_4;
      
       save("w", "w_1", "w_2", "w_3", "u_2", "u_3", "u_4"); # guardamos los w
      end
    endfunction
     
    
    
    
    function [s_1, s_2, s_3, s_4]=RNA_ap(x) #copia de RNA(x) solo que esta funcion envia lo que da cada salida
     v_min=-10^2;
     V_max=10^2;
      
     printf("%fx^2  +  %fx  +  %f=0 \n", x(1), x(2), x(3));
     s_1=scale(x, v_min, V_max, 0, 1);
     
     load("w");
     
     s_2=neuron(s_1*w_1 + u_2);
     s_3=neuron(s_2*w_2 + u_3);
     s_4=neuron(s_3*w_3 + u_4);   
     
     y=scale(s_4, 0, 1, v_min, V_max);
                                     
     if((y(1)+y(2)*i)==(y(3)+y(4)*i))
       printf("x=%f+%fi\n \n", y(1), y(2));
     else
       printf("x_1 = %f + %f i,  x_2 = %f + %f i \n \n", y(1), y(2), y(3), y(4));
     endif
    endfunction
    
    
    
    
    function s=neuron(a)
     s=sigmoid(a); #funcionamiento de neurona
    endfunction
    
    
    function y=sigmoid(x) # función sigmoide
        y=1./(1+e.^(-x));
    endfunction
    
    
    function y=scale(x, x_0, x_1, y_0, y_1) # escalado basado en función lineal
        y = ((y_1-y_0)/(x_1 - x_0))*(x - x_0) + y_0;
    endfunction
    Archivos de ejemplo de pesos ("w") y soluciones ("solutions").
    Código:
    # name: w_1
    # type: matrix
    # rows: 3
    # columns: 5
     9.479945325724249e-12 9.479945325724249e-12 9.479945325724249e-12 9.479945325724249e-12 9.479945325724249e-12
     9.085312104172701e-12 9.085312104172701e-12 9.085312104172701e-12 9.085312104172701e-12 9.085312104172701e-12
     9.4799423346112e-12 9.4799423346112e-12 9.4799423346112e-12 9.4799423346112e-12 9.4799423346112e-12
    
    
    # name: w_2
    # type: matrix
    # rows: 5
    # columns: 5
     4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06
     4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06
     4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06
     4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06
     4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06 4.349679783926101e-06
    
    
    # name: w_3
    # type: matrix
    # rows: 5
    # columns: 4
     0.004444573136243404 0 0.004444573150566376 0
     0.004444573136243404 0 0.004444573150566376 0
     0.004444573136243404 0 0.004444573150566376 0
     0.004444573136243404 0 0.004444573150566376 0
     0.004444573136243404 0 0.004444573150566376 0
    
    
    # name: u_2
    # type: matrix
    # rows: 1
    # columns: 5
     1.877219459307957e-11 1.877219459307957e-11 1.877219459307957e-11 1.877219459307957e-11 1.877219459307957e-11
    
    
    # name: u_3
    # type: matrix
    # rows: 1
    # columns: 5
     8.69935956783051e-06 8.69935956783051e-06 8.69935956783051e-06 8.69935956783051e-06 8.69935956783051e-06
    
    
    # name: u_4
    # type: matrix
    # rows: 1
    # columns: 4
     0.008889125120897654 0 0.008889125085089874 0
    Código:
    # name: x
    # type: matrix
    # rows: 4
    # columns: 3
     1 -2 1
     1 2 1
     1 0 -1
     1 0 -4
     
    
    # name: v
    # type: matrix
    # rows: 4
    # columns: 4
     1 0 1 0
     -1 0 -1 0
     1 0 -1 0
     2 0 -2 0
    Me parece bastante sencillo octave, en el sentido de poder convertir varios sumatorios en multiplicaciones matriciales, para los deltas el cálculo es elemento a elemento, lo único que carece de producto tensorial que hay que hacerlo "a mano". Si cogéis los pesos, veréis que sólo están entrenados para la primera solución.. Y otro problema que debo resolver es controlar el formato, para que salgan por pantalla números decimales pero sin necesidad de verse por ejemplo números del tipo: 12.5300000..
    A ver si consigo que funcione bien.
    Un saludo.
    Última edición por alexpglez; 03/07/2015, 15:17:53.
    [TEX=null] \vdash_T G \leftrightarrow Consis \; \ulcorner T \urcorner [/TEX]

  • #2
    Re: Minicurso perceptrón, redes neuronales artificiales

    Por ahora me he visto dos vídeos y medio. Cuando acabe intentaré también el ejercicio que dices. Decir que el nivel de matemáticas se escapa un pelín del bachillerato y que el resto del canal no me lo he mirado mucho pero pintan bien los vídeos.
    Última edición por Weip; 04/07/2015, 20:20:56.

    Comentario


    • #3
      Re: Minicurso perceptrón, redes neuronales artificiales

      Creo que lo que pasa es que le pido cosas "imposibles" a mi pobre red..
      Trataré de ver si era eso con ejemplos más simples, y puliré el código aún más, ya que creo que utilizando tensores de tercer o cuarto orden se puede simplificar más el código, pudiendo ser más general.
      Encontré este otro enlace del que introducía los métodos que se explican en esos vídeo, para luego explicar más detalladamente los "algoritmos genéticos", yo de momento sólo he leído hasta la introducción hasta los algoritmos genéticos, tengo curiosidad por saber de qué se trata...
      http://laboratorios.fi.uba.ar/lsi/be...nformatica.pdf
      Última edición por alexpglez; 06/07/2015, 00:44:56. Motivo: El enlace
      [TEX=null] \vdash_T G \leftrightarrow Consis \; \ulcorner T \urcorner [/TEX]

      Comentario


      • #4
        Re: Minicurso perceptrón, redes neuronales artificiales

        Hola, ya he acabado de ver todos los vídeos. Yo no sé de octave pero por lo que veo tu problema es que no inicializas las variables cada vez que empiezas o finalizas el proceso. Puedes hacerlo tanto al principio o al final, pero limpia las variables. Si no, pasa lo que dices: el resultado de la primera etapa se queda en la variable y los cálculos nuevos que hagas se pierden, dando siempre el mismo resultado. También deberías comprobar que las variables de entrada sean correctas mediante if's y controlar que todas las operaciones que haces salen bien, si se leen bien los archivos de datos... y si no, añadir los mensajes de error pertinentes. Esto ayuda mucho a encontrar en qué párrafo hay fallos.

        Como he dicho yo no sé de octave, podría ser que ya estuviera bien y no me haya fijado, pero lo que te he indicado no lo he visto.
        Última edición por Weip; 06/07/2015, 12:53:14.

        Comentario


        • #5
          Re: Minicurso perceptrón, redes neuronales artificiales

          No es eso, al intentar hacer una red más sencilla, que me trabajase de -3 a 3, con ecuaciones de primer grado, me daban resultados más coherentes, pero sí, debería inicializar las variables por si acaso.
          [TEX=null] \vdash_T G \leftrightarrow Consis \; \ulcorner T \urcorner [/TEX]

          Comentario

          Contenido relacionado

          Colapsar

          Trabajando...
          X