
#Carregando pacotes úteis
library(tidyverse)
library(keras)
library(imager)
library(magick)


list.files(path = "../input")

#Carregando a base de dados
labels <- read_csv("../input/dog-breed-identification/labels.csv")
breed_list <- labels %>% count(breed) %>% arrange(-n) %>% pull(breed)
output_n <- length(breed_list)

#Dividindo a base de dados em treino e validação

#validation data
set.seed(123)
#Dados de validação
labels_valid <- labels %>% group_by(breed)%>%sample_n(5)
#Dados de treinamento
labels <- labels%>%filter(!(id %in% labels_valid$id))

#Lista das raças dos cães
breed_list <- labels %>% count(breed) %>% arrange(-n) %>% pull(breed)
output_n <- length(breed_list)
#Número de raças
output_n

###########################################################
labels <- labels %>% 
                mutate(from = paste0("../input/dog-breed-identification/train/", id, ".jpg"), 
                       to = paste0("train/", breed, "/", id,".jpg"))

labels_valid <- labels_valid %>% 
                mutate(from = paste0("../input/dog-breed-identification/train/", id, ".jpg"), 
                       to = paste0("train/", breed, "/", id,".jpg"))

##############################################################################################

#Criando um directório contendo os dados de treinamento
dir.create(path = "train")
for (breed in breed_list) {
    cat("\nProcessing breed ", breed)
    dir.create(path = paste0("train/", breed))
}
file.copy(from = labels %>% pull(from), to = labels %>% pull(to), overwrite = TRUE)

#Criando um diretório contendo os dados de validação
labels_valid <- labels_valid %>% 
                mutate(from = paste0("../input/dog-breed-identification/train/", id, ".jpg"), 
                       to = paste0("train/", breed, "/", id,".jpg"))

dir.create(path = "validation")
for (breed in breed_list) {
    cat("\nProcessing breed ", breed)
    dir.create(path = paste0("validation/", breed))
}
file.copy(from = labels_valid %>% pull(from), to = labels_valid %>% pull(to), overwrite = TRUE)

#Criando o diretório de teste
sample_sub <- read.csv("../input/dog-breed-identification/sample_submission.csv")
sample_sub <- sample_sub %>% 
                mutate(from = paste0("../input/dog-breed-identification/test/", id, ".jpg"), 
                       to = paste0("test/", id,".jpg"))

dir.create(path = "test")
file.copy(from = sample_sub %>% pull(from), to = sample_sub %>% pull(to), overwrite = TRUE)
###############################################################################################


#Redimensionando as images
img_width <- 256
img_height <- 256
target_size <- c(img_width, img_height)

# RGB = 3 channels
channels <- 3

#Train path
train_image_files_path <- './train'
validation_image_files_path <- './validation'

#Gerando os dados de treinamento
train_data_gen <- image_data_generator(
  rescale = 1/255)
#Gerando os dados de validação
valid_data_gen <- image_data_generator(
  rescale = 1/255
  )  
#Gerando os dados de teste
test_data_gen <- image_data_generator(
rescale = 1/255)

#Criando o vetor de treinamento
train_image_array_gen <- flow_images_from_directory(train_image_files_path, 
                                          train_data_gen,
                                          target_size = target_size,
                                          class_mode = "categorical",
                                          classes = breed_list,
                                          seed = 1234)

#Criando o vetor de validação
valid_image_array_gen <- flow_images_from_directory(validation_image_files_path, 
                                          valid_data_gen,
                                          target_size = target_size,
                                          class_mode = "categorical",
                                          classes = breed_list,
                                          seed = 2021)

#Criando o vetor de dados de teste
path_test <- './train'
test_image_array_gen <- flow_images_from_directory(path_test,
                                                  test_data_gen,
                                                  target_size = target_size,
                                                  class_mode = "categorical",
                                                  classes = breed_list
                                                  )



#Classes de treinamento
breed_classes <- train_image_array_gen$class_indices
save(breed_classes, file = './breed_classes')
breed_classes_indices <- train_image_array_gen$class_indices

#The model
train_samples <- train_image_array_gen$n
valid_samples <- valid_image_array_gen$n
batch_size <- 32
epochs <- 15

model <- keras_model_sequential()

model %>%
  layer_conv_2d(filter = 128, kernel_size = c(3,3), padding = "same", input_shape = c(img_width, img_height, channels)) %>%
  layer_activation("relu") %>%

  layer_conv_2d(filter = 64, kernel_size = c(3,3), padding = "same") %>%
  layer_activation_leaky_relu(0.5) %>%
  layer_batch_normalization() %>%

  layer_max_pooling_2d(pool_size = c(2,2)) %>%
  layer_dropout(0.25) %>%
  
  layer_flatten() %>%
  layer_dense(100) %>%
  layer_activation("relu") %>%
  layer_dropout(0.5) %>%

  layer_dense(output_n) %>% 
  layer_activation("softmax")

# Compilando o modelo
model %>% compile(
  loss = "categorical_crossentropy",
  optimizer = optimizer_rmsprop(lr = 0.0001, decay = 1e-6),
  metrics = "accuracy"
)


hist <- model %>% fit_generator(
  train_image_array_gen,
  steps_per_epoch = as.integer(train_samples / batch_size), 
  epochs = epochs,
  validation_data = valid_image_array_gen,
  validation_steps = as.integer(valid_samples / batch_size),
  verbose = 2    
)


#REVER PARA SUBMETER
test_samples <- test_image_array_gen$n
test_samples
predict_model1 <- predict_class(model, test_image_array_gen,
                                   steps = as.integer(test_image_array_gen$n/batch_size))

