Porqué preferimos las pitones a los camellos o los rubís. Cuestión de gustos, no os enfadéis!
Avatar de Usuario
newlog
El Eterno Alumno
 
Mensajes: 170
Registrado: Lun Jun 23, 2008 7:28 pm

Hopfield Neural Network for Pattern Recognition

por newlog Mar Dic 27, 2011 11:59 pm

Buenas,

Perdonadme el título en inglés :lol:

Hoy voy a compartir con vosotros el código que he utilizado para implementar una red neuronal basada en el modelo de Hopfield con la que poder reconocer patrones, en este caso, imágenes.

Para ejecutar el código es necesario instalarse la librería pygame (la he utilizado para parsear archivos bmp). Lo cierto es que no he podido instalarla en mi mac, así que el código lo he probado en un windows 7.

Simplemente comparto este código por si alguien quiere introducirse en el mundo de las redes neuronales y, a la vez, ver lo fácil que es trabajar con, por ejemplo, listas con Python.

Imagino que con un poco de tiempo se puede entender la teoría a partir de ver qué es lo que hace el código.

Por último, tal y como sabéis, día a día voy aprendiendo un poco más, así que acepto cualquier tipo de mejora a mi código!

Main
Código: Seleccionar todo
'''
Created on 28/11/2011

@author: Newlog
'''
from ImageProcess import ImageProcess
from BasicNeuralNetwork import HopfieldNeuralNetwork

class Main(object):

    __inputImage = None
    __patternsNumber = None
    __patternsListPath = None

    def principal(self):
        ip1 = ImageProcess(self.__inputImage)
        inputImage = ip1.getImageData()
        input_size = ip1.getImageSize()
       
        if self.__patternsNumber == 1:
            for i in range(self.__patternsNumber):
                ip2 = ImageProcess(self.__patternsListPath[i])
                patternImages = ip2.getImageData()
                pattern_size = ip2.getImageSize()
        elif self.__patternsNumber > 1:
            patternImages = []
            pattern_size = []
            for i in range(self.__patternsNumber):
                ip2 = ImageProcess(self.__patternsListPath[i])
                patternImages.append(ip2.getImageData())
                pattern_size.append(ip2.getImageSize())
           
        if inputImage == None or patternImages == None:
            print '[-] The bit map(s) could not be retrieved. See you, Space Cowboy.'
            exit(-1)
        if input_size == None:
            print '[-] The input image size(s) could not be retrieved. See you, Space Cowboy.'
            exit(-1)
        if pattern_size == None:
            print '[-] The pattern image size could not be retrieved. See you, Space Cowboy.'
       
       
        print '[+] INPUT IMAGE in ones and minus ones:'
        for x in inputImage:
            print x
        print

        inputImageArray = []
        '''
        InputImage is a matrix of bits. p.ej.
        [0 1 1]
        [0 0 0]
        [1 0 1]
        '''
        for array in inputImage:
            for element in array:
                inputImageArray.append(element)
               
        tmp = []
        patternsArrayLists = []
        '''
        patternImages is a list of matrix of bits. p.ej.
        [
        [ [0 1 1]
          [0 0 0]
          [1 0 1]
        ]
        [ [0 0 0]
          [1 1 1]
          [0 1 0]
        ]
        ]
        '''
        if self.__patternsNumber == 1:
            for array in patternImages:
                for element in array:
                    patternsArrayLists.append(element)
        elif self.__patternsNumber > 1:
            for matrix in patternImages:
                for array in matrix:
                    for element in array:
                        tmp.append(element)
                patternsArrayLists.append(tmp)
                tmp = []
        '''
        patternsArrayLists is a list of every patternImages matrix as arrays.
        patternImages 1st matrix --> [ 0 0 0 0 0 0 1 1 1 1 1]
        patternImages 2n matrix -->  [ 1 1 0 1 0 1 1 1 1 0 0]
        (...)
        '''
        # For pattern size we only take into account the first pattern
        if self.__patternsNumber == 1:
            nn = HopfieldNeuralNetwork(pattern_size[0] * pattern_size[1], inputImageArray, patternsArrayLists, self.__patternsNumber)
        elif self.__patternsNumber > 1:
            nn = HopfieldNeuralNetwork(pattern_size[0][0] * pattern_size[0][1], inputImageArray, patternsArrayLists, self.__patternsNumber)
       
        finalImage = nn.activate()
        print '[+] FINAL IMAGE in ones and minus ones:'
        i = 0
        print '[ ',
        for x in finalImage:
            if x == -1:
                print "0,",
            else:
                print "%d," % (x),
            i += 1
            if i % 10 == 0:
                print ']'
                print '[ ',
        print
       
        if self.__patternsNumber > 1:
            bestPattern = nn.conclusion()
            print 'Pattern: %s' % self.__patternsListPath[bestPattern]
            bestPattern += 1
           
            print '[+] The word most approach as pattern %d' % bestPattern
                 
       
    def ask4Images(self):
        str_inputImage = raw_input('[+] Enter the path to the input image: ')
        str_pattern_num = raw_input('[+] How many patterns will you introduce? ')
       
        self.__patternsNumber = int(str_pattern_num)
               
        pattern_list_paths = []
        for i in range(self.__patternsNumber):
            i += 1
            str_pattern = raw_input('[+] Pattern number %d: ' % i)
            pattern_list_paths.append(str_pattern)
           
        return str_inputImage, pattern_list_paths
       
    def __init__(self):
        self.__inputImage, self.__patternsListPath = self.ask4Images()




 
main = Main()
main.principal()


ImageProcess
Código: Seleccionar todo
'''
Created on 22/11/2011

@author: Newlog
'''
import pygame

class ImageProcess(object):
   
    __matrix = []
    __imagePath = None
    __size = [0, 0]
    __inited = False
    __image = None
   
   
    def openFile(self):
        try:
            self.__image = pygame.image.load(self.__imagePath)
            self.__inited = True
        except:
            print '[-] The image could not be opened.'
           
   
   
    def getImageData(self):
        if not self.__inited:
            print '[-] ImageProcess class is not inited already. Go 4 it.'
            return None
       
        tmp = []
        self.__size[0] = self.__image.get_width()
        self.__size[1] = self.__image.get_height()
        for y in range(self.__size[1]):
            for x in range(self.__size[0]):
                color = self.__image.get_at((x,y))
                if color.r == 0:
                    colorValue = -1
                else:
                    colorValue = 1
                tmp.append(colorValue)
            self.__matrix.append(tmp)
            tmp = []
        return self.__matrix
       
   
   
    def createBitmap(self):
        pass
   
   
   
    def getImageSize(self):
        if ( self.__inited ) :
            return self.__size
        else:
            print '[-] ImageProcess class is not inited already. Go 4 it.'
            return None
       
   
   
    def __init__(self, imagePath):
        '''
        Constructor
        '''
        self.__imagePath =  imagePath
        self.__matrix =     []
        self.openFile()


BasicNeuralNetwork
Código: Seleccionar todo
'''
Created on 28/11/2011

@author: Newlog
'''

class HopfieldNeuralNetwork(object):   

    def build_network(self, total_nodes):
        pass

    def signFunction(self, number):
        if number < 0:
            return -1
        elif number >= 0:
            return 1

    def activate(self):
        SList = self.__inputPixels
        count = 0
        print '[+] Neural Network is running...'
        while not self.__stopNN:
            j = 0
            i = 0
            count += 1
            newSList = []
            for j in range(self.__totalNodes):
                scalarProduct = 0
                for i in range(self.__totalNodes):
                    '''
                    patternList => Wij
                    SList => Sj
                    '''
                    scalarProduct += SList[i] * self.__weightsMatrix[j][i]
                'END INNER FOR'
                newSList.append(self.signFunction(scalarProduct))
            'END OUTER FOR'

            if SList == newSList and count > 1:
                self.__stopNN = True
                print '[+] Process finished.'
            else:
                SList = []
                SList = newSList
                               
        self.__finalImage = SList           
        return SList
   
   
   
    def buildWeightsMatrix(self):
       
        if self.__patternsNumber == 1 :
           
            for i in range(self.__totalNodes):
                tmpList = []
                for j in range(self.__totalNodes):
                    tmpList.append( self.__patternsList[i] * self.__patternsList[j] )
                self.__weightsMatrix.append(tmpList)
       
        elif self.__patternsNumber > 1:
           
            tmpWeightsMatrix = []
            for p_n in range(self.__patternsNumber):
                tmpWeightsMatrix = []
                for i in range(self.__totalNodes):
                    tmpList = []
                   
                    for j in range(self.__totalNodes):
                        tmpList.append( self.__patternsList[p_n][i] * self.__patternsList[p_n][j] )
                   
                    tmpWeightsMatrix.append(tmpList)
               
                if self.__weightsMatrix == []:
                    self.__weightsMatrix = tmpWeightsMatrix
                else:
                    '''
                    If the weight matrix is not empty, we have to increment it with the other loaded patterns
                    '''
                    col = 0
                    row = 0
                    for array in tmpWeightsMatrix:
                        col = 0
                        for element in array:
                            self.__weightsMatrix[row][col] += element
                            col += 1
                        row += 1
               
    def conclusion(self):
        if self.__finalImage != None:
            if self.__patternsNumber > 1:
                i = 0
                diffList = []
                for x in range(self.__patternsNumber):
                    diffList.append(0)

                i = 0
                for array in self.__patternsList:
                    j = 0
                    for element in array:
                        if element != self.__finalImage[j]:
                            diffList[i] += 1
                        j += 1
                    i += 1
               
                minValue = 1000
                bestPattern = -1
                i = 0
                for value in diffList:
                    if value < minValue:
                        bestPattern = i
                        minValue = value
                    i += 1
               
                return bestPattern
            else:
                return -1
       
               
    def __init__(self, total_nodes, input_pixels, patterns_to_load, patterns_number):
        '''
        Constructor
        '''
        self.__totalNodes =     total_nodes
        self.__inputPixels =    input_pixels
        self.__patternsList =   patterns_to_load
        self.__patternsNumber = patterns_number
        self.__stopNN =         False
        self.__weightsMatrix =  []
        self.__finalImage = None
        self.buildWeightsMatrix()


La idea de una red neuronal que sea capaz de reconocer patrones es, a partir de una imagen posiblemente distorsionada, recuperar la imagen que realmente es. Por ejemplo, si se tiene una imagen que representa una "A" pero distorsionada, será posible reconocer que la imagen realmente es una "A".

Cómo funciona el programa? Simplemente se ha de introducir la ruta donde se encuentra la imagen distorsionada. Después necesitas x patrones, o sea, las imagenes originales. Debido a que las imagenes que os proporcionaré sólo son de 10x10 píxels, si se introducen más de cuatro patrones la red neuronal no es capaz de recuperar la imagen real de un modo fiable.

En fin, aquí os enlazo el código fuente junto con las imágenes. Enlace

Saludos!
Imagen
Avatar de Usuario
vlan7
 
Mensajes: 87
Registrado: Jue Jul 22, 2010 3:45 pm
Ubicación: Mas alla del EIP

Re: Hopfield Neural Network for Pattern Recognition

por vlan7 Jue Dic 29, 2011 2:52 pm

Hola,

Lo poco que he podido leer perfecto, a ver si le echo un ojo. Mi unica mejora posible es a uno de tus comentarios del codigo Main, el ejemplo de matriz:

Código: Seleccionar todo
'''
InputImage is a matrix of bits. p.ej.
[0 1 0]
[0 0 1]
[1 1 1]
'''

jejeje you know.

Fuera coñas, gracias por compartir tio, a ver si lo pruebo.

Un saludo.
int *p = new int[7];
p = p + 7;
*p = 42;

int a[7];
a[7] = 42; /* ESC[2;9y */
Avatar de Usuario
newlog
El Eterno Alumno
 
Mensajes: 170
Registrado: Lun Jun 23, 2008 7:28 pm

Re: Hopfield Neural Network for Pattern Recognition

por newlog Jue Dic 29, 2011 8:59 pm

Jajaja, dios, como se nota que mi mente está en letargo... He tenido que leer tu post 3 veces para darme cuenta!

En fin, sólo he posteado este código para que a la gente que le suene demasiado avanzado eso de las redes neuronales, pues que vea que no es nada del otro mundo. Bueno, al menos poner el concepto en práctica.

Saludos!
Imagen
Volver a Python

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados