{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport shutil\n#from PIL import Image\nimport matplotlib.image as mpimg\n%matplotlib inline\n\nimport pandas as pd\nimport numpy as np\nimport random\n\nimport re\nimport json\n\n#!pip install tensorflow-gpu\n#!pip install -q --upgrade tensorflow\nimport tensorflow as tf\nprint(tf.__version__)\n\nfrom tensorflow.keras import datasets, layers, models, losses, Model #draw graphs\nfrom sklearn.model_selection import train_test_split \nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport matplotlib.pyplot as plt #draw graphs\nimport os\nimport tensorflow as tf\n\n\n\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import SparseCategoricalCrossentropy\n\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\nfrom tensorflow.keras.applications import EfficientNetB3 #transfer learning model\nfrom tensorflow.keras.utils import plot_model\n\nfrom tensorflow import keras\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nfrom tensorflow.keras import optimizers\n\n\nfrom sklearn.preprocessing import OneHotEncoder","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-19T15:58:17.543538Z","iopub.execute_input":"2021-11-19T15:58:17.543847Z","iopub.status.idle":"2021-11-19T15:58:22.673407Z","shell.execute_reply.started":"2021-11-19T15:58:17.543763Z","shell.execute_reply":"2021-11-19T15:58:22.672568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def allocate_data(frac_total=0.4):\n    \"\"\"\n    \"\"\"\n    # Creating the base dir\n    base_dir = 'base_dir'\n    if os.path.isdir(base_dir):\n        shutil.rmtree(base_dir)\n        os.mkdir(base_dir)\n    else:\n        os.mkdir(base_dir)\n        \n    # Creating train and validation dir\n    train_dir = os.path.join(base_dir, \"train_dir\")\n    if not os.path.isdir(train_dir):\n        os.mkdir(train_dir)\n        \n    val_dir = os.path.join(base_dir, \"val_dir\")\n    if not os.path.isdir(val_dir):\n        os.mkdir(val_dir)\n    \n    \n    # Getting the different labels\n    json_labels = '/kaggle/input/cassava-leaf-disease-classification/label_num_to_disease_map.json'\n    with open(json_labels) as json_file:\n        labels = json.load(json_file)\n        #data_keys = data.keys()\n        labels = {key : labels[key].replace(\" \", \"_\") for key in labels.keys()} \n        #print(labels)\n    \n    # Creating the labels' directories\n    for d in [train_dir, val_dir]:\n        for label in labels.values():\n            t_dir = os.path.join(d, label)\n            if not os.path.isdir(t_dir):\n                os.mkdir(t_dir)\n                \n    print(f\"Directories for training: {os.listdir(train_dir)}\")\n    print(f\"Directories for validation: {os.listdir(val_dir)}\")\n    \n    # Load labels dataframe and sample it for train and validation\n    labels_df = pd.read_csv(\"../input/cassava-leaf-disease-classification/train.csv\")\n    #print(labels_df.head())\n    labels_df = labels_df.groupby('label').apply(lambda x: x.sample(frac=frac_total))\n    train_sample = labels_df.sample(frac = 0.70, replace=False, random_state=1998)\n    val_sample = labels_df.drop(train_sample.index)    \n    train_sample_dict = train_sample.to_dict() \n    val_sample_dict = val_sample.to_dict() \n    \n    #print(train_sample_dict['image_id'].values())\n    #print(f\"Train : {len(train_images_id)}, Validation : {len(val_images_id)}\")\n    print(f\"Train : {len(train_sample_dict['image_id'])}, Validation : {len(val_sample_dict['image_id'])}\")\n    \n    # Transfer the images\n    train_images_dir = \"../input/cassava-leaf-disease-classification/train_images\"\n    ## Train dir\n    #test = []\n    for image_key, image_value in train_sample_dict['image_id'].items():\n        label_ = train_sample_dict['label'][image_key]\n        label = labels[str(label_)]\n        image = str(image_value)\n        #test.append(image)\n        src = os.path.join(train_images_dir, image)\n        dst = os.path.join(train_dir, label, image)\n        shutil.copyfile(src, dst)\n    #print(test)\n        \n    ## Validation dir\n    for image_key, image_value in val_sample_dict['image_id'].items():\n        label_ = val_sample_dict['label'][image_key]\n        label = labels[str(label_)]\n        image = str(image_value)\n        #test.append(image)\n        src = os.path.join(train_images_dir, image)\n        dst = os.path.join(val_dir, label, image)\n        shutil.copyfile(src, dst)\n    \n    print(\"\\nTrain set:\\n\")\n    total = 0\n    for label in labels.values():\n        t = os.path.join(train_dir, label)\n        total += len(os.listdir(t))\n        print(f\"Length of {label} in {train_dir} is: {len(os.listdir(t))}\")\n    print(f\"\\nTotal: {total}\")\n    print(\"\\nVal set:\\n\")\n    \n    total = 0\n    for label in labels.values():\n        t = os.path.join(val_dir, label)\n        total += len(os.listdir(t))\n        print(f\"Length of {label} in {val_dir} is: {len(os.listdir(t))}\")\n    print(f\"\\nTotal: {total}\")","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:58:22.675905Z","iopub.execute_input":"2021-11-19T15:58:22.676226Z","iopub.status.idle":"2021-11-19T15:58:22.695548Z","shell.execute_reply.started":"2021-11-19T15:58:22.676189Z","shell.execute_reply":"2021-11-19T15:58:22.694789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"allocate_data()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:58:22.697018Z","iopub.execute_input":"2021-11-19T15:58:22.697522Z","iopub.status.idle":"2021-11-19T15:59:21.396241Z","shell.execute_reply.started":"2021-11-19T15:58:22.697487Z","shell.execute_reply":"2021-11-19T15:59:21.395473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def import_images_paths(n=5, is_random=False):\n    train_path = './base_dir/train_dir'\n    train_directories = os.listdir(train_path)\n    \n    paths_dict = {}\n    for x in train_directories:\n        t_join = os.path.join(train_path, x)\n        t_listdir = os.listdir(t_join)\n        t_len_listdir = len(t_listdir)\n        if is_random:\n            t_listdir = [t_listdir[i] for i in random.sample(range(0, t_len_listdir + 1), n)]\n        else:\n            t_listdir = os.listdir(t_join)[:n]\n        paths_dict[x] = [os.path.join(t_join, y) for y in t_listdir]\n        #print(os.listdir(os.path.join(train_path, x))[:5])\n    return paths_dict","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:21.398321Z","iopub.execute_input":"2021-11-19T15:59:21.398571Z","iopub.status.idle":"2021-11-19T15:59:21.407712Z","shell.execute_reply.started":"2021-11-19T15:59:21.398537Z","shell.execute_reply":"2021-11-19T15:59:21.407020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def import_images(n=5, is_random=False):\n    paths_dict = import_images_paths(n, is_random)\n    \n    images_dict = {}\n    for key, values in paths_dict.items():\n        t_list_images = []\n        for value in values:\n            t_list_images.append(mpimg.imread(value))\n        images_dict[key] = t_list_images\n    \n    return images_dict","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:21.409965Z","iopub.execute_input":"2021-11-19T15:59:21.410268Z","iopub.status.idle":"2021-11-19T15:59:21.417636Z","shell.execute_reply.started":"2021-11-19T15:59:21.410236Z","shell.execute_reply":"2021-11-19T15:59:21.416890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import_images_paths()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:21.419104Z","iopub.execute_input":"2021-11-19T15:59:21.419513Z","iopub.status.idle":"2021-11-19T15:59:21.425796Z","shell.execute_reply.started":"2021-11-19T15:59:21.419478Z","shell.execute_reply":"2021-11-19T15:59:21.425046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_images(n=5, is_random=False):\n    images_dict = import_images(n, is_random)\n    \n    #plt.figure(figsize=(20,10))\n    \n    columns = n#5\n    lines = len(images_dict.keys())#1\n    fig, ax = plt.subplots(lines, columns, figsize=(8 * 2.5, 6 * 2.5))\n    \n    i = 0\n    for key, values in images_dict.items():\n        for j, image in enumerate(values):\n            #plt.subplot(lines, columns, j + 1) #(len(images) / columns + 1, columns, i + 1)\n            ax[i, j].imshow(image, aspect='auto')\n            ax[i, j].set_title(key)\n        i += 1\n    #plt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:21.427372Z","iopub.execute_input":"2021-11-19T15:59:21.427697Z","iopub.status.idle":"2021-11-19T15:59:21.435664Z","shell.execute_reply.started":"2021-11-19T15:59:21.427663Z","shell.execute_reply":"2021-11-19T15:59:21.434810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_images(is_random=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:21.437083Z","iopub.execute_input":"2021-11-19T15:59:21.437377Z","iopub.status.idle":"2021-11-19T15:59:26.363538Z","shell.execute_reply.started":"2021-11-19T15:59:21.437346Z","shell.execute_reply":"2021-11-19T15:59:26.362684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_images(is_random=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:26.364682Z","iopub.execute_input":"2021-11-19T15:59:26.364956Z","iopub.status.idle":"2021-11-19T15:59:31.260351Z","shell.execute_reply.started":"2021-11-19T15:59:26.364918Z","shell.execute_reply":"2021-11-19T15:59:31.259633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def print_diseases_repartition(is_train=True):\n    if is_train:\n        path = './base_dir/train_dir'\n    else:\n        path = './base_dir/val_dir'\n    directories = os.listdir(path)\n    \n    total = 0\n    count_dict = {}\n    for x in directories:\n        t_join = os.path.join(path, x)\n        t_listdir = os.listdir(t_join)\n        t_len_listdir = len(t_listdir)\n        total += t_len_listdir\n        count_dict[x] = t_len_listdir\n    \n    count_prop = {}\n    for key, value in count_dict.items():\n        count_prop[key] = round((value / total), 2)\n        \n    return(count_prop)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:31.262892Z","iopub.execute_input":"2021-11-19T15:59:31.264066Z","iopub.status.idle":"2021-11-19T15:59:31.273916Z","shell.execute_reply.started":"2021-11-19T15:59:31.264025Z","shell.execute_reply":"2021-11-19T15:59:31.272979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print_diseases_repartition()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:31.275476Z","iopub.execute_input":"2021-11-19T15:59:31.275923Z","iopub.status.idle":"2021-11-19T15:59:31.293214Z","shell.execute_reply.started":"2021-11-19T15:59:31.275888Z","shell.execute_reply":"2021-11-19T15:59:31.292650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rgb2gray(image):\n    return np.dot(image[...,:3], [0.2989, 0.5870, 0.1140])","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:31.294146Z","iopub.execute_input":"2021-11-19T15:59:31.294786Z","iopub.status.idle":"2021-11-19T15:59:31.300924Z","shell.execute_reply.started":"2021-11-19T15:59:31.294748Z","shell.execute_reply":"2021-11-19T15:59:31.298416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_images_hist(n=5, is_random=False, is_rgb=True):\n    \"\"\"\n    \"\"\"\n    images_dict = import_images(n, is_random)\n    \n    #plt.figure(figsize=(20,10))\n    \n    columns = n#5\n    lines = len(images_dict.keys())#1\n    coef = 3\n    fig, ax = plt.subplots(lines, columns, figsize=(8 * coef, 6 * coef))\n    \n    if is_rgb:\n        colors = (\"R\", \"G\", \"B\")\n        channels = (0, 1, 2)\n    \n    i = 0\n    for key, values in images_dict.items():\n        for j, image in enumerate(values):\n            if is_rgb:\n                for channel, color in zip(channels, colors):\n                    #subfigs = fig.subfigures(1, 3)\n                    ax[i, j].hist(image[:, :, channel].ravel(), bins=256, range=(0, 256), color=color.lower())\n                    ax[i, j].set_title(key)\n                    ax[i, j].set_xlabel(\"Color Value\")\n                    ax[i, j].set_ylabel(\"Pixels\")\n            else:\n                rgb2gray(image)\n                ax[i, j].hist(image.ravel(), bins=256, range=(0.0, 1.0))\n                ax[i, j].set_xlabel(\"Color Value\")\n                ax[i, j].set_ylabel(\"Pixels\")\n                ax[i, j].set_title(key)        \n        i += 1\n    plt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:31.303085Z","iopub.execute_input":"2021-11-19T15:59:31.303584Z","iopub.status.idle":"2021-11-19T15:59:31.316974Z","shell.execute_reply.started":"2021-11-19T15:59:31.303551Z","shell.execute_reply":"2021-11-19T15:59:31.316175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_images_hist(n=5, is_random=False, is_rgb=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T15:59:31.318387Z","iopub.execute_input":"2021-11-19T15:59:31.318915Z","iopub.status.idle":"2021-11-19T16:00:16.455905Z","shell.execute_reply.started":"2021-11-19T15:59:31.318882Z","shell.execute_reply":"2021-11-19T16:00:16.455093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_images_hist(n=5, is_random=False, is_rgb=False)\n# true values ?","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:00:16.457418Z","iopub.execute_input":"2021-11-19T16:00:16.457679Z","iopub.status.idle":"2021-11-19T16:00:35.554010Z","shell.execute_reply.started":"2021-11-19T16:00:16.457646Z","shell.execute_reply":"2021-11-19T16:00:35.553270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_image_stats(n=5, is_random=False):\n    \"\"\"\n    \"\"\"\n    images_dict = import_images(n, is_random)\n    \n    colors = (\"R\", \"G\", \"B\")\n    channels = (0, 1, 2)\n    \n    mean_col_dict = {}\n    \n    for key, values in images_dict.items():\n        R_list = []\n        G_list = []\n        B_list = []\n        for i, value in enumerate(values):\n            for channel, color in zip(channels, colors):\n                if color == \"R\":\n                    R_list.append(np.mean(value[:, :, channel]))\n                elif color == \"G\":\n                    G_list.append(np.mean(value[:, :, channel]))\n                else:\n                    B_list.append(np.mean(value[:, :, channel]))\n        mean_col_dict[key] = (np.mean(R_list), np.mean(G_list), np.mean(B_list))\n    \n    return mean_col_dict","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:00:35.555543Z","iopub.execute_input":"2021-11-19T16:00:35.556069Z","iopub.status.idle":"2021-11-19T16:00:35.565688Z","shell.execute_reply.started":"2021-11-19T16:00:35.556032Z","shell.execute_reply":"2021-11-19T16:00:35.564807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_image_stats(n = 100)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:00:35.566739Z","iopub.execute_input":"2021-11-19T16:00:35.567808Z","iopub.status.idle":"2021-11-19T16:00:40.458517Z","shell.execute_reply.started":"2021-11-19T16:00:35.567767Z","shell.execute_reply":"2021-11-19T16:00:40.457764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_generators(color_mode=\"rgb\", batch_size=64):\n    \"\"\"\n    \"\"\"\n    train_path = './base_dir/train_dir'\n    val_path = './base_dir/val_dir'\n    #test_path =\n    \n    train_directories = os.listdir(train_path)\n    val_directories = os.listdir(val_path)\n    \n    num_train_samples = sum([len(os.listdir(os.path.join(train_path, x))) for x in train_directories])\n    num_val_samples = sum([len(os.listdir(os.path.join(val_path, x))) for x in val_directories])\n    print(num_train_samples)\n    print(num_val_samples)\n    \n    train_batch_size = batch_size\n    val_batch_size = batch_size\n    \n    train_steps = np.ceil(num_train_samples / train_batch_size)\n    val_steps = np.ceil(num_val_samples / val_batch_size)\n    \n    datagen = ImageDataGenerator(rescale=1.0/255)\n\n    train_gen = datagen.flow_from_directory(train_path,\n                                            target_size=(256,256),\n                                            color_mode=color_mode,#\"grayscale\", #\"rgb\"\n                                            batch_size=train_batch_size,\n                                            class_mode='categorical')\n\n    val_gen = datagen.flow_from_directory(val_path,\n                                            target_size=(256,256),\n                                            color_mode=color_mode,#\"grayscale\", #\"rgb\"\n                                            batch_size=val_batch_size,\n                                            class_mode='categorical')\n    \n    return train_gen, val_gen, train_steps, val_steps\n\ndef plot_history(history, metric=\"loss\"):\n    nb_epochs = range(1, history.params[\"epochs\"] + 1)\n    plt.plot(nb_epochs, history.history[metric], label = metric)\n    plt.plot(nb_epochs, history.history[\"val_\" + metric], label = \"val_\" + metric)\n    plt.legend()\n    ","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:00:40.461408Z","iopub.execute_input":"2021-11-19T16:00:40.461805Z","iopub.status.idle":"2021-11-19T16:00:40.472800Z","shell.execute_reply.started":"2021-11-19T16:00:40.461767Z","shell.execute_reply":"2021-11-19T16:00:40.471452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_model(classification_type = 'softmax'):\n    \"\"\"\n    \"\"\"\n    \n    base_model = keras.applications.vgg19.VGG19(\n        weights=\"imagenet\",  # Load weights pre-trained on ImageNet.\n        input_shape=(256, 256, 3),\n        include_top=False,\n    )\n    base_model.trainable = False # freeze base_model\n    \n    input_shape = (256, 256, 3)\n    inputs = keras.Input(shape=input_shape)\n    scale_layer = keras.layers.Rescaling(scale=1./127.5, offset=-1) # [-1, 1]\n    x = scale_layer(inputs)\n    #x=inputs/255\n    \n    x = base_model(x, training=False)\n    x = keras.layers.GlobalAveragePooling2D()(x)\n    x = keras.layers.Dropout(0.5)(x)  # Regularize with dropout\n    outputs = keras.layers.Dense(5, activation=classification_type)(x)\n    model = keras.Model(inputs, outputs)    \n    model.summary()\n    \n    return model\n\ndef compile_and_fit(model):\n    \"\"\"\n    \"\"\"\n    with tf.device('/GPU:0'):\n        train_gen, val_gen, train_steps, val_steps = create_generators(\"rgb\")\n\n        model.compile(\n        loss='categorical_crossentropy',\n        optimizer=optimizers.RMSprop(lr=1e-4),\n        metrics=['acc'])\n\n        #BATCH_SIZE = 16\n        epochs = 10\n        #creuser ça \n        filepath = \"VGG19_TPUmodel.h5\"\n        checkpoint = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, \n                                 save_best_only=True, mode='max')\n        reduce_lr = ReduceLROnPlateau(monitor='val_acc', factor=0.5, patience=2, \n                                       verbose=1, mode='max', min_lr=0.00001)\n        callbacks_list = [checkpoint, reduce_lr]\n    \n        history = model.fit(\n            train_gen,\n            steps_per_epoch=train_steps,\n            validation_data=val_gen,\n            validation_steps=val_steps,\n            epochs = epochs,\n            callbacks=callbacks_list)\n    \n    return history","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:15:32.359264Z","iopub.execute_input":"2021-11-19T16:15:32.359995Z","iopub.status.idle":"2021-11-19T16:15:32.371419Z","shell.execute_reply.started":"2021-11-19T16:15:32.359944Z","shell.execute_reply":"2021-11-19T16:15:32.370727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model()\nhistory = compile_and_fit(model)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:15:33.147631Z","iopub.execute_input":"2021-11-19T16:15:33.148203Z","iopub.status.idle":"2021-11-19T16:28:52.090297Z","shell.execute_reply.started":"2021-11-19T16:15:33.148164Z","shell.execute_reply":"2021-11-19T16:28:52.089504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_history(history)","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:28:52.091937Z","iopub.execute_input":"2021-11-19T16:28:52.092689Z","iopub.status.idle":"2021-11-19T16:28:52.310190Z","shell.execute_reply.started":"2021-11-19T16:28:52.092645Z","shell.execute_reply":"2021-11-19T16:28:52.309501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_history(history, \"acc\")","metadata":{"execution":{"iopub.status.busy":"2021-11-19T16:14:15.387549Z","iopub.execute_input":"2021-11-19T16:14:15.387832Z","iopub.status.idle":"2021-11-19T16:14:15.635412Z","shell.execute_reply.started":"2021-11-19T16:14:15.387803Z","shell.execute_reply":"2021-11-19T16:14:15.634714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}