Python R2


Redes Neuronales en Python RNA

Posted in Python por Arturo Anton en 16 octubre 2008
Tags: , , , , , , , ,

En un momento verdaderamente de ocio e improductividad de mi vida traduje una RNA que estaba implementada por Jeff Heaton en java a JavaSrcipt para un curso que dictaba en la consultora Everis de dicho lenguaje. La verdad me tenían medio cansado, con la pregunta ¿que se puede hacer en JS?. 😉

Hoy hablando con un amigo dije por que no hacerlo en python y mejor aun con un ejemplo mínimo y que no sea el maldito XOR para ver como se usa la RNA.

Bueno vasta de historia. Haremos un OCR que detecte números dibujados con el Mouse en una imagen jpg.

Entrenaremos la RNA con las siguientes 5 imágenes de 50×50 pixeles por número (http://picasaweb.google.com/arturoeanton/Pyrna). Y pediremos que nos entregue su representación en binario para facilitar la codificación de la salida.

#!/usr/bin/env python
#Archivo: pyOcr.py
import Image
import pyrna

def procImgRGB(arch):
    im=Image.open(arch)
    procesado=[]
    xsize,ysize=im.size

    matrixImg = map(lambda a:map(lambda a:[],range(50)),range(50))

    a = ""
    for x in range(0,xsize):
        for y in range(0,ysize):
            matrixImg[x][y]= im.getpixel((x,y))

    resp=[]
    for rangoX in [(0,10),(10,20),(20,30),(30,40),(40,50)]:
        for rangoY in [(0,10),(10,20),(20,30),(30,40),(40,50)]:
            manchado = 0
            for x in range(rangoX[0],rangoX[1]):
                for y in range(rangoY[0],rangoY[1]):
                    r,g,b=matrixImg[x][y]
                    if ((r+g+b)/3) < 50:
                        manchado += 1

            if manchado > 0:
                resp.append(1)
            else:
                resp.append(0)

    return resp

respuestas =[
    [0.00,0.00,0.00,0.00],#0
    [0.00,0.00,0.00,1.00],#1
    [0.00,0.00,1.00,0.00],#2
    [0.00,0.00,1.00,1.00],#3
    [0.00,1.00,0.00,0.00],#4
    [0.00,1.00,0.00,1.00],#5
    [0.00,1.00,1.00,0.00],#6
    [0.00,1.00,1.00,1.00],#7
    [1.00,0.00,0.00,0.00],#8
    [1.00,0.00,0.00,1.00] #9
    ]

print "Procesando ..."
entrada =[]
salidaIdeal = []
for i in range(10):
    for img in range(1,6):
        print "Procesando ./"+str(i)+"/"+str(img)+".jpg ...",
        entrada.append(procImgRGB("./"+str(i)+"/"+str(img)+".jpg"))
        salidaIdeal.append(respuestas[i])
        print "ok Respuesta esparada :",respuestas[i]

network = pyrna.classNetwork(25, 5 ,4,0.01,0.9)

print "Entrenando ..."
error = 10
i =0
while error > 0.25:
    for j in range(len(entrada)):
        network.computeOutputs(entrada[j])
        network.calcError(salidaIdeal[j])
        network.learn()
    error = network.getError(len(entrada))
    i +=1
    if i % 1000 == 0:
        print "Error: ",error,"%"
        i=0
print "Error: ",error,"%"
print "recalulo Img..."
for i in range(10):
    for img in range(1,6):
        a = "./"+str(i)+"/"+str(img)+".jpg"
        print a,"  ->",
        respDada = []
        for r in network.computeOutputs(procImgRGB(a)):
            respDada.append(round(r))
            print round(r),
        print (respDada == respuestas[i])

print "Que aprendiste?"
img = 7
for i in range(10):
    a = "./"+str(i)+"/"+str(img)+".jpg"
    print a,"  ->",
    respDada = []
    for r in network.computeOutputs(procImgRGB(a)):
        respDada.append(round(r))
        print round(r),
    print (respDada == respuestas[i])
  • Definimos la función procImgRGB que es una función recibe el nombre de una imagen y la separa en 25 cuadrados y nos dice que cuadrado esta manchado o no.
  • Definimos el vector respuestas con las respuestas esperadas. y armamos los pares (entrada – respuesta) en los vectores entrada y salidaIdeal.
  • Instanciamos una red con las 25 entradas posibles y 5 neuronas ocultas y 4 de salida. También le definimos el rate y el momentum.
  • La entrenamos hasta que el error global de la RNA sea 0.25
  • Imprimimos el resultado con las entradas propuestas.
  • Y por ultimo vemos que aprendió mediante la imagen 7.jpg de cada numero.

Para ver la salida de este script aca esta el link http://www.binsd.com.ar/pyrna/salida.txt

Links:

Como siempre espero que les guste 😉