Tutorial Rrnnaa Matlab PDF

Title Tutorial Rrnnaa Matlab
Author Xavier Vila
Course Sistemas Intelixentes
Institution Universidade da Coruña
Pages 23
File Size 598.7 KB
File Type PDF
Total Downloads 48
Total Views 127

Summary

Download Tutorial Rrnnaa Matlab PDF


Description

Introducción a las RR.NN.AA. en Matlab Sistemas Inteligentes Matlab posee un Toolbox denominado Neural Network Toolbox, que tiene implementadas las funciones necesarias para desarrollar y trabajar con RR.NN.AA. en ese entorno. Por otra parte, el Toolbox de estadística proporciona una serie de bases de datos conocidas para poder trabajar en distintos problemas. Para cargar cada una de estas bases de datos, se puede utilizar simplemente la función load. Por ejemplo: load iris_dataset

Esta línea cargará en memoria la conocida base de datos de clasificación de flores iris. Esta base de datos tiene 150 instancias y 4 atributos. Como consecuencia de la ejecución de esta línea, se generarán en memoria dos variables: irisInputs: de dimensión 4x150, con los valores de los 4 atributos para cada instancia. irisTargets: de dimensión 3x150, con la clasificación de cada instancia. Esta variable contiene, para cada instancia, 3 valores, siendo 0 para aquellas clases a las que no pertenece, y 1 para la que pertenece.

Como se puede ver por la dimensión de las variables, Matlab entiende que en las bases de datos las distintas instancias se disponen en columnas, y los atributos y salidas deseadas en filas, al contrario de lo que intuitivamente se suele pensar.

A la hora de desarrollar RR.NN.AA., Matlab distingue tres tipos principales de problemas, y para cada uno proporciona una función para crear una RNA: regresión, clasificación y ajuste de curvas.

1.- Problemas de regresión Para resolver este tipo de problemas está disponible la función feedforwardnet, que recibe, como mínimo, un único parámetro, que es un vector con la arquitectura que tendrá la red. El número de elementos del vector será el número de capas ocultas, y el valor de cada elemento del vector será el número de neuronas en cada capa oculta. Por ejemplo, para crear una red con una capa oculta y 10 neuronas en esa capa se podría escribir lo siguiente: rna = feedforwardnet([10]);

Y para crear una red con dos capas ocultas, y 12 y 6 neuronas en la primera y segunda capa oculta respectivamente, se podría escribir lo siguiente: rna = feedforwardnet([12 6]);

Sin embargo, una red creada de esta manera tiene fija la arquitectura, pero no se ha especificado el número de neuronas de entrada y de salida. Para hacer esto, se utiliza la función configure, que realiza, entre otras, esas tareas, y recibe como parámetros: Una matriz representativa de las entradas que recibirá la red. A partir de esta entrada se establece el número de neuronas de entrada que tendrá la red, así como los valores de normalización de las mismas. Una matriz representativa de las salidas que deberá emitir la red. A partir de esta entrada se establece el número de neuronas de salida que tendrá la red, así como los valores de normalización de las mismas.

En la práctica, las entradas y salidas deseadas que se le pasan a esta función son las que se utilizarán para entrenar y validar la red. Esta función devuelve una RNA preparada para ser entrenada con esos patrones que se pasaron en la llamada, o unos distintos pero similares. Esta red que devuelve deberá ser asignada a una variable para que se tenga en memoria. Por ejemplo, si se ejecutan las líneas: load house_dataset rna = feedforwardnet([8]); rna = configure(rna,houseInputs,houseTargets);

se carga primero la base de datos con los patrones sobre predicción de precios de casas en los suburbios de Boston, con lo que se crean las variables con los patrones de entrada

(houseInputs) y salidas deseadas (houseTargets). Posteriormente, se crea la red con la función feedforwardnet, para lo cual se especifica la arquitectura, en este caso una única capa oculta con 8 neuronas. Si se quisiera especificar un número distinto de neuronas o capas ocultas, se podría haber hecho cambiando el parámetro. Por ejemplo, para especificar dos capas ocultas con 12 y 6 neuronas, se haría de la siguiente manera: rna = feedforwardnet([12 6]); rna = configure(rna,houseInputs,houseTargets);

La última línea, con la llamada a la función configure, permite preparar la red para ser utilizada en este problema concreto.

De esta manera, se crea una variable en memoria, llamada rna, que contiene un objeto con una estructura con distintos campos que configura la red. De hecho, si se escribe el nombre de la variable rna para visualizar su contenido, aparecerá lo siguiente: rna = Neural Network name: 'Feed-Forward Neural Network' efficiency: .cacheDelayedInputs, .flattenTime, .memoryReduction userdata: (your custom info) dimensions: numInputs: numLayers: numOutputs: numInputDelays: numLayerDelays: numFeedbackDelays: numWeightElements: sampleTime:

1 2 1 0 0 0 121 1

connections: biasConnect: inputConnect: layerConnect: outputConnect:

[1; 1] [1; 0] [0 0; 1 0] [0 1]

subobjects: inputs: {1x1 cell array of 1 input} layers: {2x1 cell array of 2 layers}

outputs: biases: inputWeights: layerWeights:

{1x2 {2x1 {2x1 {2x2

cell cell cell cell

array array array array

of of of of

1 2 1 1

output} biases} weight} weight}

functions: adaptFcn: adaptParam: derivFcn: divideFcn: divideParam: divideMode: initFcn: performFcn: performParam: plotFcns:

'adaptwb' (none) 'defaultderiv' 'dividerand' .trainRatio, .valRatio, .testRatio 'sample' 'initlay' 'mse' .regularization, .normalization, .squaredWeighting {'plotperform', plottrainstate, ploterrhist, plotregression} plotParams: {1x4 cell array of 1 param} trainFcn: 'trainlm' trainParam: .showWindow, .showCommandLine, .show, .epochs, .time, .goal, .min_grad, .max_fail, .mu, .mu_dec, .mu_inc, .mu_max

weight and bias values: IW: {2x1 cell} containing 1 input weight matrix LW: {2x2 cell} containing 1 layer weight matrix b: {2x1 cell} containing 2 bias vectors methods: adapt: configure: gensim: init: perform: sim: train: view: unconfigure: evaluate:

Learn while in continuous use Configure inputs & outputs Generate Simulink model Initialize weights & biases Calculate performance Evaluate network outputs given inputs Train network with examples View diagram Unconfigure inputs & outputs outputs = rna(inputs)

De esta forma, se puede modificar los valores que toman los distintos campos para configurar la red de una forma u otra. Algunos de estos campos más interesantes son: rna.IW: matrices de pesos de la capa de entrada a cada una de las restantes capas. En las redes creadas con la función feedforwardnet, solamente habrá pesos a la primera capa que no sea entrada (la primera oculta). En el caso de tener 13 entradas y haber creado la red con la 12 neuronas en la primera capa

oculta, esta matriz tendrá una dimensión de 12x13, puesto que cada peso wij indica una conexión de la neurona j a la i. Es decir, en una matriz de pesos las neuronas de partida se disponen en las columnas, y las de llegada en las filas. Para referenciar y poder ver la matriz de pesos de la capa de entrada a la primera oculta, habría que escribir en Matlab: rna.IW{1}

rna.LW: pesos entre las capas que no son de entrada. En el caso de utilizar la función feedforwardnet para crear la red, solamente habrá pesos de cada capa oculta a la siguiente, y a la de salida. Por ejemplo, si se creó la red con 2 capas ocultas con 12 y 6 neuronas en cada una, al visualizar esta variable aparecería: >> rna.LW ans = [] [6x12 double] []

[] [] [1x6 double]

[] [] []

Al igual que en el caso de las neuronas, las capas de procedencia de las conexiones están en las columnas, y las de destino en las filas. Por lo tanto, una matriz de pesos en la posición (2,1) indica la presencia de una matriz de pesos de la capa 1 (primera oculta, con 12 neuronas) a la 2 (segunda oculta, con 6 neuronas), con una dimensión de 6x12. Por su lado, una matriz de pesos en la posición (3,2) indica la presencia de conexiones de la capa 2 (segunda oculta, con 6 neuronas) a la 3 (capa de salida, con 1 neurona). Para referenciar cualquiera de estas matrices, igual que antes, se pueden utilizar las llaves, por ejemplo: rna.LW{2,1}

rna.b: matrices de bias de cada capa. Para verlos, se referencian rna.b{1}, rna.b{2}, etc. rna.trainParam: Este campo, a su vez, contiene nuevos campos con distintos parámetros que controlarán el entrenamiento de la red. Si se visualiza: >> rna.trainParam ans =

Function Parameters for 'trainlm'

Show Training Window Feedback showWindow: Show Command Line Feedback showCommandLine: Command Line Frequency show: Maximum Epochs epochs: Maximum Training Time time: Performance Goal goal: Minimum Gradient min_grad: Maximum Validation Checks max_fail: Mu mu: Mu Decrease Ratio mu_dec: Mu Increase Ratio mu_inc: Maximum mu mu_max:

true false 25 1000 Inf 0 1e-005 6 0.001 0.1 10 10000000000

Algunos de los parámetros más importantes son los que permiten establecer el número máximo de ciclos del algoritmo de backpropagation (epochs), el tiempo máximo que puede estar ejecutándose (time), el error que se quiere alcanzar (goal), el hecho de querer o no que se muestre la ventana de entrenamiento (showWindow), o el número de ciclos máximo que puede transcurrir sin mejorar el error de validación antes de parar el entrenamiento (max_fail). rna.divideParam: Este campo contiene 3 campos en los que se establece el ratio de división de los patrones en los conjuntos de entrenamiento, validación y test. Antes de realizar el entrenamiento, se dividen los patrones aleatoriamente según esos valores y cada uno de esos nuevos conjuntos se utiliza con ese fin. Si se visualizan, por defecto toman valores de 60% (entrenamiento), 20% (validación) y 20% (test). rna.layers: Contiene una serie de objetos con campos, uno por cada capa que no sea de entrada. Por ejemplo, para el caso de utilizar 2 capas ocultas, se podría visualizar su contenido de la siguiente manera: >> rna.layers{1} ans = Neural Network Layer name: dimensions: distanceFcn: distanceParam: distances: initFcn: netInputFcn: netInputParam: positions: range: size: topologyFcn:

'Hidden 1' 12 (none) (none) [] 'initnw' 'netsum' (none) [] [12x2 double] 12 (none)

transferFcn: 'tansig' transferParam: (none) userdata: (your custom info) >> rna.layers{2} ans = Neural Network Layer name: dimensions: distanceFcn: distanceParam: distances: initFcn: netInputFcn: netInputParam: positions: range: size: topologyFcn: transferFcn: transferParam: userdata:

'Hidden 2' 6 (none) (none) [] 'initnw' 'netsum' (none) [] [6x2 double] 6 (none) 'tansig' (none) (your custom info)

>> rna.layers{3} ans = Neural Network Layer name: dimensions: distanceFcn: distanceParam: distances: initFcn: netInputFcn: netInputParam: positions: range: size: topologyFcn: transferFcn: transferParam: userdata:

'Output' 1 (none) (none) [] 'initnw' 'netsum' (none) [] [1x2 double] 1 (none) 'purelin' (none) (your custom info)

Donde se puede ver, por defecto, que la función de transferencia de las dos capas ocultas (el campo transferFcn) es hiperbólica tangente, mientras que la de la capa de salida es lineal. rna.trainFcn: Contiene el nombre de la función de entrenamiento. Por defecto, la que trae es trainlm, una versión del algoritmo de backpropagation que utiliza la

optimización de Levenberg-Marquardt. Esta función suele funcionar bastante bien en la mayoría de problemas, aunque tiene un consumo de memoria muy elevado. rna.inputs: Contiene un objeto con información sobre las entradas, como el procesado de las mismas (incluyendo tareas como normalización). Si se desea visualizar, aparecerá algo similar a esto: >> rna.inputs{1} ans = Neural Network Input name: feedbackOutput: processFcns: processParams: processSettings: processedRange: processedSize: range: size: userdata:

'Input' [] {'removeconstantrows', mapminmax} {1x2 cell array of 2 params} {1x2 cell array of 2 settings} [13x2 double] 13 [13x2 double] 13 (your custom info)

Esto indica que las entradas deberían de ser procesadas primero ocupándose de los valores desconocidos, después eliminando los atributos con valor constante, y, posteriormente, normalizadas entre un máximo y un mínimo.

Para entrenar una red una red se tiene la función train, que recibe como parámetros la red a entrenar y los conjuntos de entradas y salidas deseadas. El resto de parámetros del proceso de entrenamiento los toma de los campos correspondientes de la red pasada como parámetro. Como resultado, devuelve la misma red entrenada. Dado que Matlab no acepta el paso de parámetros por referencia, se deberá asignar a la misma variable para actualizar su valor con la red entrenada. De esta forma, para entrenar la red anterior se podría realizar escribiendo: rna = train(rna, houseInputs, houseTargets);

Al escribir esto en Matlab aparecerá una ventana similar a la siguiente:

En esta ventana se puede distinguir 4 zonas distintas. En primer lugar, en la parte superior, aparece un esquema con la estructura de la red. Inmediatamente debajo, aparecen descritos cuatro de los algoritmos más importantes utilizados en el entrenamiento de la red. Los tres primeros que aparecen, los más importantes, son: Método de división del conjunto de patrones en entrenamiento/validación/test: Por defecto: división aleatoria (dividerand). Algoritmo de entrenamiento. Por defecto, la variante del algoritmo de de Levenberg-Marquardt (trainlm). Función de medida de error. Por defecto, error cuadrático medio (mse).

En la tercera zona (

) se puede observar una serie de barras que van creciendo

hacia la parte derecha a medida que avanza el entrenamiento. Cada una de las barras representa un criterio distinto de parada y, en consecuencia, cuando una de las barras alcance la parte derecha, se pone de color verde y el entrenamiento se para porque ese criterio de parada se ha satisfecho. Las distintas barras indican que los criterios de parada son: Se ha realizado un número máximo de ciclos del algoritmo de entrenamiento (por defecto, 1000 ciclos). Se ha entrenado hasta llegar a un periodo de tiempo máximo (por defecto,

deshabilitado). Se ha alcanzado un error aceptable (por defecto, 0). Se ha alcanzado un valor de gradiente muy bajo (por defecto, 10-5). Se ha alcanzado un valor de mu muy alto (por defecto, 1010). Se ha alcanzado un número prefijado de ciclos en los cuales no se ha mejorado el mejor error obtenido en el conjunto de validación (

, por

defecto 6). Este suele ser el criterio de parada más común, para evitar el sobreentrenamiento.

Por último, debajo de todo hay una zona (

) donde se pueden ver distintas gráficas que

se pueden sacar como resultado del proceso de entrenamiento. En el caso de haber creado una red para resolver un problema de regresión estas gráficas son: . En esta gráfica aparece la evolución del error en cada ciclo del algoritmo de entrenamiento para los conjuntos de entrenamiento, validación y test. Aparece resaltado el ciclo en el que se obtuvo el mejor error en el conjunto de validación, y, una vez terminado el proceso de entrenamiento, se devuelve la red con los valores de los pesos en ese ciclo (con menor error de validación). De esta forma se evita el efecto del sobreentrenamiento.

. Se muestra la evolución durante el proceso de entrenamiento de tres parámetros distintos: gradiente, mu, y número de ciclos sin mejorar el mejor error en validación.

. En esta gráfica se muestra un histograma en el que se puede ver cómo se distribuye el error cometido (medido como salida deseada – salida obtenida) entre las distintas instancias (en entrenamiento, validación y test), es decir, se muestra gráficamente cuántas instancias han cometido un determinado error.

. En esta gráfica se muestran distintos modelos de regresión lineal entre las salidas deseadas y las dadas por la red para los patrones en los conjuntos de entrenamiento, validación y test, y, como cuarta gráfica, con todos los patrones unidos. En caso de que la red diese sus salidas con un error 0, estas salidas obtenidas serían igual a las deseadas, y, por lo tanto, la recta de regresión sería y=x, y todos los puntos (cada punto es un patrón) se dispondrían alrededor de esa recta. Cuanto mayor sea el error obtenido, más se alejan los patrones de esa recta, más dispersión hay y, en consecuencia, la recta tiene una pendiente distinta.

Además de devolver la red entrenada, la función train devuelve una segunda variable, que contiene un resumen del proceso de entrenamiento de la red, y que puede asignarse a una variable en el entorno. Por ejemplo: load house_dataset rna = feedforwardnet([8]); [rna, tr] = train(rna, houseInputs, houseTargets);

De esta manera, se crearía la variable tr (

) donde se guarda el resumen del

proceso de entrenamiento de la red. El contenido de esta variable podría ser el siguiente: >> tr tr = trainFcn: trainParam: performFcn: performParam: derivFcn: divideFcn: divideMode: divideParam: trainInd: valInd: testInd: stop: num_epochs: trainMask: valMask: testMask:

'trainlm' [1x1 nnetParam] 'mse' [1x1 nnetParam] 'defaultderiv' 'dividerand' 'sample' [1x1 nnetParam] [1x354 double] [1x76 double] [1x76 double] 'Validation stop.' 16 {[1x506 double]} {[1x506 double]} {[1x506 double]}

best_epoch: goal: states: epoch: time: perf: vperf: tperf: mu: gradient: val_fail: best_perf: best_vperf: best_tperf:

10 0 {1x8 cell} [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16] [1x17 double] [1x17 double] [1x17 double] [1x17 double] [1x17 double] [1x17 double] [0 0 0 0 0 1 0 0 0 1 0 1 2 3 4 5 6] 11.0673 21.5416 12.7106

En estos valores concretos de esta variable se puede ver, por ejemplo, que la red se ha entrenado durante 16 ciclos (tr.num_epochs), comenzando en el ciclo 0, pero que la red que se devuelve no es la correspondiente al último ciclo, sino la que corresponde al ciclo 10 (tr.best_epoch), puesto que es la que tiene menor error de validación, y que tiene un error en entrenamiento de 11.0673 (tr.best_perf), en validación de 21.5416 (tr.best_vperf) y en test de 12.7106 (tr.best_tperf). Estos valores se corresponden a los valores de los vectores que contienen los errores durante el entrenamiento en los conjuntos de entrenamiento, validación y test (tr.perf, tr.vperf y tr.tperf respectivamente), en el índice tr.best_epoch+1, puesto que el primer elemento de estos vectores corresponde con el ciclo 0. Otra información importante son los índices de los patrones utilizados para entrenamiento (tr.trainInd), validación (tr.valInd) y test (tr.testInd).

Una vez entrenada una red, para utilizarla se puede emplear la función sim, que recibe como parámetros la propia red y un conjunto de patrones. Por ejemplo, si se quiere emplear la red para generar salidas ante el conjunto de patrones, y calcular el error cuadrático medio con respecto a las salidas deseadas se podría escribir lo siguiente: >> houseOutputs = sim(rna, houseInputs); >> mse(houseOutputs-houseTargets) ans = 4.3944

2.- Problemas de clasificación Para resolver un problema de clasificación, se puede utilizar la función patternnet, que se utiliza de una forma similar a la función feedforwardnet. Por ejemplo, para cargar los patrones del problema de flores iris y crear una red que clasifique con una sola capa oculta y 8 neuronas en la misma, se podría escribir lo siguiente: load iris_dataset; rna = patternnet([8]); rna = configure(rna, irisInputs, irisTargets);

El problema de flores iris, descrito por Fisher en 1936, es uno de los problemas de clasificación más famosos y utilizados en la bibliografía. Consta de 150 patrones repartidos en 3 clases distintas. Mientras que una de las clases es fácilmente separable, en las otras dos hay una zona en la que unos cuantos patrones se entremezclan, con lo que no son linealmente separables.

De esta manera, se crea una estructura similar a la creada para pr...


Similar Free PDFs