Photo by rawpixel on Unsplash

Deep Learning with R

Photo by rawpixel on Unsplash

Deep Learning with R

Deep Learning has gained much attention for applications in image recognition and natural language processing showing impressively how perfomance in predictive modeling has improved. This quick example is taken from https://tensorflow.rstudio.com/keras/articles/tutorial_basic_classification.html. It shows how a neural network model is trained to classify Zalando’s article images (from the Fashion MNIST dataset).

Import the Fashion MNIST dataset

library(keras)

fashion_mnist <- dataset_fashion_mnist()

c(train_images, train_labels) %<-% fashion_mnist$train
c(test_images, test_labels) %<-% fashion_mnist$test

class_names = c('T-shirt/top',
                'Trouser',
                'Pullover',
                'Dress',
                'Coat', 
                'Sandal',
                'Shirt',
                'Sneaker',
                'Bag',
                'Ankle boot')

Explore the data

dim(train_images)
## [1] 60000    28    28
dim(train_labels)
## [1] 60000

Preprocess the data

library(tidyr)
library(ggplot2)

image_2 <- as.data.frame(train_images[2, , ])
colnames(image_2) <- seq_len(ncol(image_2))
image_2$y <- seq_len(nrow(image_2))
image_2 <- gather(image_2, "x", "value", -y)
image_2$x <- as.integer(image_2$x)

ggplot(image_2, aes(x = x, y = y, fill = value)) +
  geom_tile() +
  scale_fill_gradient(low = "white", high = "black", na.value = NA) +
  scale_y_reverse() +
  theme_minimal() +
  theme(panel.grid = element_blank())   +
  theme(aspect.ratio = 1) +
  xlab("") +
  ylab("")

train_images <- train_images / 255
test_images <- test_images / 255

par(mfcol=c(5,5))
par(mar=c(0, 0, 1.5, 0), xaxs='i', yaxs='i')
for (i in 1:25) { 
  img <- train_images[i, , ]
  img <- t(apply(img, 2, rev)) 
  image(1:28, 1:28, img, col = gray((0:255)/255), xaxt = 'n', yaxt = 'n',
        main = paste(class_names[train_labels[i] + 1]))
}
Some training images including their labels.

Figure 1: Some training images including their labels.

Setup the layers

model <- keras_model_sequential()
model %>%
  layer_flatten(input_shape = c(28, 28)) %>%
  layer_dense(units = 128, activation = 'relu') %>%
  layer_dense(units = 10, activation = 'softmax')

Compile the model

model %>% compile(
  optimizer = 'adam', 
  loss = 'sparse_categorical_crossentropy',
  metrics = c('accuracy')
)

Train the model

model %>% fit(train_images, train_labels, epochs = 5)

Evaluate accuracy

score <- model %>% evaluate(test_images, test_labels)

cat('Test loss:', score$loss, "\n")
## Test loss: 0.3735976
cat('Test accuracy:', score$acc, "\n")
## Test accuracy: 0.8655

Make predictions

predictions <- model %>% predict(test_images)

predictions[1, ]
##  [1] 1.990804e-07 1.413461e-08 3.993884e-08 1.008204e-07 9.269143e-08
##  [6] 2.593302e-04 5.936351e-07 2.583972e-03 3.131969e-07 9.971553e-01
which.max(predictions[1, ])
## [1] 10
class_pred <- model %>% predict_classes(test_images)
class_pred[1:20]
##  [1] 9 2 1 1 6 1 4 6 5 7 4 5 5 3 4 1 2 2 8 0
test_labels[1]
## [1] 9
par(mfcol=c(5,5))
par(mar=c(0, 0, 1.5, 0), xaxs='i', yaxs='i')
for (i in 1:25) { 
  img <- test_images[i, , ]
  img <- t(apply(img, 2, rev)) 
  # subtract 1 as labels go from 0 to 9
  predicted_label <- which.max(predictions[i, ]) - 1
  true_label <- test_labels[i]
  if (predicted_label == true_label) {
    color <- '#008800' 
  } else {
    color <- '#bb0000'
  }
  image(1:28, 1:28, img, col = gray((0:255)/255), xaxt = 'n', yaxt = 'n',
        main = paste0(class_names[predicted_label + 1], " (",
                      class_names[true_label + 1], ")"),
        col.main = color)
}
Predicted labels from the trained model.

Figure 2: Predicted labels from the trained model.

# Grab an image from the test dataset
# take care to keep the batch dimension, as this is expected by the model
img <- test_images[1, , , drop = FALSE]
dim(img)
## [1]  1 28 28
predictions <- model %>% predict(img)
predictions
##              [,1]         [,2]         [,3]         [,4]         [,5]
## [1,] 1.990806e-07 1.413458e-08 3.993884e-08 1.008204e-07 9.269125e-08
##            [,6]         [,7]        [,8]         [,9]     [,10]
## [1,] 0.00025933 5.936351e-07 0.002583971 3.131966e-07 0.9971553
# subtract 1 as labels are 0-based
prediction <- predictions[1, ] - 1
which.max(prediction)
## [1] 10
class_pred <- model %>% predict_classes(img)
class_pred
## [1] 9
Johannes Johow
(Dr. rer. nat., Dipl.-Biol.)