{"cells":[{"metadata":{"_uuid":"a61ae5df9bb59ef89b5de9db8f68bb9d2752da7a","_execution_state":"idle","trusted":true,"collapsed":true},"cell_type":"code","source":"# Packages ----\nlibrary(dplyr)\nlibrary(data.table)\nlibrary(filesstrings)\nlibrary(reticulate)\nlibrary(magick)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5d5ef97c08942fabe435e05c5b578b5bd2d277b5"},"cell_type":"code","source":"# Default directories ----\nids <- fread(file = \"../input/humpback-whale-identification/train.csv\") %>% as_tibble()\ndir_train_orig <- \"../input/humpback-whale-identification/train\"\ndir_test_orig <- \"../input/humpback-whale-identification/test\"\ndir_validation <- \"validation\"\ndir.create(dir_validation)\ndir_train <- \"train\"\ndir_cropped <- \"cropped\"\ndir.create(dir_cropped)\ndir.create(dir_train)\nbbox_train <- fread(\"../input//box-whale//bounding//bounding_boxes_train.csv\")\nbbox_test <- fread(\"../input//box-whale//bounding//bounding_boxes_test.csv\")\n\n# Total possible classes\nnbr_classes <- ids$Id %>% unique() %>% length()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c3bab48dd5a3b9ec9aacc01c5edca9b9fe1e3ff0"},"cell_type":"code","source":"head(bbox_train)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a696824a09fd8fe2a32295b480a68b0955dce4c7"},"cell_type":"code","source":"# Create a folder for each possible class in both the training and validation folder\nfor(i in 1:nbr_classes){\n  dir.create(file.path(dir_train, unique(ids$Id)[i]))\n  dir.create(file.path(dir_validation, unique(ids$Id)[i]))\n}\nunlink(file.path(dir_train, \"new_whale\"), recursive=TRUE)\nunlink(file.path(dir_validation, \"new_whale\"), recursive=TRUE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2fb85d011f5c64b6b42237bca68320cc50615688"},"cell_type":"code","source":"# Determine which files to move\nset.seed(1234)\nfiles_to_move <- list.files(dir_train_orig, include.dirs = F, pattern = \".jpg\") %>%\n  as_tibble() %>%\n  rename(Image = value) %>%\n  inner_join( # join with the list of all files to get the correct class\n    ids %>% filter(Id != \"new_whale\")\n  ) %>%\n  left_join(\n    bbox_train, by = \"Image\"\n  ) %>%\n  mutate(\n    ImageName = Image,\n    Image = file.path(dir_train_orig, Image),\n    Id = file.path(dir_train, Id)\n  )\nhead(files_to_move)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"198a4057a499832703627cc31bce81ddfbcaca3d"},"cell_type":"code","source":"# Select one image per class\nfiles_to_move_single <- files_to_move %>%\n    group_by(Id) %>%\n    summarize(Image = max(Image)) %>%\n    inner_join(files_to_move, by = c(\"Image\", \"Id\"))\nhead(files_to_move_single)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4916f4028695cdc83a5d7d10ae9b6bcf3faad61e"},"cell_type":"code","source":"files_to_move_single_image <- files_to_move %>%\n    add_count(Id) %>%\n    mutate(train = ifelse(n == 1, 1, 0)) %>%\n    filter(train == 1) %>%\n    select(-train, -n)\n\nfiles_to_move_rest <- files_to_move %>%\n    anti_join(files_to_move_single_image, by = \"ImageName\") %>%\n    sample_frac(0.8)\n\nfiles_to_move_single_image %>%\n    bind_rows(files_to_move_rest) %>%\n    head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1f6fca52596b97583024e68ab5fa85aa5875100e"},"cell_type":"code","source":"# TRAIN\nset.seed(1234)\nfiles_to_move_TRAIN <- files_to_move_single_image %>%\n    bind_rows(files_to_move_rest)\n#files_to_move_TRAIN <- files_to_move_single\n\n# Copy the files to respective directories\ni <- 1\nfor(file in files_to_move_TRAIN %>% pull(Image)){\n    # Before copying it, crop them \n    fileName <- files_to_move_TRAIN %>% filter(Image == file) %>% pull(ImageName)\n    x0 <- files_to_move_TRAIN %>% filter(Image == file) %>% pull(x0)\n    x1 <- files_to_move_TRAIN %>% filter(Image == file) %>% pull(x1)\n    y0 <- files_to_move_TRAIN %>% filter(Image == file) %>% pull(y0)\n    y1 <- files_to_move_TRAIN %>% filter(Image == file) %>% pull(y1)\n    \n    image <- image_read(file)\n    croppedImage <- image_crop(image, geometry_area(round(x1 - x0, 0), round(y1 - y0, 0), x0, y0))\n    image_write(croppedImage, path = file.path(dir_cropped, fileName), format = \"jpg\")\n    \n    # Then copy them\n    file.copy(file.path(dir_cropped, fileName), files_to_move_TRAIN[i, \"Id\"] %>% pull(Id))\n    i <- i + 1\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"daa1654ec66697ca54b31242d1b8b4327f30ca80"},"cell_type":"code","source":"# Test if cropping worked\nprint(image_read(\"../input/humpback-whale-identification/train/b2cabd9d8.jpg\"))\nprint(image_read(\"cropped/b2cabd9d8.jpg\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"742db7466308232bf3001310a4cb3288332e07af"},"cell_type":"code","source":"# VALIDATION\nset.seed(100)\nfiles_to_move_VALIDATION <- files_to_move %>% \nanti_join(files_to_move_TRAIN, by = \"ImageName\") %>%\nmutate(\n    Image = Image,\n    Id = gsub(\"train\", \"validation\", Id)\n  )\n\n# Copy the files to respective directories\ni <- 1\nfor(file in files_to_move_VALIDATION %>% pull(Image)){\n    # Before copying it, crop them \n    fileName <- files_to_move_VALIDATION %>% filter(Image == file) %>% pull(ImageName)\n    x0 <- files_to_move_VALIDATION %>% filter(Image == file) %>% pull(x0)\n    x1 <- files_to_move_VALIDATION %>% filter(Image == file) %>% pull(x1)\n    y0 <- files_to_move_VALIDATION %>% filter(Image == file) %>% pull(y0)\n    y1 <- files_to_move_VALIDATION %>% filter(Image == file) %>% pull(y1)\n    \n    image <- image_read(file)\n    croppedImage <- image_crop(image, geometry_area(round(x1 - x0, 0), round(y1 - y0, 0), x0, y0))\n    image_write(croppedImage, path = file.path(dir_cropped, fileName), format = \"jpg\")\n    \n    # Then copy them\n    file.copy(file.path(dir_cropped, fileName), files_to_move_VALIDATION[i, \"Id\"] %>% pull(Id))\n    i <- i + 1\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"14f027506f8d4380dfc20d6db9d460e22c48cee0","collapsed":true},"cell_type":"code","source":"###########################################################################################\n# Packages ----\nlibrary(keras)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(data.table)\nlibrary(filesstrings)\nlibrary(tibble)\nlibrary(magrittr)\nlibrary(imager)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a1a58c6c0f94cb3b4a6875347dbda2a669d861d"},"cell_type":"code","source":"files_to_move_TRAIN %>% nrow()\nfiles_to_move_VALIDATION %>% nrow()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2e2ee85c7c96c79c60e77556694f8ae3b74a923a"},"cell_type":"code","source":"# Folder Structure ----\nnbr_classes <- ids %>% filter(Id != \"new_whale\") %>% pull(Id) %>% unique() %>% length()\n\n# MODELLING ----\n# Simple Model ----\n# Create data generators\n# With Data Augmentation ----\ntrain_datagen <- image_data_generator(\n  rescale = 1/255,  \n  rotation_range = 30,  \n  width_shift_range = 0.2,  \n  height_shift_range = 0.2,\n  shear_range = 0.3,\n  #horizontal_flip = TRUE,  \n  fill_mode = \"nearest\"\n)\n\nvalidation_datagen <- image_data_generator(rescale = 1/255)\n\ntrain_generator <- flow_images_from_directory(\n  dir_train,\n  train_datagen,\n  color_mode = \"grayscale\",\n  target_size = c(150, 150),\n  batch_size = 100,\n  class_mode = \"categorical\"\n)\n\nvalidation_generator <- flow_images_from_directory(\n  dir_validation,\n  validation_datagen,\n  color_mode = \"grayscale\",\n  target_size = c(150, 150),\n  batch_size = 100,\n  class_mode = \"categorical\"\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"423a2809138f25579a7e40f938b044b7352fdcf0"},"cell_type":"code","source":"# Build own CNN\nmodel <- keras_model_sequential() %>%\n  layer_conv_2d(filters = 32, kernel_size = c(9, 9), activation = \"relu\",\n                input_shape = c(150, 150, 1)) %>%\n  #layer_max_pooling_2d(pool_size = c(2, 2)) %>%\n  layer_batch_normalization() %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_conv_2d(filters = 64, kernel_size = c(7, 7), activation = \"relu\") %>%\n  layer_max_pooling_2d(pool_size = c(3, 3)) %>%\n  layer_batch_normalization() %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_conv_2d(filters = 128, kernel_size = c(3, 3), activation = \"relu\") %>%\n  #layer_max_pooling_2d(pool_size = c(2, 2)) %>%\n  layer_batch_normalization() %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_conv_2d(filters = 256, kernel_size = c(3, 3), activation = \"relu\") %>%\n  layer_max_pooling_2d(pool_size = c(2, 2)) %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_conv_2d(filters = 512, kernel_size = c(3, 3), activation = \"relu\") %>%\n  layer_conv_2d(filters = 1024, kernel_size = c(3, 3), activation = \"relu\") %>%\n  layer_max_pooling_2d(pool_size = c(2, 2)) %>%\n  layer_conv_2d(filters = 512, kernel_size = c(3, 3), activation = \"relu\") %>%\n  layer_conv_2d(filters = 1024, kernel_size = c(3, 3), activation = \"relu\") %>%\n  layer_max_pooling_2d(pool_size = c(2, 2)) %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_conv_2d(filters = 1024, kernel_size = c(1, 1), activation = \"relu\") %>%\n  layer_conv_2d(filters = 2048, kernel_size = c(1, 1), activation = \"relu\") %>%\n  layer_flatten() %>%\n  layer_dense(units = 512, activation = \"relu\") %>%\n  layer_dropout(rate = 0.3) %>%\n  layer_dense(units = nbr_classes, activation = \"softmax\")\n\nmodel %>% compile(\n  loss = \"categorical_crossentropy\",\n  optimizer = \"adam\",\n  metrics = c(\"accuracy\", \"top_k_categorical_accuracy\")\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"79826c2485c020a27b13310cc948f0889434eecf"},"cell_type":"code","source":"# Fit model\nhistory <- model %>% fit_generator(\n  generator = train_generator,\n  steps_per_epoch = 120,\n  epochs = 50,\n  validation_data = validation_generator,\n  validation_steps = 25,\n  verbose = 1\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0a57a7bfa8d29a4af0d70abd0e3b5f308c674547"},"cell_type":"code","source":"plot(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"29760b616a56f1bdb3144c04e9b5ef5e1a034d27"},"cell_type":"code","source":"#img_path <- file.path(\"../input/humpback-whale-identification/test\", list.files(dir_test_orig))\nif(exists(\"predictions\")) {rm(predictions)}\nfor(img in list.files(dir_test_orig)){\n    img <- image_load(file.path(\"../input/humpback-whale-identification/test\", img), target_size = c(150, 150), grayscale = TRUE)\n    img_tensor <- image_to_array(img)\n    rm(img)\n    img_tensor <- array_reshape(img_tensor, c(1, 150, 150, 1))\n    img_tensor <- img_tensor / 255\n    \n    prediction <- predict(model, img_tensor)\n    rm(img_tensor)\n    if(exists(\"predictions\")){\n        predictions <- rbind(predictions, as.data.frame(prediction))\n    } else {predictions <- as.data.frame(prediction)}\n}\nnames(predictions) <- list.files(dir_train)\nhead(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4460531468d6032570eb4b9dbdf1802e6f141b87"},"cell_type":"code","source":"submission <- predictions %>% \n  mutate(Image = list.files(\"../input/humpback-whale-identification/test\")) %>%\n  gather(column, value, -Image) %>%\n  group_by(Image) %>% \n  mutate(rk = rank(-value, ties.method = \"random\")) %>%\n  filter(rk <= 5) %>% \n  arrange(Image, rk) %>%\n  mutate(column = ifelse(rk == 1 & value <= 0.85, \"new_whale\", column)) %>%\n  select(-value) %>%\n  spread(rk, column) %>%\n  unite(Id, -Image, sep = \" \")\nwrite.csv(submission, \"submission.csv\", row.names = FALSE)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"db6a7e8784f01b032e9e2867094026fba2246e28"},"cell_type":"code","source":"unlink(dir_train, recursive = TRUE)\nunlink(dir_validation, recursive = TRUE)\nunlink(dir_cropped, recursive = TRUE)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"R","language":"R","name":"ir"},"language_info":{"mimetype":"text/x-r-source","name":"R","pygments_lexer":"r","version":"3.4.2","file_extension":".r","codemirror_mode":"r"}},"nbformat":4,"nbformat_minor":1}