0% encontró este documento útil (0 votos)
230 vistas22 páginas

Redes Neuronales Haskell

Este documento describe la implementación de redes neuronales artificiales en el lenguaje de programación funcional Haskell. Se argumenta que Haskell puede ser una alternativa a lenguajes imperativos como C y Fortran para simular y entrenar redes neuronales, ya que permite desarrollar algoritmos sin usar arreglos e índices. Se presenta una biblioteca en Haskell para entrenar redes neuronales multicapa sin índices, aprovechando características funcionales como listas, funciones de alto orden y evaluación perezosa. Los resultados muestran que la biblioteca tiene un buen
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
230 vistas22 páginas

Redes Neuronales Haskell

Este documento describe la implementación de redes neuronales artificiales en el lenguaje de programación funcional Haskell. Se argumenta que Haskell puede ser una alternativa a lenguajes imperativos como C y Fortran para simular y entrenar redes neuronales, ya que permite desarrollar algoritmos sin usar arreglos e índices. Se presenta una biblioteca en Haskell para entrenar redes neuronales multicapa sin índices, aprovechando características funcionales como listas, funciones de alto orden y evaluación perezosa. Los resultados muestran que la biblioteca tiene un buen
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd

Implementacin de Redes Neuronales Artificiales en Haskell

Csar Augusto Acosta Minoli, Efran Alberto Hoyos, Julin Marn (Paper Publicado en Revista de Investigaciones Universidad del Quindo. Universidad del Quindo, v.14, p.133 - 146, 2004) Resumen
En la actualidad, la gran mayora del software de simulacin y entrenamiento de redes neuronales es desarrollado mediante lenguajes imperativos como C, Fortran y Pascal. El presente artculo tiene como fin, presentar al lenguaje de programacin funcional Haskell, como alternativa para la implementacin de algoritmos de simulacin y entrenamiento de redes neuronales aprovechando las potencialidades que este ofrece y sin recurrir al uso de arreglos e ndices, los cuales son responsables de la poca eficiencia y expresividad de los algoritmos numricos implementados en lenguajes funcionales. Se logr mostrar que es posible evitar el uso de arreglos e ndices para la implementacin de redes neuronales feedforward multicapa, generando un cdigo claro, simple y corto en comparacin con los lenguajes imperativos. Se encontr, cmo Haskell puede ser adecuado para la experimentacin con nuevos algoritmos de entrenamiento de redes neuronales gracias a su similitud sintctica con la matemtica y las fortalezas del lenguaje. Se desarroll una interfase en Haskell para que cualquier usuario pueda entrenar redes neuronales feedforward multicapa, sin tener un conocimiento profundo en programacin funcional. El estudio comparativo con Matlab mostr que la librera de redes neuronales desarrollada en Haskell tiene un buen desempeo y se puede usar como cualquier otro simulador con fines experimentales y educativos. Palabras Claves: Haskell, Redes Neuronales, Diseo e Implementacin, Lenguajes funcionales, feedfordward multilayer.

Abstract
Nowadays, most of the software to train and simulate neural network is developed in languages like C, FORTRAN and Pascal. This article intends to show how Haskell, a functional programming language, can be used to build a library to train and simulate Feedforward Multilayer Neural Network with all the features and advantages that the language can offer. This implementation doesn't use arrays nor index, which are responsible for low efficiency and little expressiveness for some numeric algorithms implemented in that way when using functional programming. We find that Haskell can be useful to develop new algorithms to train neural networks due to its syntactic similarity to mathematics and its language strengths. Good results are obtained when comparing the Matlab Neural Network toolbox and the Haskell Neural Network library. The library in this proposal can be used for educational and experimental purposes. Keywords: Haskell, Neural Networks, design and implementation, functional language, feedfordward multilayer.

"Learn at least one new [programming] language every year. Different languages solve the same problems in different ways. By learning several different approaches, you can help broaden your thinking and avoid getting stuck in a rut." The Pragmatic Programmer

Introduccin
La programacin funcional presenta una nueva alternativa para el diseo e implementacin de algoritmos; muchos son los aspectos que muestran el poder de este tipo de programacin. Actualmente existe una gran comunidad de cientficos de la computacin de diversas universidades y centros de investigacin a nivel mundial mostrando resultados interesantes en diferentes campos 1. Este tipo de programacin ofrece una forma diferente de razonar ante un problema computacional; como ejemplo es posible garantizar mediante el rigor matemtico, que el algoritmo que usted disea hace realmente lo que debe hacer, esto a primera vista lo hace ms confiable que los lenguajes imperativos y permite hacer un seguimiento ms claro del algoritmo en tiempo de diseo. Segn Richard Bird (Bird, 2000, 11), para comprender esta visin debemos tener en cuenta que: `` La programacin desde una perspectiva funcional, consiste en construir definiciones y en usar el computador para evaluar expresiones, el papel del programador consiste en definir una funcin que permita resolver un problema dado". Esta posicin propone resolver los problemas mediante la definicin de funciones explcitas, sin embargo, la prctica nos muestra que en algunos problemas existe tal imposibilidad debido a que hay una gran cantidad de situaciones que son difciles de modelar y de resolver mediante procesos algortmicos. Por tal motivo es necesario que este paradigma computacional centre sus ojos en la computacin blanda como una alternativa para ampliar su campo de accin.

Para una informacin completa y detallada de este paradigma de programacin visite www.haskell.org

Dentro de la computacin blanda y desde un punto de vista matemtico, una red neuronal se comporta como una funcin entre conjuntos, esta concepcin a pesar de ser implementada inicialmente en los lenguajes imperativos es inherentemente funcional. Para resolver un problema mediante redes neuronales se requiere bsicamente de construir una funcin a travs de un proceso iterativo, sin que exista una representacin explcita o simblica de la misma. Existen diferentes formas mediante las cuales las redes neuronales son llevadas a la prctica segn las especificaciones tericas, esto es lo que se conoce como `` Implementacin''. En la actualidad las redes neuronales se implementan bsicamente por software, es decir mediante la simulacin de la red en un PC convencional, o por hardware, mediante el uso de dispositivos electrnicos. La implementacin por software es la ms simple, inmediata y poco costosa. Alrededor de esta tendencia existen en versin comercial y freeware, una gran diversidad de herramientas para entrenar y simular redes neuronales. La gran mayora de estos desarrollos son realizados por medio de lenguajes imperativos como es el caso de C, FORTRAN y Pascal (HILERA,2000,105).

Se han hecho algunos intentos por llevar a la programacin funcional las redes neuronales (SERRARENS,1999), sin embargo han existido algunos aspectos que han impedido el avance en esta rea: la relativa juventud de los lenguajes funcionales frente a los lenguajes imperativos genera apata por parte de los programadores convencionales y por otra parte, el cambio de paradigma al cual se tiene que enfrentar un programador que ingresa al mundo de la programacin funcional produce como resultado que algunas implementaciones desarrolladas en los lenguajes funcionales luzcan como simples traducciones imperativas, este es el caso de la implementacin del lgebra Lineal mediante el uso de arreglos e ndices, la cual es a su vez el soporte matemtico de las redes neuronales. Destacadas investigaciones en el rea, muestran que el camino menos indicado para la implementacin de algoritmos de lgebra lineal en los lenguajes funcionales es mediante el uso de

arreglos e ndices, estos muestran poca eficiencia y expresividad (SERRARENS,1999) (SKIBINSKY, 1998). Dichos trabajos tambin muestran que la solucin ms prctica se obtiene por medio de listas, ya que los lenguajes funcionales son diseados teniendo en cuenta a las listas como la estructura lineal ms importante y porque cuentan con un gran nmero de funciones y operaciones para utilizarlas. Parece ser, que la ruta de una implementacin de redes neuronales sigue en esta direccin, pero cmo se implementan y se disean algoritmos para simular y entrenar una red neuronal sin ndices?

El presente artculo tiene como fin mostrar que es posible construir una librera para la simulacin y el entrenamiento de redes neuronales feedforward multicapa en Haskell sin recurrir al uso de arreglos e ndices. El objetivo es aprovechar las potencialidades que ofrece la programacin

funcional como es el caso del manejo de listas, llamados recursivos, evaluacin perezosa y funciones de alto orden para el desarrollo de software con un cdigo corto, seguro, de fcil comprensin y mantenimiento. En la primera seccin se pretende refinar los conceptos necesarios para comprender la filosofa de la programacin funcional. En la seccin siguiente se muestran los algoritmos de entrenamiento de redes neuronales que son implementados en Haskell y, finalmente se presenta una discusin sobre el desempeo de la librera a travs de un estudio comparativo con Matlab y otros lenguajes de programacin, mostrando as las posibilidades que Haskell ofrece en el diseo e implementacin de algoritmos en general.

Haskell: un lenguaje de Programacin Funcional


La gran mayora de los lenguajes de programacin existentes en la actualidad se pueden clasificar en dos grandes ramas segn la filosofa que los acoge: Los lenguajes imperativos como es el caso de C, Pascal, Fortran y los lenguajes declarativos como por ejemplo Prolog, Oz-Mozart y Lisp. Se dice que un lenguaje es imperativo si consiste de una secuencia de comandos e

instrucciones de asignacin las cuales son ejecutadas de manera estricta una despus de otra. Por su parte, el modelo declarativo se interesa ms por el qu debe ser computado, en vez del cmo debe ser computado, esta filosofa cambia las secuencias de comandos e instrucciones por declaraciones y definiciones dejando que la mquina se ocupe del resto; por este motivo los lenguajes declarativos son considerados como lenguajes de alto nivel.

La programacin funcional forma parte del pensamiento declarativo. Segn Peter Van Roy y Seif Haridi (VAN ROY P. y HARIDI S., 2002 ) la programacin funcional consiste de definir funciones las cuales son ejecutadas mediante la evaluacin de expresiones, donde las funciones son verdaderas funciones en el sentido matemtico. Se dice que un lenguaje funcional cuya nica forma de calcular sea mediante la evaluacin de funciones es un lenguaje funcional puro. Los lenguajes puramente funcionales se basan en un formalismo llamado el lambda-clculo una teora

matemtica desarrollada inicialmente por Alonzo Church, la cual consiste bsicamente en la definicin y evaluacin de funciones a travs de una serie de operaciones abstractas como lo son la unificacin, el ajuste de patrones y la evaluacin perezosa entre otras.

Haskell es un lenguaje de programacin funcional. Lleva su nombre en honor al lgico matemtico Haskell Brooks Curry (1900-1982). Haskell ha tenido algunas modificaciones desde su creacin en 1988, la ltima versin estable es Haskell 98 (JONES, PETERSON, 1999). Haskell es un lenguaje funcional puro (no posee extensiones imperativas), la computacin la realiza a travs de definiciones en vez de hacerlo por asignaciones como en los lenguajes imperativos; no existen estructuras cclicas como por ejemplo el for y el do-while de C y no existen las variables en el sentido de mutabilidad ni asignaciones destructivas, por ejemplo en Haskell es imposible hacer x:=x+1 como usualmente alguien lo hara en Pascal. A continuacin veremos algunas caractersticas que hacen de l un lenguaje moderno y atractivo para ser objeto de estudio:

Polimorfismo de Tipos: Haskell se caracteriza por ser fuertemente tipeado o estticamente tipeado, es decir los tipos de las variables y las funciones son detectados en tiempo de compilacin. El tipeado esttico permite detectar muchos errores en tiempo de compilacin y no en tiempo de ejecucin como suele suceder en algunos lenguajes. Adems el sistema de tipos de Haskell posee una propiedad muy importante conocida como polimorfismo. Para entender y apreciar su poder en detalle observe la siguiente funcin definida en Haskell: long :: [a]->Int long [] = 0 long (x:xs) = 1 + long xs
Figura 1. Funcin que calcula la longitud de una lista

La funcin que se muestra en la figura 1 calcula la longitud de una lista, la primera lnea indica el nombre de la funcin (long), en la parte derecha de (::) se observa el tipo de la funcin ([a]->Int), el polimorfismo radica en que sin importar el tipo de la lista, la funcin siempre retornar un entero. Por ejemplo al evaluar cualquiera de las siguientes tres expresiones: long [1,5,6] long [[2,3],[5,8],[9,7]] long [a,b,z]

Se obtiene como respuesta 3. En estos casos los tipos de las expresiones de entrada son respectivamente [Int], [[Int]] y [Char]. Este hecho es sumamente interesante ya que las funciones se pueden disear de forma general y por lo tanto pueden ser re-usadas con gran facilidad.

Funciones de alto nivel: Dentro de la programacin funcional algunos autores consideran que las funciones son ciudadanos de primer clase(BIRD,2000), esta frase tiene un gran significado en Haskell , ya que las funciones en s mismas son valores, las cuales pueden ser almacenadas, pueden ser pasadas como argumentos a otras funciones y tambin retornar como resultado de una funcin. Aquellas funciones que reciben funciones como argumento son consideradas como funciones de

alto nivel. Para ver esta propiedad consideremos un ejemplo clsico de la literatura en programacin funcional:

map

:: (a ->b) -> [a] ->[b]

map f [] = [] map f (x:xs) = f x: map f xs


Figura 2. Funcin map.

La funcin map que se describe en la figura 2, recibe como argumentos una funcin de la forma (ab), una lista de tipo a ([a]) y retorna una lista de tipo b ([b]), la funcin map aplica una funcin a cada uno de los elementos de una lista. Observe una vez ms la generalidad que ofrece el polimorfismo de tipos. Veamos algunos ejemplos del uso de map: map (+3) [1,2,3] = [4,5,6] map (*3) [1,2,3] = [3,6,9] map (head) [[3,4,5],[2,5],[6,8,9]] = [3,2,6] Las funciones de alto nivel son un poderoso mecanismo de abstraccin que puede mejorar sustancialmente la estructura y modularidad de muchos programas.

Evaluacin Perezosa: Haskell proporciona un mtodo para evaluar expresiones conocido como perezoso o no estricto. Este mtodo slo evala las partes necesarias de una expresin para obtener la respuesta, hay partes de la expresin que no son evaluadas del todo.

Ajuste de Patrones : El Ajuste de Patrones es otra caracterstica fundamental dentro de los lenguajes funcionales; sirve como esquema de pensamiento en el momento de definir funciones. Tomemos por ejemplo una funcin que sume los elementos de una lista de enteros ( figura 3):

suma :: [Int]->Int->Int suma [] s = s suma (x:xs) s = suma xs (x+s)


Figura 3. Funcin que suma los elementos de una lista.

Por ejemplo, si definimos suma [4,5,6] 0 obtendremos como resultado 15. La funcin suma recibe dos parmetros: la lista de enteros y un parmetro en el cual iremos acumulando la suma dentro de un proceso recursivo. Observe en la figura 3 como la funcin se define a travs de los posibles valores de entrada que pueda tomar, define la funcin suma en el caso de que una lista sea vaca: suma [] s = s, y posteriormente se define en el caso de una lista cuya cabeza es x y cola es xs suma (x:xs) s = suma xs (x+s). El evaluador busca que el valor de entrada se ajuste a algunos de los argumentos izquierdos de las definiciones y en caso de encontrar alguno entonces su expresin derecha ser usada para la llamada de la funcin. Finalmente note la importancia que tiene el ajuste de patrones a la hora de definir un proceso recursivo en Haskell. De acuerdo con lo anterior Haskell ofrece algunas ventajas que suenan bastante interesantes en el momento de desarrollar software: . Es de dominio pblico, cualquier persona puede usarlo libremente. Haskell permite eliminar los parntesis de las expresiones mediante el mecanismo de ajuste patrones por ejemplo f(x,y,z) puede ser escrito como f x y z. De manera similar las definiciones pueden ser escritas sin usar punto y coma (;) para separarlas, solo exige que las expresiones estn escritas en columnas siguiendo la misma sangra. Lo anterior hace que el cdigo sea corto, claro y de fcil mantenimiento. Pocos errores en tiempo de ejecucin. Est abierto hacia la enseanza, la investigacin y el desarrollo de aplicaciones, incluyendo la construccin de sistemas robustos

Permite re-usar el cdigo gracias a la generalidad que ofrece el polimorfismo. Por lo tanto, es posible adaptarlo con facilidad a una gran cantidad de aplicaciones.

La evaluacin perezosa y las funciones de alto orden permiten construir programas ms modulares, donde cada parte (funcin) tiene su propio significado y es independiente del programa.

Sin embargo, es imposible dar todos los crditos a Haskell pues existen algunas desventajas: Haskell ofrece al programador menos control sobre la maquina (programacin de alto nivel), esto puede traer ciertos inconvenientes cuando se quiere disear software donde el mximo desempeo se requiere a cualquier costo (programacin de bajo nivel). El recolector de basura a pesar de librar al programador del manejo de memoria tiene un costo en tiempo de ejecucin, lo cual puede repercutir en la eficiencia del programa. A pesar de todo, los autores e investigadores de Haskell (HUGHES ,1990) argumentan que el sacrificio es mnimo comparado con las ventajas que ofrece el lenguaje. Los beneficios de un modelo de programacin que ofrezca ms soporte valen ms que los modestos costos de ejecucin.

Construccin de una librera de Redes Neuronales en Haskell


Para construir un algoritmo en programacin funcional, este debe ser visto como una funcin explicita, al cual se le ingresa unos valores de entrada para retornar una salida, de manera similar una red neuronal se comporta como una funcin.. La figura 4 nos presenta de manera esquemtica la relacin. Funcin y=f(x) Haskell output = programa (input) Red Neuronal output = red (input)

Figura 4. El concepto de Red neuronal y de Algoritmo en Haskell.

Ahora bien, para lograr una implementacin con xito es necesario considerar los siguientes aspectos: estructura de datos, las funciones de lgebra Lineal y Clculo, el problema de la iteracin,

como almacenar los pesos y bias de la red, el conjunto de entrenamiento y las funciones de activacin. Estructura de datos Al momento de representar una matriz haciendo uso de la programacin funcional es necesario construir una estructura de datos que haga uso de listas en vez de arreglos e ndices por los siguientes motivos: Las listas son la estructura lineal ms importante de Haskell, adems cuenta con un gran nmero de funciones y operaciones para utilizarlas. A parte de la poca expresividad, la representacin de una matriz indexada en Haskell es poco eficiente, ya que los valores al ser atrapados en el constructor de datos Array, son de difcil acceso y esto tiene un costo computacional. La figura 5 nos muestra como se representa una matriz por medio de listas de listas, donde cada una de ellas representa una fila de la matriz.
a e h b f i c g =[[a, b, c ], [e, f , g ], [h, i, j ]] j

Figura 5. Una matriz como lista de listas.

lgebra Lineal sin ndices


El siguiente paso consiste en desarrollar una librera de operaciones bsicas de lgebra lineal para construir los algoritmos de entrenamiento. Para ver el proceso de construccin observe que en la figura 6, la funcin zipmatriz se usa para definir funciones que respectivamente sumen, resten y multipliquen elemento a elemento dos matrices, esta abstraccin hace uso del concepto de funcin de alto nivel.

10

zipFila ::(Num a)=>(a->a->a)->[a]->[a]->[a] zipFila f [] [] = [] zipFila f (x:xs)(y:ys) = (f x y):zipFila f xs ys zipMatriz ::(Num a)=>(a->a->a)->[[a]]->[[a]]->[[a]] zipMatriz f [] [] = [] zipMatriz f (x:xs)(y:ys) = zipFila f x y: zipMatriz f xs ys

sumaMatriz,restaMatriz, mulmatriz ::(Num a)=>[[a]]->[[a]]->[[a]] sumaMatriz a b = zipMatriz (+) a b restaMatriz a b = zipMatriz (-) a b mulMatriz a b = zipMatriz (*) a b Ejemplo: sumaMatriz [[3,4],[5,6]] [[8,9],[10,2]] = [[11,13],[15,8]]
Figura 6. Funcin zipmatriz.

De manera similar es posible construir funciones para desarrollar diferentes tipos de clculos matriciales sin hacer uso de arreglos e ndices, como lo son los productos entre matrices, el clculo de la inversa, solucin de sistemas de ecuaciones, el proceso de ortogonalizacin de Gram-Schmidt entre otros.

Iteracin y Recursin
El entrenamiento de una red neuronal es un proceso iterativo el cual consiste de la actualizacin de sus pesos y bias hasta que se cumpla un criterio de parada. El modelo imperativo de programacin implementa la iteracin y la actualizacin por medio de ciclos y asignaciones. En el caso de lenguaje C, el proceso iterativo se puede hacer por ejemplo por medio de la estructura dowhile(Condicin) la cual se ejecuta una y otra vez mientras la condicin sea verdadera. En el caso de la actualizacin, los lenguajes imperativos proporcionan la posibilidad de que una variable puede cambiar su valor en memoria, esto se puede hacer mediante una asignacin. Por su parte, Haskell no ofrece estructuras cclicas ni asignaciones, esto se debe a la naturaleza misma de la

11

programacin funcional la cual acta por medio de declaraciones y reduccin de expresiones. Sin embargo la iteracin y la actualizacin de variables se puede superar por medio de declaraciones recursivas. Es fcil demostrar por induccin matemtica que todo proceso iterativo se puede expresar como un proceso recursivo. La figura 7 nos muestra la funcin fIter la cual realiza un proceso Iterativo mediante la recursin. Observe como fIter se define haciendo uso de s misma y hace uso de valores enteros para determinar el nmero de ciclos de la iteracin ( init. y final). En el llamado recursivo init aumenta en una unidad y el proceso termina una vez init sea igual a final,

de lo contrario sigue modificando el valor g a travs de alguna funcin h. fIter g


fIter :: a -> Int -> Int -> b fIter g init final = if (init==final) then g else fIter (h g) (init+1) final
Figura 7. Proceso Iterativo haciendo uso de la recursin.

h(g)

La implementacin llevada a cabo se realiz pensando en los algoritmos de entrenamiento de redes feedforward multicapa. La arquitectura de una capa de este tipo de red luce como en la figura 8:

Figura 8. Arquitectura de una capa. Por lo tanto es necesario declarar los siguientes tipos como se aprecia en la figura 9:
type Input = [[Float]] type Target=[[Float]] type NeuralNetwork = ( [[Float]],[[Float]] ) Figura 9. Funcin zipmatriz.

12

Los tipos Input y Target no son ms que una redeclaracin de una matriz de tipo Float. Por su parte, el tipo NeuralNetwork se define como una pareja ordenada donde el primer componente

corresponde a la matriz de pesos y la segunda componente corresponde a la matriz de bias de la capa, es decir (W , b ) . Para simular una capa se define la funcin simlayer:
simLayer simLayer pQ (w,b) f :: Input->NeuralNetwork->(Float->Float)->Target = mapMatriz f (sumarVectorColumnas (pMatriz w pQ) b) Figura 10. Funcin simlayer.

Observe en la figura 10 la gran similitud sintctica con la formulacin matemtica de la salida de una capa, pues el llamado de esta funcin seria de la siguiente forma:

a=simlayer p (W,b) f
Un hecho interesante estriba en que la funcin de activacin f puede ser definida en un mdulo anterior y luego ser llamada, de esta forma se puede definir una arquitectura perceptron o una Adalaine respectivamente como: simLayer p (w,b) hardlim simLayer p (w,b) pureline La funcin anterior nos permite definir una funcin para el caso en el cual tenemos una arquitectura de cualquier cantidad de capas y neuronas en cada capa ( figura 11).
simMultilayer :: Input->[NeuralNetwork] ->[(Float->Float,Float->Float)] ->[Target] simMultilayer _ [] _ = [] simMultilayer pQ (g:gs) ((f,f'):fs) = a:simMultilayer a gs fs where a=(simLayer pQ g f) Figura 11. Funcin simMultilayer.

Una vez se ha definido una funcin de simulacin, se necesario considerar toda una serie de funciones auxiliares para el manejo de la informacin como lo son: Funciones de conversin lista a Neuralnetwork y viceversa Funciones para inicializar los pesos y bias.

13

Finalmente hace falta construir las funciones de entrenamiento y de interfase con el usuario para conformar la primera fase de la librera. Estas son las siguientes: Funcin trainperceptron para entrenar una red Perceptron Funcin trainAdaline para entrenar una red Adaline Funcin trainBPGSD para entrenar una red Backpropagation con gradiente descendente Funcin trainBPbm modo cascada. Funcin trainBPM para entrenar una red Backpropagation con momentum Funcin trainBPMX para entrenar una red Backpropagation con rata de aprendizaje variable Funcin trainCGBP para entrenar una red Backpropagation con gradiente conjugado Funcin trainLMBP para entrenar una red Backpropagation con Levenberg-Marquardt para entrenar una red Backpropagation con gradiente descendente en

Es de inters notar que la cantidad de cdigo para la creacin de la librera es realmente pequeo en comparacin con otros lenguajes de programacin. (No supera los 70K), para apreciar esto en detalle observe en la figura 12 el cdigo de la funcin trainperceptron, la
cual recibe como argumentos la matriz P de entrada, la matriz de T de supervisin y las matrices de pesos y bias de la red. Esta retorna las matrices de pesos y bias entrenadas.
trainPerceptron :: Input->Target->NeuralNetwork->Int->[(Int,NeuralNetwork)] trainPerceptron p t g sh = tPerceptron p' t' g size 0 sh where p' =(headArray p) t' =(headArray t) size =(fromInteger (long (head t))) tPerceptron :: [Input]->[Target]->NeuralNetwork ->Int ->Int ->Int->[(Int,NeuralNetwork)] tPerceptron p t g q epoca sh = let { prueba=trainning p t g 0; next =if ((epoca `mod` sh)==0) then (epoca,([],[])):r else r; r =tPerceptron p t (snd prueba) q (epoca+1) sh } in if (fst(prueba)==q) then [(epoca,g)] else next trainning :: [Input]->[Target]->NeuralNetwork->Int->(Int,NeuralNetwork)

14

trainning [] _ g s = (s,g) trainning (x:xs) (y:ys) g s = if (esCero e 0)==0 then trainning (xs)(ys) g (s+1) else trainning (xs) (ys)(actualizar x e g) s where e = restaMatriz y (simLayer x g hardlim) esCero :: [[Float]]->Int->Int esCero [] s = s esCero (x:xs) s = if x==[0] then esCero xs s else esCero xs (s+1) actualizar :: [[Float]]->[[Float]]->NeuralNetwork->NeuralNetwork actualizar p e (w,b) = (sumaMatriz w (pMatrizC e p) , sumaMatriz b e) Figura 12. La Funcin trainPerceptron y sus funciones auxiliares.

Sesin de Entrenamiento
Para entrenar y disear una red mediante la librera de Redes Neuronales, se puede usar Hugs 98, un programa con la capacidad de interpretar el lenguaje Haskell 98. Otra alternativa es el compilador GHC (Glasgow Haskell Compiler) con la posibilidad de crear archivos ejecutables. La librera es portable y se puede usar tanto en el interpretador Hugs 98 como en el compilador Glasgow. Como ejemplo, observe la sesin de entrenamiento de la figura 13, la cual puede ser escrita en un fichero de extensin (*.txt) y guardada con extensin (*.hs).
Module ParityProblem where import Transfer import NeuralNetwork import Interface p p t t brain brain ft ft main ::Input =[ [-1,-1,2,2],[0,5,0,5] ] ::Target =[[-1,-1,1,1]] // Matriz de Entrada // Matriz de Supervisin

:: [NeuralNetwork] // Lista de Parejas de (W,b) Matriz de Pesos y Bias = [([[-0.27,0.28],[-0.41,0.5],[0.25,0.3] ], [ [-0.48 ],[-0.13],[-0.2] ]),( [[0.09,-0.17,0.1]],[[0.48]])] :: [(Float->Float,Float->Float)] // Lista de funciones de activacin por capas = [(tansig,dvtansig),(purelin,dvpurelin)] = entrenarBPGSD p t brain ft 0.05 300 50 0.00001 Figura 13. Sesin de Entrenamiento.

Al ejecutar este mdulo y llamando a la funcin main 0.01 879 se obtiene el resultado que se muestra en la figura 14:

15

"Epoca 0/300, MSE 1.43410770/0.00001000" "Epoca 50/300, MSE 0.00170720/0.00001000" "Epoca 100/300, MSE 0.00018103/0.00001000" "Epoca 150/300, MSE 0.00004919/0.00001000" "Epoca 200/300, MSE 0.00001671/0.00001000" "Epoca 226/300, MSE 0.00000997/0.00001000" Simulacion : [-1.00466200 -0.99593710 1.00121180 0.99959400] Supervision : [-1.00000000 -1.00000000 1.00000000 1.00000000]
Figura 14. Resultados de Entrenamiento.

La librera ofrece la posibilidad de almacenar los pesos y bias de la red en un archivo de texto.

Estudio Comparativo
Para estudiar el desempeo de la implementacin se utilizaron varios problemas de referencia que aparecen en la literatura de las redes neuronales. Estos se encuentran clasificados segn su naturaleza y el tamao de la informacin que procesan. Para revisar de forma relativa la eficiencia en tiempo de entrenamiento de la librera, se realizan 20 corridas de cada funcin sobre un mismo problema, modificando los pesos iniciales de la red y los parmetros de entrenamiento de cada funcin. En esta comparacin la mejor respuesta se considera aquella que ofrezca el menor error medio cuadrtico. Dicha respuesta ser comparada con Matlab ejecutndola 10 veces y utilizando los mismos parmetros y pesos iniciales de entrenamiento, el mejor tiempo es tomado en ambos casos. Todas las pruebas se realizaron en un PC con procesador AMD-ATHLON de 850 Mhz con 256 Mb de memoria, utilizando a Windows 98 como sistema operativo. El compilador para la librera en Haskell fu GHC compiler versin 5.04.3 para Windows y los tiempos fueron capturados mediante la funcin getClockTime, una funcin pre-definida de Haskell. Para la comparacin se us Matlab versin 6.1.0.450 release 12.1. La siguiente tabla hace un resumen de los problemas de entrenamiento:

Problema Seno Encoder

Tipo de Problema Configuracin Tolerancia (mse) Aprox. Funciones 1-5-1 0.002 Aprox. Funciones 10-5-10 0.01 16

Paridad 3 bits Paridad 6 bits

Rec. de Patrones Rec. de Patrones

3-3-1 6-12-1

0.001 0.001

Tabla 1. Problemas de referencia para analizar el desempeo.

En las siguientes tablas 2, 3 y 4 se observa la comparacin realizada entre la librera de Haskell y Matlab, aqu T(s), significa tiempo en segundos, E significa el nmero de pocas y mse el error medio cuadrtico.

Haskell BPbm BPM BPMX BPGC BPLM

T(s) 151 25 50 18 3

E 15000 2419 3130 208 25

Mse 0.003 0.0019985 0.0019999 4 0.0016542 6 0.0001667 8

Matlab traingd traingdm traingdx traincgf trainlm

T(s) 70.09 75.41 14.94 1.76 0.39

E 15000 15000 3168 115 23

Mse 0.00215947 0.48345 0.00199951 0.00198608 0.001551

Tabla 2. Comparacin entre los mejores resultados obtenidos por las funciones de la librera de Haskell y sus respectivas funciones homologas en Matlab para el entrenamiento de la funcin sen(x).

Haskell BPbm BPM BPMX BPGC BPLM

T(s) 23 1 13 3 1

E 8654 459 3120 95 8

Mse 0.0009986 0.0009591 0.0008550 3 0.0006834 0.0001541 7

Matlab traingd traingdm traingdx traincgf trainlm

T(s) 34.82 2.25 13.73 1.93 0.27

E 8654 459 3230 160 8

Mse 0.000998828 0.000995905 0.000972952 0.000991767 0.000153235

Tabla 3. Comparacin entre los mejores resultados obtenidos por las funciones de la librera de Haskell y sus respectivas funciones homologas en Matlab para el problema de la paridad de 3 bits.

Haskell BPbm BPM BPMX BPGC BPLM

T(s) 53 26 3 31 123

E 3629 1595 103 172 7

Mse 0.0099923 2 0.0099820 1 0.0092706 9 0.0099747 0.0007124 1

Matlab traingd

T(s) 44.05

E 10000 10000 146 69 92

Mse 0.0513344 0.0208439 0.00930574 0.0100008 0.0100004

traingdm 47.35 traingdx traincgf trainlm 0.94 1.04 1.26

Tabla 4. Comparacin entre los mejores resultados obtenidos por las funciones de la librera de Haskell y sus respectivas funciones homologas en Matlab para el problema del Encoder 10-5-10.

17

El estudio comparativo muestra que el desempeo de la librera es bastante bueno teniendo como referente a Matlab para los problemas propuestos. La seccin anterior tambin muestra un cdigo claro, corto en comparacin con los lenguajes imperativos y sin la necesidad de usar arreglos e ndices. Sin embargo se mostr que se requiere de mucho ms tiempo para realizar las operaciones. Lo anterior permite formular la siguiente pregunta: Cul puede ser el papel de Haskell frente a la computacin numrica en la actualidad? Haskell y La computacin Numrica La programacin funcional ofrece la oportunidad de crear un cdigo mucho ms comprensible y fcil de manejar gracias a la similitud sintctica con la matemtica, los altos niveles de abstracin permiten crear un cdigo ms estructurado y reusable. No se pide obtener una alta eficiencia en tiempo por parte de Haskell, pues su misma naturaleza como lenguaje de alto nivel lo impide, adems la relativa juventud de este tipo de programacin ofrece un gran campo de investigacin en el cual se puede pensar en buscar nuevas alternativas para la construccin de compiladores ms eficientes, como tambin en la formacin de alianzas con lenguajes de bajo nivel para la optimizacin de algunas operaciones, como es el caso del producto de valores de punto flotante. Lo importante a destacar estriba en las posibilidades que tiene Haskell para la creacin y experimentacin de nuevos algoritmos en el campo de la computacin numrica. Como ejemplo es posible, aprovechar el lenguaje para la experimentar modificaciones en los algoritmos objeto de estudio, este es el caso del algoritmo para entrenar una red neuronal por medio del gradiente descendente haciendo uso del momentum para filtrar la oscilacin del algoritmo frente a la rata de aprendizaje. La regla para calcular el gradiente es:

Una posible modificacin de este algoritmo consiste en almacenar el gradiente negativo multiplicado por la rata de aprendizaje de la iteracin anterior:

18

Esta modificacin no implica un cambio significativo en la estructura del cdigo de la funcin trainBPM, sin embargo se obtienen interesantes resultados en el caso del problema de la paridad con 3 bits. La tabla 5 contiene la comparacin entre trainBPM y la funcin modificada

trainBPMmod, considerando 20 corridas de ambas funciones con diferentes pesos iniciales y diferentes parmetros de entrenamiento. En este caso se registr el nmero de pocas y el mse de cada sesin, el mximo nmero de pocas permitidas fu de 15000.
Epocas Epocas

trainBPMmod No. Semilla Lr Mo trainBPM mse mse mod 1 742 0,4 0,8 2339 0,00098567 1057 0,00090055 2 635 0,6 0,8 1662 0,00099051 617 0,00091584 3 978 0,4 0,9 15000 0,21901823 1710 0,00096925 4 30 0,7 0,9 5066 0,00099667 1469 0,00089077 5 730 0,5 0,9 691 0,0009966 679 0,00096144 6 230 0,5 0,9 768 0,00099915 835 0,000993 7 316 0,6 0,9 15000 0,4999997 804 0,00098025 8 246 0,8 0,9 2470 0,0009996 4248 0,00099187 9 77 0,6 0,9 1216 0,00099865 682 0,00096919 10 508 0,6 0,9 15000 0,5 2698 0,00093841 11 92 0,6 0,9 15000 0,499999 4251 0,00094779 12 513 0,6 0,9 943 0,00099666 1062 0,00094563 13 715 0,6 0,9 1440 0,00099993 814 0,00095915 14 524 0,6 0,9 1007 0,00099917 576 0,00099122 15 301 0,6 0,9 15000 0,16697064 787 0,00098572 16 129 0,6 0,9 15000 0,18768963 822 0,00095913 17 753 0,6 0,9 15000 0,15018547 811 0,00094694 18 171 0.6 0.9 15000 0.18825182 1031 0.00096965 19 94 0,6 0,6 337 0,00099996 657 0,00099954 20 953 0,6 0,9 15000 0.18760048 1054 0.00097735 Tabla 5. Comparacin entre los mejores resultados obtenidos por las funciones trainBPM y trainBPMmod de la librera de Haskell. Observe en la tabla 5 como la modificacin trainBPMmod permite encontrar resultados en aquellas situaciones donde la funcin original no converge. El prximo paso consistira entonces en revisar las propiedades matemticas de este resultado, las posibilidades que este ofrece, y posteriormente se puede pensar en la implementacin de la misma en un lenguaje de bajo nivel.

19

Conclusiones y Trabajo Futuro


En el transcurso de la investigacin, en lo atinente a la revisin bibliogrfica; el diseo y la implementacin de la librera; el desarrollo de la interfase y el estudio comparativo con Matlab; se destacan las siguientes conclusiones: Qued demostrado que no es necesario usar ndices y arreglos para el diseo e implementacin de algoritmos que simulen y entrenen redes neuronales. Haskell posee grandes posibilidades para el diseo y evaluacin experimental de nuevos algoritmos de forma rpida gracias a la cercana que tiene con la especificacin del problema a implementar y su similitud sintctica con la matemtica. Haskell permite expresar

algoritmos de forma clara y simple, esto es til en el momento de desarrollar y de derivar versiones ms eficientes a bajo nivel. La librera sirve con fines educativos, se puede usar para que los estudiantes aprendan a disear y a entrenar redes neuronales como tambin la forma como se implementan en lenguajes funcionales. Se desarroll una tcnica efectiva de escribir e implementar algoritmos de redes neuronales considerando todas las ventajas y propiedades esenciales de la programacin funcional. Haskell como lenguaje de programacin funcional puro, an no est preparado para competir por la eficiencia en tiempo, su caracterstica de lenguaje de alto nivel le impide tal rapidez, por tal motivo es necesario la generacin de alianzas con lenguajes de bajo nivel que se encarguen de hacer el trabajo pesado y menos significativo; en el caso de las redes neuronales el producto punto y el producto de matrices. Como ejemplo de estas alianzas, muchos de los algoritmos de Matlab estn desarrollados en una eficiente librera de bajo nivel diseada para el lgebra lineal numrica conocida como LAPACK. Adicionalmente Matlab hace un uso cuidadoso de C y ensamblador en muchas de sus rutinas. Estas alianzas han logrado optimizar significativamente las operaciones que se pueden realizar en Matlab,

20

como referencia, para ciertas versiones de Matlab, calcular el producto de matrices de tamao 528 tomaba hasta 25 segundos, las nuevas versiones pueden realizar esta operacin en menos de 3.6 segundos. Trabajo Futuro Se hace necesario un estudio sobre las posibilidades de hacer una alianza entre lenguajes de bajo nivel y Haskell para la construccin de algoritmos precompilados de bajo nivel que puedan ser usados por Haskell. A nivel terico es necesario observar las posibilidades que Haskell ofrece para el diseo de nuevos algoritmos de redes neuronales puramente funcionales, explicando la teora de las redes desde el lambda clculo.

21

Referencias
1. BIRD, R. (2000), Introduccin a la Programacin Funcional con Haskell , Prentice Hall. 2. DEMUTH, H. (2000) Neural Network Matlab Toolbox. TheMathWorks,Inc. 3. DONOSO, Y (2000) Desarrollo y anlisis del rendimiento de la programacin funcional para la solucin de ecuaciones diferenciales. Revista Ingeniera y desarrollo. Universidad del Norte, Barranquilla Colombia. 4. FAUSETT, L. (1994) Fundamentals of Neural Networks. Prentice Hall. 5. HAGAN, M. DEMUTH, H. y BEALE, M. (1995) Neural Network Design. Plus Publishing Company. 6. HILERA, J. y MARTINEZ, V.(2000) Redes Neuronales Artificiales. Alfaomega. 7. HUGHES, J. (1990) Why Functional Programming Matters. Tutorial. 8. JONES, M. y PETERSON, J. (1999) Hugs 98. Manual de Usuario 9. MOLER, C. (2000)Matlab Incorporates Lapack. Matlab News And Notes. 10. PEYTON S. (2000), A Gentle Introduction to Haskell , Tutorial. 11. RAO, V. y RAO, H (1993), (1993) C++ Neural Networks and Fuzzy Logic, EditMis Press. 12. RIEDMILER, M. (1994) Advanced Supervised Learning in Multi-Layer Perceptrons from Backpropagation to Adaptive Learning Algorithms. Journal of Computer Standards and Interfaces Special Issue on Neural Networks. 13. RUSELL, S. y NORVIG, P. (1996) Inteligencia Artificial: Un Enfoque Moderno. Prentice Hall. 14. SERRARENS, P. (1999) Implementation the Conjugate Gradient Algorithm in a Functional Language. Computer Science Institute University of Nijmegen 15. SHANG, Y. y WAH, B. (1996) Global Optimization for Neural Network Training. Coordinated Science Laboratory University of Illinois. 16. SKIBINSKY, J. (1998). Indexless Linear Algebra Algorithms. Numeric Quest Inc Hunstsville-Ontario Canada. 17. VAN ROY P. y HARIDI Computer Programming. S., (2002) Concepts, Techniques, and Models of

22

También podría gustarte