Cargamos las librerías necesarias.
library(keras)
library(tensorflow)
library(dplyr)##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
library(purrr)
library(magrittr)##
## Attaching package: 'magrittr'
## The following object is masked from 'package:purrr':
##
## set_names
Cargamos y adaptamos la base de datos.
mnist <- dataset_fashion_mnist()
x_train <- mnist$train$x
g_train <- mnist$train$y
x_test <- mnist$test$x
g_test <- mnist$test$yTal como podemos observar, hay 60 000 imágenes en los datos de entrenamiento y 10 000 en los datos de prueba. Las imágenes son de 28 × 28 y se almacenan como una matriz tridimensional, por lo que debemos remodelarlas en una matriz. Además, necesitamos codificar one-hot la etiqueta de clase.
dim(x_train)## [1] 60000 28 28
dim(x_test)## [1] 10000 28 28
Tal como describe el manual, las redes neuronales son algo sensibles a la escala de las entradas. Por ejemplo, la regularización de la cresta y el lazo se ven afectadas por la escala. Aquí las entradas son valores de escala de grises de ocho bits 26 entre 0 y 255, por lo que cambiamos la escala al intervalo unitario.
x_train <- array_reshape(x_train, c(nrow(x_train), 784))
x_test <- array_reshape(x_test, c(nrow(x_test), 784))
y_train <- to_categorical(g_train, 10)
y_test <- to_categorical(g_test, 10)
x_train <- x_train / 255
x_test <- x_test / 255Ahora ya podemos adaptar nuestra red neuronal
modelnn <- keras_model_sequential()
modelnn %>%
layer_dense(units = 256, activation = "relu",
input_shape = c(784)) %>%
layer_dropout(rate = 0.4) %>%
layer_dense(units = 128, activation = "relu") %>%
layer_dropout(rate = 0.3) %>%
layer_dense(units = 10, activation = "softmax")La primera capa va de 28 × 28 = 784 unidades de entrada a una capa oculta de 256 unidades, que utiliza la función de activación de ReLU. Esto se especifica mediante layer_dense(), que toma como entrada un objeto modelnn y devuelve otro objeto modelnn modificado. Luego, esto se canaliza a través de la eliminación de layer dropout() para realizar la regularización de la eliminación. La segunda capa oculta viene a continuación, con 128 unidades ocultas, seguida de una capa de abandono. La capa final es la capa de salida, con activación “softmax” para el problema de clasificación de 10 clases, que define el mapa desde la segunda capa oculta hasta las probabilidades de clase.
Finalmente, usamos summary() para resumir el modelo y para asegurarnos de que lo hicimos bien.
summary(modelnn)## Model: "sequential"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_2 (Dense) (None, 256) 200960
## dropout_1 (Dropout) (None, 256) 0
## dense_1 (Dense) (None, 128) 32896
## dropout (Dropout) (None, 128) 0
## dense (Dense) (None, 10) 1290
## ================================================================================
## Total params: 235,146
## Trainable params: 235,146
## Non-trainable params: 0
## ________________________________________________________________________________
Como podemos observar, los parámetros de cada capa incluyen un término de sesgo, lo que resulta en un recuento de 235,146 parámetros. Por ejemplo, la primera capa oculta implica (784 + 1) × 256 = 200,960 parámetros.
A continuación, añadimos detalles al modelo para especificar el algoritmo de ajuste.
modelnn %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))El último paso es proporcionar datos de entrenamiento y ajustar el modelo. Así podremos ver también el informe de progreso sobre el ajuste del modelo, agrupado por época
system.time(history <- modelnn %>%
fit(x_train, y_train, epochs = 30, batch_size = 128,
validation_split = 0.2))## user system elapsed
## 144.26 3.84 46.86
En la siguiente figura vemos resumido el informe de progreso sobre el ajuste del modelo, agrupado por época.
plot(history, smooth = FALSE)plot1 <-plot(history, smooth = FALSE) Para obtener el error de prueba , primero escribimos la función accuracy() que compara las etiquetas de clase predichas y verdaderas, y luego la usamos para evaluar nuestras predicciones.
accuracy <- function(pred, truth)
mean(drop(as.numeric(pred)) == drop(truth))
modelnn %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8804
La tabla también muestra un Análisis Discriminante Lineal (LDA) y regresión logística multiclase
modellr <- keras_model_sequential() %>%
layer_dense(input_shape = 784, units = 10,
activation = "softmax")
summary(modellr)## Model: "sequential_1"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_3 (Dense) (None, 10) 7850
## ================================================================================
## Total params: 7,850
## Trainable params: 7,850
## Non-trainable params: 0
## ________________________________________________________________________________
Ajustamos el modelo tal como lo hicimos anteriormente.
modellr %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))
modellr %>% fit(x_train, y_train, epochs = 30,
batch_size = 128, validation_split = 0.2)
modellr %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8453
modelnn2 <- keras_model_sequential()
modelnn2 %>%
layer_dense(units = 256, activation = "sigmoid",
input_shape = c(784)) %>%
layer_dropout(rate = 0.4) %>%
layer_dense(units = 128, activation = "sigmoid") %>%
layer_dropout(rate = 0.3) %>%
layer_dense(units = 10, activation = "sigmoid")En esta segunda red, a primera capa va de 28 × 28 = 784 unidades de entrada a una capa oculta de 256 unidades, que utiliza la función de activación de sigmoid. Esto se especifica mediante layer_dense(), que toma como entrada un objeto modelnn y devuelve otro objeto modelnn modificado. Luego, esto se canaliza a través de la eliminación de layer dropout() para realizar la regularización de la eliminación. La segunda capa oculta viene a continuación, con 128 unidades ocultas, seguida de una capa de abandono. La capa final es la capa de salida, con activación sigmoid para el problema de clasificación de 10 clases, que define el mapa desde la segunda capa oculta hasta las probabilidades de clase.
La primera capa va de 28 × 28 = 784 unidades de entrada a una capa oculta de 128 unidades, que utiliza la función de activación de sigmoid. Esto se especifica mediante layer_dense(), que toma como entrada un objeto modelnn y devuelve otro objeto modelnn modificado. Luego, esto se canaliza a través de la eliminación de layer dropout() de 0.2 para realizar la regularización de la eliminación. La segunda capa oculta viene a continuación, con 128 unidades ocultas, seguida de una capa de abandono. La capa final es la capa de salida, con activación “sigmoid” para el problema de clasificación de 5 clases, que define el mapa desde la segunda capa oculta hasta las probabilidades de clase.
Finalmente, usamos summary() para resumir el modelo y para asegurarnos de que lo hicimos bien.
summary(modelnn2)## Model: "sequential_2"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_6 (Dense) (None, 256) 200960
## dropout_3 (Dropout) (None, 256) 0
## dense_5 (Dense) (None, 128) 32896
## dropout_2 (Dropout) (None, 128) 0
## dense_4 (Dense) (None, 10) 1290
## ================================================================================
## Total params: 235,146
## Trainable params: 235,146
## Non-trainable params: 0
## ________________________________________________________________________________
Como podemos observar, Los parámetros de cada capa incluyen un término de sesgo, lo que resulta en un recuento de 109,061 parámetros. Por ejemplo, la primera capa oculta implica (784 + 1) × 128 = 200,960 parámetros.
A continuación, añadimos detalles al modelo para especificar el algoritmo de ajuste.
modelnn2 %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))El último paso es proporcionar datos de entrenamiento y ajustar el modelo. Así podremo ver también el informe de progreso sobre el ajuste del modelo, agrupado por época
system.time(history <- modelnn2 %>%
fit(x_train, y_train, epochs = 30, batch_size = 128,
validation_split = 0.2))## user system elapsed
## 151.12 3.89 47.69
En la siguiente figura vemos resumido el informe de progreso sobre el ajuste del modelo, agrupado por época.
plot(history, smooth = FALSE)plot2 <-plot(history, smooth = FALSE)Para obtener el error de prueba , primero escribimos la función accuracy() que compara las etiquetas de clase predichas y verdaderas, y luego la usamos para evaluar nuestras predicciones.
accuracy <- function(pred, truth)
mean(drop(as.numeric(pred)) == drop(truth))
modelnn2 %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8815
La tabla también muestra un Análisis Discriminante Lineal (LDA) y regresión logística multiclase
modellr <- keras_model_sequential() %>%
layer_dense(input_shape = 784, units = 10,
activation = "softmax")
summary(modellr)## Model: "sequential_3"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_7 (Dense) (None, 10) 7850
## ================================================================================
## Total params: 7,850
## Trainable params: 7,850
## Non-trainable params: 0
## ________________________________________________________________________________
Ajustamos el modelo tal como lo hicimos anteriormente.
modellr %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))
modellr %>% fit(x_train, y_train, epochs = 30,
batch_size = 128, validation_split = 0.2)
modellr %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8469
A continuación realizamos la tercera red neuronal
modelnn3 <- keras_model_sequential()
modelnn3 %>%
layer_dense(units = 512, activation = "softplus",
input_shape = c(784)) %>%
layer_dropout(rate = 0.8) %>%
layer_dense(units = 256, activation = "softplus") %>%
layer_dropout(rate = 0.3) %>%
layer_dense(units = 10, activation = "softplus")La primera capa va de 28 × 28 = 784 unidades de entrada a una capa oculta de 512 unidades, que utiliza la función de activación de softplus. Esto se especifica mediante layer_dense(), que toma como entrada un objeto modelnn y devuelve otro objeto modelnn modificado. Luego, esto se canaliza a través de la eliminación de layer dropout() para realizar la regularización de la eliminación. La segunda capa oculta viene a continuación, con 256 unidades ocultas, seguida de una capa de abandono. La capa final es la capa de salida, con activación “softplus” para el problema de clasificación de 10 clases, que define el mapa desde la segunda capa oculta hasta las probabilidades de clase.
Finalmente, usamos summary() para resumir el modelo y para asegurarnos de que lo hicimos bien.
summary(modelnn3)## Model: "sequential_4"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_10 (Dense) (None, 512) 401920
## dropout_5 (Dropout) (None, 512) 0
## dense_9 (Dense) (None, 256) 131328
## dropout_4 (Dropout) (None, 256) 0
## dense_8 (Dense) (None, 10) 2570
## ================================================================================
## Total params: 535,818
## Trainable params: 535,818
## Non-trainable params: 0
## ________________________________________________________________________________
Como podemos observar, Los parámetros de cada capa incluyen un término de sesgo, lo que resulta en un recuento de 538,388 parámetros. Por ejemplo, la primera capa oculta implica (784 + 1) × 512 = 401,920 parámetros.
A continuación, añadimos detalles al modelo para especificar el algoritmo de ajuste.
modelnn3 %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))El último paso es proporcionar datos de entrenamiento y ajustar el modelo. Así podremo ver también el informe de progreso sobre el ajuste del modelo, agrupado por época
system.time(history <- modelnn3 %>%
fit(x_train, y_train, epochs = 10, batch_size = 256,
validation_split = 0.2))## user system elapsed
## 96.19 26.64 26.64
En la siguiente figura vemos resumido el informe de progreso sobre el ajuste del modelo, agrupado por época.
plot(history, smooth = FALSE)plot3 <- plot(history, smooth = FALSE)Para obtener el error de prueba , primero escribimos la función accuracy() que compara las etiquetas de clase predichas y verdaderas, y luego la usamos para evaluar nuestras predicciones.
accuracy <- function(pred, truth)
mean(drop(as.numeric(pred)) == drop(truth))
modelnn3 %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8435
La tabla también muestra un Análisis Discriminante Lineal (LDA) y regresión logística multiclase
modellr <- keras_model_sequential() %>%
layer_dense(input_shape = 784, units = 10,
activation = "softmax")
summary(modellr)## Model: "sequential_5"
## ________________________________________________________________________________
## Layer (type) Output Shape Param #
## ================================================================================
## dense_11 (Dense) (None, 10) 7850
## ================================================================================
## Total params: 7,850
## Trainable params: 7,850
## Non-trainable params: 0
## ________________________________________________________________________________
Ajustamos el modelo tal como lo hicimos anteriormente.
modellr %>% compile(loss = "categorical_crossentropy",
optimizer = optimizer_rmsprop(), metrics = c("accuracy"))
modellr %>% fit(x_train, y_train, epochs = 30,
batch_size = 128, validation_split = 0.2)
modellr %>% predict(x_test) %>% k_argmax() %>% accuracy(g_test)## [1] 0.8462
Tal como podemos observar en la tabla siguiente, al cambiar el método de activación (diferencia entre la primera y la segunda red) disminuye el error de prueba y aumenta el ajuste del modelo. Al cambiar tanto el método de activación los parámetros referidos al número de capas, el valor de units y el dropout de cada capa, se produce un cambio más sustancial, aumentando el número de parámetros, la primera capa oculta y el ajuste de modelo, aunque disminuye el error de prueba.
| Número de parámetros | Primera capa oculta | Error de pruba | Parámetros LDA | Ajuste del modelo | |
|---|---|---|---|---|---|
| Primera red neuronal | 235,146 | 200,960 | 0.882 | 7,850 | 0.843 |
| Segunda red neuronal | 235,146 | 200,960 | 0.8809 | 7,850 | 0.8441 |
| Tercera red neuronal | 535,818 | 401,920 | 0.8435 | 7,850 | 0.846 |
Por último, a modo de resumne, incluimos las figuras donde vemos resumido el informe de progreso sobre el ajuste del modelo, agrupado por época de cada una de las tres redes.
par(mfrow = c(1,3))
plot1plot2plot3