Introduction: Red Neuronal En Intel Edison

About: Músico, matemático, computación, ciencia... insolente y subversivo, pero siempre propositivo

En 1943 McCulloch & Pitts, propusieron un modelo matemático para algoritmos que podrían aprender. Este modelo estaba inspirado en el cerebro. Ese modelo con algunas variantes es lo que hoy se conoce como red neuronal. Una RN es entonces un modelo computacional (creado para funcionar en computadoras) que trata de imitar como funcionaría una red de neuronas. Sus usos son múltiples desde una simulación de funcionamiento del cerebro, hasta sistemas sencillos que aprenden y reconocen patrones.

En este intructable, muestro como programar un red neuronal simple en un Intel Edison. La red es muy sencilla y se concentra en solamente un perceptrón, lo cual explico más adelante. Me concentro en aspectos de programación más que en detalles del armado del robot, lo cual es bastante simple. El código lo que implementa es un perceptrón, y se entrena el perceptrón mediante aprendizaje reforzado, es decir, se deja que el robot haga algo, y luego se premia o castiga basado en la observación. En este caso se trata de entrenar al robot para que siga la luz, y pueda coordinar el funcionamiento de los motores dependiendo de la información recibida por sensores de luz. El robot hace un movimiento, luego mide en el ambiente la luz, y basado en eso corrige los pesos del perceptrón.

La programación de este intructable, es con fines didácticos y está abierto a que sea modificado para mejorar o cambiarla. Considero que este intructable es para usuarios intermedios o avanzados.

Step 1: Materiales

Los materiales son:

  1. Intel Edison con pataforma
  2. 2 x servos Tower Pro 5010 (rotación continua)
  3. 2 x fotoresitores
  4. 2 x resitencias
  5. jumper cables
  6. Protoshield (facilita las conexiones pero no es necesario)
  7. Mini-breadboard (pegado al protoshield)
  8. Soporte de 4 baterías AA (alimentación para los servos)
  9. Cable para conectar batería de 9V a la plataforma

Step 2: Chasis

El chasis lo tome de un modelo de robot renacuajo. Solo utilizo algunas de las piezas, y pueden descargar acá para impresión 3D:

  1. Chasis
  2. Ruedas
  3. frente

Hubo que hacer unos pequeños huecos al chasis de plástico para acomodar la placa del Edison, y con unos espaciadores lo fijé al chasis. Las ruedas se pegan con pegamento a uno de los adaptadores que vienen con el servo como se ve en la foto. Los servos se fijan al chasis con tornillos.

Step 3: Preparando El Edison

Para poder abarcar una comunidad más grande de personas, y facilitar que el código pueda funcionar además en otras placas, decidí escribir el código en C++, y utilizar el Arduino IDE, para cargarlo al Edison. En este instructable no voy a entrar en detalles, pues hay buenas instrucciones en este sitio para dejar el Edison listo para programar. Hay otra guía de Sparkfun.

Acá partimos del hecho de que ya esta todo listo y que el "blink" ya se probó y está funcionando.

Step 4: Conexiones

Las conexiones son bastante sencillas:

  1. Los fotoresistores con un divisor de voltaje conectarlos al pin A0 (derecho) y A1 (inzquierdo)
  2. El servo conectarlo a los pines 6 (derecho) y 9 (izquierdo)
  3. Las baterías AA conectarlas directamente para alimentar a los servos. Recordar hacer una tierra común con la tierra de la plataforma Edison
  4. La batería de 9V, se conecta a la conexión de barril de la plataforma Edison.

Step 5: Programación De Un Perceptron

Un perceptrón es un algoritmo para aprendizaje supervisado. Es decir, un algoritmo que permite enseñar a una función matemática a reconocer patrones. Así por ejemplo un niño pequeño puede mover sus piernas pero aprende a caminar, es decir a coordinar sus movimientos, y lo prende con recompesas o caídas. En nuestro proyecto, el robot puede medir la luz y sabe mover sus motores, lo que intentamos lograr es que aprenda a coordinar los motores para lograr el objetivo de llegar a la luz.

Como se ve en la imágen, hay tres componentes principales de un perceptrón. Las entradas, la función de suma, y una función de activación.

Cada entrada x se multiplica por un peso w, y estas se suma tal que:

w0(t) = x1*w1+x2*w2+...+xn*wn.

Entonces sum, es la suma de cada entrada multiplicada por un peso w. La función de activación out(t), es una función que toma como valor sum, y entonces,

  1. Da como resultado -1 si w0(t) es menor que 0
  2. Da como resultado +1 si w0(t) es mayor o igual a 0

El algoritmo de aprendizaje consiste en calcular correctamente los pesos w para obtener el en out(t), que se considera correcto.

En este proyecto en particular tenemos dos entradas que provienen de dos sensores de luz. digamos entonces que son x1 y x2. A esto hay que agregarle una tercera x3 entrada que dejamos que siempre sea 1 (se conoce como bias), para evitar sumas 0. Los valores de entrada de los fotoresistores van de 0 a 1023. Entonces,

w0(t)=x1*w1+x2*w2+x3*w3

La función de activación out(t) hará que el resultado sea -1 o +1. Noten que se utiliza t para indicar una iteración, pues estos cálculos se realizan una vez por cada loop del Edison. Ahora bien, digamos que +1 indica a un servo motor moverse hacia adelante y -1 moverse hacia a atrás. Para corregir el movimiento calculamos el error de la siguiente manera,

error(t) = deseado(t) - out(t)

Por último, con este error corregimos los pesos w,

nuevo w = w + error * x * c

donde c, es una constante entre 0 y 1, de aprendizaje, que se ajusta para determinar que tan rápido debe aprender (si es muy rápido a veces nunca se estabiliza).

Para cada motor utilizaremos un perceptron que toma como entrada los dos sensores de luz. Los detalles del código están en el siguiente paso.

Para más detalles de que es un perceptrón, pueden consultar wikipedia.

Step 6: Código

Acá se encuentra el código completo. Noten que utilizo la librería SoftwareServo, en lugar de servo. La librería servo no sirve para el Edison, pues los timers son diferentes, pero la de software servo funciona de maravilla. Nada más que hay que localizar antes el punto medio, para detener el servo motor, y este va a ser ligeramente diferente para cada servo.

El perceptrón fue creado como un objeto en C++.

Al revisar en el código encontrarán en el loop principal el algoritmo:

  1. Lee la información de los fotoresistores
  2. Los asigna a las entradas de cada perceptrón (dos perceptrones)
  3. Calcula el movimiento a realizar utilizando feedForward()
  4. Realiza el movimiento
  5. Evalua con respecto al deseado, utilizando una función eval(), que indica si el movimiento fue correcto
  6. Se utiliza esa evaluación para la función train() que re-calcula los pesos.

La función eval() lo que hace es decir que si el sensor derecho es mas alto que el izquierdo, entonces el motor debería moverse hacia ese sensor, y así de forma recíproca para el otro motor.

Step 7: Funcionamiento Y Modificaciones

Al poner a funcionar el robot, inicialmente se mueve de forma errática, y después de unos minutos s mueve hacia la luz. Incluso pueden luego mover la fuente de luz y el robot se ira en dirección a ella.

Pueden modificar de muchas maneras el código, una modificación puede ser cambiando la función de evaluación para determinar que siempre busque donde hay mas o menos luz, o cualquier otra. Los perceptrones en principio, servirían para cualquier otra aplicación de aprendizaje o incluso para crear una red mas compleja con muchos perceptrones conectados.

Gracias al apoyo de CrCibernetica.com y de Intel Costa Rica por facilitarme parte de los materiales