---
title: "Introduction to deep networks (keras)"
output:
html_document:
df_print: paged
---
### What do we need
```{r}
library(magrittr)
library(keras)
```
Installing keras requires
- **Python** (2 for CPU, 3 for GPU).
- A virtual environment (virtualenv, anaconda)
- Tensorflow is the default option
```{r eval = FALSE}
install_keras(tensorflow = "default")
```
- Recommended R package: `magrittr`
### A MNIST example
- The MNIST database is a large database of handwritten digits that is commonly used for training various image processing systems.
- Handwritten digits are stored as squared matrices of size 28 by 28 (784) pixels. Each pixel has 256 values.
```{r}
mnist <- dataset_mnist()
x_train <- mnist$train$x
y_train <- mnist$train$y
x_test <- mnist$test$x
y_test <- mnist$test$y
```
- **Question:** Discriminate digit 7 ($y = 1$) from digit 2 ($y = 0$)
```{r}
# extract digits 2 and 7 from MNIST and build some training data
boo_train <- y_train == 2 | y_train == 7
x_train <- mnist$train$x[boo_train,,]
y_train <- mnist$train$y[boo_train]
# same for test data
boo_test <- y_test == 2 | y_test == 7
x_test <- mnist$test$x[boo_test,,]
y_test <- mnist$test$y[boo_test]
```
- Most "7" images look like this one (Note that french people write them differently).
```{r fig.align = "center"}
image(t(x_test[1, 28:1,]), col = grey.colors(5))
```
- We need to flatten the images (= convert them as vectors) and to rescale their values
```{r}
# Flattening
x_train <- array_reshape(x_train,
c(nrow(x_train),
784))
x_test <- array_reshape(x_test,
c(nrow(x_test),
784))
# Rescaling
x_train <- x_train/255
x_test <- x_test/255
```
- Convert the labels {2,7} into binary values
```{r}
y_train <- as.numeric(y_train == 7)
y_test <- as.numeric(y_test == 7)
```
### Building models with keras
- It is based on functional programming. Consider a single hidden layer with 128 neurons. Half of the units are dropped out during an epoch.
```{r}
model <- keras_model_sequential()
model %>%
layer_dense(units = 128,
activation = 'relu',
input_shape = 784) %>%
layer_dropout(rate = 0.5) %>%
layer_dense(units = 1,
activation = 'sigmoid')
```
- Compiling models with keras. We need to specify a loss function and a minimization method
```{r}
model %>% compile(
loss = 'binary_crossentropy',
optimizer = optimizer_sgd(lr = 0.01,
decay = 0.001),
metrics = c('accuracy')
)
```
- Fitting our neural network model
```{r}
set.seed(110101011)
history <- model %>%
fit(x_train,
y_train,
epochs = 20,
batch_size = 100,
validation_data = list(x_test, y_test),
verbose = 1
)
```
### Evaluating the results
- Log-loss and accuracy
```{r}
model %>% evaluate(x_test, y_test)
```
- Confusion matrix
```{r}
pred_class <- model %>%
predict_classes(x_test)
table(predicted = pred_class,
observed = mnist$test$y[boo_test])
```
- Let see an example of a true "two" misclassified as a "seven".
```{r fig.align = "center"}
false_positive <- which(mnist$test$y[boo_test] == 7 & pred_class[,1] == 0)
x_test[false_positive[1],] %>% matrix(nrow = 28) %>% .[,28:1] %>% image(col = grey.colors(5))
```
### For fun: using pretrained models
- Using pretrained model is one of the most common applications of DL.
```{r}
pretrained_model = application_resnet50(weights = 'imagenet')
```
Let's consider our misclassified example.
```{r}
img <- mnist$test$x[false_positive[3],,]
x <- array(NA, c(1,28,28,3))
x[1, , ,1:3] <- img
x <- image_array_resize(x, 224, 224)
x <- imagenet_preprocess_input(x)
```
And see it's prediction in Imagenet (yes, that's n'imp)
```{r}
pred <- pretrained_model %>% predict(x)
imagenet_decode_predictions(pred, top = 4)[[1]]
```