PRÁCTICA .- APRENDIZAJE CON REDES NEURONALES ...

16
PRÁCTICA .- APRENDIZAJE CON REDES NEURONALES USANDO JavaNNS: Un ejemplo sencillo sobre puertas lógicas. I. FUNCIÓN AND El objetivo de este primer apartado será construir una sencilla red neuronal sin unidades ocultas, con el fin de definir los patrones de entrenamiento para el aprendizaje de la función AND, y con el fin de entrenar la red con esos patrones. Tras lanzar el fichero JavaNNS.jar, aparece la pantalla que se ilustra aquí: Esta pantalla contiene una red vacía donde podemos empezar a construir la red que queramos. La red inicial para realizar este ejercicio tendrá dos unidades de entrada y una unidad de salida. Todas las unidades tendrán una función de activación logística. Si queremos generar las unidades tendremos que seleccionar en el menú Tools->Create->Layers. Aparecerá el panel Create layers. Hay que seleccionar como tipo de unidad Input y presionar dos veces al botón Create. Ahora seleccionad unidades de tipo Output y presionar una vez más en el botón Create. Ahora ya se puede cerrar el panel Create layers.

Transcript of PRÁCTICA .- APRENDIZAJE CON REDES NEURONALES ...

PRÁCTICA .- APRENDIZAJE CON REDES NEURONALES USANDO JavaNNS: Un ejemplo sencillo sobre puertas lógicas.

I. FUNCIÓN AND

El objetivo de este primer apartado será construir una sencilla red neuronal sin unidades ocultas, con el fin de definir los patrones de entrenamiento para el aprendizaje de la función AND, y con el fin de entrenar la red con esos patrones.

Tras lanzar el fichero JavaNNS.jar, aparece la pantalla que se ilustra aquí:

Esta pantalla contiene una red vacía donde podemos empezar a construir la red que queramos. La red inicial para realizar este ejercicio tendrá dos unidades de entrada y una unidad de salida. Todas las unidades tendrán una función de activación logística. Si queremos generar las unidades tendremos que seleccionar en el menú Tools->Create->Layers. Aparecerá el panel Create layers. Hay que seleccionar como tipo de unidad Input y presionar dos veces al botón Create. Ahora seleccionad unidades de tipo Output y presionar una vez más en el botón Create. Ahora ya se puede cerrar el panel Create layers.

Tendremos entonces una red con tres unidades representadas mediante cuadros coloreados. Eligiéndolas una a una y presionando el botón derecho del ratón sobre ellas, podemos utilizar la opción Edit units si queremos editarlas. Se pueden cambiar los nombres de las unidades, por ejemplo en lugar de "noName" podemos poner "Entr1" y "Entr2", y la unidad de salida “Sal”. Sería conveniente seleccionar las unidades con el ratón y arrastrarlas poniéndolas en lo que es la ventana de la red de forma que las unidades de entrada se en-cuentren debajo de la unidad de salida, como aparece a la derecha.

A continuación, habría que crear las conexiones. Seleccionando dos unidades (manteniendo la tecla “Ctrl” mientras que se selecciona con el ratón) y en el menú Tools->Create->Connections. El panel Create links aparece. Pulsad el botón “Mark selected units as source”. Ahora seleccionad la unidad de salida y presionad el mismo botón (ahora bajo el título “Connect source to the selected units”). Las conexiones desde las unida- des de entrada a las unidades de salida aparecerán con un número que representa el peso de la conexión. Guarda esta red como “TusApellidos_TuNombre_AND.net”. (Si soy dos 1erApellidoNombreDeUno_1erApellidoNombreDelOtro _AND.net)

En este momento se ha de generar el fichero de patrones para entrenar la función AND. Se puede hacer modificando el fichero de texto “xor.pat” que se encuentra en el directorio de ejemplos (examples) del paquete JavaNNS. Este es el texto que encontraréis:

SNNS pattern definition file V3.2 generated at Mon Apr 25 15:58:23 1994 No.

of patterns : 4 No. of input units : 2 No. of output units : 1 # Input pattern 1: 0 0 # Output pattern 1: 0 # Input pattern 2: 0 1 # Output pattern 2: 1 # Input pattern 3: 1 0 # Output pattern 3: 1 # Input pattern 4:

1 1 # Output pattern 4: 0

Intenta analizar el significado de estos patrones, define los que crees que serían necesarios para la función AND y guarda este fichero como “TusApellidos_TuNombre_AND.pat”. (Si soy dos 1erApellidoNombreDeUno_1erApellidoNombreDelOtro _AND.pat)

Ahora ya puedes abrir con JavaNNS este fichero de patrones que acabas de generar. Verás que en el panel de estatus, justo abajo del menú aparece la opción del patrón de entrenamiento.

Para observar cómo cambia el error durante el entrenamiento de la red, selecciona en el menú Tools->Control Panel, y View->Error Graph. Con el fin de observar el comportamiento (tanto

en la entrada como en la salida de la red, selecciona las tres unidades de la red y selecciona también la opción View->Projection. Como explica el manual de JavaNNS, este panel de proyección muestra la activación de las unidades ocultas o de salida en función de la activación de las dos unidades de entrada. El panel solo puede abrirse cuando se han seleccionado tres unidades dentro de la vista de una red. Así, tendríais en la pantalla activa cuatro ventanas con los paneles que se muestran en la figura

de arriba.

Para verificar los patrones de entrenamiento habría que pinchar en la pestaña Patterns del panel de control (Control Panel), asegurándote de que las unidades en la ventana con la red han sido deseleeccionadas y entonces ir moviéndote de un patrón a otro con los botones “>” y “<”. El color de los nodos refleja el grado de activación, y la correspondencia está indicada por la barra de colores de la izquierda

También se pueden cambiar las opciones de visualización para permitir que las etiquetas asociadas con los nodos muestren directamente el valor de activación.

Ahora ya podéis comenzar con la tarea de aprendizaje. Primero, habrá que inicializar los valores de los pesos de la red con la lengüeta de Learning en el panel de control (Control Panel). Observa las consecuencias en el Error Graph. Se puede cambiar el factor de acercamiento del gráfico empleando las dos flechas (triángulos) de zoom que hay junto a cada uno de los ejes de coordenadas. También se puede seleccionar View->Log para visualizar el valor numérico real del error durante el proceso de aprendizaje. Tanto en el manual de JavaNNS como en el de SNNS existen descripciones de los distintos parámetros y reglas de aprendizaje disponibles en el panel de control.

Comprueba cómo la proyección de la salida (Projection to Out) refleja el estado de aprendizaje de la red. Intenta reinicializar los pesos y repetir el aprendizaje con distintos ratios de aprendizaje. Fijaos que la visualización de esta pantalla de proyección ralentiza la ejecución de notablemente. Por ello, normalmente será preferible cerrar esta ventana y abrirla sólo al final para ver cómo ha quedado. Se puede aumentar la resolución de la proyección mediante el botón Increase resolution representado por una matriz de puntos y que se encuentra en la esquina inferior izquierda de esta ventana de proyección. Describe y explica lo sucedido. II. FUNCIÓN XOR

En este segundo paso del ejercicio, intentaremos aplicar la red que ha sido capaz de aprender la función AND para aprender también la función XOR. Revisad en los apuntes y/o bibliografía qué tipos de funciones puede aprender una red tan sencilla como esta y sin unidades ocultas. Cargad el fichero de patrones de entrenamiento “xor.pat”, reinicializad la red, lanzad el aprendizaje y observar la evolución del error. Debéis probar a aumentar el número de ciclos de

aprendizaje y los valores de los parámetros de aprendizaje. ¿Qué ocurre?

II-B. PERCEPTRÓN MULTICAPA PARA LA FUNCIÓN XOR

Acabáis de comprobar cómo la tarea de aprendizaje de la función XOR no puede ser aprendida mediante un perceptrón con una única capa. Vamos a añadirle ahora a la red una capa de neuronas e intentaremos aprender la función XOR de nuevo.

Con el patrón de entrenamiento “xor.pat” cargado, tendríamos que ir a la ventana de la red (Network) y añadir una nueva unidad, como hacíamos para la función AND. Pero esta vez necesitamos indicar que la unidad es oculta, por lo que en el tipo de unidad hay que escoger Hidden. Ponedle un nombre a la unidad que sea más representativo, por ejemplo “Oculta1”.

Ahora tendríamos que conectar esta nueva unidad oculta a la de salida, y las unidades de entrada también con la nueva unidad oculta. Guardad esta red con la misma nomenclatura que hemos seguido hasta ahora: ****_XOR1.net De este modo obtenemos una red híbrida con algunas conexiones que van directamente desde la entrada a la salida y otras que van primero a la unidad oculta. Tras inicializar los pesos, lanzad el proceso de entrenamiento y observad el grafo de error y la ventana de proyección. Mostradlos y analizarlos sacando las conclusiones que consideréis oportunas.

Ahora deberíais probar a ver qué pasa cuando eliminamos las conexiones directas desde las unidades de entrada a la salida. Para borrar una conexión hay que seleccionar los dos nodos enlazados y con el botón derecho del ratón y el cursor en alguno de los dos nodos seleccionar Delete Link. Obtendremos una red con una única unidad oculta. Guardadla llamándola ****_XOR2.net

Intenta entrenar la red con el fichero de patrones XOR. ¿Aprende la red este patrón? ¿Podrías justificar el resultado obtenido? Para obtener alguna pista, podéis mirar la proyección de la función que asocia las entradas a la unidad oculta y también a la unidad de salida.

Ahora si añadimos otra unidad oculta, conectémosla a la unidad de salida y a las dos unidades de entrada. . Guardadla llamándola ****_XOR3.net Prueba a entrenar la red con el patrón de entrenamiento XOR (para agilizar la ejecución, cierra todas las ventanas de proyección mientras que entrenas la red y vuelve a generar dichas ventas cuando acabe el entrenamiento). ¿Aprende la red el patrón? ¿Puedes justificar el resultado observado? Como pista, mira una vez más la proyección de la función que asocia las unidades de entrada con la unidad oculta y con la unidad de salida. Comparalas con las proyecciones del caso anterior y escribe lo que te sugiera esta comparación.

III. ESTUDIO DE DIFERENTES ALGORITMOS DE APRENDIZAJE PARA LA FUNCIÓN XOR

Ahora, y además de todo lo indicado anteriormente, vamos a usar esta última red ***_XOR3.net o con alguna distinta que vosotros ideéis y que se os ocurra que pueda funcionar igual o mejor ****_XOR_otra.net. En este punto se trata de experimentar con el ratio de aprendizaje para ver si puedes acelerar el proceso de aprendizaje. Comprueba cómo se comporta el aprendizaje al variar este valor y escribe las conclusiones y/o las observaciones que puedas sacar de dicho comportamiento. Además del algoritmo estándar de back-propagation (retropropragación) hay muchas variantes. Selecciona por ejemplo (y al menos)

“Backprop-Momentum” “Quickprop” y “Rprop” como función de aprendizaje (Learning function), inicializando los pesos y entrenando de nuevo la red. Varía los distintos parámetros (incluido el número de ciclos) y haz un estudio/comparativa sacando y escribiendo tus propias conclusiones. Para desarrollar este punto puedes (y sería interesante) incluir gráficos, pantallazos, cuadros, documentación sobre las funciones de aprendizaje,… y en general toda aquella información e ilustraciones que consideres oportunas.

IV. ENTRENAMIENTO Y VALIDACIÓN

Esta parte final del ejercicio trata de mostrar un ejemplo sencillo de cómo podría ser una aplicación de redes neuronales real, y os permitirá experimentar con diferentes patrones de entrenamiento y validación.

Como indica el fichero letters.README (en inglés, aquí está traducido):

La entrada de la red es una matriz de elementos binarios 5x7. Esta red presenta 10 unidades ocultas en una única capa oculta que está completamente conectada tanto a las unidades de entrada como a las de salida. Cada una de estas 26 unidades de salida

representan una letra en mayúsculas y que mostrará una salida de 1 si el patrón de entrada se corresponde con esa clase (letra) o un 0 en cualquier otro caso.

El fichero de patrones “letters.pat” contiene 26 patrones de entrenamiento (uno ejemplar para cada una de las letras mayúsculas). Estos patrones tienen valores binarios de 0 ó 1 aunque SNNS trate todas las entradas y salidas como valores reales. Puesto que cada patrón se da sólo una vez no existen patrones con ruido en este fichero, por lo que no podría usarse para generalizar.

Primero, deberías experimentar tratando de entrenar esta red, de manera similar a como lo hicimos para la función XOR. Describe lo que sucede y comenta lo que consideres importante. Después, haz una copia del fichero de patrones “letter.pat” y renómbrala como

“***letterValidacion.pat”. Ahora edita este fichero de patrones cambiando alguno de sus patrones de entrada con el fin de simular la presencia de algún ruido en los patrones de validación. Finalmente, carga el fichero de patrones “***letterValidacion.pat” y selecciónalo en la lengüeta Patterns del panel de control (Control panel) como el conjunto de validación, entrenando la red de nuevo. Para evaluar el error sobre el conjunto de validación fija en cada paso el mismo número de ciclos (Cycles) y pasos (Steps) en la lengüeta Aprendizaje (Learning) del panel de control. Observa la evolución de los errores de entrenamiento y validación en la ventana del grafo de error (Error graph). Anota tus observaciones y/ comentarios.