Showing posts with label Redes Neuronales. Show all posts
Showing posts with label Redes Neuronales. Show all posts

November 20, 2012

Reporte final

Para esta entrega final los objetivos por conseguir fueron los siguientes:
  • Hacer que la comunicación entre el Kinect y la red neuronal fuera en tiempo real, para que ésta ultima obtuviera las coordenadas del movimiento (entradas). En la entrega anterior las entradas las tomaba de un txt previamente generado (pre-procesamiento) por processing; todo esto para no tener procesamiento innecesario.
  • Agregar capas a la red, para filtrar nuestras entradas y con esto facilitar el procesamiento y obtener una respuesta de salida mejor. 
Para realizar el entrenamiento de la red neuronal utilizamos backpropagation para calcular errores y recalcular pesos en cada una de las iteraciones del procesamiento de la red.

Las complicaciones que tuvimos fueron las siguientes:
  • Conseguir que el sistema arrojara una respuesta casi inmediata al terminar el movimiento, y aunque el script utilizado para el Kinect está hecho en python, la red neuronal no recibía el arreglo de coordenadas que se obtenía. (esta parte del script del kinect realizada por mí)
  • El cálculo de los errores, en esta tarea contribuí en código a pesar de que no fue destinada para mí.
  • El entrenamiento de la red, en especial el algoritmo de backpropagation en el cual contribuí con ideas y al principio en código pero al juntarnos en equipo la mayoría se del código se fue añadiendo al código que tenía mi compañero Osvaldo y ya sobre ese trabajamos para tener mayor avance.
Bueno hay que mencionar, que al final no conseguimos el objetivo ya que a pesar de que conseguimos realizar backpropagation, tuvimos errores en la función de error y eso fue lo que nos falto solucionar ya que no nos arrojaba la salida que esperábamos al final de entrenamiento.

Mis aportes:
  • Script de Kinect
  • Obtener de errores de la red
  • Algoritmo backpropagation
  • Perceptrón simple (se encuentra en mi blog)
  • Fase 2 de la neurona sencilla (se en encuentra en mi blog).
  • Parte de la neurona con capas (fase 3 tambien en mi blog)


El repositorio en que se utilizó para este proyecto lo pueden encontrar en la siguiente liga, la entrega final y "funcional" se encuentra en la carpeta kinect.:
kinect_control_interfaz

carpeta final (dentro de la carpeta kinect)


Saludos!

Fase 3

En esta fase de la red neuronal se le agregaron capas.


from sys import argv
from numpy import *
from numpy.random import *

tasa_de_aprendizaje = 0.03
capa = list()

class neu(object):
    
    def Entrada(self,n):
        entrada = uniform(low=-1, high=1, size=(1,n))
        entrada = append(entrada, -1.0)
        return entrada
    
    def W(self, n):
        return uniform(low=-1, high=1, size=(1,n+1))
        
    
    def Condicion(self, n, w):
        return uniform(low=-1, high=1, size=(1,n+1))
        
    def respuestaDeseada(self, condicion, entrada):
        valorcondi = entrada*condicion
        valorc = valorcondi.sum()
        if (valorc>=0): return 1
        else: return 0
        
    def Act(self, w, entrada):
        a = w*entrada
        act = a.sum()
        return act
    
    def Compara(self, act):
        global capa#=list()
        if(act>=0): 
            capa = append(capa, 1)
            return 1
        else:
            capa = append(capa, 0)
            return 0
        

    def Entrena(self, w, y, respdesea, entrada):
        global tasa_de_aprendizaje
        entrenar = tasa_de_aprendizaje * (respdesea - y) * entrada
        w += entrenar
        return w
    
    def Capa(self):
        global capa
        capa = append(capa, -1)
        return capa

    def __init__(self, n, num, ncapas):
        global capa
        p=0
        w = self.W(n)
        condicion = self.Condicion(n, w)
        print w
        print condicion
        for p in range(num):
            entrada = self.Entrada(n)
            act = self.Act(w, entrada)
            y = self.Compara(act)
            respdesea = self.respuestaDeseada(condicion, entrada)
            entrena = self.Entrena(w, y, respdesea, entrada)
            w = entrena
            for i in range(len(entrada)-1):
                print entrada[i],
            print y, respdesea
        entrada = empty(0)
        act = 0
        y = 0
        respdesea = 0
        entrena = 0
        w = empty(0)
        condicion = empty(0)
        for f in range(ncapas):
            w = self.W(num)
            condicion = self.Condicion(num, w)
            print w
            print condicion
            entrada = self.Capa()
            for h in range(num):
                entrada = self.Entrada(num)
                act = self.Act(w, entrada)
                y = self.Compara(act)
                respdesea = self.respuestaDeseada(condicion, entrada)
                entrena = self.Entrena(w, y, respdesea, entrada)
                w = entrena
                for t in range(len(entrada)-1):
                    print entrada[i],
                print y, respdesea
            print w
            print "Capa",i , ":", capa
            

#se le dan como argumentos el total de entradas (tot), cuantas veces repetirá todo el proceso (num) y el total de capas
n = neu(int(argv[1]), int (argv[2]), int (argv[3]))

November 16, 2012

Entrenamiento perceptrón. Fase 2

Entrenamiento de perceptrón

En esta fase lo que se realiza es proporcionale al perceptrón la salida que queremos obtener (salida deseada), el perceptrón se encarga de ajustar/ modificar pesos para obtener esa salida.

Aquí un poco de teoría para comprender mejor como funciona esto....

Para que el el perceptrón pueda clasificar o arrojar la salida deseada se le debe proporcionar la salida deseada en la entrada de la neurona. Como la salida es dada por el vector de pesos y el umbral, entonces es necesario ajustar/modificar éstos para obtener esa salida deseada utilizando un método iterativo; en cada iteración se realizan pequeños cambios a los pesos y al umbral hasta conseguir lo requerido para obtener esa salida deseada. A este proceso se le conoce como entrenamiento de la red neuronal

Un entrenamiento supervisado es aquel en el que a la red se le proporciona un vector de entrada ( $x_i$ ) al cual le corresponde un vector de salida deseada ( $t_i$). Se le conoce como entrenamiento supervisado ya que a la red se le dice que resultado esperar y que hace en cada paso.

Veamos un ejemplo para comprender mejor: supongamos que para entrenar un perceptrón utilizamos un vector de entrada ( v ) con la salida deseada t=1 y con un vector de pesos ( w ), los cuales dan como resultado y = 0. Esto quiere decir que no se obtuvo la salida que se desea porque se esperaba un 1 y se obtuvo un 0. Para que el resultado haya sido 0 la activación de la neurona debió haber sido negativa, esto es $w * v $ fue negativo. Para cambiar este resultado hay que ajustar/cambiar el vector de pesos, pero se hace poco a poco no de manera drástica, con el cual producimos un nuevo vector de pesos w' utilizando la siguiente fórmula:

$w'= w + \alpha v$

Donde $\alpha$ es la tasa de aprendizaje con la cual la red hace pequeños cambios a los pesos

Ahora supongamos que como salida deseada queremos t=0 y obtenemos y=1. Esto nos da un escenario distinto donde la activación fue positiva y debió haber sido negativa, ahora necesitamos de igual manera ajustar/modificar los pesos pero ahora utilizamos la siguiente fórmula que no es mas que en vez de suma sea una resta esto porque hay que rotar el sentido en el que apunta el vector de de pesos ( recuerden que un vector tiene dirección y magnitud).

$w'= w + \alpha v$

Aquí una imagen para comprender mejor el porqué de los cambios:


Para realizar el entrenamiento hay que combinar estas dos fórmulas, con lo cual obtenemos lo siguiente:

$w'= \alpha (t - y)v$

Un algoritmo para realizar este entrenamiento es el siguiente:
repetir
   (for)para cada vector de entrada (v,t) //v = vector de entrada, t = salida deseada
   evaluar la salida 'y' para la entrada 'v'
   if y ≠ t
       hacer un nuevo vector de pesos // w'
   else
       no se ajustan/modifican pesos
   termina if
   termina for
hasta que y = t para cada vector

Procedimiento:
El siguiente script lo que realiza es generar de manera aleatoria los vectores de entrada, pesos y un vector de condición con el cual se genera la salida deseada ya que en este caso no está aplicado en un problema específico. Si la salida actual no es igual a la deseada los pesos se vuelven a calcular utilizando la fórmula mostrada anteriormente.

Código en Python:


Neurona Sencilla. Fase 1

Neurona Sencilla

La red neuronal más sencilla es la que se conoce como perceptrón de una capa, que consiste en sólo una capa de salida; las entradas en este caso se introducen directamente como una multiplicación de entradas (0's y 1's). Se suman estas multiplicaciones y si es mayor a un umbral la neurona se dispara (se activa).
En general en una neurona sencilla consiste en proporcionarle como parámetros el tamaño del arreglo, un umbral y las entradas de ese arreglo, que para nuestro caso serían 0's o 1's; después se crea un arreglo del mismo tamaño que las entradas pero con números aleatorios entre 0 y 1 que serían los pesos. Luego Se multiplican las entradas por su peso correspondiente y se suman dichas multiplicaciones; ya por último se compara la suma con el umbral y si es mayor al umbral se acepta (arroja un 1), en caso contrario se rechaza (arroja un 0).

Procedimiento

Para la primera fase de una neurona sencilla, el objetivo es no utilizar un umbral establecido globalmente sino que sea una entrada en el vector que se le proporciona como entrada a la neurona.

Como teoría se utilizan las siguientes formulas para saber si la neurona se activa o no, donde $w$ es el vector de pesos y $x$ el vector de entradas:

$w \cdot x >= \theta$

Con un poco de álgebra podemos ver cómo podemos utilizar el umbral en un vector de entrada
$w \cdot x -\theta >= 0$
$w \cdot x+(-1)teta >= 0$

Con esto podemos ver al umbral como un peso extra que está relacionado con una entrada $-1$ , con esto lo que hau que hacer es que necesitamos un vector de $n pesos + 1$

Y ahora para saber conocer la salida y saber si la neurona se activa utilizaríamos las siguientes fórmulas

$w \cdot x >=0 -> y=1$
$w \cdot x < 0 -> y=0$

Código en python

#!/usr/bin/python

from sys import argv
from numpy import *
from numpy.random import *

low = -1
high = 1

class neurona(object):

    #crea vector de pesos
    def getPesos(self,n):
        pesos = uniform(low,high,(1,n+1))#vector de una dimension con n+1 entradas por el umbral
        return pesos

    #crea vector de entradas con 1's y 0's y se le agrega un -1 para el umbral
    def getEntradas(self,n):
        entrada = uniform(low,high,(1,n))
 #print entrada
        entrada = append(entrada, -1.0)
        return entrada

    #función de activacion, se multiplican pesos y entradas
    def Activacion(self,pesos,entrada):
        mult = pesos * entrada
        act = mult.sum()#se suman las multiplicaciones
        return act

    #si act es mayor a cero se aceptan las entradas sino se rechazan
    def Salida(self,act):
        if(act >= 0):
            y = 1
        else:
            y = 0
        return y

    def __init__(self,n,it):
       pesos = self.getPesos(n)
       for i in range (it):
            entrada = self.getEntradas(n)
            act = self.Activacion(pesos,entrada)
            y = self.Salida(act)
            print entrada[0],entrada[1],y

#como argumentos se le proporciona el total de entradas (n) y las veces que se repetiráel proceso (it)
neu = neurona(int(argv[1]) ,int(argv[2]))

November 12, 2012

Kinect Detecta Mano en Processing

Bueno este es un .pde con el cual utilizando la libreria SImpleOpenNi y utilizando kinect, se detecta la mano y dibuja un pequeño circulo sobre ella, y además imprime la posición en el eje x en la cual se encuentra, bueno mejor dicho en el pixel en x en el cual se encuentra.


August 20, 2012

Neurona Sencilla

Aquí el código en python de una neurona sencilla.

El programa consiste en introducir como parámetros el tamaño del arreglo, un umbral y las entradas de ese arreglo, que para nuestro caso serían 0's o 1's; después se crea un arreglo del mismo tamaño que las entradas pero con números aleatorios entre 0 y 1. Luego Se multiplican las entradas por su peso correspondiente y se suman dichas multiplicaciones; ya por último se compara la suma con el umbral y si es mayor al umbral se acepta, en caso contrario se rechaza.


August 7, 2012

Proyecto

Idea.

Como idea para proyecto tengo el reconocer mediante Kinect el lenguaje de señas o de signos de los sordomudos y que la computadora en un principio responda con algún mensaje en la pantalla y como objetivo sería que responda con voz a la seña que haga la persona.

Para esto sería necesario utilizar:

  • El Kinect como sensor de movimiento y aprovecharía su funcionamiento para detectear la profundidad
  • El SDK de Kinect para programarlo y poder reconocer las señas.
  • Una red neuronal para detectar cada una de las señas con precisión y calidad.


Proceso

Todo el proceso consistiría en que en la pantalla de la computadora se muestre una simulación de una persona la cual copiaría los movimientos que realice la persona frente al kinect, esto con el fin de comprobar que se detecta a la persona y podría servir para proyectos posteriores; pero se haría mas enfoque en el movimiento de las manos para poder tomar el patron de la seña que se realiza y así poder identificarlos y despues que el software pueda producir alguna respuesta cuando detecte de que seña se trata. El Kinect detectaría los movimientos de las manos y la red neuronal procesaría el movimiento de las manos hasta reconocer el patron y así producir una respuesta

Mi idea final para proyecto ya con el reconocimiento de gestos y la respuesta con voz sería algo como esto:



Saludos!!