Introdução

A DCT é uma transformação é uma tranformação semelhante à transformada discreta de Fourier (DFT), porém descartando a parte imaginária e utilizando apenas as reais. Os DCT’s são freqüentemente utilizados no processamento de sinais e imagens, especialmente para compactação de imagens com perdas.

Objetivos

Um dos objetivos desse relatório é de continuarmos com a rede neurais regular, aplicando agora uma transformada discreta de cossenos, denominada de DCT, tal que, ao aumentarmos o número de variáveis da base de dados de treinamento, possa alcançar melhoras da acurácia dos modelos anteriores. Outra alternativa é de também aumentar o número de entradas.

Base de dados

A base de daods em questão se trata da mesma basede dígitos utilizada anteriormente. Ela é dividida em teste, treinamento e label.

library(tidyverse)
library(keras)
library(magick)
library(mrbsizeR)
# Constantes utilzada no modelo
img_rows <- 28
img_cols <- 28
n_classes <- 10

Os arquivos foram fornecidos, em formato rds.

test <- read_rds("test.rds")
label <- read_rds("label_test.rds")
train <- read_rds("train.rds")

Foi feita uma função denominada de data_augmentation, que aplica a DCT de uma base selecionada, assim, foi feito duas novas transformações, uma para base de treino (dct_result) e outra pra base de teste (dct_test).

DCT<-mrbsizeR::dctMatrix(28)
#Função para utilizar a DCT dado uma base de dados
data_autmentation <- function(x, DCT = DCT){
  image <- matrix(x, nrow = 28, ncol = 28, byrow = TRUE) %>%
    apply(2, rev) %>%
    t()
  image_dct <- DCT %*% image %*% t(DCT)
  return(c(image_dct))
}

dct_result <- train %>%
  filter(Flag==0) %>% 
  select(starts_with("pixel")) %>%
  apply(1, data_autmentation, DCT) %>% 
  t()

colnames(dct_result) <- paste("dct",1:784,sep = "")

dct_test <- test %>%
  apply(1, data_autmentation, DCT) %>% 
  t()

colnames(dct_test) <- paste("dct",1:784,sep = "")

Agora, após o resultado acima, foi adicionado nas bases antigas as respesctivas DCT’s.

#train2<- train %>% bind_cols(dct_result %>% as_tibble())
test2 <- test %>% cbind(dct_test)

Fazendo agora, o mesmo procedimento para alimentar o modelo de rede neural, a base x_train_dct representa os pixels dos dígitos juntamente com a DCT e y_train_dct é uma matriz representando que dígito aquela observação representa.

x_train <- train %>%
  filter(Flag==0) %>% 
  select(-label, -Flag) %>%
  cbind(dct_result) %>% 
  mutate_all( function(x){x/255} ) %>% 
  as.matrix()


y_train <- train %>%
  filter(Flag==0) %>% 
  select(label) %>%
  as.matrix() %>% 
  to_categorical(num_classes = 10)

Modelo

Nesta seção, será aplicado a CNN comum, aumentando apenas as colunas utlizando a tranformada discreta de cossenos (DCT). A primeira camada do modelo apresenta 2000 neurônios, a segunda camada com 1000 neurônios, a terceira com 500 neurônios e obrigatoriamente a última camada com 10 neurônios, no qual representa as 10 opções de dígitos que quero classificar. Vale salientar que, nesta última camada vai ser utilizada a função softmax, no qual ela vai pegar o neurônio com maior valor obtido, assim transformando o valor em probabilidade. Utilizando a expressão: \(\dfrac{e^{x_i}} {\sum_{i=1}^{n}e^{x_{i}}}\), sendo \(n\) o número total de neurônios restantes.

#Modelo
rnn_model <- keras_model_sequential()
rnn_model %>%
  layer_dense(units = 2000, activation = 'relu', input_shape = c(2*img_cols*img_rows)) %>%
  layer_dropout(rate = 0.4) %>% 
  layer_dense(units = 1000, activation = 'relu') %>%
  layer_dropout(rate = 0.2) %>%
  layer_dense(units = 500, activation = 'relu') %>%
  layer_dropout(rate = 0.1) %>%
  layer_dense(units = 10, activation = 'softmax')

summary(rnn_model)
## Model: "sequential"
## ___________________________________________________________________________
## Layer (type)                     Output Shape                  Param #     
## ===========================================================================
## dense (Dense)                    (None, 2000)                  3138000     
## ___________________________________________________________________________
## dropout (Dropout)                (None, 2000)                  0           
## ___________________________________________________________________________
## dense_1 (Dense)                  (None, 1000)                  2001000     
## ___________________________________________________________________________
## dropout_1 (Dropout)              (None, 1000)                  0           
## ___________________________________________________________________________
## dense_2 (Dense)                  (None, 500)                   500500      
## ___________________________________________________________________________
## dropout_2 (Dropout)              (None, 500)                   0           
## ___________________________________________________________________________
## dense_3 (Dense)                  (None, 10)                    5010        
## ===========================================================================
## Total params: 5,644,510
## Trainable params: 5,644,510
## Non-trainable params: 0
## ___________________________________________________________________________
rnn_model %>% compile(
  loss = 'categorical_crossentropy', #categorical_accuracy
  optimizer = optimizer_rmsprop(),
  metrics = c('accuracy')
)

Como o cálculo computacional desse modelo é bem menor em relação à uma rede convolucional, então, foi realizado 40 iterações no modelo, uma condição de parada no algoritmo, tal que, após as realizações dos resultados, se com isso for atingido o esperado, o programa vai parar com até 20 iterações.

# Training and Evaluation
history <- rnn_model %>% fit(
  x_train, y_train,
  epochs = 40, batch_size = 128,
  validation_split = 0.2,
  callbacks = list(
    callback_early_stopping(monitor = "val_acc", min_delta = 0.001,
                            patience = 20,
                            verbose = 0,
                            mode = "auto",
                            restore_best_weights = TRUE))
)
plot(history)   

# Evaluate
rnn_model %>% evaluate(test2, label)
## $loss
## [1] 0.5370688
## 
## $acc
## [1] 0.9793251

Vizualizando as interações do modelo e a acurácia final, podemos dizer que não houve um bom resultado, visto que essas redes neurais mais “simples” não apresentam um alto grau de competitividade em relação às redes convolucionais, pois geralmente apresentam muito overfitting. A aplicação da DCT foi útil, pórem outras técnicas que foram exploradas em outros relatórios, poderiam ser adicionadas juntas com a DCT, como por exemplo a utilização de bootstrap, aumentando o número de observações.