Вы находитесь на странице: 1из 47

Captulo 10.

Redes
Neuronales
Usted no me puede procesar con un cerebro normal.-
Charlie Sheen

Estamos en el final de nuestra historia. Este es el ltimo captulo


oficial de este libro (aunque preveo material complementario
adicional para el sitio web y tal vez nuevos captulos en el
futuro). Comenzamos con objetos inanimados que viven en un
mundo de fuerzas y dio esos objetos deseos, la autonoma y la
capacidad de actuar de acuerdo con un sistema de reglas. A
continuacin, se permiti a los objetos a vivir en una poblacin y
evolucionan con el tiempo. Ahora nos preguntamos: Qu es el
proceso de toma de decisiones de cada objeto? Cmo puede ajustar
sus opciones de aprendizaje en el tiempo? Puede un proceso
entidad computacional su entorno y generar una decisin?

El cerebro humano se puede describir como una red de una red


interconectada neural biolgica de las neuronas que transmiten
patrones elaborados de seales elctricas. Las dendritas reciben
seales de entrada y, en base a estas entradas, el fuego una seal de
salida a travs de un axn. O algo as. Cmo el cerebro humano
funciona realmente es un misterio elaborada y compleja, que desde
luego no vamos a tratar de abordar en riguroso detalle en este
captulo.

Figura 10.1
La buena noticia es que el desarrollo de los sistemas de acoplamiento
animados con cdigo no requiere rigor cientfico o exactitud, como
hemos aprendido a lo largo de este libro. Simplemente puede ser
inspirado por la idea de la funcin cerebral.

En este captulo, vamos a empezar con una visin general conceptual


de las propiedades y caractersticas de las redes neuronales y
construimos el ejemplo ms simple posible de una (una red que
consta de una sola neurona). A continuacin, vamos a examinar las
estrategias para la creacin de un objeto cerebro que se puede
insertar en nuestro vehculo de clase y se utiliza para determinar la
direccin. Por ltimo, tambin veremos las tcnicas para la
visualizacin y animacin de una red de neuronas.

10.1 Artificial Neural Networks:


Introduccin y Aplicacin
Cientficos de la computacin de largo se han inspirado en el cerebro
humano. En 1943, Warren S. McCulloch, un neurocientfico, y Walter
Pitts, un lgico, desarroll el primer modelo conceptual de una red
neuronal artificial. En su artculo, "Un clculo lgico de las ideas
inminentes en la actividad nerviosa, que describe el concepto de una
neurona, una sola clula viva en una red de clulas que recibe entradas,
procesa esas entradas, y genera una salida.

Su trabajo, y el trabajo de muchos cientficos e investigadores que


siguieron, no estaba destinado a describir con precisin cmo funciona el
cerebro biolgico. Por el contrario, una red neuronal artificial (que ahora
vamos a referir simplemente como una red neuronal) fue diseado como
un modelo computacional basado en el cerebro para resolver ciertos tipos
de problemas.

Es probable que sea bastante obvio para usted que hay problemas que son
increblemente sencilla para un equipo para resolver, pero es difcil par a
usted. Tomar la raz cuadrada de 964 324, por ejemplo. Una lnea rpida
de cdigo produce el valor 982, un procesamiento de nmero computado
en menos de un milisegundo. Hay, por otro lado, los problemas que son
increblemente simple para que usted o yo a resolver, pero no tan fcil para
un ordenador. Mostrar ningn nio una foto de un gatito o un perrito y que
ser capaz de decirle muy rpidamente cul es cul. Saludar y estrechar mi
mano una maana y usted debera ser capaz de elegir de entre una multitud
de personas que al da siguiente. Pero necesita una mquina para llevar a
cabo una de estas tareas? Los cientficos ya han pasado carreras enteras
investigacin y aplicacin de soluciones complejas.

La aplicacin ms comn de las redes neuronales en el clculo de hoy es


llevar a cabo una de estas tareas fciles-de-a-humana, difcil-por-un-
mquina, a menudo referido como el reconocimiento de patrones. Las
aplicaciones van desde el reconocimiento ptico de caracteres (girando
exploraciones impresas o escritas a mano en texto digital) para el
reconocimiento facial. No tenemos el tiempo o la necesidad de utilizar
algunos de estos ms elaborados algoritmos de inteligencia artificial aqu,
pero si usted est interesado en la investigacin de redes neuronales, lo
recomiendo los libros de Inteligencia Artificial: Un Enfoque moderno por
Stuart J. Russell y Peter Norvig y AI para los desarrolladores de
juegos por David M. Bourg y Glenn Seemann.

Figura 10.2
Una red neuronal es un sistema computacional conexionista. Los
sistemas computacionales que escribimos son de procedimiento; un
programa se inicia en la primera lnea de cdigo, lo ejecuta, y pasa a la
siguiente, siguiendo las instrucciones de una manera lineal. Una verdadera
red neuronal no sigue una trayectoria lineal. Ms bien, la informacin se
procesa en conjunto, en paralelo a lo largo de una red de nodos (los nodos,
en este caso, siendo neuronas).

Aqu tenemos otro ejemplo de un sistema complejo, muy parecidos a los


que hemos examinado en los captulos 6, 7 y 8. Los elementos individuales
de la red, las neuronas, son simples. Ellos leen una entrada, procesarla y
generar una salida. Una red de muchas neuronas, sin embargo, puede
exhibir comportamientos increblemente ricos e inteligentes.

Uno de los elementos clave de una red neuronal es su capacidad


para aprender . Una red neuronal no es slo un sistema complejo, sino un
complejo de adaptacin del sistema, lo que significa que puede cambiar
su estructura interna basada en la informacin que fluye a travs de
l. Tpicamente, esto se logra mediante el ajuste de pesos . En el diagrama
anterior, cada lnea representa una conexin entre dos neuronas e indica la
va para el flujo de informacin. Cada conexin tiene un peso , un nmero
que controla la seal entre las dos neuronas. Si la red genera un buen de
salida (que definiremos ms adelante), no hay necesidad de ajustar los
pesos. Sin embargo, si la red genera un pobre salida un error, por decirlo
as, entonces el sistema se adapta, la alteracin de los pesos con el fin de
mejorar los resultados subsecuentes.

Hay varias estrategias para el aprendizaje, y vamos a examinar dos de ellos


en este captulo.

El aprendizaje supervisado -esencialmente, una estrategia que


implica un maestro que es ms inteligente que la propia red. Por
ejemplo, tomemos el ejemplo de reconocimiento facial. El profesor
muestra la red un montn de caras, y el maestro ya sabe el nombre
asociado a cada cara. La red hace sus conjeturas, a continuacin, el
maestro proporciona la red con las respuestas. La red puede luego
comparar sus respuestas a las correctas conocidos y hacer ajustes
de acuerdo a sus errores. Nuestra primera red neuronal en la
siguiente seccin seguir este modelo.

Aprendizaje no supervisado -Requerido cuando no es un ejemplo de


datos establecidos con respuestas conocidas. Imagnese la bsqueda
de un patrn oculto en un conjunto de datos. Una aplicacin de esto
es la agrupacin, es decir, la divisin de un conjunto de elementos
en grupos de acuerdo a un patrn desconocido. No vamos a estar
buscando en ningn ejemplo de aprendizaje no supervisado en este
captulo, ya que esta estrategia es menos relevante para nuestros
ejemplos.

Aprendizaje por refuerzo estrategia -A basa en la


observacin. Piense en un pequeo ratn que corre a travs de un
laberinto. Si se gira a la izquierda, se pone un trozo de queso; si se
gira a la derecha, recibe una pequea descarga. (No se preocupe, esto
es slo un ratn de mentira.) Presumiblemente, el ratn aprender
con el tiempo para girar a la izquierda. Su red neuronal toma una
decisin con un resultado (gire a la izquierda o derecha) y observa
su entorno (yum o ay). Si la observacin es negativo, la red puede
ajustar sus pesos con el fin de tomar una decisin diferente la
prxima vez. Aprendizaje por refuerzo es comn en la robtica. En
el momento t , el robot realiza una tarea y observa los
resultados. Se chocar contra una pared o se caiga de una mesa? O
es ileso? Pronto nos ocuparemos de aprendizaje por refuerzo en el
contexto de nuestros vehculos de direccin simulados.

Esta capacidad de una red neuronal para aprender, para realizar ajustes en
su estructura con el tiempo, es lo que hace tan til en el campo de la
inteligencia artificial. stos son algunos de los usos habituales de las redes
neuronales en el software de hoy en da.

Reconocimiento de Patrones -Hemos mencionado esto varias veces


ya y que es probablemente la aplicacin ms comn. Ejemplos de
ello son el reconocimiento facial, reconocimiento ptico de
caracteres, etc.
Serie de tiempo de prediccin redes -Neural se pueden utilizar para
hacer predicciones. Aumentar la accin o caer maana? Llover o
sean de sol?
Procesamiento de Seales implantes -Cochlear y audfonos
necesitan para filtrar el ruido innecesario y amplificar los sonidos
importantes. Las redes neuronales pueden ser entrenados para
procesar una seal de audio y filtrar de manera adecuada.
Control de -Usted puede haber ledo acerca de los avances recientes
de la investigacin en los coches de auto-conduccin. Las redes
neuronales se utilizan a menudo para manejar las decisiones de
direccin de vehculos fsicos (o simulados).
Sensores Soft sensor -A suaves se refiere al proceso de anlisis de
una coleccin de muchas mediciones. Un termmetro que puede
decir la temperatura del aire, pero lo que si tambin saba que la
humedad, la presin baromtrica, punto de roco, la calidad del aire,
la densidad del aire, etc.? Las redes neuronales se pueden emplear
para procesar los datos de entrada procedentes de muchos sensores
individuales y evaluarlos como un todo.
Deteccin de anomalas redes neuronales -Debido son tan buenos
en el reconocimiento de patrones, sino que tambin pueden ser
entrenados para generar una salida cuando ocurre algo que no encaja
con el patrn. Pensar en una red neuronal seguimiento de su rutina
diaria durante un largo perodo de tiempo. Despus de aprender los
patrones de su comportamiento, podra alertar cuando algo anda
mal.

Esto es de ninguna manera una lista completa de las aplicaciones de las


redes neuronales. Pero es de esperar que le da una sensacin general de las
caractersticas y posibilidades. La cosa es, las redes neuronales son
complicados y difciles. Implican toda clase de matemticas de
fantasa. Mientras todo esto es fascinante (y muy importante para la
investigacin cientfica), muchas de las tcnicas no son muy prcticos en
el mundo de la construccin de bocetos de procesamiento interactivas,
animadas. Por no mencionar que con el fin de cubrir todo este material,
necesitaramos otro libro-o, ms probablemente, una serie de libros.
As que en lugar, vamos a empezar nuestro ltimo grito en la naturaleza de
cdigo con el ms simple de todas las redes neuronales, en un esfuerzo por
entender cmo se aplican los conceptos generales en el cdigo. A
continuacin vamos a ver algunos bocetos de procesamiento que generan
resultados visuales inspirados por estos conceptos.

10.2 El Perceptrn
Inventado en 1957 por Frank Rosenblatt en el Laboratorio de Aeronut ica
Cornell, un perceptrn es la red neural sencilla posible: un modelo
computacional de una sola neurona. A perceptrn consta de una o ms
entradas, un procesador, y una nica salida.

Figura 10.3: El perceptron

A perceptrn sigue el modelo feed-forward, lo que significa entradas son


enviados en la neurona, se procesan, y el resultado en una salida. En el
diagrama anterior, esto significa que la red (una neurona) se lee de
izquierda a derecha: entradas vienen en, la salida se apaga.

Vamos a seguir cada uno de estos pasos con ms detalle.

Paso 1: Recibe las entradas.

Digamos que tenemos un perceptrn con dos entradas-


Llammosles x1 y x2 .

Entrada 0: x1 = 12
Entrada 1: x2 = 4

Paso 2: entradas de peso.


Cada entrada que se enva en la neurona debe primero ser ponderado, es
decir, se multiplica por un cierto valor (a menudo un nmero entre -1 y
1). Al crear un perceptrn, vamos comienzan tpicamente mediante la
asignacin de pesos aleatorios. A continuacin, vamos a dar a las entradas
de los siguientes pesos:

Peso 0: 0,5
Peso 1: -1

Tomamos cada entrada y se multiplica por su peso.

Entrada 0 * Peso 0 12 * 0,5 = 6

Entrada 1 * Peso 1 4 * -1 = -4

Paso 3: entradas Sum.

Las entradas ponderadas se suman entonces.

Suma = 6 + 2 = -4

Paso 4: Generar salida.

La salida de un perceptron es generado por paso, que suma a travs de una


funcin de activacin. En el caso de una simple salida binaria, la funcin
de activacin es lo que le dice a los perceptrn si fuego o no. Se puede
prever un LED conectado a la seal de salida: si se dispara, la luz se
enciende; si no, se queda fuera.

funciones de activacin pueden conseguir un poco peludo. Si usted


comienza a leer uno de esos libros de texto de inteligencia artificial en
busca de ms informacin sobre las funciones de activacin, es posible que
pronto se encontrar que alcanza para un libro de clculo. Sin embargo,
con nuestro amigo el perceptrn simple, vamos a hacer algo realmente
fcil. Vamos a hacer la activacin de la funcin del signo de la suma. En
otras palabras, si la suma es un nmero positivo, la salida es 1; si es
negativo, la salida es -1.

Salida signo = (suma) signo (2) 1


Vamos a revisar y condensar estos pasos para poder ponerlas en prctica
con un fragmento de cdigo.

El Perceptrn Algoritmo:

1. Para cada entrada, que se multiplican de entrada por su peso.


2. Resumiendo todas las entradas ponderadas.
3. Calcular la salida del perceptrn basado en que suma pasado a
travs de una funcin de activacin (la seal de la suma).

Supongamos que tenemos dos conjuntos de nmeros, las entradas y los


pesos. Por ejemplo:
Mostrar Raw
float[] inputs = {12 , 4};
float[] weights = {0.5,-1};

Por cada entrada implica un bucle que multiplica cada entrada por su
peso correspondiente. Puesto que necesitamos la suma, podemos sumar
los resultados en ese mismo bucle.
Mostrar Raw
Los pasos 1 y 2: Sume todas las entradas ponderadas.
float sum = 0;
for (int i = 0; i < inputs.length; i++) {
sum += inputs[i]*weights[i];
}

Una vez que tenemos la suma podemos calcular la salida.


Mostrar Raw
Paso 3: Paso de la suma a travs de una funcin de activacin
float output = activate(sum);

La funcin de activacin
int activate(float sum) {
Devolucin de un 1 si es positivo, -1 si es negativo.
if (sum > 0) return 1;
else return -1;
}
Reconocimiento 10.3 Modelo simple uso
de un Perceptrn
Ahora que entendemos el proceso de clculo de un perceptrn, podemos
ver un ejemplo de uno de cada accin. Hemos dicho que las redes
neuronales se utilizan a menudo para aplicaciones de reconocimiento de
patrones, como el reconocimiento facial. Incluso perceptrones simples
pueden demostrar los fundamentos de la clasificacin, como en el siguiente
ejemplo.

Figura 10.4

Considere una lnea en el espacio bidimensional. Puntos en que el espacio


se pueden clasificar como viviendo en cualquiera de un lado de la lnea o
la otra. Si bien este es un ejemplo un tanto tonta (ya que no es evidente que
no hay necesidad de una red neuronal, podemos determinar en qu lado de
un punto se encuentra con un poco de lgebra simple), que muestra cmo
un perceptrn puede ser entrenado para reconocer los puntos en un lado
frente a otro .

Digamos que un perceptrn tiene 2 entradas (la X e Y. coordenadas de un


punto). Utilizando una funcin de activacin de seal, la salida ser o bien
-1 o 1, es decir, los datos de entrada se clasifica de acuerdo a la seal de la
salida. En el diagrama anterior, podemos ver cmo cada punto es o bien
debajo de la lnea (-1) o superior (1).
El perceptrn s mismo puede ser diagramado de la siguiente manera:

Figura 10.5

Podemos ver cmo hay dos entradas ( x y Y ), un peso para cada entrada
( peso x y peso y ), as como una neurona de procesamiento que genera la
salida.

Hay un problema muy importante en este caso, sin embargo. Vamos a


considerar el punto (0,0). Lo que si enviamos este punto en el perceptrn
como su entrada: x = 0 ey = 0? Cmo ser la suma de las entradas
ponderadas ser? No importa lo que los pesos son, la suma siempre ser
0! Pero esto no puede ser correcto, despus de todo, el punto (0,0) sin duda
podra estar por encima o por debajo de varias lneas en nuestro mundo de
dos dimensiones.

Para evitar este dilema, nuestros perceptrn requerirn una tercera entrada,
tpicamente referido como un sesgo de entrada. Una entrada de carga
siempre tiene el valor de 1 y tambin se pondera. Aqu est nuestra
perceptrn con la adicin de la polarizacin:

Figura 10.6
Volvamos al punto (0,0). Aqu estn nuestras entradas:

0 * peso para x = 0
0 * peso para y = 0
1 * peso de sesgo = peso de sesgo

La salida es la suma de los tres valores anteriores, 0 plus 0 ms el peso del


sesgo. Por lo tanto, el sesgo, por s mismo, responde a la pregunta acerca
de dnde (0,0) est en relacin a la lnea. Si el peso del sesgo es positivo,
(0,0) est por encima de la lnea; negativo, es abajo. It sesgos la
comprensin del perceptrn de la posicin de la lnea con respecto a (0,0).

10.4 Codificacin del Perceptrn


Ahora estamos listos para ensamblar el cdigo de
un Perceptrn clase. Los nicos datos que el perceptrn necesita para
realizar un seguimiento son los pesos de entrada, y que se poda utilizar
una serie de flotadores para almacenar estos.
Mostrar Raw
class Perceptron {
float[] weights;

El constructor podra recibir un argumento que indica el nmero de


entradas (en este caso tres: x, y, y un sesgo) y el tamao de la matriz en
consecuencia.
Mostrar Raw
Perceptron(int n) {
weights = new float[n];
for (int i = 0; i < weights.length; i++) {
Los pesos son recogidos al azar para comenzar.
weights[i] = random(-1,1);
}
}
Un perceptrn tiene que ser capaz de recibir entradas y generar una
salida. Podemos empaquetar estos requisitos en una funcin
llamada feedforward () . En este ejemplo, tendremos los perceptrn
reciben sus entradas como una matriz (que debe ser la misma longitud que
la matriz de pesos) y devolver la salida como un entero.
Mostrar Raw
int feedforward(float[] inputs) {
float sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += inputs[i]*weights[i];
}
El resultado es el signo de la suma, -1 o +1. Aqu el perceptrn est haciendo una conjetura. Es que en un
lado de la lnea o el otro?
return activate(sum);
}

Es de suponer que, ahora podramos crear un Perceptrn objeto y


pedirle que hacer una conjetura para cualquier punto dado.

Figura 10.7

Mostrar Raw
Crear el Perceptrn.
Perceptron p = new Perceptron(3);
La entrada es de 3 valores: x, y y el sesgo.
float[] point = {50,-12,1};
La respuesta!
int result = p.feedforward(point);
Los perceptrn hacer las cosas bien? En este punto, el perceptrn no tiene
mejor que un 50/50 oportunidad de llegar a la respuesta correcta. Recuerde,
cuando la creamos, nos dimos por cada peso de un valor aleatorio. Una red
neuronal no es magia. No va a ser capaz de adivinar correctamente a menos
que nada lo enseamos cmo!

Para entrenar una red neuronal para responder correctamente, vamos a


emplear el mtodo de aprendizaje supervisado que hemos descrito en la
seccin 10.1 .

Con este mtodo, la red est provista de entradas para las que existe una
respuesta conocida. De esta manera la red puede averiguar si se ha hecho
una suposicin correcta. Si es incorrecta, la red puede aprender de su error
y ajustar sus pesos. El proceso es el siguiente:

1. Proporcionar el perceptrn con entradas para las que hay una


respuesta conocida.
2. Pedir al perceptrn de adivinar una respuesta.
3. Calcular el error. (Lleg hasta la respuesta correcta o incorrecta?)
4. Ajuste todos los pesos de acuerdo con el error.
5. Volver al paso 1 y repita!

Pasos 1 a 4 pueden ser empaquetados en una funcin. Antes de que


podamos escribir la funcin entera, sin embargo, es necesario examinar los
pasos 3 y 4 con ms detalle. Cmo definimos el error del perceptrn? Y
cmo debemos ajustar los pesos de acuerdo con este error?

El error del perceptrn puede ser definida como la diferencia entre la


respuesta deseada y su conjetura.

ERROR = salida deseada - SALIDA GUESS

La frmula anterior puede tener un aspecto familiar para usted. En el


captulo 6 , se calcul una fuerza de direccin como la diferencia entre
nuestra velocidad deseada y nuestra velocidad de la corriente.

DIRECCIN = velocidad deseada - velocidad de la corriente


Este fue tambin un clculo de error. La velocidad de la corriente acta
como una conjetura y el error (la fuerza de gobierno) nos dice cmo ajustar
la velocidad en la direccin correcta. En un momento, vamos a ver cmo
ajustar la velocidad del vehculo para seguir un objetivo al igual que el
ajuste de los pesos de una red neuronal para llegar a la respuesta correcta.

En el caso de la perceptrn, la salida tiene solamente dos valores


posibles: 1 o -1 . Esto significa que slo hay tres posibles errores.

Si el perceptrn adivina la respuesta correcta, entonces la conjetura es igual


a la salida deseada y el error es 0. Si la respuesta correcta es -1 y hemos
adivinado 1, entonces el error es de -2. Si la respuesta correcta es 1 y hemos
adivinado -1, entonces el error es 2.

Deseado Adivinar Error

-1 -1 0

-1 1 -2

1 -1 2

1 1 0

El error es el factor determinante de cmo se deben ajustar los pesos del


perceptrn. Para cualquier peso dado, lo que estamos buscando para el
clculo es el cambio en el peso, a menudo llamado weight (o peso delta,
delta es la letra griega ).

Nuevo peso = peso + WEIGHT

weight se calcula como el error multiplicado por la entrada.

WEIGHT = ERROR DE ENTRADA *


Por lo tanto:

NUEVO PESO PESO = + * ERROR DE ENTRADA

Para entender por qu esto funciona, podemos de nuevo volver a la


direccin . Una fuerza de direccin es esencialmente un error en la
velocidad. Si aplicamos esa fuerza como nuestro aceleracin (velocity),
entonces ajustamos nuestra velocidad para moverse en la direccin
correcta. Esto es lo que queremos hacer con los pesos de nuestra red
neuronal. Queremos ajustarlos en la direccin correcta, como se define por
el error.

Con direccin, sin embargo, tuvimos una variable adicional que controla
la capacidad del vehculo para conducir: la fuerza mxima . Con una alta
fuerza mxima, el vehculo era capaz de acelerar y girar muy
rpidamente; con una fuerza menor, el vehculo podra tomar ms tiempo
para ajustar su velocidad. La red neuronal emplear una estrategia similar
con una variable llamada el aprendizaje constante. Vamos a aadir en el
aprendizaje constante de la siguiente manera:

NUEVO PESO PESO = + ERROR DE ENTRADA * * CONSTANTE


APRENDIZAJE

Observe que una constante de aprendizaje alta significa que el peso va a


cambiar ms drsticamente. Esto puede ayudarnos a llegar a una solucin
ms rpida, pero con tan grandes cambios en el peso es posible vamos a
sobrepasar los pesos ptimos. Con una pequea constante aprendizaje, los
pesos se ajustan lentamente, lo que requiere ms tiempo de entrenamiento,
sino que permite la red para hacer ajustes muy pequeos que podran
mejorar la precisin global de la red.

Suponiendo que la adicin de una variable c para la constante de


aprendizaje, ahora podemos escribir una funcin de entrenamiento para el
perceptrn siguiendo los pasos anteriores.
Mostrar Raw
Una nueva variable se introduce para controlar la velocidad de aprendizaje.
float c = 0.01;
Paso 1: Proporcionar las entradas y respuesta conocido. Estos se pasan como argumentos para entrenar
().
void train(float[] inputs, int desired) {

Paso 2: Guess de acuerdo con estas entradas.


int guess = feedforward(inputs);

Paso 3: Calcular el error (diferencia entre respuesta y adivinar).


float error = desired - guess;

Paso 4: Ajuste todos los pesos de acuerdo con el error y aprendizaje constante.
for (int i = 0; i < weights.length; i++) {
weights[i] += c * error * inputs[i];
}
}

Ahora podemos ver el Perceptrn clase en su conjunto.


Mostrar Raw
class Perceptron {
El Perceptrn almacena sus pesos y las constantes de aprendizaje.
float[] weights;
float c = 0.01;

Perceptron(int n) {
weights = new float[n];
Pesos comienzan al azar.
for (int i = 0; i < weights.length; i++) {
weights[i] = random(-1,1);
}
}

Devolver una salida basada en los insumos.


int feedforward(float[] inputs) {
float sum = 0;
for (int i = 0; i < weights.length; i++) {
sum += inputs[i]*weights[i];
}
return activate(sum);
}
La salida es un 1 o -1.
int activate(float sum) {
if (sum > 0) return 1;
else return -1;
}

Entrenar a la red con los datos conocidos.


void train(float[] inputs, int desired) {
int guess = feedforward(inputs);
float error = desired - guess;
for (int i = 0; i < weights.length; i++) {
weights[i] += c * error * inputs[i];
}
}
}

Para entrenar el perceptrn, necesitamos un conjunto de entradas con una


respuesta conocida. Podramos empaquetar esto en una clase de este
modo:
Mostrar Raw
class Trainer {

Un objeto "Trainer" almacena las entradas y la respuesta correcta.


float[] inputs;
int answer;

Trainer(float x, float y, int a) {


inputs = new float[3];
inputs[0] = x;
inputs[1] = y;
Tenga en cuenta que el entrenador tiene la entrada de polarizacin integrado en su matriz.
inputs[2] = 1;
answer = a;
}
}

Ahora la pregunta es, qu elegimos un punto y saber si est por encima


o por debajo de una lnea? Vamos a empezar con la frmula para una
lnea, donde y se calcula como una funcin de x :
y = f (x)

En trminos genricos, una lnea puede ser descrito como:

y = ax + b

He aqu un ejemplo concreto:

y = 2 * x + 1

entonces podemos escribir una funcin de procesamiento con esto en


mente.
Mostrar Raw
Una funcin para calcular y basado en x a lo largo de una lnea de
float f(float x) {
return 2*x+1;
}

Por lo tanto, si hacemos un punto:


Mostrar Raw
float x = random(width);
float y = random(height);

Cmo sabemos si este punto est por encima o por debajo de la


lnea? La funcin de lnea de f (x) nos da la y valor en la lnea para
que x posicin. Vamos a llamar a que Yline .
Mostrar Raw
La posicin y en la lnea de
float yline = f(x);

Si el y el valor que estamos examinando es encima de la lnea, ser


menos de Yline .
Figura 10.8

Mostrar Raw
if (y < yline) {
La respuesta es -1 si y es por encima de la lnea.
answer = -1;
} else {
answer = 1;
}

Entonces podemos hacer un entrenador objeto con las entradas y la


respuesta correcta.
Mostrar Raw
Trainer t = new Trainer(x, y, answer);

Suponiendo que habamos un Perceptrn objeto ptron , podramos


entrenar mediante el envo de las entradas, junto con la respuesta
conocida.
Mostrar Raw
ptron.train(t.inputs,t.answer);

Ahora, es importante recordar que esto es slo una demostracin. Recuerde


que nuestros monos Shakespeare de tipificacin ? Le pedimos a nuestro
algoritmo gentico para resolver ser o no ser -una respuesta que ya
sabamos. Hicimos esto para asegurarse de nuestro algoritmo gentico
funcionaba correctamente. El mismo razonamiento se aplica a este
ejemplo. No necesitamos un perceptrn de decirnos si un punto est por
encima o por debajo de una lnea; podemos hacer eso con las matemticas
simples. Estamos utilizando este escenario, una que podemos resolver
fcilmente sin un perceptrn, para demostrar el algoritmo del perceptrn,
as como fcil confirmar que est funcionando correctamente.

Veamos cmo el perceptrn funciona con una serie de muchos puntos de


entrenamiento.

REINICIAR PAUSA

Ejemplo 10.1: El Perceptron


Mostrar Raw
el Perceptrn
Perceptron ptron;
2.000 puntos de entrenamiento
Trainer[] training = new Trainer[2000];
int count = 0;

La frmula para una lnea de


float f(float x) {
return 2*x+1;
}

void setup() {
size(640, 360);

ptron = new Perceptron(3);

Hacer 2.000 puntos de entrenamiento.


for (int i = 0; i < training.length; i++) {
float x = random(-width/2,width/2);
float y = random(-height/2,height/2);
Es la respuesta correcta 1 o -1?
int answer = 1;
if (y < f(x)) answer = -1;
training[i] = new Trainer(x, y, answer);
}
}

void draw() {
background(255);
translate(width/2,height/2);

ptron.train(training[count].inputs, training[count].answer);
Para la animacin, estamos formando un punto a la vez.
count = (count + 1) % training.length;

for (int i = 0; i < count; i++) {


stroke(0);
int guess = ptron.feedforward(training[i].inputs);
Mostrar la clasificacin, sin relleno de -1, negro de 1.
if (guess > 0) noFill();
else fill(0);
ellipse(training[i].inputs[0], training[i].inputs[1], 8, 8);
}
}

ejercicio 10.1
En lugar de utilizar el modelo de aprendizaje supervisado anteriormente,
se puede entrenar la red neuronal para encontrar los pesos adecuados
mediante el uso de un algoritmo gentico?

ejercicio 10.2
Visualizar el perceptrn s. Dibujar las entradas, el nodo de
procesamiento, y la salida.

10.5 un perceptrn de direccin


Mientras clasificando puntos en funcin de su posicin por encima o por
debajo de una lnea fue una demostracin til del perceptrn en accin, que
no tiene mucha relevancia prctica para los dems ejemplos de este
libro. En esta seccin, se abordan los conceptos de un perceptrn (variedad
de entradas, salida nica), lo aplicamos a los comportamientos de
direccin, y demostramos aprendizaje por refuerzo a lo largo del camino.

Ahora vamos a tomar licencia creativa significativa con el concepto de una


red neuronal. Esto nos permitir seguir con los conceptos bsicos y evitar
algunos de los altamente complejos algoritmos asociados a las redes
neuronales ms sofisticados. Aqu no estamos tan preocupados con las
siguientes reglas descritas en los libros de texto de inteligencia artificial-
estamos slo con la esperanza de hacer algo interesante y el cerebro
similar.

Recuerde que nuestro buen amigo el vehculo de clase? Ya sabes, que uno
para la fabricacin de objetos con una ubicacin, velocidad y
aceleracin? Esto podra obedecer a las leyes de Newton con
una applyForce () la funcin y se mueven alrededor de la ventana de
acuerdo con una variedad de reglas de direccin?

Y si aadimos una variable ms en nuestro vehculo de clase?


Mostrar Raw
class Vehicle {

Dando al vehculo un cerebro!


Perceptron brain;

PVector location;
PVector velocity;
PVector acceleration;
//etc...

Aqu es nuestro escenario. Digamos que tenemos un boceto de


procesamiento con un ArrayList de objetivos y un solo vehculo.

Figura 10.9
Digamos que el vehculo busca todos los objetivos. De acuerdo con los
principios del Captulo 6, tendramos prxima escribir una funcin que
calcula una fuerza de direccin hacia cada destino, la aplicacin de cada
fuerza uno a la vez a la aceleracin del objeto. Suponiendo que los
objetivos son un ArrayList de PVector objetos, se vera algo as como:
Mostrar Raw
void seek(ArrayList<PVector> targets) {
for (PVector target : targets) {
Para cada objetivo, aplicar una fuerza de direccin hacia el objetivo.
PVector force = seek(targets.get(i));
applyForce(force);
}
}

En el captulo 6, que tambin examin la forma en que podra crear


simulaciones dinmicas ms ponderando cada fuerza de direccin de
acuerdo con alguna regla. Por ejemplo, podramos decir que cuanto ms
lejos se est de un objetivo, mayor ser la fuerza.
Mostrar Raw
void seek(ArrayList<PVector> targets) {
for (PVector target : targets) {
PVector force = seek(targets.get(i));
float d = PVector.dist(target,location);
float weight = map(d,0,width,0,5);
Ponderando cada fuerza de direccin de forma individual
force.mult(weight);
applyForce(force);
}
}

Pero lo que si en vez de poder pedir nuestro cerebro (es decir perceptrn)
para disfrutar de todas las fuerzas como una entrada, procesarlos de
acuerdo con los pesos de las entradas perceptrn, y generar una fuerza de
direccin de salida? Y si pudiramos decir lugar:
Mostrar Raw
void seek(ArrayList<PVector> targets) {

Hacer una serie de insumos para nuestro cerebro.


PVector[] forces = new PVector[targets.size()];

for (int i = 0; i < forces.length; i++) {


Llenar la matriz con una fuerza de direccin para cada objetivo.
forces[i] = seek(targets.get(i));
}

Pedir a nuestro cerebro para un resultado y aplicar que a medida que la fuerza!
PVector output = brain.process(forces);
applyForce(output);
}

En otras palabras, en lugar de ponderar y acumular las fuerzas dentro de


nuestro vehculo, simplemente pasar una matriz de fuerzas al objeto
cerebro del vehculo y permitir que el cerebro de peso y la suma de las
fuerzas para nosotros. La salida se aplica entonces como una fuerza de
direccin. Esto abre un abanico de posibilidades. Un vehculo puede tomar
decisiones en cuanto a cmo dirigir por s mismo, aprendiendo de sus
errores y responder a los estmulos de su entorno. Vamos a ver cmo
funciona esto.

Podemos utilizar la clasificacin de la lnea perceptrn como modelo, pero


con una diferencia importante: las entradas no son nmeros individuales,
pero los vectores! Veamos cmo el feedforward () funcin trabaja en
perceptrn de nuestro vehculo, junto con el de nuestro ejemplo anterior.

PVector entradas de vehculos entradas de lnea de flotacin

int feedforward (float [] entradas) {


PVector feedforward
// Suma es un flotador.
(fuerzas PVector []) {
flotador suma = 0;
// Suma es un PVector.
for (int i = 0; i <weights.length; i ++) {
PVector suma = new
// suma escalar y multiplicacin
PVector ();
sum + = entradas [i] * pesos [i];
for (int i = 0; i
<weights.length; i ++) {
}
// Adems Vector y
// funcin de activacin
multiplicacin
Activar (suma) de retorno;
fuerzas [i] .mult (el }
peso de [i]);
sum.add (fuerzas [i]);
}
// No hay funcin de
activacin
suma de retorno;
}

Tenga en cuenta cmo estas dos funciones implementan algoritmos casi


idnticos, con dos diferencias:

1. Resumiendo PVectors. En lugar de una serie de nmeros aadidos


juntos, cada entrada es un PVector y debe ser multiplicado por el
peso y se aadi a una suma de acuerdo con las
matemticas PVector funciones.
2. Sin funcin de activacin. En este caso, nos estamos tomando el
resultado y aplicarlo directamente como una fuerza de direccin para
el vehculo, por lo que no estamos pidiendo un simple valor
booleano que lo clasifica en una de dos categoras. Ms bien,
estamos pidiendo la salida pura en s, la fuerza total resultante.

Una vez que se ha aplicado la fuerza de direccin resultante, es el momento


de dar retroalimentacin al cerebro, es decir, el aprendizaje por
refuerzo . Fue la decisin de mantenerse en esa direccin particular, una
buena o una mala? Es de suponer que si algunos de los objetivos eran
depredadores (que resulta en ser comido) y algunos de los objetivos eran
los alimentos (que resulta en una mayor salud), la red sera ajustar sus
pesos con el fin de dirigir lejos de los depredadores y hacia la comida.

Vamos a tomar un ejemplo ms simple, cuando el vehculo simplemente


quiere estar cerca del centro de la ventana. Vamos a entrenar el cerebro de
la siguiente manera:
Mostrar Raw
PVector desired = new PVector(width/2,height/2);
PVector error = PVector.sub(desired, location);
brain.train(forces,error);
Figura 10.10

Aqu estamos pasando el cerebro una copia de todos los insumos (que va a
necesitar para la correccin de errores), as como una observacin acerca
de su entorno: el PVector que apunta desde su ubicacin actual a donde
desea ser. Este PVector sirve esencialmente como el error en el ms largo
es el PVector , peor es el vehculo est funcionando; cuanto ms corto,
mejor.

Entonces, el cerebro puede aplicar este vector error (que tiene dos
valores de error, una para x y una para y ) como un medio para ajustar los
pesos, tal como lo hicimos en el ejemplo de clasificacin de lnea.

El entrenamiento del Vehculo El entrenamiento del clasificador

tren vaco (fuerzas PVector [], error PVector) { tren vaco (flotar entradas [], in

int conjetura = feedforward (


error flotador = deseada - a

for (int i = 0; i <weights.length; i ++) { for (int i = 0; i <weights.leng


pesos [i] + = c * error.x * fuerzas [i] .x; Pesos [i] + = c * Error * en
Pesos [i] + = c * error.y * fuerzas [i] .y;
} }
} }

Debido a que el vehculo respete su propio error, no hay necesidad de


calcular uno; simplemente podemos recibir el error como un
argumento. Observe cmo se procesa el cambio en el peso dos veces, una
vez para el error a lo largo del eje x y una vez para el eje y.
Mostrar Raw
weights[i] += c*error.x*forces[i].x;
weights[i] += c*error.y*forces[i].y;

Ahora podemos mirar el vehculo clase y ver cmo el novillo funcin


utiliza un perceptrn para controlar la fuerza de la direccin general. El
nuevo contenido de este captulo se resalta.

REINICIAR PAUSA

Ejemplo 10.2: direccin Perceptron


Mostrar Raw
class Vehicle {

El vehculo tiene ahora un cerebro.


Perceptron brain;

antiguas variables mismos para la fsica


PVector location;
PVector velocity;
PVector acceleration;
float maxforce;
float maxspeed;

El vehculo crea un perceptrn con n entradas y una constante aprendizaje.


Vehicle(int n, float x, float y) {
brain = new Perceptron(n,0.001);
acceleration = new PVector(0,0);
velocity = new PVector(0,0);
location = new PVector(x,y);
maxspeed = 4;
maxforce = 0.1;
}

El mismo viejo actualizacin de la funcin ()


void update() {
velocity.add(acceleration);
velocity.limit(maxspeed);
location.add(velocity);
acceleration.mult(0);
}
la funcin misma edad applyForce ()
void applyForce(PVector force) {
acceleration.add(force);
}

void steer(ArrayList<PVector> targets) {


PVector[] forces = new PVector[targets.size()];

for (int i = 0; i < forces.length; i++) {


forces[i] = seek(targets.get(i));
}
Todas las fuerzas de direccin son entradas.
PVector result = brain.feedforward(forces);

Se aplica el resultado.
applyForce(result);

El cerebro est entrenado de acuerdo con la distancia al centro.


PVector desired = new PVector(width/2,height/2);
PVector error = PVector.sub(desired, location);
brain.train(forces,error);

la funcin misma edad seek ()


PVector seek(PVector target) {
PVector desired = PVector.sub(target,location);
desired.normalize();
desired.mult(maxspeed);
PVector steer = PVector.sub(desired,velocity);
steer.limit(maxforce);
return steer;
}

ejercicio 10.3
Visualizar los pesos de la red. Se puede intentar peso correspondiente de
cada objetivo a su brillo.
ejercicio 10.4
Pruebe diferentes reglas para el aprendizaje por refuerzo. Qu pasa si
algunos objetivos son deseables y algunos son indeseables?

10.6 Es una red Recuerde?


S, un perceptrn puede tener mltiples entradas, pero sigue siendo una
neurona solitaria. El poder de las redes neuronales viene en el propio
trabajo en red. Perceptrones son, por desgracia, muy limitados en sus
capacidades. Si usted lee un libro de texto de AI, se dir que un perceptrn
slo se puede resolver linealmente separables problemas. Qu es un
problema linealmente separables? Vamos a echar un vistazo a nuestro
primer ejemplo, que determinan si los puntos estaban en un lado de una
lnea o el otro.

Figura 10.11

A la izquierda de la figura 10.11, tenemos datos linealmente separables


clsicos. Grfico todas las posibilidades; si se puede clasificar los datos
con una lnea recta, entonces es linealmente separables. A la derecha, sin
embargo, es no lineal de datos separables. No se puede trazar una lnea
recta para separar los puntos negros de los grises.

Uno de los ejemplos ms simples de un problema no linealmente


separables es XOR , o exclusivo o. Todos estamos familiarizados
con Y . Por Un Y B para ser verdad, tanto A y B debe ser verdad. Con O ,
ya sea A o B pueden ser verdad para A OR B para evaluar como
verdadero. Estos son ambos problemas linealmente separables. Veamos el
espacio de soluciones, una tabla de verdad.

Figura 10.12

Ver cmo se puede dibujar una lnea para separar las salidas verdaderos
de los falsos?

XOR es el equivalente de OR y NOT y . En otras palabras, A XOR B slo


evala a cierto si una de ellas es verdadera. Si ambos son falsos o ambas
son verdaderas, entonces tenemos falsa. Echar un vistazo a la siguiente
tabla de verdad.

Figura 10.13

Esto no es linealmente separable. Trate de dibujar una lnea recta para


separar las salidas verdadero de lo falso-los que no se puede!

As perceptrones ni siquiera pueden resolver algo tan simple


como XOR . Pero lo que si realizamos una red de dos perceptrones? Si uno
perceptrn puede resolver O y uno perceptrn puede resolver NO Y , a
continuacin, dos perceptrones combinados pueden resolver XOR .
Figura 10.14

El diagrama anterior se conoce como un perceptrn de mltiples capas ,


una red de muchas neuronas. Algunos son neuronas de entrada y recibir las
entradas, algunos son parte de lo que se llama una capa de oculto (ya que
estn conectados a ni las entradas ni las salidas de la red directamente), y
luego estn las neuronas de salida, de la que leemos Los resultados.

La formacin de estas redes es mucho ms complicado. Con el perceptrn


simple, podramos evaluar fcilmente cmo cambiar los pesos de acuerdo
con el error. Pero aqu hay tantas conexiones diferentes, cada uno en una
capa diferente de la red. Cmo se sabe la cantidad de cada neurona o
conexin contribuyeron al error total de la red?

La solucin a la optimizacin de pesos de una red de varias capas se conoce


como backpropagation . La salida de la red se genera en la misma manera
que un perceptrn. Las entradas multiplicadas por los pesos se suman y se
alimentan hacia delante a travs de la red. La diferencia aqu es que pasan
a travs de capas adicionales de neuronas antes de llegar a la salida. El
entrenamiento de la red (es decir, el ajuste de los pesos) tambin consiste
en tomar el error (resultado deseado - adivinar). El error, sin embargo, debe
ser alimentado hacia atrs a travs de la red. El error final en ltima
instancia ajusta los pesos de todas las conexiones.

Retropropagacin es un poco ms all del alcance de este libro y consiste


en una funcin ms elegante de activacin (llamado la funcin sigmoide),
as como algunos clculos bsicos. Si usted est interesado en cmo
funciona la propagacin hacia atrs, consultar la pgina web del libro (y
GitHub repositorio) para un ejemplo que soluciona XOR utilizando una red
de alimentacin directa de varias capas con propagacin hacia atrs.

En cambio, aqu nos centraremos en un marco de cdigo para la


construccin de la arquitectura visual de una red. Haremos Neuron objetos
y conexin objetos de los que una red objeto puede ser creados y
animados para mostrar el proceso de avance de alimentacin. Esto se
asemejan mucho a algunos de los ejemplos de grfico dirigido por fuerza
hemos examinado en el captulo 5 (toxiclibs).

10.7 diagramas de redes neuronales


Nuestro objetivo ser crear el siguiente diagrama de red simple:

Figura 10.15

El bloque de construccin principal de este diagrama es una neurona. Para


los fines de este ejemplo, la neurona clase describe una entidad con una (x,
y) de ubicacin.
Mostrar Raw
Un increblemente simples tiendas de la categora neurona y muestra la ubicacin de una sola neurona.
class Neuron {
PVector location;

Neuron(float x, float y) {
location = new PVector(x, y);
}

void display() {
stroke(0);
fill(0);
ellipse(location.x, location.y, 16, 16);
}
}

La Red de clase, entonces puede gestionar un ArrayList de las neuronas,


as como tener su propia ubicacin (de modo que cada neurona se dibuja
en relacin con el centro de la red). Esta es sistemas de partculas 101.
Tenemos un solo elemento (una neurona) y una red (un sistema de
muchas neuronas).
Mostrar Raw
Una red es una lista de las neuronas.
class Network {
ArrayList<Neuron> neurons;
PVector location;

Network(float x, float y) {
location = new PVector(x,y);
neurons = new ArrayList<Neuron>();
}

Podemos aadir una neurona a la red.


void addNeuron(Neuron n) {
neurons.add(n);
}

Podemos extraer toda la red.


void display() {
pushMatrix();
translate(location.x, location.y);
for (Neuron n : neurons) {
n.display();
}
popMatrix();
}
}
Ahora podemos hacer con bastante facilidad el diagrama anterior.
Mostrar Raw
Network network;

void setup() {
size(640, 360);
Hacer una red.
network = new Network(width/2,height/2);

Hacer las neuronas.


Neuron a = new Neuron(-200,0);
Neuron b = new Neuron(0,100);
Neuron c = new Neuron(0,-100);
Neuron d = new Neuron(200,0);

Aadir las neuronas de la red.


network.addNeuron(a);
network.addNeuron(b);
network.addNeuron(c);
network.addNeuron(d);
}

void draw() {
background(255);
Mostrar la red.
network.display();
}

Los rendimientos anteriores:


Lo que falta, por supuesto, es la conexin. Podemos considerar
una conexin objeto que se compone de tres elementos, dos neuronas
(de Neurona una a la neurona b ) y un peso .
Mostrar Raw
class Connection {
Una conexin es entre dos neuronas.
Neuron a;
Neuron b;
Una conexin tiene un peso.
float weight;

Connection(Neuron from, Neuron to,float w) {


weight = w;
a = from;
b = to;
}

Una conexin se dibuja como una lnea.


void display() {
stroke(0);
strokeWeight(weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
}
}

Una vez que tenemos la idea de una conexin objeto, podemos escribir
una funcin (vamos a ponerlo dentro de la Red de clase) que conecta dos
neuronas juntos, el objetivo es que, adems de hacer las neuronas en la
configuracin () , tambin podemos conectarlos .

Mostrar Raw
void setup() {
size(640, 360);
network = new Network(width/2,height/2);

Neuron a = new Neuron(-200,0);


Neuron b = new Neuron(0,100);
Neuron c = new Neuron(0,-100);
Neuron d = new Neuron(200,0);
Hacer conexiones entre las neuronas
network.connect(a,b);
network.connect(a,c);
network.connect(b,d);
network.connect(c,d);

network.addNeuron(a);
network.addNeuron(b);
network.addNeuron(c);
network.addNeuron(d);
}

La red , por lo tanto clase necesita una nueva funcin llamada connect
() , que hace una conexin objeto entre las dos neuronas especificados.

Mostrar Raw
void connect(Neuron a, Neuron b) {
Conexin tiene un peso aleatorio.
Connection c = new Connection(a, b, random(1));

// But what do we do with the Connection object?


}

Presumiblemente, podramos pensar que la red debe almacenar


una ArrayList de conexiones, al igual que lo almacena un ArrayList de
las neuronas. Si bien es til, en este caso un tal ArrayList no es necesario
y no se encuentra una caracterstica importante que necesitamos. En ltima
instancia, tenemos la intencin de alimentar hacia adelante" las neuronas
a travs de la red, por lo que la neurona objetos mismos deben saber a qu
neuronas estn conectadas en la direccin hacia adelante. En otras
palabras, cada neurona debe tener su propia lista de conexin de objetos.
Cuando una se conecta a b , queremos una para almacenar una referencia
de esa conexin para que pueda pasar a su salida a b cuando llegue el
momento.
Mostrar Raw
void connect(Neuron a, Neuron b) {
Connection c = new Connection(a, b, random(1));
a.addConnection(c);
}
En algunos casos, tambin puede ser que desee neurona b para saber
acerca de esta conexin, pero en este ejemplo particular, slo vamos a
pasar la informacin en una sola direccin.

Para que esto funcione, tenemos que aadir una ArrayList de conexiones
a la neurona clase. A continuacin, ponemos en prctica
la AddConnection () la funcin que almacena la conexin en
ese ArrayList .
Mostrar Raw
class Neuron {
PVector location;

La neurona almacena sus conexiones.


ArrayList<Connection> connections;

Neuron(float x, float y) {
location = new PVector(x, y);
connections = new ArrayList<Connection>();
}

Adicin de una conexin con esta neurona


void addConnection(Connection c) {
connections.add(c);
}

La neurona de pantalla () funcin puede dibujar las conexiones


tambin. Y, por ltimo, tenemos nuestro diagrama de la red.

REINICIAR PAUSA

Ejemplo 10.3: Diagrama de Red Neural


Mostrar Raw
void display() {
stroke(0);
strokeWeight(1);
fill(0);
ellipse(location.x, location.y, 16, 16);

Dibujo todas las conexiones


for (Connection c : connections) {
c.display();
}
}
}

10,8 Animating Feed Forward


Un problema interesante a considerar es cmo visualizar el flujo de
informacin a medida que viaja a travs de una red neuronal. Nuestra red
se basa en el modelo de alimentacin hacia adelante, lo que significa que
una entrada llega a la primera neurona (dibujado en la parte izquierda de
la ventana) y la salida de esa neurona fluye a travs de las conexiones hacia
la derecha hasta que sale como salida desde la red s mismo.

Nuestro primer paso es agregar una funcin a la red para recibir esta
entrada, lo que vamos a hacer un nmero aleatorio entre 0 y 1.
Mostrar Raw
void setup() {
Toda nuestra antigua red creada cdigo

Una nueva funcin para enviar en una entrada


network.feedforward(random(1));
}

La red, que gestiona todas las neuronas, se puede optar por el cual las
neuronas se debern aplicar esta entrada. En este caso, vamos a hacer algo
sencillo y simplemente alimentar a una sola entrada en la primera neurona
en el ArrayList , que pasa a ser ms a la izquierda uno.
Mostrar Raw
class Network {

Una nueva funcin para alimentar a una entrada en la neurona


void feedforward(float input) {
Neuron start = neurons.get(0);
start.feedforward(input);
}
Qu hicimos? Bueno, hemos hecho que es necesario aadir una funcin
llamada feedforward () en la neurona clase que recibir la entrada y
procesarla.
Mostrar Raw
class Neuron

void feedforward(float input) {


Qu hacemos con la entrada?

Si recuerdan al trabajar con nuestra perceptrn, la tarea estndar que


realiza la unidad de procesamiento es de resumir todas sus entradas. As
que si nuestra neurona clase aade una variable llamada suma ,
simplemente se puede acumular las entradas de medida que se reciben.
Mostrar Raw
class Neuron

int sum = 0;

void feedforward(float input) {


Acumula las sumas.
sum += input;
}

La neurona puede entonces decidir si debe fuego, o pasar una salida a


travs de cualquiera de sus conexiones a la siguiente capa en la red. Aqu
podemos crear una funcin de activacin muy simple: si la suma es mayor
que 1, el fuego!
Mostrar Raw
void feedforward(float input) {
sum += input;
Activar la neurona y el fuego de las salidas?
if (sum > 1) {
fire();
Si hemos disparado nuestra produccin, podemos restablecer nuestra suma a 0.
sum = 0;
}
}

Ahora bien, qu es lo que hacemos en el fuego () la funcin? Si


recuerdan, cada neurona realiza un seguimiento de sus conexiones con
otras neuronas. As que todo lo que tenemos que hacer es recorrer esas
conexiones y alimentacin hacia delante () de salida de la
neurona. Para este ejemplo sencillo, slo tendremos que tomamos de la
neurona suma variable y lo convierten en la salida.
Mostrar Raw
void fire() {
for (Connection c : connections) {
La neurona enva la suma a travs de todas sus conexiones
c.feedforward(sum);
}
}

Aqu es donde las cosas se complican un poco. Despus de todo, nuestro


trabajo aqu no es para hacer realmente una red neuronal que funciona,
pero para animar una simulacin de uno. Si la red neuronal se acaba
contina su trabajo, que pasara al instante esas entradas (multiplicado por
el peso de la conexin) a lo largo de las neuronas conectadas. Nos dicen
algo como:
Mostrar Raw
class Connection {

void feedforward(float val) {


b.feedforward(val*weight);
}

Pero esto no es lo que queremos. Lo que queremos hacer es dibujar algo


que podemos ver que viaja a lo largo de la conexin de
la neurona una a la neurona b .

Primero vamos a pensar en cmo podemos hacer eso. Sabemos que la


ubicacin de la neurona una ; que es
el PVector a.location . Neurona b se encuentra
en b.location . Tenemos que empezar algo que se mueve desde la
neurona un creando otro PVector que almacenar el camino de nuestros
datos de viaje.
Mostrar Raw
PVector sender = a.location.get();

Una vez que tenemos una copia de ese destino, podemos utilizar cualquiera
de los algoritmos de movimiento que hemos estudiado en este libro para
moverse a lo largo de este camino. Aqu, vamos a elegir algo muy simple
y justo interpolar de una a b .
Mostrar Raw
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);

Junto con la lnea de la conexin, podemos dibujar un crculo en ese


lugar:
Mostrar Raw
stroke(0);
line(a.location.x, a.location.y, b.location.x, b.location.y);
fill(0);
ellipse(sender.x, sender.y, 8, 8);

Esto se asemeja a lo siguiente:

Figura 10.16

OK, as que eso es lo que podramos mover algo a lo largo de la


conexin. Pero, cmo sabemos cundo hacerlo? Comenzamos este
proceso, el momento en que la conexin objeto recibe la seal
feedforward. Podemos hacer un seguimiento de este proceso mediante el
empleo de un simple booleano para saber si la conexin est enviando o
no. Antes, tenamos:
Mostrar Raw
void feedforward(float val) {
b.feedforward(val*weight);
}
Ahora, en lugar de enviar el valor de inmediato, vamos a activar una
animacin:
Mostrar Raw
class Connection {

boolean sending = false;


PVector sender;
float output;

void feedforward(float val) {


Enviando ahora es cierto.
sending = true;
Iniciar la animacin en el lugar de la neurona A.
sender = a.location.get();
Almacenar el resultado de cuando en realidad es hora de alimentar hacia adelante.
output = val*weight;
}

Observe cmo nuestra conexin clase necesita ahora tres nuevas


variables. Necesitamos un booleano enviar que se inicia tan falsa y que
va a realizar un seguimiento de si es o no la conexin est enviando de
forma activa (es decir, animacin). Necesitamos un PVector emisor
para la ubicacin en la que dibujaremos el punto de viajar. Y ya que no
estamos pasando la salida a lo largo de este instante, tendremos que
almacenarlo en una variable que va a hacer el trabajo ms tarde.

La alimentacin hacia delante () la funcin se llama el momento de


la conexin se activa. Una vez que est activo, tendremos que llamar a otra
funcin continua (cada vez a travs de sorteo () ), que se actualizar la
ubicacin de los datos de viaje.
Mostrar Raw
void update() {
if (sending) {
Mientras que estamos enviando, interpolar los puntos.
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);
}
}
Nos falta un elemento clave, sin embargo. Tenemos que comprobar si el
remitente ha llegado a la ubicacin B, y si lo tiene, alimentar hacia adelante
que la salida al siguiente neurona.
Mostrar Raw
void update() {
if (sending) {
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);

Cun lejos estamos de neurona b?


float d = PVector.dist(sender, b.location);

Si somos lo suficientemente cerca (a menos de un pxel) pasan en la salida. Desactivar el envo.


if (d < 1) {
b.feedforward(output);
sending = false;
}
}
}

Veamos la conexin de la clase todos juntos, as como nuestro


nuevo sorteo () funcin.

REINICIAR PAUSA

Ejemplo 10.4: Animacin de un diagrama de red neural


Mostrar Raw
void draw() {
background(255);
La Red tiene ahora un nuevo mtodo de actualizacin () que actualiza todos los objetos de conexin.
network.update();
network.display();

if (frameCount % 30 == 0) {
Estamos eligiendo a enviar una entrada cada 30 tramas.
network.feedforward(random(1));
}
}

class Connection {
Los datos de la conexin
float weight;
Neuron a;
Neuron b;

Variables para realizar un seguimiento de la animacin


boolean sending = false;
PVector sender;
float output = 0;

Connection(Neuron from, Neuron to, float w) {


weight = w;
a = from;
b = to;
}

La conexin se activa con los datos que viajan desde a hasta b.


void feedforward(float val) {
output = val*weight;
sender = a.location.get();
sending = true;
}

Actualizacin de la animacin si est enviando.


void update() {
if (sending) {
sender.x = lerp(sender.x, b.location.x, 0.1);
sender.y = lerp(sender.y, b.location.y, 0.1);
float d = PVector.dist(sender, b.location);
if (d < 1) {
b.feedforward(output);
sending = false;
}
}
}

Dibuje la conexin como una lnea y el crculo de viajar.


void display() {
stroke(0);
strokeWeight(1+weight*4);
line(a.location.x, a.location.y, b.location.x, b.location.y);
if (sending) {
fill(0);
strokeWeight(1);
ellipse(sender.x, sender.y, 16, 16);
}
}
}

ejercicio 10.5
La red en el ejemplo anterior se ha configurado manualmente mediante el
establecimiento de la localizacin de cada neurona y sus conexiones con
los valores codificados de forma rgida. Reescribir este ejemplo para
generar el diseo de la red a travs de un algoritmo. Se puede hacer un
diagrama de red circular? Un azar? Un ejemplo de una red de mltiples
capas est por debajo.

REINICIAR PAUSA

ejercicio 10.6
Reescribir el ejemplo para que cada neurona realiza un seguimiento de su
avance y las conexiones hacia atrs. Se puede alimentar las entradas a
travs de la red en cualquier direccin?

ejercicio 10.7
En lugar de lerp () , utilice cuerpos en movimiento con fuerzas de
direccin para visualizar el flujo de informacin en la red.

El Proyecto del Ecosistema


Paso 10 Ejercicio:

Trate de incorporar el concepto de un cerebro en sus criaturas.

Utilizar el aprendizaje por refuerzo en el proceso de toma de


decisiones de las criaturas.
Crear una criatura que cuenta con una visualizacin de su
cerebro como parte de su diseo (incluso si el cerebro en s
no es funcional).
Puede el ecosistema en su conjunto emular el
cerebro? Pueden los elementos del entorno que las neuronas
y las criaturas actuar como entradas y salidas?

El fin
Si todava ests leyendo, gracias! Usted ha llegado al final del libro. Pero
para todo el material que contiene este libro, apenas hemos araado la
superficie del mundo en que vivimos y de las tcnicas para la simulacin
de la misma. Es mi intencin de este libro para vivir como un proyecto en
curso, y espero seguir aadiendo nuevos tutoriales y ejemplos a la pgina
web del libro , as como ampliar y actualizar el material impreso. Su
opinin es apreciado verdad, as que por favor ponerse en contacto por
correo electrnico a (daniel@shiffman.net) o contribuyendo al repositorio
GitHub , de acuerdo con el espritu de cdigo abierto del
proyecto. Compartir su trabajo. Mantenerse en contacto. Vamos a ser dos
con la naturaleza.

Вам также может понравиться