Redes neuronales con Perceptrón multicapas backpropagation

AUTOR: Hugo Miguez CREADO: 2018-06-15 11:16:15

El Perceptrón multicapas soluciona la limitación del Perceptrón simple donde los datos tienen que estar separados por una recta. Como ejemplo práctico realizaremos una predicción para saber el tipo de flor entre tres especies distintas. 

El Perceptrón multicapas

El perceptrón multicapas permitío solucionar el problema del perceptrón simple y poder tratar datos que éste ultimo no podría. Puedes leer más sobre el perceptrón simple. A pesar de que existen muchas librerias sobre redes neuronales ( tensorflow, OpenCV, PyBrain, etc ) hemos optado por un algoritmo básico de perceptrón multicapas y así poder ver su estructura y modificarlo si es necesario.

En 1969, Minsky y Papert, demuestran que el perceptrón simple y ADALINE no puede resolver problemas no lineales (por ejemplo, XOR). La combinación de varios perceptrones simples podría resolver ciertos problemas no lineales pero no existía un mecanismo automático para adaptar los pesos de la capa oculta (Extraido de wikipedia).

La principal diferencia del Perceptrón simple y el Perceptrón multicapas es que éste último añade una zona de capas ocultas. Compuesto por capa de entrada, capa ocultas y capa de salida.



En 1982 Jhon Hopfield publica un artículo donde presenta el algoritmo "backpropagation": es un método de cálculo del gradiente utilizado en algoritmos de aprendizaje supervisado utilizados para entrenar redes neuronales artificiales. Puedes leer más sobre la backpropagation en wikipedia

Para el siguiente ejemplo hemos utilizado el algoritmo de perceptrón multicapa creado por Gilberto Augusto de Oliveira Bastos y publicado en GitHub (ver en GitHub). Aunque lo hemos modificado levemente para adaptarlo mejor al ejemplo.

En la siguiente tabla podrás observar distintos datos (largo y ancho del sépalo y largo y ancho del pétalo extraidos de wikiwand.com). Éstos datos indican de qué especie de flor se trata. Al final de la tabla podrás observar una nueva linea resaltada con amarillo, éstos son los datos que pondremos para predecir de que flor se trata. 

Para que sea más sencillo puedes presionar el botón de radio y seleccionar una fila de datos para poder predecir (los datos de la fila seleccionada quedará fuera del aprendizaje de la red neuronal).

Largo del sépaloAncho del sépaloLargo del pétaloAncho del pétaloEspecie

Tasa de acierto

Ajustes


Tasa de acierto

La función de salida para generar la tasa de acierto es sigmoide dando valores entre 0 y 1. El valor más cercano a 1 es el correcto.

Ajustes del perceptrón

Puedes variar los datos de inicialización del perceptrón como las épocas, la tasa de aprendizaje, la tasa de error y los pesos.

  • MUESTRAS: cantidad de muestras para realizar el entrenamiento. Cuanto mayor cantidad sean las muestras más efectiva será la predicción pero mayor tiempo puede demorar el mismo. 
  • EPOCAS: el valor detemina el máximo de épocas que realizará dentro del bucle de entrenamiento de la neurona. Lo limitamos ya que en algunos casos llevaría mucho tiempo el procesado para obtener la tasa de error deseada y bloqueará el programa. (recordar que es un ejemplo práctico, en ejemplos reales es necesario un código en Python o similar y en una máquina potente).
  • TASA DE APRENDIZAJE: este valor se emplea para actualizar los pesos de las entradas.
  • TASA DE ERROR: durante el entrenamiento de las neuronas este valor limita el error recogido del algoritmo de backpropagation.
  • PESO MINIO Y MÁXIMO: se utiliza para inicializar los pesos iniciales de forma aleatoria dentro de estos rangos.
Puedes bajar las muestras a 5 y verás que algunos resultados no logra predecir correctamente ya que la cantidad de muestras para el aprendizaje no son suficientes o bien la cantidad de épocas no son suficientes y debes aumentar las mismas para obtener mejores resultados. En consecuencia cuanto más muestras y mayores épocas obtendremos mejores resultados pero también más procesos necesita.

Más abajo una vez que inicies la predicción podrás ver las gráficas correspondientes.

Gráfica Ancho y alto del sépalo



Gráfica Ancho y alto del pétalo


Fuentes


Código detallado del ejemplo anterior

Es importante haber leido sobre el funcionamiento del Perceptrón simple. Recordar que un perceptrón necesita de datos para poder aprender y poder darnos una predicción. Un perceptrón sigue los siguientes pasos:

  • Inicialización de los pesos sinápticos
  • Entrenamiento (es necesario tener los datos en un array con 1-n datos de entrada y uno de salida de tipo binario 0 o 1).
  • Predicción (es necesario indicar los datos, con la misma cantidad de datos que el entrenamiento. y nos devolverá de 0 a 1. los valores más cercanos a 1 es verdadero en caso contrario es falso)

En el ejemplo anterior tenemos una serie de datos para tres tipo de flores distintas. con lo cual son tres datos de salida. 

  • 0 para la setosa
  • 1 para la versicolor
  • 2 para la verginica
Pero lo cierto es que este algoritmo de Perceptrón multicapas solo nos dá una única salida. con lo cual no sería posible analizar tres especies de flores distintas. Para solucionar este problema tenemos que analizar cada especie por separado comprobando los datos de una con los datos de las otras dos. La primera le indicamos que tendrá salida 1 y para las otras la salida será de 0.

var data = [[1,0,0], [0,1,0], [0,0,1]];

Hemos creado una matriz para almacenar para cada especie los tres datos de salida que tendrán. El el primer elemento está la setosa con salida 1 [1,0,0] y la entrenamos con los datos de las otras dos especies cuyas salidas las hemos puesto en 0.

for(var n=0; n < 3; n++){
    var inputs = getData(data[n][0], data[n][1], data[n][2], index, count_muestras);

    var x = [ls, as, lp, ap];

    pm.init(inputs, tasa_aprendizaje, tasa_error, peso_min, peso_max, max_epocas);

     var val = pm.predic(x);

    if(n===0)$('#perceptron_setosa').val(val);
    else if(n===1)$('#perceptron_versicolor').val(val);
    else if(n===2)$('#perceptron_verginica').val(val);

    if(val > resultado){
        resultado = val;
        especie_resultado = especies[n];
    }
}

for(var n=0; n &lt; 3; n++){
A continuación el bucle recorre las tres especies que obtiene los datos para el entrenamiento.

getData(param1, param2, param3, param4, param5)
Esta función nos devuelve los datos para el entrenamiento

PARAMETROS de getData:

  • param1: array con los valores de salida para la primer especie.
  • param2: array con los valores de salida para la segunda especie.
  • param3: array con los valores de salida para la tercera especie.
  • param4: posición cuyo dato no incluirá en la muestra para evitar lo use para el entrenamiento
  • param5: cantidad máxima de muestras.

var x = [ls, as, lp, ap];
Son los datos que usaremos para la predicción.

pm.init(inputs, tasa_aprendizaje, tasa_error, peso_min, peso_max, max_epocas);
pm es el objeto que creamos de PerceptronMulticapas (lo podrás descargar el código completo) y los parametros son los obtenidos de getData más las variables de tasa_aprendizaje, tasa_error, etc que provienen de los campos del formulario. el método init inicializa los pesos sinápticos de las distintas entradas y .
posteriormente llama al funcion train para realizar el entrenamiento.

var val = pm.predic(x);
pm.predict es la función para realizar la predicción. el único parámetro son los datos para la predicción.

Código completo

Descarga código completo

Comentar

Para poder realizar comentarios. Primero debes inicar sesión o crear una cuenta.