Práctica de autoasociadores (redes de Hopfield)

El objetivo es conseguir que la red "aprenda" una serie de patrones (en nuestro caso van a ser imágenes) y luego, nosotros le demos uno que recuerda a alguno de ellos y la red lo recupera.
Como hemos dicho los patrones son imágenes, concretamente son imágenes de señales de tráfico: la red se aprende una serie de señales, luego nosotros le damos un bosquejo y ella nos saca la señal correcta.
Para evitar sobrecarga de memoria y procesador, vamos a trabajar con imágenes de 50×50 Eso quiere decir que el bosquejo también tendrá que tener ese tamaño.
Ya tenemos una serie de datos preparados. Están comprimidas en este fichero, que debes descargar y descomprimir en la carpeta o directorio en que vayas a trabajar. ¡Vamos con ello!

Matlab (toolbox propia)

  1. Carga el conjunto de imágenes de unas cuantas señales con el comando load senhales
  2. Tal y como está implementado en Matlab, los datos han de ser binarios, así que las señales están en binario puro: blanco/negro. Puedes visualizar las que quieras con el comando imshow(busbn) o similar.
  3. Elige un subconjunto de las señales y ponlas en una matriz, cada uno ocupando una columna. Puede ser, por ejemplo,
    matriz1=[busbn(:) crucebn(:) deslizbn(:) desprenbn(:)]; Nada más un aviso: cuantas más señales cojas, más tiempo tardará en crearse la red, así que si coges ocho, puede que te tires diez minutos mirando a un Matlab "colgado"
  4. La implementación de Matlab necesita que codifiquemos los estados binarios como -1/1, pero en una imagen es 0/1, así que tenemos que hacer la conversión: matriz1=2*matriz1-1;
  5. Ahora ya podemos crear la red que aprenda eso, con el comando, por ejemplo: aa1=newhop(matriz1); Según sea de grande la matriz tardará un minuto, o cinco, o quince Si te aburres, páralo y repite con una menor.
  6. Cuando acabe, ha llegado el momento de probarla. En el fichero de datos ya hay un bosquejo preparado, se llama prueba Si quieres hacer otros, puedes utilizar el programa tipo Paint de dibujo básico del sistema. La secuencia de trabajo es:
    1. Crea en el programa la imagen que quieras en tamaño 50×50 No te molestes en el colorido, porque recuerda que vamos a quedarnos sólo con blanco/negro. Guárdala en un formato como PNG, JPG o similar en la carpeta de trabajo.
    2. Cárgala en Matlab. Si se llama dificil.png el comando sería dificil=imread('dificil.png');
    3. Da igual el colorido que tenga, el formato supone que es a todo color. Debemos pasarla a escala de grises con dificil=rgb2gray(dificil);
    4. Todavía no hemos llegado, porque necesitamos ponerlo en la escala -1/1 Lo primero es pasarlo a 0/1 y luego operarlo, es decir, dificil=im2double(dificil)*2-1;
  7. Sea como sea, vamos a suponer que fuese prueba Si es otra, cambia el nombre. Para trabajar con la red conviene meterlo en una celda y además desarrollado en una columna, o sea, datos{1}=prueba(:);
  8. Para pasarla por la red, hay que pensar cuántas iteraciones necesita para estabilizarse. Eso depende de las similitudes entre los patrones aprendidos y el bosquejo. Vamos a suponer 50; el comando es sale=sim(aa1,{1 50},{},datos);
  9. En sale nos van a salir 50 celdas, una por cada iteración. Para sacar la imagen correspondiente a la última sería
    resul=(reshape(sale{50},[50 50])+1)/2; Y la podemos ver con imshow(resul);
  10. Si sale lo que esperabas ¡enhorabuena! Si no, pueden haber pasado dos cosas: que necesite más iteraciones para estabilizarse o que no consiga distinguir ciertos patrones. Para ver si estamos en el primer caso, échale un vistazo, por ejemplo a la imagen de la iteración 40: si es idéntica a la 50 entonces no es el caso, si es distinta, entonces sí, y tendrás que volver a lanzarla con más iteraciones. Si ése no era el problema entonces hay que probar a que aprenda otros patrones más diferenciados o que el bosquejo sea más fácil.
  11. Itera con distintos conjuntos de señales y distintos bosquejos hasta saciarte.

Octave

Usaremos unas macros del libro ``Redes neuronales artificiales un enfoque práctico'' de Juan Manuel Corchado et al. (descomprímelas en tu carpeta de trabajo). Necesitaremos también la función hardlim que es tan simple como hardlim(a):=(a>=0);

  1. Carga el conjunto de imágenes de unas cuantas señales con el comando load senhales
  2. Las señales están en binario puro: blanco/negro. Puedes visualizar las que quieras con el comando imshow(busbn) o similar.
  3. Elige un subconjunto de las señales y ponlas en una matriz, cada uno ocupando una columna. Puede ser, por ejemplo,
    matriz1=[busbn(:) crucebn(:) deslizbn(:) desprenbn(:)];
  4. La implementación está pensada para que codifiquemos los estados binarios como -1/1, pero en una imagen es 0/1, así que tenemos que hacer la conversión: matriz1=2*matriz1-1;
  5. Ahora ya podemos crear la red que aprenda eso, con el comando, por ejemplo: pesoshop=trainhop(matriz1);
  6. Ha llegado el momento de probarla. En el fichero de datos ya hay un bosquejo preparado, se llama prueba Si quieres hacer otros, puedes utilizar el programa tipo Paint de dibujo básico del sistema. La secuencia de trabajo es:
    1. Crea en el programa la imagen que quieras en tamaño 50×50 No te molestes en el colorido, porque recuerda que vamos a quedarnos sólo con blanco/negro. Guárdala en un formato como PNG, JPG o similar en la carpeta de trabajo.
    2. Cárgala. Si se llama dificil.png el comando sería dificil=imread('dificil.png');
    3. Si te la carga a color, tienes que pasarla a escala de grises con dificil=rgb2gray(dificil);
    4. Todavía no hemos llegado, porque necesitamos ponerlo en la escala -1/1 Según tu versión, puede que ya esté en escala 0/1 Si no, lo puedes pasar con dificil=im2double(dificil); Para pasarlo a escala -1/1 es dificil=dificil*2-1;
  7. Sea como sea, vamos a suponer que fuese pruebh (por ejemplo, sacado de pruebh=prueba(:)*2-1;) Si es otra, cambia el nombre. Para trabajar con la red conviene que esté desarrollado en una columna.
  8. Para pasarla por la red, el comando es sale=applyhop(pesoshop,pruebah);
  9. Para pasar el resultado a imagen sería
    resul=(reshape(sale,[50 50])+1)/2; Y la podemos ver con imshow(resul);
  10. Si sale lo que esperabas ¡enhorabuena! Si no, puede pasar que no consiga distinguir ciertos patrones. Entonces hay que probar a que aprenda otros patrones más diferenciados o que el bosquejo sea más fácil.
  11. Itera con distintos conjuntos de señales y distintos bosquejos hasta saciarte/cansarte.