Este relatório tem como objetivo principal demonstrar em forma de tutorial, como construir/utilizar uma rede neural para treinar um modelo que identifique o dígitos em imagens. Utilizando também transformações em imagens, como rotação, espelhamento, compactação, etc.
A base de dados utilizada foi: digit.recognizer
, que pode ser encontrada no site Kaggle atráves do link https://www.kaggle.com/c/digit-recognizer.
#Inicio
Para inciar, temos que carregar os pacotes utilizados, chamar as bases de dados, definir o numero de linhas colunas e o total de classe..
suppressMessages(suppressWarnings(library(tidyverse)))
suppressMessages(suppressWarnings(library(keras)))
img_rows <- 28 # Numero de linhas
img_cols <- 28 # Numero de colunas
n_classes <- 10 # Numero de Classes
test <- read.csv("/opt/datasets/digits/test.csv")
label <- read.csv("/opt/datasets/digits/sample_submission.csv")
train <- read.csv("/opt/datasets/digits/train.csv")
train2<-train
train <- train2 %>%
mutate(Flag = sample(x = c(0, 1),
size = n(),
replace = TRUE,
prob = c(.8,.2))) %>%
sample_frac(1, replace = FALSE)
Uma nova variavel foi criada, para posteriormente separarmos nossa matriz de treinamento, em teste e treino. O primeiro passo é visualizarmos um digito. Algumas mudanças são necessarias para visualização do digito, então ao lado do codigo seguem os comentarios.
set.seed(1)
# Visualizing a random digit
train %>%
select(-label, -Flag) %>%
sample_n(1) %>%
unlist() %>% #Transforma em vetor
matrix(nrow = 28, byrow = TRUE) %>%
#Pega linha e transforma numa matriz 28x28. byrow = TRUE faz mudança na linha, FALSE mexe nas colunas
apply(2, rev) %>% #Faz o efeito do digito espelhado. ex: (1...12) -> (12...1). apply(1, rev) 1 = linha, 2=coluna
t() %>% #Rotaciona o digito em 90°
image()
Visualizando 9 digitos :
# 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) ##Define quantos digitos
##
## Removing label column...
## Removing Flag column...
Como foi falado no incio, sera necessario criar as matrizes de treino e teste. Então iremos contar com o auxilio da nova variavel criada `Flag’.
set.seed(123)
x_train <- train %>%
filter(Flag == 0) %>%
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 %>%
filter(Flag == 0) %>%
select(label) %>% as.matrix() %>%
keras::to_categorical(num_classes = 10)
y_test <- train %>%
filter(Flag == 1) %>%
select(label) %>%
as.matrix() %>%
to_categorical(num_classes = 10)
É necessario ter o tensorflow
ja instalado, poiss o keras
ira utiliza-lo.
Definindo o método de modelagem e o hiperparâmetros do modelo, a serem utilizados.
Os modelos de redes neurais são estimados por meio de camadas. O comando layer_dense
define estas camadas. Este modelo por sua vez é construidas em 3 camadas, contendo 256, 128 e 10 neurônios respectivamente.
Em resumo, os parametros são: units
- número de parâmetros.
activation
- função de ativação. input_shape
- número das colunas da matriz e o número de colunas que serão utilizadas. layer_drop
- Utilizado para nao gerar overfitting.
rnn_model <- keras_model_sequential()
rnn_model %>%
layer_dense(units = 256, activation = 'relu', input_shape = c(img_cols*img_rows)) %>%
layer_dropout(rate = 0.4) %>%
layer_dense(units = 128, activation = 'relu') %>%
layer_dropout(rate = 0.2) %>%
layer_dense(units = n_classes, activation = 'softmax')
rnn_model %>% compile(
loss = 'categorical_crossentropy', #categorical_accuracy
optimizer = optimizer_rmsprop(),
metrics = c('accuracy')
)
history <- rnn_model %>% fit(
x_train, y_train,
epochs = 10, batch_size = 128,
validation_split = 0.2)
plot(history)
rnn_model %>% evaluate(x_test, y_test)
## $loss
## [1] 0.1021235
##
## $accuracy
## [1] 0.9740493
Ao utilizar a função evaluate
pode se verficar a acúracia no modelo.
Antes de testar o modelo com a imagem inseridaa, sera testado com a propria base de dados.
## [1] "list"
## [1] 6
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 2e-05 2e-05 0.99832 0 0.00163 0 0 0 1e-05
Testando o modelo na pratica, utiliza-se uma imagem qu contem um numero. O pacote imager
será utilizado para carregar a imagem.
suppressMessages(suppressWarnings(library(imager)))
digit <- load.image("digit2.png")
plot(digit,axes = FALSE)
Desta forma podemos visualizar o numero que foi inserido.
digit28 <- digit %>% resize(size_x = 28, size_y = 28, interpolation_type = 1L)
digit28 <- rowMeans(digit28, dims = 2)
digit28 %>%
apply(1, rev) %>%
t() %>%
image(col = grey.colors(256), axes = FALSE)
Forma que o modelo recebe a imagem.
digit_test_2 <- digit28 %>%
apply(2,function(x) x/255) %>%
apply(1, rev) %>%
t() %>%
as.vector()
# Prevendo
Y = (1 - digit_test_2) %*% Input + t(Input_bias)
Y_relu = Y * (Y > 0) # Activation Function
Z = Y_relu %*% Layer + t(Layer_bias)
Z_relu = Z * (Z > 0) # Activation Function
W = Z_relu %*% Output + t(Output_bias)
f_exp = exp(W)
W_softmax = f_exp/sum(f_exp)# softmax output
round(W_softmax, 5)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 0 0 1 0 0 0 0 0 0 0
A saída representa as probabilidades para cada digito, onde a coluna que apresentar a a maior probabilidade será escolhido para a predição. obs:
A coluna 1, representa o digito 0, a coluno dois o digito 1 e assim sucessivamente.
O nosso modelo estimou uma probabilidade 1 de ser o número 2 (coluna 3 ), que a imagem inserida, Logo o modelo acertou com 100%.