.

library(tensorflow)
library(keras)
cifar <- dataset_cifar10()
class_names <- c('airplane', 'automobile', 'bird', 'cat', 'deer',
               'dog', 'frog', 'horse', 'ship', 'truck')
index <- 1:30
par(mfcol = c(5,6), mar = rep(1, 4), oma = rep(0.2, 4))
cifar$train$x[index,,,] %>% 
  purrr::array_tree(1) %>%
  purrr::set_names(class_names[cifar$train$y[index] + 1]) %>% 
  purrr::map(as.raster, max = 255) %>%
  purrr::iwalk(~{plot(.x); title(.y)})

model <- keras_model_sequential() %>% 
  layer_conv_2d(filters = 32, kernel_size = c(3,3), activation = "relu", 
                input_shape = c(32,32,3)) %>% 
  layer_max_pooling_2d(pool_size = c(2,2)) %>% 
  layer_conv_2d(filters = 64, kernel_size = c(3,3), activation = "relu") %>% 
  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_conv_2d(filters = 64, kernel_size = c(3,3), activation = "relu")
model %>% 
  layer_flatten() %>% 
  layer_dense(units = 64, activation = "relu") %>% 
  layer_dense(units = 10, activation = "softmax")
model %>% compile(
  optimizer = "adam",
  loss = "sparse_categorical_crossentropy",
  metrics = "accuracy"
)
history <- model %>% 
  fit(
    x = cifar$train$x, y = cifar$train$y,
    epochs = 20,
    batch_size = 2048, validation_split = 0.2,
    #validation_data = unname(cifar$test),
    verbose = 2
  )
Train on 40000 samples, validate on 10000 samples
Epoch 1/20
 - 3s - loss: 14.1008 - acc: 0.1040 - val_loss: 13.9567 - val_acc: 0.1114
Epoch 2/20
 - 2s - loss: 13.8353 - acc: 0.1117 - val_loss: 13.5708 - val_acc: 0.1125
Epoch 3/20
 - 2s - loss: 13.2778 - acc: 0.1156 - val_loss: 13.1787 - val_acc: 0.1079
Epoch 4/20
 - 2s - loss: 13.0358 - acc: 0.1199 - val_loss: 13.1141 - val_acc: 0.1199
Epoch 5/20
 - 2s - loss: 13.0067 - acc: 0.1296 - val_loss: 13.1017 - val_acc: 0.1260
Epoch 6/20
 - 2s - loss: 12.1693 - acc: 0.1333 - val_loss: 2.6650 - val_acc: 0.1096
Epoch 7/20
 - 2s - loss: 2.1910 - acc: 0.1987 - val_loss: 1.8873 - val_acc: 0.3049
Epoch 8/20
 - 2s - loss: 1.7768 - acc: 0.3458 - val_loss: 1.6561 - val_acc: 0.3962
Epoch 9/20
 - 2s - loss: 1.5835 - acc: 0.4229 - val_loss: 1.5444 - val_acc: 0.4392
Epoch 10/20
 - 2s - loss: 1.4765 - acc: 0.4636 - val_loss: 1.4720 - val_acc: 0.4673
Epoch 11/20
 - 2s - loss: 1.4007 - acc: 0.4945 - val_loss: 1.4132 - val_acc: 0.4943
Epoch 12/20
 - 2s - loss: 1.3333 - acc: 0.5232 - val_loss: 1.3811 - val_acc: 0.5135
Epoch 13/20
 - 2s - loss: 1.2844 - acc: 0.5421 - val_loss: 1.3450 - val_acc: 0.5261
Epoch 14/20
 - 2s - loss: 1.2531 - acc: 0.5547 - val_loss: 1.3100 - val_acc: 0.5402
Epoch 15/20
 - 2s - loss: 1.2160 - acc: 0.5685 - val_loss: 1.2805 - val_acc: 0.5471
Epoch 16/20
 - 2s - loss: 1.1694 - acc: 0.5856 - val_loss: 1.2569 - val_acc: 0.5562
Epoch 17/20
 - 2s - loss: 1.1318 - acc: 0.5979 - val_loss: 1.2384 - val_acc: 0.5681
Epoch 18/20
 - 2s - loss: 1.1037 - acc: 0.6120 - val_loss: 1.2145 - val_acc: 0.5761
Epoch 19/20
 - 2s - loss: 1.0989 - acc: 0.6142 - val_loss: 1.2022 - val_acc: 0.5813
Epoch 20/20
 - 2s - loss: 1.0463 - acc: 0.6313 - val_loss: 1.2448 - val_acc: 0.5700

Results with Dropout

plot(history)+ggdark::dark_theme_bw()
Inverted geom defaults of fill and color/colour.
To change them back, use invert_geom_defaults().

Results without Dropout

LS0tCnRpdGxlOiAiRHJvcG91dCBwcm9ibGVtcyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQouCmBgYHtyfQpsaWJyYXJ5KHRlbnNvcmZsb3cpCmxpYnJhcnkoa2VyYXMpCmNpZmFyIDwtIGRhdGFzZXRfY2lmYXIxMCgpCmBgYApgYGB7cn0KY2xhc3NfbmFtZXMgPC0gYygnYWlycGxhbmUnLCAnYXV0b21vYmlsZScsICdiaXJkJywgJ2NhdCcsICdkZWVyJywKICAgICAgICAgICAgICAgJ2RvZycsICdmcm9nJywgJ2hvcnNlJywgJ3NoaXAnLCAndHJ1Y2snKQoKaW5kZXggPC0gMTozMAoKcGFyKG1mY29sID0gYyg1LDYpLCBtYXIgPSByZXAoMSwgNCksIG9tYSA9IHJlcCgwLjIsIDQpKQpjaWZhciR0cmFpbiR4W2luZGV4LCwsXSAlPiUgCiAgcHVycnI6OmFycmF5X3RyZWUoMSkgJT4lCiAgcHVycnI6OnNldF9uYW1lcyhjbGFzc19uYW1lc1tjaWZhciR0cmFpbiR5W2luZGV4XSArIDFdKSAlPiUgCiAgcHVycnI6Om1hcChhcy5yYXN0ZXIsIG1heCA9IDI1NSkgJT4lCiAgcHVycnI6Oml3YWxrKH57cGxvdCgueCk7IHRpdGxlKC55KX0pCmBgYApgYGB7cn0KbW9kZWwgPC0ga2VyYXNfbW9kZWxfc2VxdWVudGlhbCgpICU+JSAKICBsYXllcl9jb252XzJkKGZpbHRlcnMgPSAzMiwga2VybmVsX3NpemUgPSBjKDMsMyksIGFjdGl2YXRpb24gPSAicmVsdSIsIAogICAgICAgICAgICAgICAgaW5wdXRfc2hhcGUgPSBjKDMyLDMyLDMpKSAlPiUgCiAgbGF5ZXJfbWF4X3Bvb2xpbmdfMmQocG9vbF9zaXplID0gYygyLDIpKSAlPiUgCiAgbGF5ZXJfY29udl8yZChmaWx0ZXJzID0gNjQsIGtlcm5lbF9zaXplID0gYygzLDMpLCBhY3RpdmF0aW9uID0gInJlbHUiKSAlPiUgCiAgbGF5ZXJfbWF4X3Bvb2xpbmdfMmQocG9vbF9zaXplID0gYygyLDIpKSAlPiUgbGF5ZXJfZHJvcG91dCgwLjUpICU+JQogIGxheWVyX2NvbnZfMmQoZmlsdGVycyA9IDY0LCBrZXJuZWxfc2l6ZSA9IGMoMywzKSwgYWN0aXZhdGlvbiA9ICJyZWx1IikKCm1vZGVsICU+JSAKICBsYXllcl9mbGF0dGVuKCkgJT4lIAogIGxheWVyX2RlbnNlKHVuaXRzID0gNjQsIGFjdGl2YXRpb24gPSAicmVsdSIpICU+JSAKICBsYXllcl9kZW5zZSh1bml0cyA9IDEwLCBhY3RpdmF0aW9uID0gInNvZnRtYXgiKQpgYGAKCmBgYHtyfQptb2RlbCAlPiUgY29tcGlsZSgKICBvcHRpbWl6ZXIgPSAiYWRhbSIsCiAgbG9zcyA9ICJzcGFyc2VfY2F0ZWdvcmljYWxfY3Jvc3NlbnRyb3B5IiwKICBtZXRyaWNzID0gImFjY3VyYWN5IgopCgpoaXN0b3J5IDwtIG1vZGVsICU+JSAKICBmaXQoCiAgICB4ID0gY2lmYXIkdHJhaW4keCwgeSA9IGNpZmFyJHRyYWluJHksCiAgICBlcG9jaHMgPSAyMCwKICAgIGJhdGNoX3NpemUgPSAyMDQ4LCB2YWxpZGF0aW9uX3NwbGl0ID0gMC4yLAogICAgI3ZhbGlkYXRpb25fZGF0YSA9IHVubmFtZShjaWZhciR0ZXN0KSwKICAgIHZlcmJvc2UgPSAyCiAgKQpgYGAKCiMjIyBSZXN1bHRzIHdpdGggRHJvcG91dApgYGB7cn0KcGxvdChoaXN0b3J5KStnZ2Rhcms6OmRhcmtfdGhlbWVfYncoKQpgYGAKCiMjIyBSZXN1bHRzIHdpdGhvdXQgRHJvcG91dApgYGB7cn0KcGxvdChoaXN0b3J5KStnZ2Rhcms6OmRhcmtfdGhlbWVfYncoKQpgYGAKCg==