Está en la página 1de 12

Cómo Programar una Red Neuronal

desde 0 en R
En R existen varios paquetes que nos permiten crear Redes Neuronales, como
neuralnet o las más recientes (y conocidas) tensorflow y keras. Sí son paquetes
muy potentes y seguramente escriba sobre ellos en un futuro, pero me gustaría
comenzar explicando qué es una red neuronal, qué partes tiene y cómo podemos
programar una desde 0 en R. Así que vamos a ello.

Datos para nuestra Red Neuronal


Lo primero que necesitamos es un problema a resolver. En nuestro caso, siguiendo
el ejemplo de DotCSV, crearemos un problema de clasificación.
Para ello, he creado una función que genera datos circulares según un radio R. Con
esto, podremos dibujar dos círculos concéntricos que se solapen un poco, para ver
qué tal se le da a nuestra red neuronal.
Esto lo he hecho con el siguiente código y siguiendo este enlace.

Así pues, nuestros datos tienen la siguiente forma:


Cr
eamos las matrices X e Y y con esto ya tenemos nuestro problema de clasificación
listo para ser resuelto con nuestra red neuronal programada desde cero en R.
¡Vamos a ello!
Partes de una red neuronal
La idea es sencilla: programar cada parte de la red por separado, para así ir
explicando en qué consisten las redes neuronales. Una vez tengamos todo
programado, probaremos la red neuronal en nuestro problema para ver que funciona
correctamente.
Así pues, podríamos decir que una red neuronal se programa en 3 partes:
 La estructura de la red neuronal: simplemente defines el número de capas,
neuronas por cada capa, funciones de activación, la capa de salida… en definitiva, el
esqueleto. Además, damos unos valores iniciales a dichos parámetros.
 Forward Propagation: “arrancamos” la red neuronal y hacemos que nos
devuelva un resultado.
 Back Propagation: en base al error de la estimación, ajustamos los parámetros
de la última capa a las capas anteriores. Además, usamos el descenso del gradiente
(Gradient Descent) para reajustar los parámetros e ir entrenando a la red neuronal.
Por último tendríamos que entrenar a la red en un problema real y ver cómo
funciona. Fácil, ¿verdad? Pues al lío
Programar una red neuronal en R: la estructura de la
red neuronal
Las redes neuronales son neuronas conectadas entre ellas de manera secuencial. A
cada una de esas secuencias las llamamos capas.
Las capas siempre tienen la misma estructura: neuronas de la capa, número de
conexiones, parámetros b (bias) y w. Por eso, como siempre es la misma estruco
código más simple.
La forma en la que lo he hecho ha sido mediante objetos S4. No hay mucha info al
respecto… pero bueno, (en este enlace puedes aprender cómo funcionan).
Esta clase tendrá los siguientes parámetros:
 Número de neuronas en la capa.
 Número de neuronas en la capa anterior.
 Bias(b): el número que se suma a la neurona antes de a pasarla por la función
de activación.
 El número de conexiones que entran a la capa (W): indica el número de
conexiones que entran en la capa. Como cada neurona está conectada con todas las
neuronas de la capa siguiente, el número de conexiones de una capa dependerá del
número de neuronas en la capa anterior y el número de neuronas en la capa actual.
 Función de activación dentro de la capa: indicando la “transformación” que
se aplicará a en las neuronas de esa capa. En este caso, todas las neuronas dentro de
la misma capa aplicarán la misma función de activación, aunque se podrán aplicar una
función diferente en cada capa.
Así pues, creamos una clase S4 que contenga estos elementos. Además,
aprovecharemos esta clase para inicializar los valores W y b de forma aleatoria,
usando la función runif.
Asimismo, deberemos programar las funciones de activación para poder usarlas
en la red neuronal. En este caso, usaremos dos tipos de funciones de activación:
función sigmoide y función relu.
Además, aprovecharemos estas funciones, no solo para que nos devuelvan el valor
de la función en sí, sino también su derivada. ¿Por qué? Pues porque las derivadas
son necesarias para calcular el descenso del gradiente.
Además, incluir los dos valores en la misma función es más sencillo a la hora de
programar. ¿Qué quieres el resultado de la función de activación? Eliges el primer
valor de la lista que devuelve. ¿Qué quieres la derivada? Eliges el segundo valor.
Así pues, empezamos programar con la función sigmoide, que es así:

Ahora solo nos queda programar la función relu, junto con su derivada, como hago a
continuación:
Por último, nos queda poner todo de forma conjunta para crear la estructura de la red
neuronal, es decir, las capas que conforman la red.
En nuestro caso, al haber creado la clase neurona, crearemos las capas de manera
iterativa. Así, esta misma forma de programar las neuronas nos servirá también para
otras redes neurionales con otra estructura.
Ahora que ya tenemos la estructura de la red neuronal, pero de momento esto nos
sirve de poco. Tenemos que entrenar a nuestra red neuronal, así que vamos a ello.
Programar una red neuronal en R: entrenando a la
red neuronal
El entrenamiento de una red neuronal tiene tres pasos:
 Front propagation: la red neuronal recibirá unos valores de entrada. Capa a
capa se irán haciendo unas operaciones hasta que la red nos devuelva un valor.
Seguramente, como la red no esté entrenada fallará más que una escopeta de feria,
por lo que habrá que ir haciendo ajustes, mediante los dos siguientes pasos:
 Back propagation: una vez hemos recibido el resultado, lo comparamos con el
resultado real. Esta comparación la hacemos aplicando una función de coste, lo cual
nos devolverá un error. Utilizaremos ese error para ir ajustando los valores de la red
neuronal hacia atrás: última capa, anteúltima, etc.
 Optimizamos la función de coste: a medida que se va propagando hacia
atrás, usamos una función de optimización (general
 mente el descenso del gradiente) para ir optimizando los parámetros b y W.
Así, la red irá mejorando en el entrenamiento poco a poco.
Hechas las introducciones, ¡vamos con la propagación hacia adelante!
Entrenando a la Red Neuronal: Propagación hacia adelante
A la hora de hacer la propagación hacia adelante, iremos guardando el resultado de
la neurona antes (a) y después de aplicar la función de activación (z). ¿Por qué?
Pues para tener los valores guardados para cuando hagamos la propagación hacia
atrás, más que nada.

Si ejecutamos la función, tendremos los valores predichos, como vemos a


continuación:
Pero claro, esta predicción… pues seguramente esté lejos de ser certera. Y es que,
tenemos que entrenar a nuestra red neuronal. Pero, ¿cómo sabemos cuánto falla?
Para eso existe la función de coste;)
Entrenando a la Red Neuronal: Función de Coste
La función de coste es una función que compara todas las predicciones con el valor
real para saber en qué medida nuestra red neuronal ha fallado y así poder ir
mejorándola.
En nuestro caso vamos a usar una función de coste muy típica: el error cuadrático
medio, que es el resultado de hacer la media de las diferencias entre el valor
predicho y el valor real elevados al cuadrado.
Esta es una función de coste típica que se usa en muchos algortimos, como la
regresión lineal. Básicamente la idea es que lo que falla el algoritmo es la distancia al
cuadrado entre los puntos predichos sobre el valor real.
¿Por qué la distancia al cuadrado? Pues para que los errores positivos (valor
predicho > valor real, es decir, te has “pasado” en la predicción) y los errores
negativos (te has quedado “corto” en la predicción) no se neutralicen entre ellos.
Al igual que hemos hecho con las funciones de activación, aprovecharemos la para
que la función de coste nos devuelva su derivada parcial, puesto que la
necesitaremos para el descenso del gradiente.

Ya tenemos nuestra función de coste para “juzgar” nuestra red neuronal programada
en R. Ahora, vamos a entrenarla.
Entrenando a la Red Neuronal: Back Propagation
En este caso, tenemos que hacer la propagación hacia atrás. Para ello, usaremos la
funciónrev, la cual devuelve el reverso del objeto que le pasemos, en nuestro caso,
la lista out, que son los resultados por capa del front propagation.
Ahora, en cada caso tendremos que calcular el error de la capa respecto al coste,
también conocido como la delta. Para calcular la delta respecto a la capa previa,
habría dos casos:
 En la última capa debemos multiplicar la derivada de la función de coste y el
resultado de la función de activación en la última capa.
 En las demás capas, debemos usar el error (delta) de la capa anterior, multiplicado
de forma matricial por el vector de pesos de la capa siguiente, para así moverlo
hacia atrás.

¡Backpropagation listo! Vamos ahora con el punto final: gradient descent.


Entrenando a la Red Neuronal: Gradient Descent
Por último, vamos a optimizar los parámetros de nuestra red mediante las deltas que
ya tenemos calculadas. Como gradient descent requiere pasar por cada capa para
optimizar los parámetros, vamos a aprovechar el pase hacia atrás que ya hemos
programado.
Así pues, lo que haremos será actualizar los valores de by W. Además, usaremos un
ratio conocido como learning Rate para determinar en cómo queremos que la red
entrene.
Sin embargo, el learning rate es algo sensible ya que si es muy pequeño, el
aprendizaje será más “seguro”, pero mucho más lento, mientras que si es muy alto,
puede que la función de activación no converja. Os dejo un enlace a un vídeo de
Deeplearning.ai donde Andrew Ng lo explica de forma muy clara.
En cualquier caso, la función de backpropagation quedaría así:
Juntando todo: entrenando a la red neuronal desde 0
Ya hemos programado la red neuronal desde 0 en R. Ahora queda lo mejor: ver
cómo funciona.
Para ello, lo primero que vamos a hacer es juntar la parte de front propagation con la
de backpropagation y gradient descent en una misma función:
Vamos a probar que nuestra función red neuronal funciona correctamente.

¡F
unciona! Ahora solo queda lo último. Iterar para que la red vaya aprendiendo.
Además, iremos mostrando el error de la red para ir viendo cómo va mejorando a
medida que pasa el tiempo.
Para ello, vamos a hacer 1000 iteraciones e ir calculando y guardando el error cada
20 iteraciones.

Y por último, visualizamos el error de nuestra red neuronal:


¡Funciona! Como véis, la red neuronal ha ido aprendiendo poco a poco hasta llegar a
las 750 iteraciones, donde ya ha dejado de aprender, porque la red ya está
optimizada.
Asi que esto es todo. Espero te haya servido y que hayas podido aprender nuevas
cosas. ¡Nos vemos en el próximo post!

También podría gustarte