A base de dados utilizada para o programa está dísponível por meio do link: https://www.kaggle.com/c/digit-recognizer/leaderboard. Os arquivos de dados train.csv e test.csv contêm uma série de números desenhados, sendo eles de 1 à 9. Cada imagem tem uma certa quantidade de pixel, e o código em questão deverá analisar percorrer linhas e colunas de pixels de uma imagem preenchida por números com a finalidade de mostrar quais números em questão estão presentes.
#Loading Libraries
library(tidyverse)
## -- Attaching packages ------------------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.1 v purrr 0.3.3
## v tibble 2.1.3 v dplyr 0.8.3
## v tidyr 1.0.0 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.4.0
## -- Conflicts ---------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(keras)
library("magick")
## Linking to ImageMagick 6.9.9.14
## Enabled features: cairo, freetype, fftw, ghostscript, lcms, pango, rsvg, webp
## Disabled features: fontconfig, x11
Na primeira parte, observamos que estão sendo carregados os pacotes necessários para o funcionamento do programa.
img <- image_read("D:/Users/Usuario/Downloads/RedesNeuraisDigit.jpg")
img
img28x28 <- img %>% image_scale(geometry = 28)
img28x28
img_dados <- image_data(img28x28, channels = "gray")
img_num <- img_dados %>% as.numeric()
img_num2 <- img_num[,,1]
image(img_num2)
imgD2 <- image_read("D:/Users/Usuario/Downloads/RedesNeuraisDigit.jpg") %>%
image_scale(geometry = "28x28") %>%
image_data(channels = "gray") %>%
.[1,,] %>%
as.numeric()
imgD2 %>% matrix(nrow = 28, byrow = TRUE) %>%
image()
imgD2neg <- 1-imgD2
imgD2 <- image_read("D:/Users/Usuario/Downloads/RedesNeuraisDigit.jpg") %>%
image_scale(geometry = "28x28") %>%
image_data(channels = "gray") %>%
.[1,,] %>%
as.numeric()
imgD2 %>% matrix(nrow = 28, byrow = TRUE) %>%
image()
imgD2neg <- (255-imgD2)/255
imgD6n <- (255-imgD2)/255
imgD0n2 <- ifelse(imgD2neg < .4, 0, 1)
imgD6n2 <- ifelse(imgD2neg < .4, 0, 1)
imgD0n2 %>% matrix(nrow = 28, byrow = TRUE) %>%
image(col = grey.colors(255))
imgD2neg %>% matrix(nrow = 28, byrow = TRUE) %>%
apply(2,rev) %>%
t() %>%
image()
O código acima serve para gerar os caracteres em qual vão ser baseadas as leituras. Os caracteres vão ser enumerados de 0 à 9 e todos têm a mesma quantidade de pixels e estão apresentados em uma escala de cor cinza para que o programa reconheça melhor a forma e seja mais fácil compreendido na hora de determinar quais os números correspondentes na imagem que irá ser adicionada.
test <- read_rds("teste.rds")
label <- read_rds("label_test.rds")
train <- read_rds("train.rds")
# Constants
img_rows <- 28
img_cols <- 28
n_classes <- 10
O número de classes da variável resposta e as dimensões da matriz são fixadas.
# Creating a function
# Start Function
Label <- function(digits, base, nrows = 28, ncols = 28){
stopifnot(digits %in% 1:nrow(base))
if ("label" %in% colnames(base))
{
cat("\nRemoving label column...")
base <- base %>% select(-label)
}
if ("Flag" %in% colnames(base))
{
cat("\nRemoving Flag column...")
base <- base %>% select(-Flag)
}
# Check graphical parameters
val <- par(no.readonly=TRUE)
n <- ceiling(sqrt(length(digits)))
par(mfrow = c(ceiling(length(digits)/n),n), mar = c(0.1, 0.1, 0.1, 0.1))
for (i in digits){
m <- base %>%
filter(row_number() == i) %>%
unlist() %>%
matrix(nrow = nrows, ncol = ncols, byrow = TRUE) %>%
apply(2, rev) %>%
t() %>%
image(col = grey.colors(255), axes = FALSE)
}
# reset the original graphics parameters
par(val)
}
# Call Function
Label(101:109, train)
x_train <- train %>%
select(-label, -Flag) %>%
mutate_all(function(x) x/255) %>%
as.matrix()
x_test <- train %>%
filter(Flag == 1) %>%
select(-label, -Flag) %>%
mutate_all(function(x) x/255) %>%
as.matrix()
y_train <- train %>%
select(label) %>%
as.matrix() %>%
to_categorical(num_classes = 10)
# Evaluate# Defining the RNN Model
rnn_model <- keras_model_sequential()
rnn_model %>%
layer_dense(units = 64, activation = 'relu', input_shape = c(img_cols*img_rows)) %>%
layer_dropout(rate = 0.4) %>%
layer_dense(units = 32, activation = 'relu') %>%
layer_dropout(rate = 0.2) %>%
layer_dense(units = 16, activation = 'relu') %>%
layer_dropout(rate = 0.1) %>%
layer_dense(units = n_classes, activation = 'softmax')
summary(rnn_model)
##
predict_classes(rnn_model, t(imgD2neg))
t(predict(rnn_model, t(imgD2neg))) %>% round(2)
#
rnn_model %>% compile(
loss = 'categorical_crossentropy', #categorical_accuracy
optimizer = optimizer_rmsprop(),
metrics = c('accuracy')
)
# Training and Evaluation
history <- rnn_model %>% fit(
x_train, y_train,
epochs = 30, batch_size = 128,
validation_split = 0.2,
callbacks = list(
callback_early_stopping(monitor = "val_acc", min_delta = 0.001,
patience = 10,
verbose = 1,
mode = "auto",
restore_best_weights = TRUE))
)
plot(history)
rnn_model %>% evaluate(test,label)
#imager
predict_classes(rnn_model, t(test[1,]))
O processo de leitura da imagem vai avançando à medida em que vai percorrendo cada pixel da mesma sendo comparada com os números presente na base de dados. Logo depois é possível observar o processo no gráfico, onde nos é mostrado os valores da função de perda e de acurácia. Por fim o programa gera a probabilidade de cada número da base de dados que correspondem ao número da imagem escolhida e de qual número a imagem se trata.