Para comenzar cree un directorio de trabajo en su directorio raíz. Para fines de ejemplo, denomínelo ‘anns’ y haga de ‘anns’ su directorio actual.
Después de que haya creado el entorno de trabajo, continúe e inicie SNNS escribiendo:
xgui
Cuando SNNS haya iniciado, enviará una ventana de inicio y la ventana del gestor SNNS. De click en cualquier parte de la ventana de inicio y haga que desaparezca. La ventana restante del gestor debe lucir como la siguiente.
En la ventana del gestor se puede controlar que otras están visibles tras dar click en los botones. Las ventanas importantes para este tutorial son la ventana File, la ventana de Control, la ventana de Info, la ventana Display, la Graph y la Help. Nota: la ayuda de SNNS no es tan mala, empleando la ventana de Ayuda puede otorgarnos más información acerca de los temas que trata este tutorial.
Cargando una Red
De click en el botón File para traer la ventana de File.
Note que el botón de Network es resaltado, lo que significa que solo los archivos de red se mostrarán en la lista de archivos. Los otros tipos de archivo serán asimismo mostrados únicamente en ese tipo. Los dos tipos de archivo que serán de interés para este tutorial son los Network y los Pattern, los archivos Network guardan configuraciones de la red y valores pesados, los archivos Pattern guardan patrones de entrada/salida para fines de entrenamiento y prueba.
Continúe con la carga del archivo Network xor dando doble click en el nombre del archivo y después en el botón LOAD. Debería mirar que el SNNS ha impreso un aviso de que la red fue cargada del archivo. El texto aparece en la consola donde se ha iniciado el SNNS. El SNNS empleará esta ventana para mantenerlo informado de sus actividades.
Deje la ventana File abierta para la siguiente tarea. Antes de cargar algún otro archivo, sin embargo, de una mirada a la red que acaba de cargar. Haga esto regresando a la ventana del gestor, dando click en el botón DISPLAY. La ventana Display debería aparecer y verse como la siguiente:
Esta es la representación de una Red Neuronal Artificial (podría decirse que no una muy buena). Note un par de objetos, primero, cada bloque es llamado nodo. Cada nodo representa una simple neurona en la red. El valor entero sobre cada nodo es el ID del nodo. El número debajo es el valor actual del nodo. El tamaño del cuadro negro también representa el valor actual del nodo. Los nodos con valores cerca de 1 tienen largos recuadros verdes, mientras que los nodos con valores cerca al cero tienen largos recuadros azules.
En esta red, los dos nodos en la parte inferior son nodos de entrada, el nodo en la mitad es el nodo escondido y el nodo en la parte superior es el nodo de salida. Por lo tanto, la entrada actual a la red es un 1.0 de la izquierda y otro 1.0 en la derecha, con el valor de salida en la red igual a 0.104, que es cercano al 0. Como la red fue entrenada para simular la función XOR, se tiene un valor correcto de salida cercano a 0 para entradas (1 1). Lo que no se observa en una RNA son los pesos y las relaciones entre los nodos. Para mostrar estas partes de la red, se necesita cambiar la configuración de la ventana de display. Para hacer esto primero damos click en el botón SETUP para traer la ventana de Setup.
Note que los botones tras el campo de relaciones no están resaltados. Las relaciones (links) del botón en ON dicen a SNNS que muestre las relaciones de la red, el botón links: -2.35 dice a SNNS que muestre los pesos de las conexiones, y el botón de links: -> dice a SNNS que muestre la dirección de las relaciones en la red. Continúe y de click en los dos primeros botones para activar la visualización de las relaciones (links) y los pesos. Ahora de click en el botón DONE para efectuar los cambios. La ventana de Display de la red debería mostrarse como esto:
Note que las líneas de la conexión y los pesos indican su fortaleza.
Ahora ha terminado de cargar y mostrar un archivo Network, pero la red no tiene ningún dato que procesar. El siguiente paso es trabajar con el SNNS para cargar un archivo Pattern el cual contiene pares de entrada/salida. La primera cosa que se debe hacer es retornar al menú File y dar click en el botón PATTERNS para que todos los archivos Pattern en el directorio sean mostrados en la lista de archivos. El resultado debe ser como la siguiente imagen:
De doble click en el archivo xor y de click en el botón LOAD para cargarlo dentro la memoria activa. En la ventana de texto del SNNS, debería decir que se ha cargado un archivo Pattern. Favorablemente, SNNS permite tener más de un archivo Pattern en la memoria activa, mientras que la memoria este disponible (SNNS nos dirá si no es así).
Continúe dando doble click en xor_bigtrain y cargue el archivo Pattern (dando click una ves en el botón LOAD), y ahora de doble click en xor_bigtest y cargue el archivo Pattern.
Ahora tiene tres archivos Pattern en la memoria activa y como podrá ver, puede escoger que conjunto de patrones usar para entrenar y cuales patrones usar para el conjunto de prueba. Ahora, desde que ha hecho cosas referentes a la carga, continúe cerrando la ventana File dando click en el botón DONE.
NUNCA CIERRE UNA VENTANA SNNS UTILIZANDO [X] DEL MENU DE VENTANA O DANDO DOBLE CLICK EN EL RECUADRO SUPERIOR IZQUIERDO DE LA VENTANA. ESTO CERRARÁ TODO EL SIMULADOR.
Una de las cosas importantes que se deben hacer cuando se esta trabajando con una RNA es el entender que es lo que hace con las entradas que se estén dando. En otras palabras, se quiere mirar a la red en acción. Solo así se puede tener sentido de que es lo que esta haciendo con las entradas. En orden para controlar que patrones observa la red y ejecuta el algoritmo de entrenamiento por backpropagation, se necesita abrir la ventana de Control dando click en el botón CONTROL en la ventana del gestor. La ventana de control debe lucir como esto:
Los campos modificables de lado izquierdo de la ventana se relacionan con los parámetros de entrenamiento que se pueden poner, y los abarcaremos después. Los demás botones también controlan otros aspectos del entrenamiento y los patrones de prueba. En la parte media de la ventana se nota el nombre del archivo patrón (Pattern) que se ha cargado por última vez. El nombre superior indica el conjunto de entrenamiento que la red utilizará si se dice que comience su entrenamiento en ese instante. El nombre inferior indica el conjunto de prueba que la red utilizará para mirar que tan buena es generalizando su habilidad para resolver el problema. De click en el botón superior USE para seleccionar xor como el actual conjunto de entrenamiento y xor_bigtest como el conjunto de prueba. La ventana de Control debe parecer como la imagen mostrada anteriormente.
Ahora lo que se hará es mirar como la red desempeña en cada uno de los cuatro patrones la xor [(0 0), (0 1), (1 0), (1 1)]. El botón TEST en la parte media de la segunda fila permite pasar a través de los actuales conjuntos de entrenamiento, aplique cada patrón a la red y calcule las salidas de la misma. Continúe dando click en el botón TEST por cuatro ocasiones, mirando como SNNS aplica los cuatro diferentes patrones a la red. Note que con los dos patrones (1 1) y (0 0) las salidas de la red son valores cercanos a cero, mientras que para los otros dos las salidas de la red son valores cercanos a 1. También note que los campos modificables cercanos a la palabra PATTERN cambian los números cuando se da click a través de los diferentes patrones de entrada. El valor en el campo PATTERN indica cual patrón de la red se esta observando.
Continúe cambiando el conjunto de entrenamiento (botón superior) a xor_bigtrain y de click a través de alguno de estos patrones. Note que las entradas no son valores claros de 0 o 1, pero se encuentran entre ellos. Pregúntese si la salida de la red tiene sentido con las entradas dadas. En general, si las dos entradas son similares, la salida de la red debería ser cercana a cero. Ahora ha cargado exitosamente una red, cargado varios conjuntos de patrones (pattern), iniciado las pruebas (testing), entrenando conjunto de patrones y pasado a través de distintos conjuntos de patrones y probado el comportamiento de la red con ellos.
Entrenando la red
Los siguientes pasos en el tutorial son para re inicializar la red XOR con pesos aleatorios y después entrenarla con la función XOR. Note que puede hacer lo que sea con la red (reiniciar los pesos, adherir nodos, borrar nodos) y todos los cambios solo existirán en la memoria activa hasta que salve explícitamente la red.
El primer paso para entrenar una red es inicializar los pesos de las conexiones de la red con pequeños valores aleatorios. El botón INIT en la línea superior de la ventana de Control hará esto por usted. Continúe dando click en el botón INIT. Note que los números que indican los pesos de la conexión han cambiado. Ahora seleccione el patrón xor como el pattern de entrenamiento y use el botón de TEST para saltarlos y mirar como la red los efectúa. Note que la red no otorga más respuestas apropiadas para los distintos patrones de entrada.
Ahora, durante el proceso de entrenamiento vamos a querer observar el comportamiento de la red así que conocemos cuando parar el entrenamiento (para evadir el sobre entrenamiento). Ahora retorne a la ventana del gestor y de click en el botón GRAPH para abrir la ventana de Graph.
Los botones con las flechas a lado de las palabras Scale X y Scale Y controlan la escala horizontal y vertical de la gráfica (la cual se necesitará cambiar para obtener una buena imagen de que es lo que esta sucediendo). SNNS no efectúa la escala de la gráfica automáticamente en la dirección vertical.
Ahora retorne a la ventana de Control, los botones importantes durante el entrenamiento para una red estándar feed-forward backpropagation (que es con la que estamos trabajando) son para la mayoría, en la segunda línea a la derecha de la palabra CYCLES; el botón SINGLE hará el entrenamiento backpropagation usando solo el patrón actual (al cual se ha dado su ID en el campo PATTERN). El botón ALL hará el entrenamiento backpropagation usando todos los patrones en el actual conjunto de entrenamiento. El número de pasadas, SNNS las ejecutará con el valor determinado en el campo CYCLES. El orden en el cual los patrones se mostrarán a la red se determina por el botón SHUFFLE. Si el botón SHUFFLE no esta resaltado, entonces los patrones serán mostrados a la red en el orden de cómo aparecen en el archivo pattern.
Como quiera que sea, si el botón SHUFFLE esta resaltado, entonces SNNS hará un mezcla aleatoria de los patrones antes de cada ciclo de entrenamiento backpropagation. Usar la opción de shuffle (barajear) es importante porque de otro modo la red puede oscilar entre ciertos estados conforme los patrones son mostrados en el mismo orden en cada entrenamiento epoch.
Desde que un solo epoch de entrenamiento (mirando todos los patrones como sólo uno) no hace mucho por la red, es mejor dejar el campo de CYCLES en 50 o 100 para principiantes en este problema. Continúe y haga eso ahora.
Después de click en el botón SHUFFLE para que los patrones se presenten en orden aleatorio. Ahora coloque el conjunto de entrenamiento (sobre el botón USE) a xor_bigtrain y el conjunto de prueba (debajo del botón USE) a xor_bigtest. Después de hacer esta acción, la ventana de Control debe mirarse como:
Ahora continúe dando click en el botón ALL para ejecutar 50 o 100 epochs de entrenamiento backpropagation. Note que nada aparece en la ventana de la gráfica. Aparece cuando se cambia la escala en Y dando click unas cuantas veces en la flecha derecha a lado del texto Scale Y en la ventana de Graph, y debe observar lo siguiente:
Lo que esto muestra es el error de la suma de cuadrados correspondiente al conjunto de entrenamiento (compare que produce la red con sus valores objetivo, elévelo al cuadrado y súmelo con todos los parámetros de entrenamiento). Continúe dando click en el botón ALL algunas veces más y observe que sucede.
En algún momento alrededor de las 1200 epochs la cruva debería caer y virar hacia fuera. Un ejemplo de que debería estar viendo es lo siguiente:
Es importante determinar que en su caso pueda lucir distinto. Como la función INIT establece los pesos de la conexión a valores aleatorios, dos entrenamientos ejecutados se verán exactamente de la misma manera.
También debe notar que SNNS imprime información cuantitativa en la ventana donde se inició el programa. De esta información cuantitativa se puede decir exactamente que es lo que la red esta haciendo.
Hasta este punto, intentemos tener un mejor entendimiento de que tan bien la red ha aprendido sobre la función. De la gráfica anterior podemos observar el error de la suma de cuadrados que se ha reducido alrededor de 3 a solo unos 0.1. ¿Ha realmente aprendido la red la función XOR y mejorado su comportamiento?
Si miramos la columna MSE en la consola (Mean Squared Error), se ha quedado muy baja. En el ejemplo mostrado anteriormente alcanzó alrededor de 0.003, lo que significa un error menor a 1% en el conjunto de valores de entrenamiento.
Ahora es tiempo de observar que tan bien opera la red con un conjunto de patrones simple (0 0), (1 1), (0 1) y (1 0). Retorne a la ventana de Control y haga xor el patrón de entrenamiento actual (botón superior USE) y de click a través de los patrones utilizando el botón TEST. La red debe comportarse razonablemente bien. La salida para (0 0) y (1 1) deben ser cercanos a 0, mientras que los valores para (0 1) y (1 0) deben ser cercanos a 1.
Validación y Sobreentrenamiento
En el ejemplo previo, durante el adiestramiento solo miramos el comportamiento de la RNA en el conjunto de entrenamiento. Se observó el comportamiento de la red con un pequeño conjunto de prueba (xor) a mano. Cuando se entrena una RNA, por consiguiente, necesitamos conocer cuando terminar el entrenamiento. Un indicador que se usa es la curva SSE en el conjunto de entrenamiento, que es el que bloqueamos en la sección previa. Sin embargo, las RNA pueden ser sobre entrenadas y comenzar a perder su habilidad para generalizar la función a entradas que no han sido vistas durante el entrenamiento. Para reducir este problema, necesitamos periódicamente probar la RNA en un conjunto patrón de entrenamiento. Este conjunto patrón de entrenamiento no debe ser el conjunto patrón utilizado para entrenar la red, desde que el propósito es probar la red con entradas que no han sido vistas durante el adiestramiento.
SNNS permite hacer este arreglo de validaciones para el entrenamiento. El botón inferior USE en la ventana de Control especifica que conjunto patrón se usara como conjunto de validación. Continúe y determine el conjunto patrón de validación a xor_bigtest y reinicie el conjunto patrón de entrenamiento (botón superior USE) a xor_bigtrain. Lo que podrá notar es que la ventana de Control es igual a la misma que se tuvo cuando entrenamos a la red en la sección previa. Muestra eso en orden de activar la prueba de validación que se debe decir al SNNS que tan a menudo debe validar la red. El campo editable a la do de VALID en la ventana de Control actualmente contiene 0. Cambie este valor por 10. Lo que significa es que cada 10 epochs, SNNS mostrará todos los patrones de validación a la red y calculará el SSE para el conjunto patrón. No entrenará la red utilizando el conjunto de validación, solo hará el paso de forward.
Ahora reinicie la red a conexión de pesos aleatorios utilizando el botón de INIT y cambie el campo CYCLES a 100 para no tener que oprimir el botón ALL considerable número de veces. La ventana de Control debe lucir como:
Antes de comenzar a entrenar de nuevo, vaya a la ventana de Graph y limpie el display dando click en el botón CLEAR. Ahora comience otro entrenamiento dando click en el botón ALL para ejecutar entrenamiento por backpropagation empleando el conjunto de entrenamiento actual y validar usando el conjunto de validación.
Este tiempo la gráfica SSE contiene dos líneas. La línea negra es el conjunto de entrenamiento y la línea roja es el conjunto de validación. Con estos conjuntos de entrenamiento, la red no efectúa ningún despliegue de sobreentrenamiento, el cual esta indicado por el SSE para el conjunto de prueba y el cual comienza a ponerse peor.
Un ejemplo de que debería estar mirando en la gráfica es lo siguiente:
Ahora intentemos utilizar otro conjunto de entrenamiento. Continúe y determine el conjunto de entrenamiento a xor y deje xor_bigtest como el conjunto de validación. Note que a diferencia de xor_bigtrain (que contiene 50 puntos de ejemplo para la función XOR), xor_small solo contiene cuatro puntos de ejemplo. Por lo tanto, su realización no provee de un buen modelo de la función. Veamos como afecta esto al entrenamiento.
Reinicie la red a valores de peso iniciales aleatorios utilizando el botón de INIT en la ventana de Control. Ahora, asegúrese que xor_small es el conjunto de entrenamiento (parte superior) y xor_bigtest es el conjunto de validación (inferior), limpie la gráfica y comience con el entrenamiento (utilice el botón ALL). Pueda obtener un resultado que luce más o menos como el siguiente:
Ahora, considere que es lo que pasa. El conjunto de entrenamiento (línea negra) se pone cada vez mejor. De hecho, el SSE para el conjunto de entrenamiento se aproxima a cero, lo que significa que otorga una respuesta correcta un tanto considerable para cada patrón (pattern). Sin embargo, observe el conjunto validación (línea roja). Cuando el conjunto de entrenamiento comienza a mejorar, el de validación comienza también a mejorar. En algún punto, como sea, la red comienza a memorizar el conjunto entrenamiento y su comportamiento en el conjunto validación, comenzando ahí a empeorar de nuevo. Además, aun en su punto más bajo el SSE para el conjunto validación es mucho peor que su mejor valor usando xor_bigtrain. Lo que este ejemplo realmente muestra es que el tamaño y calidad del conjunto de entrenamiento puede afectar considerablemente el desempeño de la red, aun con problemas simples.
El siguiente paso en el tutorial es crear una red desde nada. Para este ejemplo se creará una nueva red para el problema de la función XOR. La red tendrá dos nodos de entrada, dos nodos escondidos y uno nodo de salida. La manera más fácil de crear redes simples feed-forward es utilizar la herramienta bignet. De click en el botón BIGNET en el panel del gestor y seleccione ‘general’ de la lista de opciones. Debería observar una ventana que luce como la siguiente.
La sección superior es donde se definen los nodos de la red, la inferior es donde se definen las conexiones. Con esta herramienta crea una capa de la red por ves y se pueden especificar arrays 1D o 2D de nodos (arrays 2D son útiles para procesamiento de imágenes).
Comience creando una capa de entrada. Click en el botón TYPE hasta que el campo superior en la columna derecha diga ‘input’ (debería por defecto). Ahora coloque un 2 en el siguiente campo y un 1 en el siguiente campo. Esto crea una capa de entrada de 2x1 que es lo que necesitamos para la función XOR. El campo z-coordenado puede quedar vacío. Finalmente, de click en el botón POS para determinar la posición relativa para esta capa de lado izquierdo ‘left’. Cuando haya llenado los campos correctamente, de click en ENTER para mover la información a la columna de lado izquierdo, por tanto creando el plano actual.
Para crear la segunda capa (oculta), comience dando click en el botón TYPE para determinar el campo superior derecho en ‘hidden’. Ahora ingrese 2 para x y 1 para y. Defina la posición relativa a ‘below’ dando click en el botón POS. Finalmente de click en ENTER para crear la segunda capa.
Para la capa final (salida), defina el tipo a ‘output’ y haga la capa de 1x1 (solo 1 nodo de salida) y deje la posición relativa en ‘below’. De click en ENTER para construir la capa de salida.
Para una red simple feedforward tal como esta, la manera mas fácil de construir la conexión es dando click en el botón de FULL CONNECTION en la parte inferior de la ventana. Finalmente, de click en CREATE NET para construir la red. SNNS solo puede trabajar con una red a la ves, por ello advierte acerca de eliminar la red actual ya asegurarse de que eso es lo que quiere hacer. En este punto debe observar una red que luce como la siguiente:
Tal cual se utilizó la ventana de File para cargar redes y archivos pattern, se puede emplear la misma ventana para salvar la red en su estado actual. Solo posicione al directorio en donde se desea salvar la red, escriba el nombre del archivo y de click en SAVE. No necesita agregar el sufijo .net, ya que SNNS lo hace por nosotros. Ahora que ha creado su propia red, dirijase al panel de control, presione el botón INIT e intente entrenar la red en el problema XOR.
Pattern Files
SNNS permite incluso crear archivos pattern, pero es un proceso lento e irritante. Es mucho mejor escribir su propio programa para que lo haga por usted y todo lo que necesita saber es el formato con el cual SNNS espera leer esos archivos. Básicamente, los archivos pattern de SNNS tienen la siguiente forma:
{HEADER}
{DATA}
Donde el encabezado es similar a lo siguiente:
SNNS pattern definition file V3.2
generated at Wed Oct 30 12:38:53 1996
No. of patterns : 4
No. of input units : 2
No. of output units : 1
El encabezado necesita decir a SNNS que es un archivo pattern y después decir a SNNS cuantos patterns, cuantas entradas y cuantas salidas. La parte de datos del archivo debe lucir como sigue:
1 0 1
0 1 1
0 0 0
1 1 0
Donde los primeros dos valores son los dos valores de entrada y el ultimo valor es el 1 de salida. Si por ejemplo, se tenía una red con 9 entradas y dos salidas, entonces se deberían necesitar 11 valores en cada línea (9 entradas seguidos por 2 salidas). Cuando se creen los patrones (patterns), recuerde que el valor de salida de los nodos por de facto (que usan la función sigmoid) en SNNS son del rango [0 . . . 1]. En otras palabras, no pregunte a la red que genera valores fuera de esos límites. Así mismo, es inteligente escalar las entradas a que estén en un rango entre [0 . . . 1] y también si se esta utilizando la función estándar sigmoid.
Página del Dr. Bruce A. Maxwell, Departamento de Ciencias Computacionales del Colby College, U.S.A.
http://palantir.cs.colby.edu/maxwell/classes/tutorials/snns/