A continuación los pasos para tener un inicio exitoso con Keras.
Lo primero que se debe hacer es instalar Python, para esto se recomienda seguir los pasos de este video.
Instalar el paquete devtools de R.
install.packages("devtools")
Instalar el paquete keras de R.
devtools::install_github("rstudio/keras")
La interfaz de Keras usa como motor TensorFlow asà que debemos instalarlo si aún no le tenemos. La función install_keras permite instalar Keras (de Python) y TensorFlow.
library(keras)
install_keras()
En este ejemplo se utilizará la base de datos Fashion MNIST que contiene imágenes de artÃculos de una tienda de moda online alemana llamada Zalando. Todas las imágenes son de 28 x 28 en escala de grises.
La base de datos está disponible dentro del paquete keras. Para acceder a la base de datos usamos:
library(keras)
dataset <- keras::dataset_fashion_mnist()
names(dataset)
## [1] "train" "test"
¿Qué hay dentro de dataset?
names(dataset)
## [1] "train" "test"
¿Qué hay dentro de dataset$train y dataset$test?
names(dataset$train)
## [1] "x" "y"
names(dataset$test)
## [1] "x" "y"
Vamos a crear los conjuntos de entrenamiento y de prueba.
x_train <- dataset$train$x
y_train <- dataset$train$y
x_test <- dataset$test$x
y_test <- dataset$test$y
y_true <- dataset$test$y # Esto para luego comparar
Veamos que tan grande es la base de datos de entrenamiento.
dim(x_train)
## [1] 60000 28 28
El objeto x_train es un arreglo de dimensión 60000, 28, 28. Eso significa que para el entrenamiento del modelo tenemos 60000 imagénes de 28 x 28. Para explorar la primer imágen se puede escribir View(x_train[1, , ]) en la consola de R y el resultado será algo muy similar a lo mostrado en la siguiente figura. Una matriz de 28 x 28 llena de números.
En la figura anterior se incluyó una silueta en color rojo para observar más fácil el artÃculo que está en la imagen, y se logra observar que se asemeja a la silueta de una bota. Ahora se dibujará la matriz en R para verificar el artÃculo que contiene.
im <- dataset$train$x[1 , ,] / 255
im <- 1 - t(apply(im, 2, rev))
image(x=1:28, y=1:28, z=im, col=gray((0:255)/255), xlab='')
Ahora vamos a ver los primeros 16 artÃculos de la base de datos de entrenamiento pero cambiando de colores para obtener un constraste.
# visualize the digits
par(mfcol=c(4, 4))
par(mar=c(0, 0, 3, 0), xaxs='i', yaxs='i')
for (j in 1:16) {
im <- x_train[j, , ]
im <- t(apply(im, 2, rev))
image(x=1:28, y=1:28, z=im, col=gray((0:255)/255),
xaxt='n', main=paste(y_train[j]))
}
En la matriz y_train encontramos las etiquetas correspondientes a cada imagen perteneciente a la base de datos de entrenamiento. Cada etiqueta representa un artÃculo de moda de la siguiente forma:
| Etiqueta | Clase |
|---|---|
| 0 | Camiseta/top |
| 1 | Pantalones |
| 2 | Pull-over |
| 3 | Vestido |
| 4 | Abrigo |
| 5 | Sandalias |
| 6 | Camisa |
| 7 | Zapatilla de deporte |
| 8 | Bolso |
| 9 | BotÃn |
Antes de construir el modelo, es necesario escalar los valores dentro de las matrices x_train y x_test en un rango de 0 a 1. Para lograrlo, se dividen estos valores por 255.
# rescale
x_train <- x_train / 255
x_test <- x_test / 255
Para definir el modelo se usa la función keras_model_sequential().
modelo <- keras_model_sequential()
Luego se deben agregar las capas. La primera capa de la red se encarga de transformar el formato de las imágenes de una arreglo bi-dimensional (28x28 pixeles) a un arreglo uni-dimensional (784 pixeles). Posteriormente, se encuentran dos capas completamente conectadas, la primera de 128 nodos o neuronas y la segunda de 10 nodos softmax, de tal forma que el modelo entregue un arreglo de 10 probabilidades que corresponden a la probabilidad de que una imagen pertenezca a una de las 10 clases.
Para agregar una capa se usa la función layer_dense(units, activation, input_shape). A continuación se muestra cómo se construye la red neuronal.
modelo %>%
layer_flatten(input_shape = c(28, 28)) %>%
layer_dense(units = 128) %>%
layer_activation('relu') %>%
layer_dense(units = 10) %>%
layer_activation('softmax')
Para observar un resumen del modelo creado se usa lo siguiente:
summary(modelo)
## Model: "sequential"
## ___________________________________________________________________________
## Layer (type) Output Shape Param #
## ===========================================================================
## flatten (Flatten) (None, 784) 0
## ___________________________________________________________________________
## dense (Dense) (None, 128) 100480
## ___________________________________________________________________________
## activation (Activation) (None, 128) 0
## ___________________________________________________________________________
## dense_1 (Dense) (None, 10) 1290
## ___________________________________________________________________________
## activation_1 (Activation) (None, 10) 0
## ===========================================================================
## Total params: 101,770
## Trainable params: 101,770
## Non-trainable params: 0
## ___________________________________________________________________________
¿De dónde salen los número de la tabla de arriba?
784 * 128 + 128.128 * 10 + 10.El siguiente paso consiste en compilar el modelo, para esto se usa la función compile(object, optimizer, loss, metrics). El argumento loss mide que tan exacto es el modelo en el proceso de entrenamiento, el argumento optimizer se refiere al oprtimizador que se desea utilizar para el entrenamiento de la red neuronal y el agumento metrics que monitorea el desempeño del modelo.
modelo %>% compile(
loss = 'sparse_categorical_crossentropy',
optimizer = 'adam',
metrics = c('accuracy')
)
Para entrenar el modelo se usa la función fit().
modelo %>% fit(x_train, y_train, epochs=50)
Evaluar el desempeño del modelo en los datos de prueba:
modelo %>% evaluate(x_test, y_test)
## $loss
## [1] 0.5110569
##
## $acc
## [1] 0.8875
Hacer predicciones con datos nuevos:
prediccion <- modelo %>% predict_classes(x_test)
tabla_confusion <- table(prediccion, y_true)
tabla_confusion
## y_true
## prediccion 0 1 2 3 4 5 6 7 8 9
## 0 859 4 24 33 0 0 124 0 5 0
## 1 2 970 0 5 0 0 2 0 0 0
## 2 13 0 778 11 63 0 78 0 5 0
## 3 16 14 12 869 23 1 25 0 4 0
## 4 2 4 119 39 862 0 81 0 4 0
## 5 0 0 0 0 0 958 0 10 3 5
## 6 97 3 63 35 48 0 680 0 5 1
## 7 1 1 0 0 1 23 0 962 5 26
## 8 10 2 4 7 2 1 9 0 969 0
## 9 0 2 0 1 1 17 1 28 0 968
sum(diag(tabla_confusion)) / sum(tabla_confusion)
## [1] 0.8875
Haciendo una predicción para las primeras i=5 imagenes.
i <- 5
modelo %>% predict_classes(x_test[1:i, ,]) # prediccion
## [1] 9 2 1 1 6
y_true[1:i] # real
## [1] 9 2 1 1 6
En esta sección vamos a probar el clasificador usando fotos de artÃculos de nuestro armario. En la siguiente figura se presenta una una foto de una camisa que fue editada y que tiene un tamaño de 28 por 28 pixeles.
Ahora vamos a cargar y a dibujar esta imagen en R de la siguiente forma:
library(png)
imagen <- readPNG("camisa14.png")
#Gráfica imagen
prenda <- abs(1-imagen)
im <- 1-t(apply(prenda,2,rev))
image(1:28, 1:28, im, col=gray((0:255)/255))
Finalmente, vamos a predecir el tipo de artÃculo de la imagen usando el clasificador construido.
#Transformación de matriz imagenfinal en arreglo
imagenreshape <- array_reshape(im, c(1,28, 28))
#Predicción
prediccion <- modelo %>% predict(imagenreshape)
predclase <- modelo %>% predict_classes(imagenreshape)
predclase
## [1] 0
Del resultado anterior se observa que según el clasificador, la prenda pertenece a la etiqueta 0 que corresponde a camiseta.