informe tarea n°2 - u-cursos...el4106 – clasificador de dígitos con redes neuronales u. de...
TRANSCRIPT
Universidad de Chile
Facultad de Ciencias Físicas y Matemáticas
Departamento de Ingeniería Eléctrica
EL4106 – Inteligencia Computacional
INFORME TAREA N°2
CLASIFICADOR DE DÍGITOS CON REDES
NEURONALES
Nombre
Alumno :
Sebastián Gálvez
Profesor : Javier Ruiz del Solar
Profesor
Auxiliar :
Daniel Herrmann
Felipe Valdés
Fecha : 14/04/2014
Santiago, Chile.
Contenido
Contenido ............................................................................................. II
Índice de Figuras y Tablas .......................... ¡Error! Marcador no definido.I
1. .................................................................................................................. Introducción
............................................................................................................ 1
2.................................................................................................................... Desarrollo
............................................................................................................ 2
2.1. Teoría ........................................................................................................ 2
2.2. División de la Base de Datos ................................................................ 10
2.3. Clasificador Multiclase .......................................................................... 12
2.4. Análisis ...................................................................................................... 17
3. ................................................................................................................. Conclusiones
...........................................................................................................20
4. ............................................................................................................................ Anexos
...........................................................................................................21
5. ........................................................................................... Bibliografía y referencias
...........................................................................................................26
Índice de Figuras y Tablas
Figura 1: Modelo no lineal de una neurona, con el bias asignado como peso sináptico ..... 2
Figura 2: Estructura de una RNA multicapas ..................................................................... 3
Figura 3: Notación de variables y pesos para una RNA de 3 capas. .................................. 4
Figura 4: Diagrama de bloques para entrenamiento con BackPropagation. ....................... 5
Figura 5: Curvas de error de validación y entrenamiento. .................................................. 8
Figura 6: Ejemplo de una Matriz de Confusión. .................................................................. 9
Figura 7: Interfaz de entrenamiento y simulación de Neural Network Matlab Toolbox. ..... 14
Figura 8: Matriz de confusión para el clasificador de dígitos con 13 neuronas en la capa
oculta. .............................................................................................................................. 15
Figura 9: Performance Plot para el MSE en cada época. ................................................. 16
Figura 10: Matrices de Confusión para distintos números de neuronas de la capa oculta.
........................................................................................................................................ 17
Tabla 1: Errores de validación, tiempos de entrenamiento y número de clasificaciones
correctas para los distintos números de neuronas en capa oculta. (Conjunto de prueba
posee 2199 elementos) …………………………………………………………………………18
Figura 11: (arriba-izq) Número de clasificaciones correctas, para un total de 2199. (arriba-
der) Tiempos de entrenamiento. (abajo) Error de validación. ........................................... 19
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~1~
Introducción
1. Introducción
Esta tarea tiene como objetivo general la implementación de un clasificador de
dígitos trazados en la pantalla táctil de un Tablet. El objetivo particular consiste en
implementar el clasificador utilizando distintas redes neuronales generadas,
entrenadas y calibradas por el toolbox de redes neuronales de Matlab, para
distintos tamaños y topologías de la red.
La base de datos a utilizar es Pen-Based Recognition of Handritten Digits Data
Set, tomada del UC Irvine Machine Learning Repository. La cual contiene
información de 10992 muestras y consiste en dos matrices: La primera, “trazos”,
contiene las mediciones de presión en la pantalla táctil de 8 puntos (x,y) equi-
espaciados en longitud de arco, las cuales se traducen 16 características medidas
para cada muestra, cuyos valores fueron ajustados para ser enteros dentro del
rango [0,100]. La segunda matriz “digitos” contiene información sobre qué dígito
fue representado en cada muestra, para esto se cuenta con 10 filas, donde cada
columna posee un valor “1” en la fila correspondiente al dígito representado y un
valor “0” en el resto, por ejemplo: [1;0;0;0;0;0;0;0;0;0] indica la 1ª fila, por lo que la
clase indicada corresponde al dígito “0” y [0;0;0;0;0;0;0;1;0;0] indica la 8ª fila,
correspondiente al dígito “7”.
En ambas matrices cada muestra corresponde a una columna. Si se desea
tener más detalles sobre cómo se obtuvo la información de la base de datos la
información la puede encontrar en la página del repositorio:
http://archive.ics.uci.edu/ml/datasets/Pen-Based+Recognition+of+Handwritten+Digits
En el desarrollo de esta tarea se explicará a grandes rasgos la teoría acerca de
las redes neuronales y el método de entrenamiento a utilizar. También se debe
separar la base de datos en un conjunto de entrenamiento y un conjunto de
prueba, utilizando cantidades de muestras con una razón de 4:1. Finalmente se
implementará el clasificador usando el toolbox de redes neuronales de Matlab con
distintas topologías y tamaños y analizar el rendimiento del mismo mediante la
Matriz de Confusión.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~2~
Desarrollo
2. Desarrollo
2.1. Teoría a) ¿Qué es una Red Neuronal Artificial?
Una red neuronal artificial (RNA) corresponde a un sistema de procesamiento de información compuesto de una red distribuida de elementos que realizan procesamientos simples, a las cuales se les llama neuronas. Este sistema trata de emular en cierto grado el complejo proceso realizado en el cerebro al modelar cada neurona como una operación simple con un peso sináptico y lograr que una red de neuronas pueda realizar un procesamiento más complejo que el de cada individuo al entrenar el sistema fijando los pesos sinápticos adecuadamente para lograr resolver una tarea. Si bien existen varias formas de modelar una neurona, la forma no-lineal presentada a continuación en la Figura 1 constituye la más aceptada, y consiste en un elemento básico que realiza una suma ponderada de las entradas junto a un peso característico de la neurona (bias o sesgo), y la salida corresponde al resultado de evaluar una función no lineal en el valor de la suma realizada.
Figura 1: Modelo no lineal de una neurona, con el bias asignado como peso sináptico
En este caso se observa la „k-ésima‟ neurona de una red neuronal, la cual
cuenta con entradas , para cada una de las cuales existe un coeficiente , llamado peso sináptico. En este modelo se incluyó el peso característico (único
para cada neurona) como un peso sináptico asociado a una entrada fija = 1, así el bias es el coeficiente . Llamando activación ∑
a la suma
ponderada, la salida de la neurona ( ) es la evaluación de una función no-lineal llamada función de activación, las más utilizadas son las sigmoidales o tangentes hiperbólicas.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~3~
Desarrollo
Este modelo se repite para cada una de las neuronas de la red, utilizando la misma función de activación, pero distintos pesos sinápticos y distintos bias. Si bien una sola neurona se puede considerar como una “red neuronal artificial”, lo interesante de este tipo de sistema es conformar una red de varias capas de neuronas, donde se pueden experimentar distintas topologías según cuantas capas se utilicen y cuántas neuronas componen cada capa. La estructura de una RNA multicapas consiste de 3 tipos de capas de neuronas, estas son la capa de entrada, las capas ocultas (hidden layers), que puede ser sólo una o más de una, y la capa de salida. En la Figura 2 se muestra cómo se compone la topología de una RNA que es pre-alimentada o feedforward, lo que quiere decir que la información va desde la entrada a la salida en un solo sentido.
Se observa que las neuronas de la capa correspondiente a las entradas contienen una entrada cada una y tienen tantas salidas como neuronas hay en la capa siguiente. La función de las neuronas de la capa de entrada es netamente distributiva, ya que permite que a cada neurona de la capa siguiente le lleguen como entradas todas las entradas de la RNA. Así, las neuronas pertenecientes a la capa de entrada poseen un peso sináptico unitario y un bias nulo, y su función de activación sería la identidad. El resto de las neuronas, tanto de las capas ocultas como de la capa de salida sí poseen pesos sinápticos y bias que deben ser entrenados para que la red logre el objetivo propuesto.
Figura 2: Estructura de una RNA multicapas
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~4~
Desarrollo
En las capas ocultas cada neurona recibe todas las salidas de la capa anterior, y genera tantas salidas como neuronas hay en la capa siguiente.
Finalmente, la capa de salida entrega los valores que corresponden a la salida de la red neuronal. Si se mira una RNA a escala global, al no conocer los pesos de cada neurona y
observar sólo la relación entrada-salida { }, una vez entrenada la red con un set
de pares de datos { }, relacionados por una función desconocida , la red se puede identificar como una aproximación de esta función en base a una superposición de operaciones simples realizadas por cada neurona. Para entender la notación utilizada en este informe en la Figura 3 se presenta como ejemplo una RNA de 3 capas (llamada de 2 puesto que no considera la capa de entrada), donde se definen los nombres de las variables asociadas a cada parte: Cada entrada a cada neurona de la capa de entrada de la red se denota con
la variable , los pesos de una neurona de la capa oculta (primera capa) para una entrada se denotan como , su activación corresponde a la suma
ponderada de todas sus entradas ∑ . Cada neurona genera una salida
, donde es la función de activación.
Finalmente, los pesos de la segunda capa para la neurona que actúan sobre las entradas , se denominan . La activación es ∑ , y la salida
generada por cada neurona de la segunda (y última) capa es .
Figura 3: Notación de variables y pesos para una RNA de 3 capas.
En el caso correspondiente a la tarea, la tarea a resolver por la RNA es una clasificación de 10 clases, por lo que las entradas que llegan a la capa de entrada
corresponden a los valores de las características identificadas para los dígitos, y las salidas de la red deben indicar a cuál de las 10 clases pertenece la información ingresada a la red.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~5~
Desarrollo
b) Número sugerido de neuronas para una RNA con una capa oculta.
Si bien no existe un método empírico para calcular este número, en base a la experiencia y a heurística se sugiere que para RNA feed-forward de una capa oculta se utilice una cantidad de neuronas en esta capa correspondiente al promedio entre el número de neuronas en la capa de entrada y el número de neuronas en la capa de salida. Sin embargo, también se sugiere realizar pruebas con distintos números de neuronas en esta capa, y así evaluar qué topología funciona mejor.i
c) Algoritmo de backpropagation secuencial.
Al contar con una base de datos para entrenar la red se deben ir adaptando
los valores de los pesos para poder configurar un clasificador eficaz. Para esto,
se utiliza un algoritmo llamado “Backpropagation”, que consiste en dar valores
iniciales arbitrarios a cada peso, ingresar la información de una muestra del
conjunto de entrenamiento y observar la salida de la red. Al cuantificar el error
que existe entre la salida y el resultado correcto (conocido, ya que es un
aprendizaje supervisado), se pueden ajustar los pesos de la capa de salida para
disminuir este error, para luego propagar el error asociado a los pesos de las
capas anteriores y ajustar las capas ocultas una a una desde la salida hacia la
entrada.
El esquema de la Figura 4 indica gráficamente cómo funciona el método de
“backpropagation”, donde para cada muestra del conjunto de entrenamiento
tiene asociada la salida esperada , y se ingresa a la red, generando una salida
. Luego se calcula el error y se ingresa a la red para ajustar los pesos.
Figura 4: Diagrama de bloques para entrenamiento con BackPropagation.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~6~
Desarrollo
Si se define que en cada unidad de tiempo se ingresa una muestra, el valor de los pesos será , , por lo que se desea realizar un ajuste en función
del error calculado en el instante de tiempo anterior, de la siguiente manera:
Considerando la función suma de error cuadrático para ajustar los pesos.
∑(
)
El objetivo es minimizar este error en cada instante de tiempo. Una manera de resolver esto es con el método del descenso del gradiente, que consiste en
hacer las variaciones y proporcionales al gradiente (o derivada) del error en el sentido en que este disminuye. Este método requiere que la función de
activación debe ser diferenciable. Así, mediante un desarrollo matemático se obtienen las ecuaciones principales del algoritmo para ajustar los pesos:
)())(('))()(()()()()1( tztaftytdtzttt jiiijiijij (1)
k
kikjijiijij ttxtuftxttvtv )()())((')()()()1( (2)
Donde, fijando pesos iniciales arbitrarios para toda la red, primero se debe
ajustar los pesos de la capa de salida calculando el término y luego ajustar los pesos de la capa oculta, mediante el cálculo de , que requiere conocer . El parámetro corresponde a lo que se conoce como tasa de aprendizaje, que permite controlar el paso al que avanza el método del descenso del gradiente para encontrar el error mínimo y permite que el método no se quede en mínimos locales. Analizando la ecuación (1) se observa que el ajuste de los pesos de la capa de salida se considera el error generado en la salida de esa neurona, mientras que en la ecuación (2) se debe considerar el error generado en todos los caminos de cada una de las salidas de la neurona de la capa oculta. Por esto es que se debe realizar una propagación hacia atrás para ajustar los pesos. Si existiera otra capa oculta el procedimiento es el mismo que en (2), sólo que
en vez de utilizar el error de la capa de salida , se utilizaría el término en la sumatoria, y así se generaliza para más de 2 capas ocultas.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~7~
Desarrollo
Finalmente, el algoritmo se puede resumir en tres pasos por cada instante de tiempo: 1.- Forward Pass: Ingresar las características de una muestra del conjunto de
entrenamiento a la red para pesos iniciales arbitrarios.
2.- Backward Pass: Calcular la función de error en la salida utilizando e . 3.- Ajuste de pesos: Desde la capa de salida hacia la capa de entrada, en el caso
expuesto, ajustar primero y luego utilizando las ecuaciones (1) y (2),
respectivamente.
d) Sobre-entrenamiento (Sobreajuste o Overfitting)
Cuando se entrena un clasificador se usa un conjunto de entrenamiento que debe tener un buen nivel de representación de lo que se está clasificando. El objetivo es lograr que con este conjunto finito de datos el clasificador pueda generalizar y predecir la clase a la que pertenece una muestra nueva, distinta a las del conjunto de entrenamiento. Claramente, si se desea un buen clasificador, se requiere un conjunto de entrenamiento con alto grado de representatividad y con una gran cantidad de muestras, como esto no siempre es posible se recurre a utilizar el mismo conjunto de entrenamiento (puede ser variando el orden en que se entregan las muestras) un cierto número de veces. Cada instancia en que se entrena el clasificador con el conjunto de entrenamiento se denomina una época. El problema de sobre-entrenamiento se da cuando se utiliza muchas veces el conjunto de entrenamiento, de manera que el clasificador finalmente funciona sólo para los elementos de este conjunto, perdiendo la capacidad de generalizar. En el caso de las redes neuronales esto se da por ajustar los pesos utilizando el mismo conjunto de entrenamiento por un número muy grande de épocas. Para evitar este problema, durante el entrenamiento se deben tomar en cuenta dos errores, el de la clasificación de datos de entrenamiento y el de la clasificación de los datos “no vistos”. Este último error debe ser medido durante el entrenamiento cada cierto tiempo para la clasificación de datos pertenecientes a un conjunto aparte al de entrenamiento, llamado conjunto de validación, el cual no influye en los ajustes a los pesos de la red.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~8~
Desarrollo
Figura 5: Curvas de error de validación y entrenamiento.
La Figura 5 muestra cómo evolucionan el error de entrenamiento y el error de validación a medida que se entrena con distintos tiempos de entrenamiento. Se observa que el criterio para detener el entrenamiento es cuando el error de validación deja de disminuir y comienza a aumentar. Se debe destacar que el hecho de que el error de entrenamiento siga disminuyendo no es conveniente si se desea un buen rendimiento del clasificador. El utilizar datos de validación para saber cuándo empieza a producirse el sobre-ajuste es conocido como Cross-Validation, y constituye una forma eficaz de medir la generalización del clasificador y evitar el sobre-entrenamiento.
e) Matriz de Confusión
Para evaluar el rendimiento de un clasificador de dos clases sobre un conjunto de prueba se utiliza la curva ROC y resulta bastante intuitivo identificar si el clasificador satisface los requerimientos con los que se desea aplicar. Sin embargo, cuando se trata de un problema de clasificación de más de dos clases este método no permite una visualización sencilla, por lo que se requiere una nueva forma de evaluar el rendimiento, como lo es la matriz de confusión. Considerando que el conjunto de prueba posee información sobre las clases verdaderas de los datos ingresados al clasificador, y que éste a su vez realiza predicciones sobre la clase de cada dato, se pueden ingresar en las filas de una matriz el número de predicciones para cada muestra, y el número de instancias para cada clase verdadera según cual sea la clase predicha en las columnas. Luego se puede normalizar las cantidades por filas para obtener una matriz de confusión, llamada así debido a que muestra las formas en las que se “confunde” el clasificador.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~9~
Desarrollo
Normalmente se utiliza una escala de colores para mostrar los distintos valores en cada celda de la matriz, ya que esto ayuda a visualizar de manera más intuitiva si el clasificador presenta un buen rendimiento o no. En la Figura 6 se puede apreciar cómo se ve una matriz de confusión junto a su escala de colores para el caso de clasificación de 4 clases para cada tipo de objeto: “Autos”, “Rostros”, “Frutas” y “Sofás”.
Figura 6: Ejemplo de una Matriz de Confusión.
La matriz de confusión de un buen clasificador debe tener la diagonal con los valores más cercanos a 1 y el resto de las casillas con los valores más cercanos a 0, es decir, para esta escala de colores un clasificador con buen rendimiento debería tener una diagonal roja y el fondo completamente azul.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~10~
Desarrollo
2.2. División de la Base de Datos
El programa generado en el archivo “basededatos.m” contiene una función
“[entren,clases_entren,prueba,clases_prueba]=basededatos(data,clases)”, que tiene como objetivo dividir la base de datos en los conjuntos de entrenamiento y prueba, para retornarlos en las matrices respectivas. El
argumento “data” contiene en cada columna las mediciones sobre las distintas
características correspondientes a las filas. El argumento “clases” contiene una columna por cada muestra, donde existe un “1” para la fila correspondiente a la clase de esa muestra y un “0” para el resto de las filas. Al cargar la base de datos de los dígitos trazados en una Tablet utilizando
“load BaseDatosTarea2” se puede separar invocando la función de la forma
“[en en_c pr pr_c]=basededatos(trazos,digitos);”
Para construir esta función, primero se revisó que todos los datos en la matriz “trazos” estuvieran efectivamente entre 0 y 100, y que en la matriz “dígitos” no hubiera columnas con más de un “1”. Luego, se procedió a juntar ambas matrices en una sola para poder trabajar separando tanto datos como información de la clase al mismo tiempo y se prosigue calculando a qué clase pertenecen los distintos índices de las columnas de esta matriz.
function [entren, clases_entren, prueba, clases_prueba]=
basededatos(data,clases)
N=length(data(1,:)); nfeats=length(data(:,1)); % n° de caracteristicas nc=length(clases(:,1)); % n° de clases
%Uno los datos con las clases en una sola matriz, para asociar los %índices de las columnas a cada clase distinta. newdata=[data;clases];
%ordeno y obtengo los índices de las muestras de cada clase. [aux ind]=sort(newdata,2); szs=zeros(1,nc); subclase_ind=[]; %debo encontrar los indices de los que efectivamente pertenecen a cada %clase, para guardarlos en una matriz y luego separarlos. for i=1:nc ind_aux=find(aux(nfeats+i,:),1,'first'); subclase_ind=[subclase_ind ind(nfeats+i,ind_aux:end)]; szs(i)=length(ind(nfeats+i,ind_aux:end));%calculo cuántos hay por clase. end ind_bord=cumsum(szs); %esto me indica los indices que separan las clases
en el vector subclase_ind
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~11~
Desarrollo
Posteriormente, teniendo información sobre cuántas muestras hay por cada clase, se calcula el 20% de la cantidad de muestras a utilizar en el conjunto de prueba, y luego extraer ese número de datos aleatoriamente por cada clase.
%Se quiere 20% de los datos por cada clase para el conjunto de prueba pr_szs=round(szs.*0.2); ind_bord_pr=cumsum(pr_szs);%esto me sirve para saber cuántos datos
seleccionar por cada clase en las iteraciones. sz_prueba=sum(pr_szs); %tamaño total del conjunto de prueba. prueba=zeros(nfeats+nc,sz_prueba); r_vec=zeros(1,sz_prueba); %vector que tendrá los indices seleccionados.
%Selección de datos de prueba (20% por cada clase) %primera iteración for i=1:ind_bord_pr(1) r=randi([1 ind_bord(1)]);
%selecciono un indice de los indices al azar en del rango de la clase '0'. % y me aseguro que sea distinto a alguno seleccionado. while(find(r_vec==subclase_ind(r)))
r=randi([1 ind_bord(1)]); end prueba(:,i)=newdata(:,subclase_ind(r)); %guardo los datos y la clase a
la que pertenece el dato elegido en el conjunto de prueba r_vec(i)=subclase_ind(r); %guardo el indice para luego borrar ese
dato del conjunto y que lo que quede sea el de entrenamiento end
% repito para el resto de las clases. for j=2:nc for i=(ind_bord_pr(j-1)+1):ind_bord_pr(j) r=randi([(ind_bord(j-1)+1) ind_bord(j)]); while(find(r_vec==subclase_ind(r))) r=randi([(ind_bord(j-1)+1) ind_bord(j)]); end prueba(:,i)=newdata(:,subclase_ind(r)); r_vec(i)=subclase_ind(r); end end
Con esto, ya se tiene listo el conjunto de prueba, por lo que para generar el conjunto de entrenamiento basta extraer del conjunto original los datos utilizados para el conjunto de prueba.
%extraigo del conjunto original los datos utilizados para el conjunto de
prueba entren=newdata; entren(:,r_vec)=[]; sz_entren=length(entren(1,:));
Finalmente, se verificó la representatividad de ambos conjuntos visualizando la razón de datos de cada clase respecto el tamaño del conjunto, y se comparó con la proporción en el conjunto original, logrando un error máximo en algunas clases del 0.0002%, lo cual se consideró totalmente aceptable.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~12~
Desarrollo
2.3. Clasificador Multiclase En primer lugar, definimos la topología a utilizar para la red neuronal, fijando
el número de capas ocultas y su número de neuronas. Se sabe que para la
mayoría de los problemas sencillos una sola capa oculta es suficiente para lograr
clasificar con un buen rendimiento, por lo que la RNA generada en esta tarea
tendrá una capa oculta.
Para el número de neuronas de la capa oculta se utilizará el número óptimo
según el criterio expuesto en 2.1 b), según lo cual, se debe considerar que en la
capa de entrada habrán 16 neuronas (una por cada característica), y en la capa
de salida habrán 10 neuronas (una por cada clase), por lo que el número óptimo
sugerido de neuronas será de 13.
a) Entrenamiento
Una vez separada la base de datos con el comando “[en en_c pr
pr_c]=basededatos(trazos,digitos);” se fija el número de neuronas y se inicializa la RNA feed forward, utilizando la función “newff” de la siguiente forma:
nn=28; %número de neuronas de la capa oculta net=newff(en,en_c,[nn]); %inicializo la red
Se pide utilizar un entrenamiento con algoritmo de aprendizaje “trainlm”, que
se refiere al algoritmo de gradiente descendente de segundo orden Levenberg-
Marquardt, pero como es el algoritmo usado por defecto no se requiere ingresar
como argumento.
Luego, se deben configurar los parámetros como tasa de aprendizaje, número
máximo de épocas y una meta esperada de rendimiento para entrenar la red, con
los siguientes comandos:
net.trainParam.epochs=100; %número máximo de épocas net.trainParam.showWindow=1; %mostrar ventana de entrenamiento net.trainParam.goal=0.0005; %meta de performance net.trainParam.mu=0.001; %tasa de aprendizaje
Para determinar la tasa de aprendizaje se probó con varias combinaciones,
siendo el valor 0.001 el que produjo mejores resultados, y el número máximo de
épocas se fijó arbitrariamente luego de varias pruebas, ya que el método
terminaba siempre antes de las 100 épocas debido al criterio de detención por
cross-validation.
Finalmente, se procede a entrenar la red con el comando “train”, se debe
considerar que el conjunto de validación se extrae del conjunto de entrenamiento.
net=train(net,en,en_c); %entreno la red
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~13~
Desarrollo
b) Simulación
Luego de entrenar la red se debe simular utilizando el conjunto de prueba,
para lo cual se usa el comando “sim” de la siguiente forma:
salida=sim(net,pr);
Esta salida sin embargo, no corresponde directamente a la clasificación, ya que funciona con una especie de lógica difusa, asignándole a cada objeto del conjunto de prueba un valor entre 0 y 1 por cada clase, por lo que la clase predicha por el clasificador finalmente corresponde a la de la fila que posea el valor máximo. Así, como se desea comparar las clases predichas con las clases verdaderas, se calculan de la siguiente manera:
[~, clases_salida]=max(salida); %guardo índice de fila del máximo clases_salida=clases_salida-1; %clase corresponde al dígito "fila -1"
[~, clases_prueba]=max(pr_c); %guardo índice de fila del máximo clases_prueba=clases_prueba-1; %clase corresponde al dígito "fila -1"
Donde la función “max” retorna el valor del máximo y el índice de la fila donde se encontraba este valor, puesto que nos interesa el índice y no el valor, se utiliza el operador ~ para indicar que no se desea utilizar esa salida de la función. Finalmente, se puede calcular el número de muestras correctamente clasificadas y mostrarlo en la consola definiendo el vector “err” y calculando la suma de todos sus elementos.
err=clases_prueba==clases_salida;
str=sprintf('Total bien clasificados para %d neuronas = %d',nn,sum(err)); display(str)
En la Figura 7 se muestran la ventana de entrenamiento y simulación, donde se observa en la parte superior un diagrama con la topología de la red, y en la parte inferior se ve el número de épocas que se necesitó para entrenar la red con los parámetros fijados, el tiempo de entrenamiento, el valor del gradiente y el rendimiento finales del clasificador. En este caso el algoritmo de entrenamiento se detuvo en la época 57 debido a los errores de validación, para evitar el overfitting.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~14~
Desarrollo
Figura 7: Interfaz de entrenamiento y simulación de Neural Network Matlab Toolbox.
c) Matriz de Confusión
Matlab cuenta con una función llamada “confusionmat”, que permite generar
la matriz de confusión, sin embargo no se encuentra normalizada, para lo cual las
instrucciones a realizar son:
%Generar matriz de confusión C=confusionmat(clases_prueba',clases_salida'); C=C./sum(C(:,1)); %normalizo la matriz de confusión
Para visualizarla se utilizó el comando “imagesc()”, que escala los valores de
la matriz a colores y “colorbar” para ver la escala de colores utilizada. También se
invierte el orden de los ejes para visualizarla como se describió en 2.1e)
imagesc(C) axis('ij')
colorbar;
En la Figura 8 se observa la matriz de confusión generada con este método.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~15~
Desarrollo
Figura 8: Matriz de confusión para el clasificador de dígitos con 13 neuronas en la capa oculta .
Esta matriz de confusión muestra relativamente un buen rendimiento, ya que la diagonal tiene valores muy cercanos a 1, por lo que la RNA clasifica correctamente una gran cantidad de dígitos, se pueden notar colores rojos más oscuros para las clases „1‟,‟2‟ y‟4‟, por lo que hay menor errores en la clasificación de estos dígitos. También se identifica que el clasificador confunde más habitualmente un „8‟ con un „0‟ debido a que en esa celda se tiene un azul más claro que el resto, por lo que indica un valor más alto de predicciones erradas en ese caso. Otras confusiones visibles, pero a menor escala son „7‟ con el „1‟, „7‟ con „4‟, „9‟ con „4‟, „2‟ con „7‟ , entre otras. En este caso, el comando ingresado para visualizar cuántos datos del conjunto de prueba indicó un “Total bien clasificados para 13 neuronas = 2100”, correspondiente al 95,5% del conjunto de prueba.
Finalmente, la herramienta de redes neuronales de Matlab nos permite
generar un gráfico de la performance del clasificador, mostrado en la Figura 9,
donde es posible identificar que el mecanismo de cross-validation detuvo el
proceso a las 57 épocas, debido a 6 errores de validación seguidos, lo cual es el
tope fijado por la herramienta. El mínimo error de validación logrado fue de 1.54%,
en la época 51, y finalmente se observan las curvas de los distintos errores,
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~16~
Desarrollo
reconociendo que en las primeras épocas se disminuye rápidamente, pero luego
posee un comportamiento casi asintótico.
Figura 9: Performance Plot para el MSE en cada época.
El código desarrollado para esta parte de la tarea se encuentra en el archivo
“redneuronal.m”, visible también en la sección Anexos.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~17~
Desarrollo
2.4. Análisis a) Cantidad óptima de neuronas en la capa oculta
A partir del código generado para 2.3, se vuelve a utilizar la misma serie de
comandos para distintos números de neuronas en la capa oculta, utilizando un
“for”, para valores entre 5 y 40 neuronas. Los resultados obtenidos se muestran
en la Tabla 1. Además, se generaron las matrices de confusión correspondientes,
donde las que deben destacarse son mostradas en la Figura 10.
Figura 10: Matrices de Confusión para distintos números de neuronas de la capa oculta.
A simple vista se puede apreciar que a mayor número de neuronas en la capa
oculta, mejor es la clasificación. Sin embargo, al utilizar más de 38 HLN, la
tendencia es que comienza a aumentar el error nuevamente. Considerando esto y
la información de la Tabla 1, se puede afirmar que la mejor configuración de la
RNA con una capa oculta corresponde a la que posee 38 neuronas en ella, con
un porcentaje de 98,68% de clasificaciones acertadas en el conjunto de prueba.
En base a lo anterior, se aprecia que la sugerencia de número óptimo de
neuronas de la capa oculta, no representa la mejor elección para este caso. Sin
embargo se puede ver que los clasificadores entre 10 y 16 HLN cuentan con
muchos menos errores de clasificación que los que tienen menos neuronas.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~18~
Desarrollo
Número de neuronas en la capa oculta
Best Validation Performance
Tiempo de entrenamiento [épocas]
Número de clasificaciones correctas
5 0.04869 67 1458
6 0.04172 40 1790
7 0.03387 48 1788
8 0.02161 41 1884
9 0.01835 29 1989
10 0.01852 43 2038
11 0.01874 36 2052
12 0.01651 50 2083
13 0.01482 49 2065
14 0.01277 70 2108
15 0.01805 55 2115
16 0.00845 33 2131
17 0.00796 41 2135
18 0.00982 26 2136
19 0.00831 39 2144
20 0.00869 38 2143
21 0.00653 50 2152
22 0.00813 28 2142
23 0.00584 88 2149
24 0.00867 51 2158
25 0.00660 35 2140
26 0.00616 48 2153
27 0.00718 95 2155
28 0.00670 37 2151
29 0.00650 37 2164
30 0.00706 43 2173
31 0.00688 38 2158
32 0.00689 33 2164
33 0.00585 75 2171
34 0.00568 80 2168
35 0.00648 41 2166
36 0.00684 35 2168
37 0.00571 26 2178
38 0.00528 17 2170
39 0.00576 91 2177
40 0.00649 15 2162
Tabla 1: Errores de validación, t iempos de entrenamiento y número de clasificaciones correctas para
los distintos números de neuronas en capa oculta. (Conjunto de prueba posee 2199 elementos)
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~19~
Desarrollo
Finalmente, a partir de la información de la tabla se generaron los gráficos de
la Figura 11, donde se observa que el tiempo de entrenamiento no posee una
clara relación con el número de neuronas de la capa oculta, y esto se debe
posiblemente a que depende de los pesos iniciales que se la asignaron
aleatoriamente a la red, ya que en algunos casos se inicia más cerca de la
solución que en otros. Para el número de clasificaciones correctas y el error de
validación la relación es clara, a medida que se aumenta el número de neuronas
en la capa oculta, el primero aumenta y el segundo disminuye, mostrando ambos
un comportamiento tipo asintótico para cantidades más grandes de HLN.
Figura 11: (arriba-izq) Número de clasificaciones correctas, para un total de 2199. (arriba -der)
Tiempos de entrenamiento. (abajo) Error de validación.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~20~
Conclusiones
3. Conclusiones
Durante el desarrollo de esta tarea se revisaron los conceptos teóricos acerca de
las redes neuronales artificiales, logrando resumir sus componentes básicos, el método de entrenamiento de backpropagation, el problema de sobre-entrenamiento y cómo prevenirlo mediante la cross-validation. Además se definió la matriz de confusión y su utilidad para visualizar intuitivamente el rendimiento de un clasificador multiclase.
Al implementar el clasificador de dígitos con una red neuronal en Matlab, se logró
demostrar la utilidad del toolbox de redes neuronales, el cual permite fácilmente la creación de una RNA, su entrenamiento y simulación, permitiendo realizar de una manera más sencilla el arduo proceso de encontrar la topología adecuada para la RNA que resuelve el problema, junto con los parámetros de entrenamiento adecuados.
Finalmente, luego de probar distintas topologías, el mejor clasificador de una capa
oculta implementado corresponde al que posee 38 neuronas en la capa oculta, logrando un error de validación de 0.00528 y un porcentaje de clasificaciones correctas del 98,68%. Sin embargo, también se puede concluir que a partir de una capa oculta con 13 neuronas o más se logran resultados cuya variación de error es muy pequeña, por lo que el número sugerido de neuronas para esta capa según 2.1b) puede ser considerado una buena cota inferior para comenzar el proceso de prueba y error que determine la cantidad óptima de neuronas para la mejor resolución del problema.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~21~
Anexos
4. Anexos
A continuación se muestran los códigos contenidos en cada uno de los archivos
entregados en la tarea.
“basededatos.m”
function [entren, clases_entren, prueba, clases_prueba]=
basededatos(data,clases)
%[entren clases_entren, prueba, clases_prueba]= basededatos(data,clases)
recibe la matriz 'data' con los datos de %los trazos de los digitos y genera dos conjuntos representativos
'entren' con el 80% de los datos y %'prueba' con el 20%, y dos conjuntos que llevan información sobre la
clase verdadera de cada muestra.
N=length(data(1,:)); nfeats=length(data(:,1)); % n° de caracteristicas nc=length(clases(:,1)); % n° de clases
%Uno los datos con las clases en una sola matriz, para asociar los %índices de las columnas a cada clase distinta. newdata=[data;clases];
%ordeno y obtengo los índices de las muestras de cada clase. [aux ind]=sort(newdata,2); szs=zeros(1,nc); subclase_ind=[]; %debo encontrar los indices de los que efectivamente pertenecen a cada %clase, para guardarlos en una matriz y luego separarlos. for i=1:nc ind_aux=find(aux(nfeats+i,:),1,'first'); subclase_ind=[subclase_ind ind(nfeats+i,ind_aux:end)]; szs(i)=length(ind(nfeats+i,ind_aux:end)); %también calculo cuántos
hay por clase. end
ind_bord=cumsum(szs); %esto me indica los indices que separan las
clases en el vector subclase_ind
%Se quiere 20% de los datos por cada clase para el conjunto de prueba pr_szs=round(szs.*0.2); ind_bord_pr=cumsum(pr_szs);%esto me sirve para saber cuántos datos
seleccionar por cada clase en las iteraciones. sz_prueba=sum(pr_szs); %tamaño total del conjunto de prueba. prueba=zeros(nfeats+nc,sz_prueba); r_vec=zeros(1,sz_prueba); %vector que tendrá los indices seleccionados.
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~22~
Anexos
%Selección de datos de prueba (20% por cada clase)
%primera iteración for i=1:ind_bord_pr(1) r=randi([1 ind_bord(1)]); while(find(r_vec==subclase_ind(r))) %selecciono un indice de
los indices al azar dentro del rango de la clase '0'. % y me aseguro que sea
distinto a alguno seleccionado. r=randi([1 ind_bord(1)]); end prueba(:,i)=newdata(:,subclase_ind(r)); %guardo los datos y la clase
a la que pertenece el dato elegido en el conjunto de prueba r_vec(i)=subclase_ind(r); %guardo el indice para luego borrar ese
dato del conjunto y que lo que quede sea el de entrenamiento end % repito para el resto de las clases. for j=2:nc for i=(ind_bord_pr(j-1)+1):ind_bord_pr(j) r=randi([(ind_bord(j-1)+1) ind_bord(j)]); while(find(r_vec==subclase_ind(r))) r=randi([(ind_bord(j-1)+1) ind_bord(j)]); end prueba(:,i)=newdata(:,subclase_ind(r)); r_vec(i)=subclase_ind(r); end end prueba2 = prueba(:,randperm(length(prueba(1,:)))); %desordeno el
orden de las columnas prueba=prueba2; clear prueba2;
%extraigo del conjunto original los datos utilizados para el conjunto de
prueba entren=newdata; entren(:,r_vec)=[]; sz_entren=length(entren(1,:));
%Verificar representatividad
%calculo cantidad de datos por clase en cada conjunto [aux ind]=sort(prueba,2); [aux2 ind2]=sort(entren,2); ver_szs_prueba=zeros(1,nc); ver_szs_entren=zeros(1,nc); for i=1:nc ind_aux=find(aux(16+i,:),1,'first'); ind_aux2=find(aux2(16+i,:),1,'first'); ver_szs_prueba(i)=length(ind(16+i,ind_aux:end)); %calculo cuántos
datos hay por clase en el conjunto de prueba construido. ver_szs_entren(i)=length(ind2(16+i,ind_aux2:end)); %y cuántos por
clase en el conjunto de entrenamiento end
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~23~
Anexos
%verifico proporciones parecidas por clase en ambos conjuntos.
(DESCOMENTAR %PARA VERIFICAR)
% repr_total=szs./N % repr_prueba=ver_szs_prueba./sz_prueba % repr_entren=ver_szs_entren./sz_entren
%verifico proporción 80/20 de los datos en cada conjunto.
% sz_entren/N % sz_prueba/N
%Separo datos de información sobre la clase a la que pertenece cada uno.
clases_entren = entren(17:end,:); entren(17:end,:)=[]; clases_prueba = prueba(17:end,:); prueba(17:end,:)=[];
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~24~
Anexos
“redneuronal.m”
close all; clear all; load BaseDatosTarea2 [en en_c pr pr_c]=basededatos(trazos,digitos);
%Parte 3) Clasificador Multiclase
nn=13; %número de neuronas de la capa oculta net=newff(en,en_c,[nn]); %inicializo la red %seteo parámetros net.trainParam.epochs=100; %número máximo de épocas net.trainParam.showWindow=1; %mostrar ventana de entrenamiento net.trainParam.goal=0.0005; %meta de performance net.trainParam.mu=0.001; %tasa de aprendizaje
%entreno la red net=train(net,en,en_c);
%simular clasificación con conjunto de prueba salida=sim(net,pr); [~, clases_salida]=max(salida); %guardo índice de fila del máximo clases_salida=(clases_salida-1); %clase corresponde al dígito "fila
-1"
[~, clases_prueba]=max(pr_c); %guardo índice de fila del máximo clases_prueba=(clases_prueba-1); %clase corresponde al dígito "fila
-1"
err=clases_prueba==clases_salida;
str=sprintf('Total bien clasificados para %d neuronas =
%d',nn,sum(err)); display(str) %Generar matriz de confusión C=confusionmat(clases_prueba',clases_salida'); C=C./sum(C(:,1)); %normalizo la matriz de confusión imagesc(C) axis('ij') colorbar; xlabel('Clases Verdaderas') ylabel('Clases Predichas') title('Matriz de Confusión')
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~25~
Anexos
%Para parte 4) se debe descomentar esta parte y comentar la Parte 3).
% for i=5:40 % net=newff(en,en_c,[i]); % net.trainParam.epochs=100; % net.trainParam.showWindow=1; % net.trainParam.goal=0.005; % net.trainParam.mu=0.001; % % [net tr]=train(net,en,en_c); % % salida=sim(net,pr); % [~, clases_salida]=max(salida); % clases_salida=clases_salida-1; % [~, clases_prueba]=max(pr_c); % clases_prueba=clases_prueba-1; % err=clases_prueba==clases_salida; % str=sprintf('Total bien clasificados para %d neuronas =
%d',i,sum(err)); % display(str) % C=confusionmat(clases_prueba,clases_salida); % C=C./sum(C(:,1)); % figure; % plotperform(tr); % str=sprintf('Numero de neuronas en capa oculta = %d', i); % text(1,1,str) % figure; % imagesc(C) % h=colorbar; % ylim(h,[0,1]); % axis('ij') % str=sprintf('Matriz de confusión para %d neuronas en capa
oculta', i); % title(str) % end
EL4106 – Clasificador de Dígitos con Redes Neuronales
U. de Chile. FCFM. DIE ~26~
Bibliografía y referencias
5. Bibliografía y referencias
Presentación “EL4106 - Inteligencia Computacional - Introducción RNA”-
P.Estévez y C.Held, Otoño 2014, Adaptada por Javier Ruiz del Solar.
Presentación “Multi-Layer Perceptron (MLP) – Lectures 5-6 Neural Networks”
– Dr Andy Philippides, University of Sussex, UK.
http://www.cs.sunysb.edu/~skiena/jaialai/excerpts/node16.html
http://en.wikibooks.org/wiki/Artificial_Neural_Networks
Presentación “EL4106 – Inteligencia Computacional – Performance
Evaluation” – Otoño 2014.
Referencias:
i http://sabia.tic.udc.es/sc/web2/frame_capitulo5.html#neuronas (Departamento de Dept.
Tecnologías de la Información y las Comunicaciones, Universidade da Coruña, España)