martes, 5 de agosto de 2014

La regla delta generalizada y consideraciones prácticas


1. Describa en detalle el aprendizaje por descenso de gradiente.

Para el aprendizaje por descenso de gradiente se necesita tomar en cuenta los siguientes factores:

 
-  El propósito del aprendizaje de redes neuronales o entrenamiento es reducir al mínimo los errores de salida en un determinado conjunto de datos de entrenamiento mediante el ajuste de los pesos de la red.


-  Definimos una función de error que según las mediciones determina hasta qué punto la red es correctamente entrenada.

-  Las derivadas parciales de la función de error nos dicen en qué dirección tenemos que movernos en el espacio de pesos para reducir el error.

-   La razón de aprendizaje n especifica los tamaños de los pasos que damos en el espacio de pesos para cada iteración de la ecuación de actualización de pesos.

-  Seguimos paso a paso a través del espacio de pesos hasta que los errores sean lo suficientemente pequeños.

-  Si elegimos funciones de activación de las neuronas con derivadas que asumen formas particularmente simples, podemos hacer los cálculos de actualización de pesos muy eficaz.



2. Describa el procedimiento para entrenar un perceptrón multicapa.



Para el entrenamiento de un perceptrón multicapa se sigue el siguiente procedimiento:



-   Se toma un conjunto de patrones de entrenamiento que se desea que la red aprenda.


-   Se configura la red con unidades de entrada ninputs plenamente conectados a unidades ocultas nhidden, a través de conexiones con pesos wij, que a su vez están todos conectados a unidades de salida noutputs a través de conexiones con pesos.



-   Generar pesos iniciales aleatorios.



-   Seleccionar una función de error E(wij) y una razón de aprendizaje n apropiados.
 
-   Aplicar la ecuación de actualización de los peso:

a cada peso wij para cada patrón de entrenamiento. Un conjunto de actualizaciones de todos los pesos para todos los patrones de entrenamiento es llamado una época de entrenamiento.



-   Repetir el paso 5 hasta que la función de error es suficientemente pequeña.


3. Escriba el código para implementar: a) Salida de sectores planos de la función error, b) Uso de la función de activación tanh.

Parte a



in1 = [0 0 1 1];
in2 = [0 1 0 1];
target = [0.1 0.9 0.9 0.1];

%Pesos iniciales
a01=-1+(1-(-1))*rand(1); a02=-1+(1-(-1))*rand(1); a11=-1+(1-(-1))*rand(1);
a12=-1+(1-(-1))*rand(1); a21=-1+(1-(-1))*rand(1); a22=-1+(1-(-1))*rand(1);
b0=-1+(1-(-1))*rand(1); b1=-1+(1-(-1))*rand(1); b2=-1+(1-(-1))*rand(1);
n = 0.1; %Factor de aprendizaje
alfa = 4;
error_epoca=0;

for j=1:1:400
  suma_error = 0;
  aux_a01 = 0; aux_a11 = 0; aux_a12 = 0;
  aux_a02 = 0; aux_a21 = 0; aux_a22 = 0;
  aux_b0 = 0; aux_b1 = 0; aux_b2 = 0;
  for i=1:1:4
    net1 = a01+a11*in1(i)+a21*in2(i);
    y1 = 1 / (1 + exp(-alfa*net1));
    net2 = a02+a12*in1(i)+a22*in2(i);
    y2 = 1 / (1 + exp(-alfa*net2));
    net = b0+b1*y1+b2*y2;
    z = 1 / (1 + exp(-alfa*net));
    error = 1/2*(target(i)-z)^2;
    suma_error = suma_error+error;
   
    %Calculo de las variaciones de los pesos 
    deltaa01 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b1*(alfa*y1*(1-y1)+0.1);
    deltaa11 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b1*(alfa*y1*(1-y1)+0.1)*in1(i);
    deltaa12 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b2*(alfa*y2*(1-y2)+0.1)*in1(i);
    deltaa02 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b2*(alfa*y2*(1-y2)+0.1);
    deltaa21 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b1*(alfa*y1*(1-y1)+0.1)*in2(i);
    deltaa22 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*b2*(alfa*y2*(1-y2)+0.1)*in2(i);
    deltab0 = n*(target(i)-z)*(alfa*z*(1-z)+0.1);
    deltab1 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*y1;
    deltab2 = n*(target(i)-z)*(alfa*z*(1-z)+0.1)*y2;
    aux_a01 = aux_a01+deltaa01;
    aux_a11 = aux_a11+deltaa11;
    aux_a12 =  aux_a12+deltaa12;
    aux_a02 = aux_a02+deltaa02;
    aux_a21 = aux_a21+deltaa21;
    aux_a22 = aux_a22+deltaa22;
    aux_b0 = aux_b0+deltab0;
    aux_b1 = aux_b1+deltab1;
    aux_b2 = aux_b2+deltab2;
  end
  %Calculo actualización de pesos
  a01 = a01 + aux_a01;
  a11 = a11 + aux_a11;
  a12 = a12 + aux_a12;
  a02 = a02 + aux_a02;
  a21 = a21 + aux_a21;
  a22 = a22 + aux_a22; 

  b0 = b0 + aux_b0;
  b1 = b1 + aux_b1;
  b2 = b2 + aux_b2;
  error_epoca(j) = suma_error;
end



%Curva de aprendizaje 
figure(1)
plot(error_epoca)
title('Curva de aprendizaje')
xlabel('Época');
ylabel('Error cuadrático');



%Comprobacion aprendizaje
for i=1:1:4
  net1 = a01+a11*in1(i)+a21*in2(i);
  y1 = 1/(1 + exp(-alfa*net1));
  net2 = a02+a12*in1(i)+a22*in2(i);
  y2 = 1/(1 + exp(-alfa*net2));
  salida(i) = hardlim(b0+b1*y1+b2*y2);
end
salida
target


[x1, x2]= meshgrid(0:0.01:1, 0:0.01:1);
net1 = a01+a11*x1+a21*x2;
y1 = 1./(1 + exp(-alfa*net1));
net2 = a02+a12*x1+a22*x2;
y2 = 1./(1 + exp(-alfa*net2));
net = b0+b1*y1+b2*y2;
z = 1./(1 + exp(-alfa*net));
figure(2)
subplot(121)
mesh(x1,x2,z)
title('Función de la neurona')
xlabel('in1');
ylabel('in2');
subplot(122)
aux = round(z);
mesh(x1,x2,aux)
title('Línea de Frontera')
xlabel('in1');
ylabel('in2');
figure(3)
aux1=round(y1);
subplot(221)
mesh(x1,x2,aux1)
title('Neurona 1')
xlabel('in1');
ylabel('in2');
aux2=round(y2);
subplot(222)
mesh(x1,x2,aux2)
title('Neurona 2')
xlabel('in1');
ylabel('in2');
subplot(223)
mesh(x1,x2,aux)
title('Neurona Global')
xlabel('in1');
ylabel('in2');

Parte b

inputs=[0 0; 0 1; 1 0; 1 1];targ=[0;1;1;0];
a01=1.2;a11=0.6;a12=0.5;a02=0.2;a21=0.5;a22=0.1;b0=0.2;b1=0.1;b2=0.1;
input01=1;input02=1;input03=1;n=0.1;errorepoca=0;
for e=1:400
    auxb0=0;auxb1=0;auxb2=0;auxa01=0;auxa11=0;auxa12=0;
    auxa02=0;auxa21=0;auxa22=0;    sumaerr=0;
    for i=1:length(targ)
        y1=tanh(input01*a01+inputs(i,1)*a11+inputs(i,2)*a21);
        y2=tanh(input02*a02+inputs(i,1)*a12+inputs(i,2)*a22);
        z=tanh(input03*b0+y1*b1+y2*b2);
        deltab0=n*(targ(i)-z)*alfa*z*(1-z);
        deltab1=n*(targ(i)-z)*alfa*z*(1-z)*y1;
        deltab2=n*(targ(i)-z)*alfa*z*(1-z)*y2;
        deltaa01=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b1*y1*(1-y1);
        deltaa11=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b1*y1*(1-y1)*inputs(i,1);
        deltaa12=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b2*y2*(1-y2)*inputs(i,1);
        deltaa02=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b2*y2*(1-y2);
        deltaa21=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b1*y1*(1-y1)*inputs(i,2);
        deltaa22=n*(targ(i)-z)*alfa*z*(1-z)*alfa*b2*y2*(1-y2)*inputs(i,2);
        auxb0=auxb0+deltab0;
        auxb1=auxb1+deltab1;
        auxb2=auxb2+deltab2;
        auxa01=auxa01+deltaa01;
        auxa11=auxa11+deltaa11;
        auxa12=auxa12+deltaa12;
        auxa02=auxa02+deltaa02;
        auxa21=auxa21+deltaa21;
        auxa22=auxa22+deltaa22;
        error=1/2*(targ(i)-z)^2; %obtiene el error
        sumaerr=sumaerr+error;%suma todos los errorres
    end
    b0=b0+auxb0; b1=b1+auxb1; b2=b2+auxb2;
    a01=a01+auxa01;a11=a11+auxa11;a12=a12+auxa12;a02=a02+auxa02;
    a21=a21+auxa21;a22=a22+auxa22;
    errorepoca(e)=sumaerr;
end
    [in1,in2] = meshgrid(0:.01:1, 0:.01:1); %grafica
    net1=input01*a01+in1*a11+in2*a21;
    net2=input02*a02+in1*a12+in2*a22;
    Gy1=1./(1+exp(-alfa*net1));
    Gy2=1./(1+exp(-alfa*net2));
    net=input03*b0+Gy1*b1+Gy2*b2;
    Gz = 1./(1+exp(-alfa*net));
    subplot(2,2,1);
    mesh(in1,in2,Gz)
    xlabel('in1');ylabel('in2');
    subplot(2,2,2);
    plot(errorepoca)
    aux = round(Gz-0.4); %Para  graficar la linea de frontera
    subplot(2,2,3);
    mesh(in1,in2,aux)
    view(0,90);xlabel('in1');ylabel('in2');
%para comprobar si funcionan los pesos
for s=1:length(targ)
    y1=sigmf(input01*a01+inputs(s,1)*a11+inputs(s,2)*a21,[alfa 0]);
    y2=sigmf(input02*a02+inputs(s,1)*a12+inputs(s,2)*a22,[alfa 0]);
    salida(s)=sigmf(input03*b0+y1*b1+y2*b2,[alfa 0]);
end
salida