Aprendizaje Autom´atico
Redes Neuronales Multicapa
curso 2014-2015
Roberto Paredes, Francisco Casacuberta, Enrique Vidal, Vicente Bosch
Departamento de Sistemas Inform´aticos y Computaci´on Universidad Polit´ecnica de Valencia
1. Introducci´on
El objetivo de esta pr´actica es experimentar con redes neuronales multicapa dentro de octave, en concreto con redes Multilayer Perceptron (MLP). Para ello utilizaremos la librer´ıa nnet para octave que se puede descargar en:
http://octave.sourceforge.net/nnet
La instalaci´on es muy sencilla. Simplemente se necesita disponer de los ficheros que definen las funciones requeridas por la librer´ıa en el directorio de trabajo o en el PATH. Se ha dejado disponible el fichero nnet toolkit.tar.gz que contiene dos directorios:
1. El directorio data contiene los distintos corpus de datos que usaremos para realizar los distintos experimentos.
2. El directorio nnet contiene todos los ficheros de la librer´ıa de redes neuronales.
Por tanto, para utilizar dicha librer´ıa se aconseja disponer de ambas carpetas en el directorio de trabajo y simplemente a˜nadir la ruta a la librer´ıa al PATH mediante el co- mando
addpath("nnet")
N´otese que la ruta anterior es relativa al directorio de trabajo.
2. Ejemplo de entrenamiento y clasificaci´on con MLP
2.1. Corpus de ejemplo
Para ilustrar el funcionamiento de la librer´ıa utilizaremos el corpus de hart que ya hemos visto en pr´acticas anteriores. Es un corpus de dos clases donde los puntos se rep- resentan en dos dimensiones y se encuentra dentro del directorio data/hart. Los pasos a seguir podr´ıan ser:
1. Ejecutamos octave en el directorio nnet toolkit. Una vez en octave recordemos que hay que incluir la librer´ıa en el PATH:
octave:1> addpath("nnet");
2. Cargamos los ficheros con los datos y las etiquetas de clase tanto del corpus de entrenamiento como del de test:
octave:2> load data/hart/tr.dat;
octave:3> load data/hart/trlabels.dat;
octave:4> load data/hart/ts.dat;
octave:5> load data/hart/tslabels.dat;
3. La librer´ıa nnet trabaja con los datos por columnas en lugar de por filas, por lo que es necesario trasponer los datos:
octave:6> mInput = tr’;
octave:7> mOutput = trlabels’;
octave:8> mTestInput = ts’;
octave:9> mTestOutput = tslabels’;
Para trabajar con MLP y la librer´ıa nnet tendremos que procesar y preparar los datos previamente. Hay varios aspectos a tener en cuenta.
2.2. Conjuntos de entrenamiento y validaci´on
El entrenamiento de MLP tiene dos posibles criterios de parada: entrenar durante un n´umero determinado de epochs o entrenar hasta que el error al clasificar un conjunto de validaci´on deje de mejorar. Normalmente se suele utilizar el segundo criterio, por lo que debemos dividir el conjunto de entrenamiento en 2.
Con las siguientes ´ordenes obtenemos el n´umero de muestras (nSamples) y nos quedare- mos con el 80 % de las mismas para entrenamiento y el 20 % restante para validaci´on:
octave:10> [nFeat, nSamples] = size(mInput);
octave:11> nTr=floor(nSamples*0.8);
octave:12> nVal=nSamples-nTr;
Queremos que la elecci´on de qu´e muestras forman parte de cada conjunto sea aleatoria.
Para ello utilizamos la funci´on randperm(n) que devuelve una permutaci´on aleatoria de elementos desde 1 hasta n:
octave:13> indices=randperm(nSamples);
Y ya tenemos todo lo necesario para dividir los conjuntos (recordad que en esta librer´ıa trabajamos con los datos ordenados por columnas):
octave:14> mTrainInput=mInput(:,indices(1:nTr));
octave:15> mTrainOutput=mOutput(indices(1:nTr));
octave:16> mValiInput=mInput(:,indices((nTr+1):nSamples));
octave:17> mValiOutput=mOutput(indices((nTr+1):nSamples));
2.3. Preproceso y formato de los datos
Dado un problema de clasificaci´on en C clases, la capa de salida de la MLP suele tener C neuronas de forma que la neurona i-´esima se activa para la clase i. Por ejemplo, en un problema de clasificaci´on en 3 clases, ´estas se codificar´ıan como [0, 0, 1], [0, 1, 0] y [1, 0, 0].
Por ello, debemos transformar las etiquetas de clase al formato correspondiente en forma de vector.
Ejercicio: Implementar la codificaci´on de las etiquetas de clase en el formato requerido por las librer´ıa de redes neuronales.
Una vez disponemos de los datos de entrenamiento y validaci´on, solo quedan realizar un par de pasos m´as. En primer lugar, es conveniente normalizar los datos de modo que tengan media cero y desviaci´on t´ıpica uno. Esto se consigue con el comando:
octave:25> [mTrainInputN,cMeanInput,cStdInput] = prestd(mTrainInput);
tal que mTrainInputN son los datos normalizados y cMeanInput y cStdInput son respec- tivamente la media y desviaci´on t´ıpica de los datos originales.
Por ´ultimo, el conjunto de validaci´on debe representarse en una estructura especial con 2 campos, P para los datos de entrada y T para la salida (validoutDisp son las etiquetas de validaci´on en forma de vector previamente descrita):
octave:26> VV.P = mValiInput;
octave:27> VV.T = validoutDisp;
as´ı como debemos normalizar los datos utilizando los mismos par´ametros que en el con- junto de entrenamiento
octave:28> VV.P = trastd(VV.P,cMeanInput,cStdInput);
2.4. Entrenamiento
Antes entrenar la red tenemos que crearla. Debemos especificar la topolog´ıa de la misma, los valores m´aximo y m´ınimo de los datos de entrenamiento (calculado por la funci´on min max) y las distintas funciones de activaci´on y entrenamiento. Una posible configuraci´on para una topolog´ıa de una capa oculta de tama˜no nHidden y con nOutput neuronas en la capa de salida la crear´ıamos mediante:
octave:29> MLPnet = newff(min_max(mTrainInputN),[nHidden nOutput],\
{"tansig","logsig"},"trainlm","","mse");
siendo tansig ∈ [−1, 1] la funci´on de activaci´on de la capa oculta y logsig ∈ [0, 1]
la funci´on de la capa de salida. El m´etodo trainlm es el algoritmo de entrenamiento backpropagation para redes neuronales y la m´etrica a minimizar es el error cuadr´atico medio (mse).
Con la red creada en MLPnet podemos establecer algunos par´ametros de entrenamiento:
octave:30> MLPnet.trainParam.show = 10;
octave:31> MLPnet.trainParam.epochs = 300;
donde el par´ametro show indica cada cu´antas epochs de entrenamiento queremos que se imprima informaci´on, y el par´ametro epochs es el n´umero m´aximo de epochs que queremos que realice (adicionalmente al criterio del conjunto de validaci´on).
Finalmente ya podemos entrenar la red (trainoutDisp son las etiquetas de entre- namiento en forma de vector):
octave:32> net = train(MLPnet,mTrainInputN,trainoutDisp,[],[],VV);
TRAINLM, Epoch 0/300, MSE 0.378153/0, Gradient 149.445/1e-10 TRAINLM, Epoch 10/300, MSE 0.0798137/0, Gradient 7.6783/1e-10 TRAINLM, Epoch 20/300, MSE 0.0672102/0, Gradient 12.3743/1e-10 TRAINLM, Epoch 30/300, MSE 0.0316977/0, Gradient 4.10449/1e-10 TRAINLM, Validation stop.
de forma que obtenemos en net la red entrenada. Adem´as, aparecer´a una gr´afica con la evoluci´on del error.
NOTA: Es posible que en ocasiones aparezcan avisos por motivos de calculo num´erico:
warning: matrix singular to machine precision, rcond = * warning: attempting to find minimum norm solution
warning: dgelsd: rank deficient *x* matrix, rank = *
2.5. Clasificaci´on y estimaci´on de la tasa de acierto
Antes de clasificar el conjunto de test con la red neuronal entrenada en la etapa anterior (variable net), debemos aplicar la normalizaci´on a los datos como hemos hecho con el resto de conjuntos:
octave:33> mTestInputN = trastd(mTestInput,cMeanInput,cStdInput);
y ya podemos clasificar los datos mediante la orden:
octave:34> simOut = sim(net,mTestInputN);
A diferencia de otras librer´ıas no obtenemos el porcentaje de error o precisi´on, sino que obtenemos los valores de salida de la red para cada muestra. Por tanto, debemos calcular el error nosotros mismos.
Ejercicio: Implementar una funci´on que reciba la salida de la MLP para el conjunto de test (simOut) y sus etiquetas (tslabels) y devuelva el porcentaje de error de clasificaci´on.
3. Tareas de clasificaci´on: Spam y USPS
En los directorios data/spam y data/usps se encuentran los ficheros de datos de las tareas Spam y USPS respectivamente. Tal y como vimos en las sesiones de pr´acticas de SVM, Spam es una tarea de clasificaci´on en dos clases d´onde el objetivo es clasificar correos electr´onicos en la clase Spam o No-Spam. Mientras que USPS es una tarea de clasificaci´on en 10 clases. En ambos directorios se encuentran los ficheros de training y test que deber´an emplearse.
El alumno deber´a usar el fichero de training para estimar los mejores par´ametros de la red neuronal a entrenar: n´umero de neuronas en la capa oculta, funciones de activaci´on, constante de aprendizaje, etc. Para ello deber´a dividir dichos datos de entrenamiento en entrenamiento y validaci´on tal y como se ha visto en el ejemplo anterior. El conjunto de test deber´a emplearse s´olo para estimar el error de la red neuronal que menor error haya obtenido sobre el conjunto de validaci´on. Todo ello debe quedar reflejado en una funci´on octave que realice la preparaci´on y partici´on de los datos, variaci´on de par´ametros y estimaci´on de error con el conjunto de test final.
Ejercicio: Implementar una funci´on para cada problema (spam,usps) que realice el ex- perimento completo. As´ı mismo se debe presentar una breve tabla de resultados con el error de clasificaci´on sobre el conjunto de validaci´on con respecto a los par´ametros m´as importantes, aquellos que m´as han influido en dicho error.