domingo, 25 de octubre de 2009

IMPLEMENTACIÓN DE UNA RED NEURONAL UTILIZANDO SOFTWARE TLEARN

En este Post voy a enseñar como diseñar una red neuronal Feedforward de dos capas.

Vamos a implementar una red neuronal que permita reconocer escrituras de dígitos (0 - 9). Presentemos la red como una malla 3x5, que contiene un dibujo binario del digito.

Cantidad de neuronas de entrada:

La cantidad de neuronas de entrada serán 3x5 = 15 neuronas de entrada.

Esta cantidad se escogió puesto que representa un mejor manera de dibujar el digito en la matriz, y además para no complicar en demasía la estructura de la red.

Cantidad por capas ocultas:

La cantidad de capas ocultas corresponderá a una, la cual contiene 6 neuronas en el nivel intermedio, esto puesto que un nivel intermedio demasiado grande extenderá drásticamente el número de iteraciones requerido para probar la red y reducirá la fiabilidad de la rellamada.

Cantidad de neuronas de salida:

El nivel de salida debe tener 4 neuronas, para darnos la salida de 4 bits, esto porque a los dígitos 8 y 9 le corresponden 4 bits, para poder representarlos de forma binaria.

Estructura de datos utilizada para la neurona:

Construimos red neuronal feedforward multicapas para que cada nivel esté completamente conectado al siguiente. Cada neurona en un nivel mandará su salida a cada neurona del siguiente nivel.

Configuración de la red:


Para configurar la red utilizamos el archivo RED.CF, donde definimos los valores de la red neuronal. En el ejemplo se puede apreciar 10 nodos, 15 patrones de entrada, 4 neuronas de salida definida entre los nodos del 7 al 10.

Las conexiones la establecemos en la etiqueta CONNECTIONS, donde definimos las conexiones de las 15 neuronas de entrada con las 6 neuronas de la capa intermedia y así mismo de las neuronas intermedias a las neuronas de salida.

NODES:

nodes = 10

inputs = 15

outputs = 4

output nodes are 7-10

CONNECTIONS:

groups = 0

1-6 from i1-i15

7-10 from 1-6


SPECIAL:

selected = 1-6

weight_limit = 1.0

Diagrama de red neuronal:

Entrenamiento de la red:

Para configurar la red neuronal utilizamos los archivos DATA y TEACH, que nos permitirán ingresar a la red neuronal los valores de entrada y salida respectivamente.

Configuración archivo DATA:

Para cada digito representado se eligieron 5 ejemplos para el entrenamiento seleccionados de forma aleatoria, cada ejemplo tuvo una distorsión de 1 ó 2 bits como máximo, donde el primer ejemplo de cada digito representa el digito original.

0

1

111101101101111

111101000101111

111101100101111

111101101101110

011101101101111

010110010010010

010110010000010

010010010010010

000110010010010

001011001001001

2

3

111001111100111

111001111100110

111001111000111

011001111100111

111001011100111

111001011001111

011001011001111

111001010001111

101001011001111

110001011001111

4

5

101101111001001

000101111001001

001101111001001

101101101001001

101101111000001

111100111001111

111100111001101

111100111001110

011100111001111

111100110001111

6

7

111100111101111

111100111101101

111100111101110

110100111101111

111100111101011

111001010010010

111001011010010

011001011010010

111001010000010

111001000010010

8

9

111101111101111

111101111101111

101101111101111

111101010101111

111101110101111

111101111001111

111101111001011

011101111001111

111111111001111

111101110001111

Ejemplo de representación grafica de cada digito:


Configuración archivo TEACH:

Cada digito se represento de forma binaria, esto para poder realizar los 5 ejemplos de entrenamiento para cada digito.

0 0 0 0 = 0

0 0 0 1 = 1

0 0 1 0 = 2

0 0 1 1 = 3

0 1 0 0 = 4

0 1 0 1 = 5

0 1 1 0 = 6

0 1 1 1 = 7

1 0 0 0 = 8

1 0 0 1 = 9

Resultado del entrenamiento:

Una vez configurados los archivos DATA y TEACH se procede al entrenamiento de la red, en este caso realizamos entrenamientos de 10000 y 20000 iteraciones, obteniendo como resultado las siguientes graficas y valores correspondientes.

Para el caso de los entrenamientos vamos a considerar los valores arrojados de la siguiente forma: Para valores mayores 0,6 lo consideraremos como valor 1 y para valores menores a 0.6 lo consideraremos 0.

Entrenamiento de la red con 10000 iteraciones:

Output activations

using red-10000.wts and red.data (Training Set)

0.074 0.000 0.012 0.005

0.035 0.000 0.007 0.062

0.084 0.000 0.009 0.005

0.058 0.001 0.012 0.022

0.075 0.000 0.007 0.032

0.013 0.029 0.000 0.997

0.025 0.002 0.000 0.977

0.041 0.015 0.045 1.000

0.036 0.003 0.000 0.978

0.095 0.000 0.066 0.919

Entrenamiento de la red con 20000 iteraciones:

Output activations

using red-20000.wts and red.data (Training Set)

0.031 0.001 0.019 0.000

0.031 0.001 0.022 0.001

0.039 0.001 0.014 0.001

0.037 0.001 0.017 0.001

0.039 0.001 0.013 0.001

0.007 0.026 0.000 1.000

0.032 0.001 0.000 1.000

0.000 0.019 0.019 1.000

0.027 0.001 0.000 1.000

0.024 0.017 0.002 0.974

Prueba y verificación del entrenamiento:

Cada digito fue distorsionado de una forma diferente al entrenamiento que fue realizado, esto para verificar si su aprendizaje.

Para el digito cero 111101101101111, se aplico la siguiente nueva configuración:

111101101101100

Obteniendo como resultado los siguientes valores para 10000 y 20000 iteraciones:

Output activations

using red-10000.wts and red.data (Training Set)

0.184 0.007 0.026 0.003

Output activations

using red-20000.wts and red.data (Training Set)

0.009 0.007 0.009 0.004

Lo cual refleja los valores de las cuatro neuronas de salida representan el numero binario: 0 0 0 0 = 0, esto demuestra que para este ejemplo la red neuronal pudo reconocer el digito a pesar de la distorsión impuesta.

Para nuestro 2 ejemplo se utilizo el digito uno, 010110010010010 y se aplico la siguiente nueva configuración:

010110000010010

Obteniendo como resultado los siguientes valores para 10000 y 20000 iteraciones:

Output activations

using red-10000.wts and red.data (Training Set)

0.002 0.010 0.002 1.000

Output activations

using red-20000.wts and red.data (Training Set)

0.013 0.030 0.000 1.000

Lo cual refleja los valores de las cuatro neuronas de salida representan el numero binario: 0 0 0 1 = 1, esto demuestra que para este ejemplo la red neuronal pudo reconocer el digito a pesar de la distorsión impuesta.

De manera similar se realizaron pruebas para los siguientes dígitos obteniendo equivalentes resultados.

IMPLEMENTACIÓN DEL SOFTWARE

Interfaz del Software:

El Software implementado presenta una interfaz, la cual presenta una grilla de entrada, que permite ingresar el digito a evaluar, a su costado presenta la cadena de bit del digito ingresado que representa los valores de los patrones de entrada de la neurona.

Una vez ingresados los datos de entrada y al presionar el botón Reconocer, automáticamente se generan los datos de salida correspondiente al digito evaluado, esto es en la grilla salida.




Código del Software:

Los valores que ocupa el programa se guardaran en las siguientes estructuras

Los valores de entrada se guardan en un vector entrada (1 to 10).

Ls valores de la neuronas se guardaran en una matriz llamada cap1(10,15) , donde el primer índice representa la neurona y el segundo índice representa los pesos de entrada

Estos valores se rescatan del archivo red-20000.wts ingresándolo de la siguiente forma:

' datos entrada neurona 1

cap1(1, 0) = -1.0992292166

cap1(1, 1) = 0.2268614322

cap1(1, 2) = 3.3533549309

‘datos entrada neurona 2.

El cálculo de los valores de las neuronas se realiza mediante la suma de la multiplicación del valor de entrada por el peso de la neurona + el peso del bias

‘sumatoria del las entradas de la neurona

For i = 0 To 6

For j = 1 To 15

valor(i) = valor(i) + cap1(i, j) * entrada(j)

Next j

Next i

‘ suma del bias que se encuentra en la posición 0 del la matriz cap1()

valor(1) = cap1(1, 0) + valor(1)

valor(2) = cap1(2, 0) + valor(2)

valor(3) = cap1(3, 0) + valor(3)

valor(4) = cap1(4, 0) + valor(4)

valor(5) = cap1(5, 0) + valor(5)

valor(6) = cap1(6, 0) + valor(6)

Finalmente se le aplica la función sigmoidea para la salida de cada neurona

For i = 1 To 6

valor(i) = sigmoidea(valor(i))

Next i

Para las neuronas de salida es la suma de la multiplicación de el valor de salida de la capa escondida por el peso de la neurona

For i = 7 To 10

For j = 0 To 6

valor(i) = valor(i) + cap1(i, j) * valor(j)

Next j

Next i

domingo, 27 de septiembre de 2009

Algoritmo genérico para formulas de aproximación por diferencias

Bueno este Post es de una tarea que me toco hacer del ramo de Calculo Numérico de Ingeniería civil en Computación de la Universidad Arturo Prat, Iquique, decidí compartirlo ya que lo encuentro muy útil, este algoritmo permite evaluar la derivada de cualquier orden de una función en un punto....aquí va...

Fundamento teórico
Este algoritmo describe un forma general para la obtención de formulas de aproximación por diferencia de una derivada de orden n, estableciendo un número de puntos requeridos m dependiendo de la precisión que se busca.
Si tenemos m puntos en un sub – intervalo, enumerados en , donde y n el orden de la derivada. Las abscisas de los puntos de la retícula son con.
Por tanto la aproximación por diferencias de la derivada de orden n conm puntos se expresa:
O bien.
(1)
En donde hasta son los m coeficientes indeterminados; son las coordenadas que se usarán y E es el máximo error de la aproximación, que se escribe como.






(2)
Una vez obtenido la formula (1) de aproximación por diferencias dado un orden n y m puntos, se sustituye en esta ecuación por los desarrollos de Taylor de, para así calcular los coeficientes indeterminados de forma que el término E sea el máximo orden posible.
Para efectos de este Post simplificaremos la expresión para obtener una mejor conceptualización del desarrollo, supondremos. Entonces la ecuación (1) queda.


(3)


En donde son los tres coeficientes indeterminados y son los puntos de la retícula que se utilizarán. Sustituimos los desarrollos dealrededor de x en la ecuación (3).
Reagrupando…
(4)

La ecuación (4) contiene tres coeficientes indeterminados, los cuales se pueden definir mediante tres condiciones formando un sistema. Para minimizar el error de la ecuación (4), hacemos los coeficientes de iguales a 0, 1, 0 respectivamente, debido a que el único termino existente es , que es la derivada buscada, por tanto el sistema nos queda de la siguiente manera:
(5)

Una vez resuelto el sistema anterior obtendremos los valores de los tres coeficientes indeterminados, los cuales son:
Una vez encontrado estos valores se sustituyen en la ecuación (3) y obtendremos finalmente la ecuación por diferencias para nuestro caso en particular, dondedonde la derivada aproxima a cualquier función f(x) alrededor de x.
Por otro lado, los términos no nulos de la ecuación (4) constituyen el error.

(6)


Al comparar las ecuaciones (2) y (6) obtenemos que:

De lo que se obtiene, sustituyendo
Debido a que el primer término del error no es nulo, ecuación (6), ignoramos el segundo término y escribimos el término del error como:
En el caso en que el primer término del error se anule, el segundo término pasará a representar el error.

Resolución del algoritmo genérico en Maple
Una vez planteado el fundamento teórico del algoritmo genérico para la obtención de formulas de aproximación por diferencia de una derivada de orden n, desarrollaremos un programa basado en Maple que nos permita utilizar dicho método.
Basándonos en m como el número de puntos en la retícula y con n como orden de la derivada, nos basaremos en la siguiente ecuación.

Donde utilizaremos los desarrollos de Taylor para los m términos, donde son los m puntos, estos puntos necesitaremos almacenarlos en un vector que llamaremos V[m] de largo m, quedando:




Donde cada uno de estos elementos se reemplaza por la serie de Taylor correspondiente, donde se almacenaran en una columna de una matriz, quedando de la siguiente manera:
Cada termino de Taylor se truncara hasta el termino m, donde los términos m + 1 y m + 2
Se utilizaran para el cálculo de error, nótese que en la matriz sólo se almacena el término que acompaña a cada derivada de la serie.
Con lo que podemos observar que cada fila corresponde al argumento los cuales corresponden a los argumentos principales, y las columnas corresponden a los a1,…,aL que serán los argumentos a agrupar.
Con esta idea podremos construir nuestro sistema de ecuaciones, multiplicando por el coeficiente propio de la formula anterior y ampliando nuestra matriz a .




Expresada como:


Ahora generaremos el código Maple para poder ingresar estos valores descritos a la matriz MA [ ] Procedimiento para ingresar valores a la matriz MA [].
For i from 1 to m do
For j from 1 to m do
MA [j,i]:=(V[i]*h)^(j-1)/(j-1)!*(1/h^n);
od;
od;
MA [n+1,m+1]:=1;
En donde la matriz que contiene los coeficientes dese expresa:
En donde los términos del error se guardan en un vector e[] de dimensión 2 :
Procedimiento para ingresar los valores al vector e[]
V[1]:=0: V[2]:=1: V[3]:=2;
e[1]:=0;
e[2]:=0;
For i from m+1 to m+2 do
For j from 1 to m do
e[i-m]:=e[i-m]+a[j]*(V[j]*h)^(i-1)/(i-1)!*(1/h^n);
od;
od;
Una vez ingresadas las dos matrices se procede a su cálculo, para calcular la matriz MA[]
utilizaremos el comando LinearSolve, de la siguiente manera
a:=LinearSolve(MA);

Para calcular la expresión del error comprobamos si el primer término es nulo
if e[1]=0 then;
E=e[2]*(D@@L)(f);
else;
E=e[1]*(D@@L)(f);
end if;
Utilización del programa
Para comenzar a utilizar el programa se debe ingresar la instrucción Maplets[Display](maplet), esta instrucción mostrarla pantalla de presentación

Que nos dara la opción de ir a la ventana de entrada de valores, esta ventana nos dara la opción de ingresar los valores de la derivada, los puntos la función, y el valor del h que por defecto es 0.005, luego nos salimos de la ventana de ingreso de valores y con el comando, Maplets[Display](mostrar):, inicializamos la ventana de los resultados,
que mostrara la formula de error y derivada, y la evaluación en los puntos correspondientes.

ahí va el código completo.....


Diferenciación Numérica Polinomios de Taylor

> restart;
> with(LinearAlgebra):

> AproxDiferencia:= proc(p,L,LI,F,X,H)
> local i,j,expresion,E,B,e,a,f,fp,fe,po,po1;
> B:=Matrix(L,L+1);
> e:=Vector(2); # Verctor de coeficientes de error
>
> for i from 1 to L do
> for j from 1 to L do
> B[j,i]:=(LI[i]*h)^(j-1)/(j-1)!*(1/h^p); # 'LI' es el valor del punto de la reticula
> od;
> od;
> B[p+1,L+1]:=1;

> a:=LinearSolve(B);
>
> f:=unapply(F,x);
> expresion:=sum('a[k]*f(x+LI[k]*h)','k'=1..L)/h^p;

> e[1]:=0;
> e[2]:=0;
> for i from L+1 to L+2 do
> for j from 1 to L do
> e[i-L]:=e[i-L]+a[j]*(LI[j]*h)^(i-1)/(i-1)!*(1/h^p); # 'LI' es el valor del punto de la reticula
> od;
> od;
> if e[1]=0 then;
> E:=e[2]*diff(f(x),x$p);;
> else;
> E:=e[1]*diff(f(x),x$p);;
> end if;


> fp:=unapply(expresion,x,h); Maplets:-Tools:-Set( 'visor' = MathML[Export](expresion));
> fe:=unapply(E,x,h); Maplets:-Tools:-Set( 'visor2' = MathML[Export](E));
> po:=fp(X,H);Maplets:-Tools:-Set( 'TF9' = evalf(po) );
> po1:=fe(X,H);Maplets:-Tools:-Set( 'TF10' = evalf(po1) );
> print(evalf(po));
> print(evalf(po1));
> print(E);

>
>
> end proc:




> with(Maplets[Elements]):maplet1:= Maplet([["Orden de la Derivada: ", TextField['TF1'](5)],
> ["Numero de Puntos: ", TextField['TF2'](5)],
> ["Puntos: ",TextField['TF3']("\[,\]",10)],
> ["Funcion: ",TextField['TF4'](10)],
> ["Punto a evaluar - x:",TextField['TF5'](8)],
> ["Amplitud h: ",TextField['TF6']("0.005", 10)],
> ["Ecuacion de la Derivada: "],
> [MathMLViewer( 'reference'='visor')],
> ["Error: "],
> [MathMLViewer( 'reference'='visor2')],
> ["Valor Derivada: ",TextField['TF9'](10)],
> ["Valor Eror: ",TextField['TF10'](10)],
> [Button("Derviar por Diferencias", Evaluate('function' = 'AproxDiferencia(TF1,TF2,TF3,TF4,TF5,TF6)')), Button("Salir", Shutdown(['TF1']))
> ]]):
> Maplets[Display](maplet1);






Emprendedores: ¿Quién es tu cliente?

“Hay dos tipos de personas en el mundo: hay personas que inventan excusas, y hay empresarios” Hace poco termine de leer el libro  Disc...