{"cells":[{"metadata":{},"cell_type":"markdown","source":"This is a fork from notebook-https://www.kaggle.com/demetrypascal/fork-of-simple-convnet-is-healthy/notebook#Predict . Iam learning Image classification by doing this notebook and using my knowledge of reading the book \"Deep learning with R\" by christopher Manning .\n\nHope one day I will be able to code these promptly and try to get efficiency."},{"metadata":{"_uuid":"051d70d956493feee0c6d64651c6a088724dca2a","_execution_state":"idle","trusted":true},"cell_type":"code","source":"# This R environment comes with many helpful analytics packages installed\n# It is defined by the kaggle/rstats Docker image: https://github.com/kaggle/docker-rstats\n# For example, here's a helpful package to load\n\nlibrary(tidyverse) # metapackage of all tidyverse packages\nlibrary(keras)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nlist.files(path = \"../input\")\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"library(tidyverse)\nlibrary(magrittr)\nlibrary(onehot)\nlibrary(splitstackshape)\nlibrary(caret)\n\n\noptions(warn = -1, repr.plot.width = 14, repr.plot.height =  10)\n\nfig <- function(width, heigth){\n    options(repr.plot.width = width, repr.plot.height = heigth)\n}\n\ntarget_size = c(250, 250)\nfactor = .4\nreduceFrom = 2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels <- read_csv('/kaggle/input/cassava-leaf-disease-classification/train.csv')\n#test_labels = read_csv('')\nhead(labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#CHeck how many unique labels\nsort(unique(labels$label))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"counts = labels %>% group_by(label) %>% summarize(n())\ncolnames(counts)[2] = 'count'\ncounts","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dmap <- jsonlite::read_json('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json') %>% \n  as_tibble() %>% \n  pivot_longer(matches(\"[[:digit:]]\"), names_to = \"label\", values_to = \"disease\") %>% \n  mutate(label = as.integer(label),\n         disease = str_remove(disease, \"\\\\(.*\\\\)\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ggplot(counts %>% left_join(dmap, by = \"label\"), aes(y = count, x = disease)) + geom_col(width = 0.5, fill = 'red') + \n    labs(x = '', y ='') + theme_bw() + theme(axis.text.x = element_text(angle = 10, hjust = 1))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Convert labels to one hot encoding\ntt = labels[,'label'] %>% mutate(label = factor(label))\n\nencoder <- onehot(tt)\n\nout <- predict(encoder, tt)\n\ncolnames(out) <- c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy')\n\ny_train <- cbind(labels, out)\n\n#y_train$Healthy = as.character(y_train$Healthy)\n\nhead(y_train)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#split to train and valid\nset.seed(1)\n\nclasses_cols = c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy') #c('CMD','Healthy','Another')\n\ntmp = stratified(y_train, classes_cols, 0.8, bothSets = TRUE)\n\nshuffle = function(df){\n    return(df[sample(1:nrow(df), nrow(df)),])\n}\n\ny_train = shuffle(tmp[[1]])\ny_valid = shuffle(tmp[[2]])\n\ndim(y_train)\ncolSums(y_train[,-(1:2)])\nhead(y_train[,c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy')])\n\ndim(y_valid)\ncolSums(y_valid[,-(1:2)])\nhead(y_valid[,c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy')])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"summary(y_train)\nsummary(y_valid)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Data generators\n\nWatchGenerator <- image_data_generator(\n    #samplewise_std_normalization = TRUE,\n  width_shift_range = 0.1,\n  height_shift_range = 0.1,\n  zoom_range = 0.25,\n  rotation_range = 30,\n  shear_range = 30/180 * pi,\n  horizontal_flip = TRUE,\n    vertical_flip = TRUE, \n  fill_mode = \"reflect\"\n)\n\nFitGenerator <- image_data_generator(\n  width_shift_range = 0.1,\n  height_shift_range = 0.1,\n  zoom_range = 0.25,\n  rotation_range = 30,\n  shear_range = 30/180 * pi,\n  fill_mode = \"reflect\",\n  horizontal_flip = TRUE,\n  vertical_flip = TRUE,\n  rescale = 1/255\n)\n\nTestGenerator <- image_data_generator(\n  rescale = 1/255\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Lets check some images\nimg_path<-\"/kaggle/input/cassava-leaf-disease-classification/train_images/1000015157.jpg\"\n\nimg <- image_load(img_path, target_size = target_size)\nimg_array <- image_to_array(img)\nimg_array <- array_reshape(img_array, c(1, target_size, 3))\nimg_array<-img_array/255\n\n# Generated that will flow augmented images\naugmentation_generator <- flow_images_from_data(\n  img_array, \n  generator = WatchGenerator, \n  batch_size = 1 \n)\nop <- par(mfrow = c(3, 3), pty = \"s\", mai = c(0.1, 0, 0.1, 0))\nfor (i in 1:9) {\n  batch <- generator_next(augmentation_generator)\n  plot(as.raster(batch[1,,,]))\n}\npar(op)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#train\nimage_path <- '/kaggle/input/cassava-leaf-disease-classification/train_images'\n\nbatch_size = 64\n\ntrain_generator <- flow_images_from_dataframe(dataframe = y_train, \n                                              directory = image_path,\n                                              generator = FitGenerator,\n                                              class_mode = \"other\",\n                                              x_col = \"image_id\",\n                                              y_col = c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy'), #c('CMD','Healthy','Another'),\n                                              target_size = target_size,\n                                              batch_size = batch_size,\n                                              shuffle = TRUE,\n                                              drop_duplicates = FALSE,\n                                              interpolation = \"nearest\"\n                                             )\n\nvalidation_generator <- flow_images_from_dataframe(dataframe = y_valid, \n                                              directory = image_path,\n                                              generator = FitGenerator,     \n                                              class_mode = \"other\",\n                                              x_col = \"image_id\",\n                                              y_col = c('CBB', 'CBSD', 'CGM', 'CMD', 'Healthy'), #c('CMD','Healthy','Another'),\n                                              target_size = target_size,\n                                              batch_size = batch_size,\n                                              shuffle = TRUE,\n                                              drop_duplicates = FALSE,\n                                              interpolation = \"nearest\"\n                                                  )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Using keras pretrained model data set\ninput = layer_input(shape = c(target_size, 3))\n\nconv_net = application_inception_v3(\n      include_top = FALSE,\n      weights = \"../input/keras-pretrained-models/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5\",\n      input_shape = c(target_size, 3),\n    input_tensor = input\n)\nxcept = application_xception(\n      include_top = FALSE,\n     weights = \"../input/keras-pretrained-models/xception_weights_tf_dim_ordering_tf_kernels_notop.h5\",\n      input_shape = c(target_size, 3),\n    input_tensor = input\n)\n\nfreeze_weights(conv_net)\nfreeze_weights(xcept)\n\n\ninput1 <- conv_net$input\ninput2 = xcept$input\n\noutput1 <- conv_net$output %>%\n    #layer_conv_2d(filters = 32, kernel_size = c(11, 11), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(3, 3), stride = 2) %>% \n\n    #layer_conv_2d(filters = 64, kernel_size = c(11, 11), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(3, 3), stride = 2) %>% \n\n    #layer_conv_2d(filters = 64, kernel_size = c(7, 7), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(3, 3), stride = 2) %>% \n\n    #layer_conv_2d(filters = 128, kernel_size = c(5, 5), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(3, 3), stride = 1) %>% \n\n    #layer_conv_2d(filters = 256, kernel_size = c(5, 5), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(3, 3)) %>% \n\n    #layer_conv_2d(filters = 256, kernel_size = c(3, 3), activation = 'relu') %>%\n    #layer_max_pooling_2d(pool_size = c(2, 2)) %>% \n\n    layer_conv_2d(filters = 256, kernel_size = c(1, 1), activation = 'relu') #%>%\n        \n    #layer_global_max_pooling_2d() %>%\n\noutput2 = xcept$output %>% layer_conv_2d(filters = 256, kernel_size = c(3, 3), activation = 'relu')\n\noutput = layer_concatenate(list(output1, output2)) %>%\n    layer_flatten() %>%\n    layer_batch_normalization() %>% \n    layer_dropout(rate = 0.2) %>%\n    layer_dense(units = 64, activation=\"elu\")%>% \n    layer_batch_normalization() %>% \n    layer_dense(units = 64, activation=\"relu\")%>% \n    layer_batch_normalization() %>%\n    layer_dropout(rate = 0.2) %>%\n    layer_dense(units = 5, activation=\"softmax\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Keras model\nmodel <- keras_model(input, output)\n\nsummary(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#callback params\ncallback_lr_init <- function(logs){\n      iter <<- 0\n      lr_hist <<- c()\n      iter_hist <<- c()\n}\ncallback_lr_set <- function(batch, logs){\n      iter <<- iter + 1\n      LR <- l_rate[iter] # if number of iterations > l_rate values, make LR constant to last value\n      if(is.na(LR)) LR <- l_rate[length(l_rate)]\n      k_set_value(model$optimizer$lr, LR)\n}\n\ncallback_lr <- callback_lambda(on_train_begin=callback_lr_init, on_batch_begin=callback_lr_set)\n\n\n\nreduce_lr <- callback_reduce_lr_on_plateau(factor = factor, patience = reduceFrom, verbose = 0, mode = \"auto\", monitor = \"val_accuracy\")\n\n#stop <- callback_early_stopping(monitor = 'val_accuracy', patience = early_stop)\n\ncheck_point <- callback_model_checkpoint(\"model.h5\", save_best_only = TRUE, verbose = 0, mode = \"auto\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#model\nnb_epochs = 40\n\nmodel %>% compile(\n    optimizer = optimizer_adam(),\n    loss = \"categorical_crossentropy\",#'binary_crossentropy',#\n    metrics = \"categorical_accuracy\"#'binary_accuracy' \n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#The following code came from the tutorial of Keras \"tutorial_save_and_restore\".\ncheckpoint_dir <- \"checkpoints\"\nunlink(checkpoint_dir, recursive = TRUE)\ndir.create(checkpoint_dir)\nfilepath <- file.path(checkpoint_dir, \"eff_net_weights.{epoch:02d}.hdf5\")\ncheck_point_callback <- callback_model_checkpoint(\n  filepath = filepath,\n  save_weights_only = TRUE,\n  save_best_only = TRUE\n)\ncallback_list <- list(callback_lr, check_point_callback) #callback to update lr\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#fit model\nhistory <- model %>% fit_generator(\n    train_generator,\n    steps_per_epoch = round(nrow(y_train) / batch_size),\n    epochs = nb_epochs,\n    #callbacks = callback_list, #callback to update cylic lr\n    callbacks = list(check_point, reduce_lr), \n    validation_data = validation_generator,\n    validation_step = round(nrow(y_valid) / batch_size)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Plot history\nplot(history)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Predict for test image\nsample_submission <- read_csv(\"/kaggle/input/cassava-leaf-disease-classification/sample_submission.csv\")\ntest_generator <- flow_images_from_dataframe(dataframe = sample_submission, \n                                              directory = '../input/cassava-leaf-disease-classification/test_images',\n                                              class_mode = NULL,\n                                              x_col = \"image_id\",\n                                              y_col = NULL,\n                                              target_size = target_size,\n                                              shuffle = FALSE,\n                                              generator = TestGenerator, \n                                              batch_size=1)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_test_images <- nrow(sample_submission)\n\npred <- model %>% predict_generator(test_generator, steps = num_test_images)\n\nhead(pred)\nlabel <- apply(pred, 1, which.max) - 1\n\nprediction <- tibble(image_id = sample_submission$image_id, label = label)\n\nhead(prediction)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"write_csv(prediction, file='submission.csv')\n\n","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"name":"ir","display_name":"R","language":"R"},"language_info":{"name":"R","codemirror_mode":"r","pygments_lexer":"r","mimetype":"text/x-r-source","file_extension":".r","version":"3.6.3"}},"nbformat":4,"nbformat_minor":4}