Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
hipotenusas
Comprobemos en la práctica la anterior aseveración de que una ANN puede
aprender por sí misma virtualmente cualquier función. El objetivo es obtener una
ANN capaz de calcular la hipotenusa a partir de las medidas de lo catetos, pero sin
facilitarle la fórmula exacta para hacerlo. Para ello nos serviremos del
paquete neuralnet de R.
El primer paso es cargar el paquete, introduciendo en la consola de R el siguiente
comando:
library(neuralnet)
Datos de ejemplo
Lo primero que necesitamos son algunos datos de ejemplo que permitan a la ANN
aprender la función. Para ello vamos a preparar un data.frame (un tipo de dato de R
similar a una matriz) con 100 filas, un centenar de ejemplos, cada una de las cuales
tendrá tres columnas. Las dos primeras contendrán las medidas de dos catetos y
las obtendremos así:
set.seed(42) # Establece la semilla aleatoria para asegurar reproducibilidad
head(data)
## Cat1 Cat2
## 1 9 7
## 2 9 3
## 3 4 3
## 4 8 5
## 5 7 9
## 6 6 10
La función runif() devuelve valores de una distribución uniforme. En este caso
concreto le solicitamos 100 valores entre 1 y 10 para cada uno de los catetos.
Podemos comprobar cuál es el contenido del data.frame simplemente escribiendo
en la consola data y pulsando Intro. Esto mostraría las 100 filas. Para comprobar la
estructura es suficiente con algunas de ellas, devueltas por la función head().
El data.frame debe tener una columna adicional con la hipotenusa correspondiente
a cada pareja de catetos. La añadimos de la siguiente manera:
data$Hyp <- sqrt(data$Cat1*data$Cat1 + data$Cat2*data$Cat2)
head(data)
## Cat1 Cat2 Hyp
## 1 9 7 11.401754
## 2 9 3 9.486833
## 3 4 3 5.000000
## 4 8 5 9.433981
## 5 7 9 11.401754
## 6 6 10 11.661904
head(test)
## Cat1 Cat2 Hyp
## 92 2 2 2.828427
## 93 2 6 6.324555
## 29 7 8 10.630146
## 81 8 4 8.944272
## 62 5 6 7.810250
## 50 9 1 9.055385
head(train)
## Cat1 Cat2 Hyp
## 1 6 4 7.211103
## 2 6 6 8.485281
## 3 8 7 10.630146
## 4 8 4 8.944272
## 5 7 7 9.899495
## 6 8 3 8.544004
Con la expresión data[fold.test, ] estamos tomando del data.frame original las
tres columnas de las filas cuyos índices contiene fold.test. La expresión data[-
fold.test, ] es similar, pero tomando las filas cuyos índices no están en el
vector fold.test. De esta forma obtenemos dos conjuntos disjuntos de ejemplos,
uno en la variable train y otro en la variable test. Ambas son objetos data.frame,
con las mismas tres columnas que data.
Los dos primeros parámetros son obligatorios. El primero es una fórmula mediante
la que se indica qué variables son predictoras (los catetos) y qué variables se van a
predecir (la hipotenusa). La sintaxis es simple: disponemos los nombres de las
columnas del data.frame que contienen datos a obtener como resultado de la red
neuronal, en este caso es solo una, separados entre sí mediante el operador +. A
continuación, tras el símbolo ~, se facilitan las variables de entrada de la misma
manera. El segundo parámetro es el data.frame que contiene las variables a las que
se hace referencia en la anterior fórmula.
El parámetro hidden es opcional. Con él indicamos el número de neuronas que
existirá en cada una de las capas ocultas de la ANN. En este caso vamos a tener
una sola capa oculta con 10 neuronas. Por defecto la función neuralnet() efectúa
una sola vez el proceso de entrenamiento de la ANN. Con el parámetro rep se
cambia el número de repeticiones (en el proceso hay una componente aleatoria
que provoca que cada red obtenida tras el entrenamiento sea distinta), con el
objetivo de obtener la mejor ANN posible.
Finalizado el proceso de aprendizaje, la estructura de las distintas ANN obtenidas
queda almacenada en la variable ann. Podemos imprimirla para obtener un
resumen del rendimiento de las ANN:
ann
## Call: neuralnet(formula = Hyp ~ Cat1 + Cat2, data = train, hidden = 10,
rep = 3)
##
## 3 repetitions were calculated.
##
## Error Reached Threshold Steps
## 1 0.006725962 0.009883311 7593
## 3 0.012119691 0.009604500 8799
## 2 0.028969166 0.009210339 28154
Por cada repetición se indica el error cometido, el umbral alcanzado y el número de
pasos que ha demandado el aprendizaje. El número de pasos, también conocido
como épocas, puede limitarse o ampliarse, lo cual afectará a la precisión de la ANN.
Durante el proceso de aprendizaje se usa un algoritmo que determina, para las
entradas facilitadas, el error que ha cometido la ANN en su salida. En función de la
magnitud de ese error se ajustarán los pesos asociados a las conexiones entre las
neuronas de las distintas capas. Esto provoca que para unos valores de entrada se
genere una cierta salida que en el futuro, tras efectuar cambios en dichos pesos
como resultado del procesamiento de otros ejemplos, será distinta. Para estabilizar
la red se procesan los mismos ejemplos de manera reiterada y en distinto orden,
hasta que se converge a un cierto umbral de mejora o se alcanza un máximo de
pasos.