1 Primeros pasos

A continuación los pasos para tener un inicio exitoso con Keras.

1.1 Instalar Python

Lo primero que se debe hacer es instalar Python, para esto se recomienda seguir los pasos de este video.

1.2 Instalar Keras

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()

2 Base de datos Fashion MNIST

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


3 Preparar los datos

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

4 Definir el modelo

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?

  • El 100480 se obtiene de la operación 784 * 128 + 128.
  • El 1290 se obtiene de la operación 128 * 10 + 10.

5 Compilar el modelo

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')
)

6 Entrenar el modelo

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

7 Pruebas con artículos de nuestro armario

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.


Ahora es tu turno, toma una foto de una prenda de tu armario y prueba el clasificador.