Crea una red neuronal simple



Traducción de hacer una red neuronal simple

Que haremos Intentaremos crear una red neuronal simple y muy pequeña, que explicaremos y le enseñaremos a distinguir algo. Al mismo tiempo, no entraremos en la historia y la jungla matemática (dicha información es muy fácil de encontrar); en su lugar, intentaremos explicar el problema (no el hecho de que sea posible) a usted y a nosotros mismos con dibujos y código.

Muchos de los términos en redes neuronales están relacionados con la biología, así que comencemos desde el principio:


El cerebro es algo complicado, pero también se puede dividir en varias partes y operaciones principales:



El agente causal también puede ser interno (por ejemplo, una imagen o una idea):



Ahora echemos un vistazo a las partes básicas y simplificadas del cerebro:


El cerebro generalmente se parece a una red de cable.

Una neurona es la unidad principal de cálculo en el cerebro, recibe y procesa las señales químicas de otras neuronas y, dependiendo de una serie de factores, no hace nada o genera un impulso eléctrico o Potencial de acción, que luego envía señales a las neuronas conectadas vecinas a través de sinapsis:



Los sueños, los recuerdos, los movimientos autorreguladores, los reflejos y, de hecho, todo lo que piensas o haces se debe a este proceso: millones o incluso miles de millones de neuronas trabajan en diferentes niveles y crean conexiones que crean diferentes subsistemas paralelos y representan una red neuronal biológica. .

Por supuesto, todas estas son simplificaciones y generalizaciones, pero gracias a ellas podemos describir una simple
red neuronal:



Y descríbalo formalmente usando el gráfico:



Se requiere alguna aclaración aquí. Los círculos son neuronas, y las líneas son conexiones entre ellas,
y, para no complicarse en esta etapa, la relación es un movimiento directo de información de izquierda a derecha . La primera neurona está actualmente activa y atenuada. También le asignamos un número (1 - si funciona, 0 - si no). Los números entre las neuronas indican el peso de la conexión.

Los gráficos anteriores muestran el momento de la red, para una visualización más precisa, debe dividirlo en períodos de tiempo:



Para crear su propia red neuronal, necesita comprender cómo los pesos afectan a las neuronas y cómo se entrenan las neuronas. Como ejemplo, tome un conejo (conejo de prueba) y póngalo en las condiciones de un experimento clásico.



Cuando una corriente segura de aire se dirige hacia ellos, los conejos, como las personas, parpadean:



Este modelo de comportamiento se puede graficar:



Como en el diagrama anterior, estos gráficos muestran solo el momento en que el conejo siente un respiro, y de esta manera codificamos el golpe como un valor lógico. Además, calculamos si la segunda neurona se activa en función del valor del peso. Si es 1, entonces se activa la neurona sensorial, parpadeamos; Si el peso es inferior a 1, no parpadeamos: la segunda neurona tiene un límite de 1.

Presentamos un elemento más: una señal de sonido segura:



Podemos modelar el interés de un conejo de la siguiente manera:



La principal diferencia es que ahora el peso es cero , por lo que no hemos recibido un conejo parpadeante, bueno, al menos por ahora. Ahora enseña al conejo a parpadear en el equipo, mezclando
irritantes (señal sonora y aliento):



Es importante que estos eventos ocurran en diferentes períodos de tiempo, en gráficos se verá así:



El sonido en sí mismo no hace nada, pero el flujo de aire todavía hace que el conejo parpadee, y lo mostramos a través de pesos multiplicados por los estímulos (rojo).

Aprender sobre el comportamiento complejo puede expresarse de manera simplista como un cambio gradual de peso entre las neuronas conectadas a lo largo del tiempo.

Para entrenar al conejo, repita los pasos:



Para los primeros tres intentos, los esquemas se verán así:



Tenga en cuenta que el peso del estímulo sonoro crece después de cada repetición (resaltado en rojo), este valor ahora es arbitrario: elegimos 0.30, pero el número puede ser cualquier cosa, incluso negativo. Después de la tercera repetición, no notará un cambio en el comportamiento del conejo, pero después de la cuarta repetición ocurrirá algo sorprendente: el comportamiento cambiará.



Eliminamos el efecto del aire, ¡pero el conejo todavía parpadea cuando escucha un pitido! Este último comportamiento puede explicar este comportamiento:



Entrenamos al conejo para responder al sonido parpadeando.


En un experimento real de este tipo, se pueden requerir más de 60 repeticiones para lograr un resultado.

Ahora dejaremos el mundo biológico del cerebro y los conejos e intentaremos adaptar todo lo que
aprendí a crear una red neuronal artificial. Primero, intentemos hacer una tarea simple.

Digamos que tenemos una máquina con cuatro botones que entrega comida cuando presiona el botón derecho
botones (bueno, o energía si eres un robot). La tarea es descubrir qué botón da la recompensa:



Podemos representar (esquemáticamente) lo que hace el botón cuando se hace clic de la siguiente manera:



Este problema se resuelve mejor en su totalidad, así que veamos todos los resultados posibles, incluido el correcto:


Presione el tercer botón para obtener su cena.

Para reproducir una red neuronal en código, primero tenemos que hacer un modelo o gráfico con el que se pueda asociar la red. Aquí hay un gráfico adecuado para la tarea, además, muestra bien su contraparte biológica:



Esta red neuronal solo recibe información entrante, en este caso será la percepción de qué botón se presionó. Además, la red reemplaza la información entrante con pesos y llega a una conclusión basada en la adición de una capa. Suena un poco confuso, pero veamos cómo se presenta el botón en nuestro modelo:


Tenga en cuenta que todos los pesos son 0, por lo que la red neuronal, como un bebé, está completamente vacía, pero completamente interconectada.

Por lo tanto, comparamos el evento externo con la capa de entrada de la red neuronal y calculamos el valor en su salida. Puede o no coincidir con la realidad, pero por ahora la ignoraremos y comenzaremos a describir la tarea de una manera amigable con la computadora. Comencemos ingresando pesos (usaremos JavaScript):

var inputs = [0,1,0,0]; var weights = [0,0,0,0]; //       

El siguiente paso es crear una función que recopile valores y pesos de entrada y calcule el valor en la salida:

 function evaluateNeuralNetwork(inputVector, weightVector){ var result = 0; inputVector.forEach(function(inputValue, weightIndex) { layerValue = inputValue*weightVector[weightIndex]; result += layerValue; }); return (result.toFixed(2)); } //   ,  ,    —    /    

Como se esperaba, si ejecutamos este código, obtendremos el mismo resultado que en nuestro modelo o gráfico ...

 evaluateNeuralNetwork(inputs, weights); // 0.00 

Ejemplo en vivo: Neural Net 001 .

El siguiente paso para mejorar nuestra red neuronal será una forma de verificar su propia salida o valores de resultados comparables a la situación real,
codifiquemos primero esta realidad particular en una variable:



Para detectar inconsistencias (y cuántas), agregamos una función de error:

 Error = Reality - Neural Net Output 

Con él, podemos evaluar el rendimiento de nuestra red neuronal:



Pero lo más importante, ¿qué pasa con las situaciones en que la realidad da un resultado positivo?



Ahora sabemos que nuestro modelo de red neuronal no funciona (y sabemos cuánto), ¡genial! Esto es genial porque ahora podemos usar la función de error para controlar nuestro aprendizaje. Pero todo esto tendrá sentido si redefinimos la función de error de la siguiente manera:

 Error = <b>Desired Output</b> - Neural Net Output 

Una discrepancia evasiva, pero tan importante, que muestra tácitamente que lo haremos
usar resultados obtenidos previamente para comparar con acciones futuras
(y para entrenamiento, como veremos más adelante). Existe en la vida real, llena de
patrones repetitivos, por lo que puede convertirse en una estrategia evolutiva (bueno, en
La mayoría de los casos).

A continuación, en nuestro código de muestra, agregaremos una nueva variable:

 var input = [0,0,1,0]; var weights = [0,0,0,0]; var desiredResult = 1; 

Y una nueva característica:

 function evaluateNeuralNetError(desired,actual) { return (desired — actual); } // After evaluating both the Network and the Error we would get: // "Neural Net output: 0.00 Error: 1" 

Ejemplo en vivo: Neural Net 002 .

Para resumir el subtotal . Comenzamos con la tarea, elaboramos su modelo simple en forma de red neuronal biológica y obtuvimos una forma de medir su rendimiento en comparación con la realidad o el resultado deseado. Ahora necesitamos encontrar una manera de corregir la discrepancia, un proceso que puede considerarse como un entrenamiento tanto para computadoras como para personas.

¿Cómo entrenar una red neuronal?

La base de la enseñanza de las redes neuronales biológicas y artificiales es la repetición.
y algoritmos de entrenamiento , por lo que trabajaremos con ellos por separado. Comience con
algoritmos de aprendizaje

En la naturaleza, los algoritmos de aprendizaje se entienden como cambios físicos o químicos.
Características de las neuronas después de los experimentos:



Una ilustración dramática de cómo dos neuronas cambian con el tiempo en el código y nuestro modelo de "algoritmo de aprendizaje" significa que cambiaremos algo con el tiempo para facilitarnos la vida. Por lo tanto, agreguemos una variable para indicar el grado de facilitación de la vida:

 var learningRate = 0.20; //   ,      :) 

¿Y qué va a cambiar?

Esto cambiará el peso (¡como un conejo!), Especialmente el peso de la salida que queremos:



Cómo codificar un algoritmo de este tipo es su elección, por simplicidad agrego el coeficiente de entrenamiento al peso, aquí tiene la forma de una función:

 function learn(inputVector, weightVector) { weightVector.forEach(function(weight, index, weights) { if (inputVector[index] > 0) { weights[index] = weight + learningRate; } }); } 

Cuando se usa, esta función de aprendizaje simplemente agregará nuestro coeficiente de aprendizaje al vector de peso de la neurona activa , antes y después del círculo de entrenamiento (o repetición), los resultados serán los siguientes:

 // Original weight vector: [0,0,0,0] // Neural Net output: 0.00 Error: 1 learn(input, weights); // New Weight vector: [0,0.20,0,0] // Neural Net output: 0.20 Error: 0.8 //    ,      1 ( ) — ,    ,    ,       

Ejemplo en vivo: Neural Net 003 .

Bien, ahora que nos estamos moviendo en la dirección correcta, el último detalle de este rompecabezas será la introducción de repeticiones .

No es tan difícil, en la naturaleza simplemente hacemos lo mismo una y otra vez, y en el código solo indicamos la cantidad de repeticiones:

 var trials = 6; 

Y la introducción de la función de número de repeticiones en nuestra red neuronal de entrenamiento se verá así:

 function train(trials) { for (i = 0; i < trials; i++) { neuralNetResult = evaluateNeuralNetwork(input, weights); learn(input, weights); } } 

Bueno, nuestro informe final:

 Neural Net output: 0.00 Error: 1.00 Weight Vector: [0,0,0,0] Neural Net output: 0.20 Error: 0.80 Weight Vector: [0,0,0.2,0] Neural Net output: 0.40 Error: 0.60 Weight Vector: [0,0,0.4,0] Neural Net output: 0.60 Error: 0.40 Weight Vector: [0,0,0.6,0] Neural Net output: 0.80 Error: 0.20 Weight Vector: [0,0,0.8,0] Neural Net output: 1.00 Error: 0.00 Weight Vector: [0,0,1,0] // Chicken Dinner ! 

Ejemplo en vivo: Neural Net 004 .

Ahora tenemos un vector de peso que dará un solo resultado (pollo para la cena), si el vector de entrada corresponde a la realidad (presionando el tercer botón).

Entonces, ¿qué es tan genial que acabamos de hacer?

En este caso particular, nuestra red neuronal (después del entrenamiento) puede reconocer los datos de entrada y decir qué conducirá al resultado deseado (aún necesitamos programar situaciones específicas):



Además, es un modelo escalable, un juguete y una herramienta para nuestra capacitación. Pudimos aprender algo nuevo sobre aprendizaje automático, redes neuronales e inteligencia artificial.

Precaución a los usuarios:

  • No se proporciona un mecanismo de almacenamiento para las escalas estudiadas, por lo que esta red neuronal olvidará todo lo que sabe. Al actualizar o reiniciar el código, necesita al menos seis reintentos exitosos para que la red esté completamente capacitada si cree que una persona o una máquina presionarán los botones al azar ... Esto llevará algún tiempo.
  • Las redes biológicas para aprender cosas importantes tienen una velocidad de aprendizaje de 1, por lo que solo necesita una repetición exitosa.
  • Hay un algoritmo de aprendizaje que es muy similar a las neuronas biológicas, tiene un nombre pegadizo: regla widroff-hoff o entrenamiento widroff-hoff .
  • Los umbrales de las neuronas (1 en nuestro ejemplo) y los efectos del reentrenamiento (con una gran cantidad de repeticiones, el resultado será más de 1) no se tienen en cuenta, pero son de naturaleza muy importante y son responsables de grandes y complejos bloques de reacciones conductuales. Como los pesos negativos.

Notas y referencias para lecturas adicionales


Traté de evitar las matemáticas y los términos estrictos, pero si está interesado, construimos un perceptrón , que se define como un algoritmo para el aprendizaje supervisado ( enseñanza con un maestro ) de clasificadores dobles , algo difícil.

La estructura biológica del cerebro no es un tema simple, en parte debido a la inexactitud, en parte debido a su complejidad. Es mejor comenzar con la neurociencia (Purves) y la neurociencia cognitiva (Gazzaniga). Modifiqué y adapté el ejemplo de conejo de Gateway to Memory (Gluck), que también es una gran guía para el mundo de los gráficos.

Otro magnífico recurso, Introducción a las redes neuronales (Gurney), es adecuado para todas sus necesidades relacionadas con la inteligencia artificial.

¡Y ahora en Python! Gracias a Ilya Andschmidt por la versión de Python proporcionada:

 inputs = [0, 1, 0, 0] weights = [0, 0, 0, 0] desired_result = 1 learning_rate = 0.2 trials = 6 def evaluate_neural_network(input_array, weight_array): result = 0 for i in range(len(input_array)): layer_value = input_array[i] * weight_array[i] result += layer_value print("evaluate_neural_network: " + str(result)) print("weights: " + str(weights)) return result def evaluate_error(desired, actual): error = desired - actual print("evaluate_error: " + str(error)) return error def learn(input_array, weight_array): print("learning...") for i in range(len(input_array)): if input_array[i] > 0: weight_array[i] += learning_rate def train(trials): for i in range(trials): neural_net_result = evaluate_neural_network(inputs, weights) learn(inputs, weights) train(trials) 

Y ahora en GO! Gracias por esta versión de Kieran Maher.

 package main import ( "fmt" "math" ) func main() { fmt.Println("Creating inputs and weights ...") inputs := []float64{0.00, 0.00, 1.00, 0.00} weights := []float64{0.00, 0.00, 0.00, 0.00} desired := 1.00 learningRate := 0.20 trials := 6 train(trials, inputs, weights, desired, learningRate) } func train(trials int, inputs []float64, weights []float64, desired float64, learningRate float64) { for i := 1; i < trials; i++ { weights = learn(inputs, weights, learningRate) output := evaluate(inputs, weights) errorResult := evaluateError(desired, output) fmt.Print("Output: ") fmt.Print(math.Round(output*100) / 100) fmt.Print("\nError: ") fmt.Print(math.Round(errorResult*100) / 100) fmt.Print("\n\n") } } func learn(inputVector []float64, weightVector []float64, learningRate float64) []float64 { for index, inputValue := range inputVector { if inputValue > 0.00 { weightVector[index] = weightVector[index] + learningRate } } return weightVector } func evaluate(inputVector []float64, weightVector []float64) float64 { result := 0.00 for index, inputValue := range inputVector { layerValue := inputValue * weightVector[index] result = result + layerValue } return result } func evaluateError(desired float64, actual float64) float64 { return desired - actual } 

Source: https://habr.com/ru/post/es423647/


All Articles