{"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":"markdown","source":"## Import Libraries","metadata":{}},{"cell_type":"code","source":"%matplotlib inline\n%config InlineBackend.figure_format = 'retina'\nimport os\nimport glob\nimport json\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nimport cv2\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix, classification_report\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D,GlobalAveragePooling2D, Flatten, Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.callbacks import ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras.optimizers import Adam\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport logging\nlogger = tf.get_logger()\nlogger.setLevel(logging.ERROR)\n","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:05.216623Z","iopub.execute_input":"2023-04-05T20:13:05.21746Z","iopub.status.idle":"2023-04-05T20:13:05.245181Z","shell.execute_reply.started":"2023-04-05T20:13:05.217412Z","shell.execute_reply":"2023-04-05T20:13:05.244239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:05.713009Z","iopub.execute_input":"2023-04-05T20:13:05.713325Z","iopub.status.idle":"2023-04-05T20:13:05.718288Z","shell.execute_reply.started":"2023-04-05T20:13:05.713296Z","shell.execute_reply":"2023-04-05T20:13:05.717079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_files(base_dir, target_dir):\n    count = 0\n    path = get_path(base_dir, target_dir)\n    for dirname, _, filenames in os.walk(path):\n        for filename in filenames:\n            count+=len(glob.glob(os.path.join(dirname, filename)))\n        return path, count\n    \ndef get_path(base_dir, target_dir):\n    path = os.path.join(base_dir,target_dir)\n    return path","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:05.790208Z","iopub.execute_input":"2023-04-05T20:13:05.790588Z","iopub.status.idle":"2023-04-05T20:13:05.796378Z","shell.execute_reply.started":"2023-04-05T20:13:05.790559Z","shell.execute_reply":"2023-04-05T20:13:05.795358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Directory Setup","metadata":{}},{"cell_type":"code","source":"base_dir = '/kaggle/input/cassava-leaf-disease-classification'\ntrain_dir = 'train_images'\nlabels_file = 'train.csv'\ntest_dir = 'test_images'\njson_file = 'label_num_to_disease_map.json'\n\ntrain_path, train_count = get_files(base_dir,train_dir)\ntest_path, test_count = get_files(base_dir,test_dir)\n\nwith open(get_path(base_dir,json_file)) as f:\n    class_names = json.load(f)\n    class_dict = pd.Series(class_names.values()).to_dict()\n    f.close()\n\ndata = pd.read_csv(get_path(base_dir, labels_file))\ndata['class_name'] = data.label.map(class_dict)\n\nprint(\"No of Train Images: {}\".format(train_count))\nprint(\"No of Test Images: {}\".format(test_count))\nprint(\"No of Classes: {}\".format(len(class_dict)))\nprint(\"Classes:\")\nfor v in class_dict.values():\n    print(\" \\u2022 {}\".format(v))","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2023-04-05T20:13:05.959016Z","iopub.execute_input":"2023-04-05T20:13:05.959333Z","iopub.status.idle":"2023-04-05T20:13:08.169529Z","shell.execute_reply.started":"2023-04-05T20:13:05.959304Z","shell.execute_reply":"2023-04-05T20:13:08.168626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.info()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:08.174916Z","iopub.execute_input":"2023-04-05T20:13:08.179758Z","iopub.status.idle":"2023-04-05T20:13:08.205493Z","shell.execute_reply.started":"2023-04-05T20:13:08.17969Z","shell.execute_reply":"2023-04-05T20:13:08.204595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data['class_name'].value_counts().plot(kind='bar')","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:08.210652Z","iopub.execute_input":"2023-04-05T20:13:08.212962Z","iopub.status.idle":"2023-04-05T20:13:08.509898Z","shell.execute_reply.started":"2023-04-05T20:13:08.21292Z","shell.execute_reply":"2023-04-05T20:13:08.509065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for dirname, _, filenames in os.walk(train_path):\n    for filename in filenames:\n        image = cv2.imread(os.path.join(train_path, filename))\n        image_size = image.shape\n        break\n\nimage_size","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:08.514501Z","iopub.execute_input":"2023-04-05T20:13:08.515173Z","iopub.status.idle":"2023-04-05T20:13:09.375736Z","shell.execute_reply.started":"2023-04-05T20:13:08.515135Z","shell.execute_reply":"2023-04-05T20:13:09.374819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualization","metadata":{}},{"cell_type":"code","source":"def visualize_img(images):\n    fig = plt.figure(figsize=(20, 15))\n    for i,a in enumerate(images):\n        fig.add_subplot(4, 4, i+1, xticks=[], yticks=[])\n        path = get_path(train_path, a)\n        img = cv2.imread(path)\n        plt.imshow(img)\n        plt.title(data[data.image_id == a].class_name.values[0])\n    \nfig = plt.figure(figsize=(15, 15))\np=0\nfor i in range(5):\n    images = data[data.label == i].image_id\n    images = np.random.choice(images , 4)\n    visualize_img(images)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:09.378656Z","iopub.execute_input":"2023-04-05T20:13:09.379218Z","iopub.status.idle":"2023-04-05T20:13:13.953201Z","shell.execute_reply.started":"2023-04-05T20:13:09.379177Z","shell.execute_reply":"2023-04-05T20:13:13.951899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plotImages(images_arr):\n    fig, axes = plt.subplots(1, 5, figsize=(20,20))\n    axes = axes.flatten()\n    for img, ax in zip(images_arr, axes):\n        ax.imshow(img)\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:13.955161Z","iopub.execute_input":"2023-04-05T20:13:13.955471Z","iopub.status.idle":"2023-04-05T20:13:13.961559Z","shell.execute_reply.started":"2023-04-05T20:13:13.95544Z","shell.execute_reply":"2023-04-05T20:13:13.960643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Example of Image Augmentation","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 64\nIMG_SHAPE  = 224\n\ntrain_image_gen = ImageDataGenerator(rescale=1./255,\n                                     width_shift_range=0.1,\n                                     height_shift_range=0.1,\n                                     brightness_range=[0.2,1.0],\n                                     zoom_range=0.2,\n                                     horizontal_flip=True,\n                                     vertical_flip=True,\n                                     fill_mode='nearest')\n\ntrain_gen = train_image_gen.flow_from_dataframe(data,\n                                          directory=train_path,\n                                          x_col='image_id',\n                                          y_col='class_name',\n                                          class_mode='categorical',\n                                          batch_size=BATCH_SIZE,\n                                          shuffle=True,\n                                          target_size=(IMG_SHAPE,IMG_SHAPE))","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:13.963147Z","iopub.execute_input":"2023-04-05T20:13:13.96369Z","iopub.status.idle":"2023-04-05T20:13:14.304236Z","shell.execute_reply.started":"2023-04-05T20:13:13.963656Z","shell.execute_reply":"2023-04-05T20:13:14.301009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"augmented_images = [train_gen[0][0][1] for i in range(5)]\nplotImages(augmented_images)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:14.305701Z","iopub.execute_input":"2023-04-05T20:13:14.306075Z","iopub.status.idle":"2023-04-05T20:13:21.937985Z","shell.execute_reply.started":"2023-04-05T20:13:14.306038Z","shell.execute_reply":"2023-04-05T20:13:21.935924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Preprocessing","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import LabelBinarizer\n\ntrain, val = train_test_split(data, test_size = 0.25, random_state=42)\n\nlb = LabelBinarizer()\nlb.fit(data.label)\n\ntrain_lb = lb.transform(train.label)\nval_lb = lb.transform(val.label)\n\ntrain = train.reset_index().drop(labels='index', axis=1)\ny_train = pd.DataFrame(train_lb).add_prefix('label_')\n\nval = val.reset_index().drop(labels='index', axis=1)\ny_val = pd.DataFrame(val_lb).add_prefix('label_')\n\ntrain = pd.concat([train, y_train], axis=1)\nval = pd.concat([val, y_val], axis=1)\n\nprint(\"Training set has {} samples\".format(train.shape[0]))\nprint(\"Validation set has {} samples\".format(val.shape[0]))","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:21.939463Z","iopub.execute_input":"2023-04-05T20:13:21.940046Z","iopub.status.idle":"2023-04-05T20:13:21.977422Z","shell.execute_reply.started":"2023-04-05T20:13:21.940009Z","shell.execute_reply":"2023-04-05T20:13:21.976569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Helper Functions","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 32\nIMG_SHAPE  = 224\nEPOCHS = 10\n\ndef gen():\n    train_image_gen = ImageDataGenerator(rescale=1./255,\n                                         width_shift_range=0.1,\n                                         height_shift_range=0.1,\n                                         brightness_range=[0.2,1.0],\n                                         zoom_range=0.2,\n                                         horizontal_flip=True,\n                                         vertical_flip=True,\n                                         fill_mode='nearest')\n\n    train_gen = train_image_gen.flow_from_dataframe(train,\n                                              directory=train_path,\n                                              x_col='image_id',\n                                              y_col=[f'label_{x}' for x in np.arange(5)],\n                                              class_mode='raw',\n                                              batch_size=BATCH_SIZE,\n                                              shuffle=True,\n                                              target_size=(IMG_SHAPE,IMG_SHAPE))\n\n\n    val_image_gen = ImageDataGenerator(rescale=1./255)\n\n    val_gen = val_image_gen.flow_from_dataframe(val,\n                                              directory=train_path,\n                                              x_col='image_id',\n                                              y_col= [f'label_{x}' for x in np.arange(5)],\n                                              class_mode='raw',\n                                              batch_size=BATCH_SIZE,\n                                              target_size=(IMG_SHAPE,IMG_SHAPE))\n    return train_gen, val_gen\n","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:21.979208Z","iopub.execute_input":"2023-04-05T20:13:21.979944Z","iopub.status.idle":"2023-04-05T20:13:21.989434Z","shell.execute_reply.started":"2023-04-05T20:13:21.979908Z","shell.execute_reply":"2023-04-05T20:13:21.988582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot(history):\n\n    training_accuracy = history.history['accuracy']\n    validation_accuracy = history.history['val_accuracy']\n\n    training_loss = history.history['loss']\n    validation_loss = history.history['val_loss']\n\n    epochs_range=range(len(training_accuracy))\n\n    plt.figure(figsize=(8, 8))\n    plt.subplot(1, 2, 1)\n    plt.plot(epochs_range, training_accuracy, label='Training Accuracy')\n    plt.plot(epochs_range, validation_accuracy, label='Validation Accuracy')\n    plt.legend(loc='lower right')\n    plt.title('Training and Validation Accuracy')\n\n    plt.subplot(1, 2, 2)\n    plt.plot(epochs_range, training_loss, label='Training Loss')\n    plt.plot(epochs_range, validation_loss, label='Validation Loss')\n    plt.legend(loc='upper right')\n    plt.title('Training and Validation Loss')\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:21.99085Z","iopub.execute_input":"2023-04-05T20:13:21.991447Z","iopub.status.idle":"2023-04-05T20:13:22.0031Z","shell.execute_reply.started":"2023-04-05T20:13:21.991412Z","shell.execute_reply":"2023-04-05T20:13:22.001933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\ndef predict(image_path, model):\n    im = Image.open(image_path)\n    test_image = np.asarray(im)\n    processed_test_image = process_image(test_image)\n    processed_test_image = np.expand_dims(processed_test_image, axis = 0)\n    \n    ps = model.predict(processed_test_image)\n    return ps\n    \ndef process_image(image):\n    image = tf.cast(image , tf.float32)\n    image = tf.image.resize(image , (224 , 224))\n    image = image/255\n    image = image.numpy()\n    return image\n","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:22.004694Z","iopub.execute_input":"2023-04-05T20:13:22.005308Z","iopub.status.idle":"2023-04-05T20:13:22.014803Z","shell.execute_reply.started":"2023-04-05T20:13:22.005274Z","shell.execute_reply":"2023-04-05T20:13:22.013719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.utils import class_weight\n\nclass_weights = class_weight.compute_class_weight('balanced', np.unique(train['label']), train.label)\nclass_weights = dict(enumerate(class_weights))\nclass_weights","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:22.016325Z","iopub.execute_input":"2023-04-05T20:13:22.017017Z","iopub.status.idle":"2023-04-05T20:13:22.031045Z","shell.execute_reply.started":"2023-04-05T20:13:22.016983Z","shell.execute_reply":"2023-04-05T20:13:22.030294Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Modeling","metadata":{}},{"cell_type":"markdown","source":"1. **VGG-16 Model** ","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import VGG16\nfrom tensorflow.keras.applications.vgg16 import preprocess_input as vgg16_preprocess\ntf.keras.backend.clear_session()\n\nbase = VGG16(weights = 'imagenet' , include_top=False, input_shape=(IMG_SHAPE, IMG_SHAPE, 3))   \n\nvgg16_model = Sequential()\nvgg16_model.add(base)\nvgg16_model.add(GlobalAveragePooling2D())\nvgg16_model.add(Dropout(0.5))\nvgg16_model.add(BatchNormalization())\nvgg16_model.add(Dense(128, activation='relu'))\nvgg16_model.add(Dropout(0.5))\nvgg16_model.add(Dense(5, activation='softmax'))\n\nvgg16_model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:22.032828Z","iopub.execute_input":"2023-04-05T20:13:22.033482Z","iopub.status.idle":"2023-04-05T20:13:22.430045Z","shell.execute_reply.started":"2023-04-05T20:13:22.033448Z","shell.execute_reply":"2023-04-05T20:13:22.425586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(vgg16_model, to_file='vgg16_model.png', show_shapes=True, show_layer_names=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:22.431505Z","iopub.execute_input":"2023-04-05T20:13:22.431883Z","iopub.status.idle":"2023-04-05T20:13:22.643035Z","shell.execute_reply.started":"2023-04-05T20:13:22.431846Z","shell.execute_reply":"2023-04-05T20:13:22.641893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_gen, val_gen = gen()\n\noptm = Adam(lr=0.0001)\nvgg16_model.compile(loss='categorical_crossentropy', optimizer=optm, \n                  metrics=['accuracy'])\n\nEarlyStopping = EarlyStopping(monitor='val_loss',\n                              min_delta=.0001,\n                              patience=5,\n                              verbose=1,\n                              mode='auto',\n                              baseline=None,\n                              restore_best_weights=True)\n\nmodel_save = ModelCheckpoint('./vgg16.h5',\n                             save_best_only = True, \n                             save_weights_only = False,\n                             monitor = 'val_loss', \n                             mode = 'min', verbose = 1)\n\n\nvgg_history = vgg16_model.fit_generator(train_gen,\n                                    steps_per_epoch = train_gen.samples // BATCH_SIZE,\n                                    epochs = 10,\n                                    validation_data = val_gen,\n                                    validation_steps = val_gen.samples // BATCH_SIZE,\n                                    callbacks=[EarlyStopping, model_save])","metadata":{"execution":{"iopub.status.busy":"2023-04-05T20:13:22.644856Z","iopub.execute_input":"2023-04-05T20:13:22.645433Z","iopub.status.idle":"2023-04-05T21:16:31.420888Z","shell.execute_reply.started":"2023-04-05T20:13:22.645389Z","shell.execute_reply":"2023-04-05T21:16:31.420059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot(vgg_history)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:16:31.427051Z","iopub.execute_input":"2023-04-05T21:16:31.427374Z","iopub.status.idle":"2023-04-05T21:16:31.792734Z","shell.execute_reply.started":"2023-04-05T21:16:31.427343Z","shell.execute_reply":"2023-04-05T21:16:31.791774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images = os.listdir(test_path)    \nfor image in test_images:\n    vgg16_pred = predict(os.path.join(test_path, image) , vgg16_model)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:22:20.688153Z","iopub.execute_input":"2023-04-05T21:22:20.688478Z","iopub.status.idle":"2023-04-05T21:22:20.871451Z","shell.execute_reply.started":"2023-04-05T21:22:20.688447Z","shell.execute_reply":"2023-04-05T21:22:20.870667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_pred","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:22:21.117362Z","iopub.execute_input":"2023-04-05T21:22:21.117633Z","iopub.status.idle":"2023-04-05T21:22:21.125025Z","shell.execute_reply.started":"2023-04-05T21:22:21.117604Z","shell.execute_reply":"2023-04-05T21:22:21.123929Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.argmax(vgg16_pred)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:22:21.363708Z","iopub.execute_input":"2023-04-05T21:22:21.364047Z","iopub.status.idle":"2023-04-05T21:22:21.370061Z","shell.execute_reply.started":"2023-04-05T21:22:21.364016Z","shell.execute_reply":"2023-04-05T21:22:21.369063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg16_preds = vgg16_model.predict(val_gen)\nvgg16_preds = np.argmax(vgg16_preds, axis=-1)\norg_label = val['label'].astype('int')\n\nmatrix=confusion_matrix(org_label, vgg16_preds)\nsns.heatmap(matrix,square=True, annot=True, fmt='d', cbar=False,\n            xticklabels=['0', '1', '2', '3', '4'],\n            yticklabels=['0', '1', '2', '3', '4'])\nplt.xlabel('Predicted label')\nplt.ylabel('True label');\n","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:22:21.823107Z","iopub.execute_input":"2023-04-05T21:22:21.823392Z","iopub.status.idle":"2023-04-05T21:23:06.921685Z","shell.execute_reply.started":"2023-04-05T21:22:21.823364Z","shell.execute_reply":"2023-04-05T21:23:06.920733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"2. MobileNetV2","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2\n\nbase = MobileNetV2(weights = 'imagenet', include_top = False, input_shape = (224, 224, 3))\ntf.keras.backend.clear_session()\n\nfor layers in base.layers:   \n    layers.trainable = True\n    \nfor layer in base.layers[:100]:\n    layer.trainable =  False\n\nmobilenet_model = Sequential()\nmobilenet_model.add(base)\nmobilenet_model.add(GlobalAveragePooling2D())\nmobilenet_model.add(BatchNormalization())\nmobilenet_model.add(Dense(256, activation='relu'))\nmobilenet_model.add(Dropout(0.5))\nmobilenet_model.add(BatchNormalization())\nmobilenet_model.add(Dense(128, activation='relu'))\nmobilenet_model.add(Dropout(0.5))\nmobilenet_model.add(Dense(5, activation='softmax'))\n\nmobilenet_model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:44.141223Z","iopub.execute_input":"2023-04-05T21:23:44.141597Z","iopub.status.idle":"2023-04-05T21:23:45.578079Z","shell.execute_reply.started":"2023-04-05T21:23:44.141564Z","shell.execute_reply":"2023-04-05T21:23:45.574447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(mobilenet_model, to_file='mobilenetV2.png', show_shapes=True, show_layer_names=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:48.54585Z","iopub.execute_input":"2023-04-05T21:23:48.546194Z","iopub.status.idle":"2023-04-05T21:23:48.763945Z","shell.execute_reply.started":"2023-04-05T21:23:48.546162Z","shell.execute_reply":"2023-04-05T21:23:48.762896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_gen, val_gen = gen()\n\noptm = Adam(lr=0.0001)\nmobilenet_model.compile(loss='categorical_crossentropy', optimizer=optm, \n                  metrics=['accuracy'])\n\nEarlyStopping = EarlyStopping(monitor='val_loss',\n                              min_delta=.0001,\n                              patience=3,\n                              verbose=1,\n                              mode='auto',\n                              baseline=None,\n                              restore_best_weights=True)\n\nmodel_save = ModelCheckpoint('./mobilenetV2.h5',\n                             save_best_only = True,\n                             save_weights_only = False,\n                             monitor = 'val_loss', \n                             mode = 'min', verbose = 1)\n\n\nmob_history = mobilenet_model.fit(train_gen,\n                              steps_per_epoch = train_gen.samples // BATCH_SIZE,\n                              epochs = 10,\n                              validation_data = val_gen,\n                              validation_steps = val_gen.samples // BATCH_SIZE,\n                              callbacks=[EarlyStopping, model_save])","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:24:06.557673Z","iopub.execute_input":"2023-04-05T21:24:06.55804Z","iopub.status.idle":"2023-04-05T21:24:07.637372Z","shell.execute_reply.started":"2023-04-05T21:24:06.558008Z","shell.execute_reply":"2023-04-05T21:24:07.635903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot(mob_history)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:28.596425Z","iopub.execute_input":"2023-04-05T21:23:28.596784Z","iopub.status.idle":"2023-04-05T21:23:28.622255Z","shell.execute_reply.started":"2023-04-05T21:23:28.596733Z","shell.execute_reply":"2023-04-05T21:23:28.620935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(mob_history.history['val_accuracy'][-4])\nprint(mob_history.history['val_loss'][-4])","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.681022Z","iopub.status.idle":"2023-04-05T21:23:15.682061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images = os.listdir(test_path)    \nfor image in test_images:\n    mobilenet_pred = predict(os.path.join(test_path, image) , mobilenet_model)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.683469Z","iopub.status.idle":"2023-04-05T21:23:15.68582Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mobilenet_pred","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.687126Z","iopub.status.idle":"2023-04-05T21:23:15.688022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.argmax(mobilenet_pred)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.689368Z","iopub.status.idle":"2023-04-05T21:23:15.690284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mob_preds = mobilenet_model.predict(val_gen)\nmob_preds = np.argmax(mob_preds, axis=-1)\norg_label = val['label'].astype('int')\n\nmatrix=confusion_matrix(org_label, mob_preds)\nsns.heatmap(matrix,square=True, annot=True, fmt='d', cbar=False,\n            xticklabels=['0', '1', '2', '3', '4'],\n            yticklabels=['0', '1', '2', '3', '4'])\nplt.xlabel('Predicted label')\nplt.ylabel('True label');","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.69161Z","iopub.status.idle":"2023-04-05T21:23:15.69247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"3. DenseNet169","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications.densenet import DenseNet169\nfrom tensorflow.keras.applications.densenet import preprocess_input as densenet_preprocess\nbase = DenseNet169(weights = 'imagenet', include_top = False, input_shape = (224, 224, 3))\ntf.keras.backend.clear_session()\n\nfor layer in base.layers:   \n    layer.trainable = False\n\ndensenet_model = Sequential()\ndensenet_model.add(base)\ndensenet_model.add(GlobalAveragePooling2D())\ndensenet_model.add(BatchNormalization())\ndensenet_model.add(Dense(256, activation='relu'))\ndensenet_model.add(Dropout(0.5))\ndensenet_model.add(BatchNormalization())\ndensenet_model.add(Dense(128, activation='relu'))\ndensenet_model.add(Dropout(0.5))\ndensenet_model.add(Dense(5, activation='softmax'))\n\ndensenet_model.summary()","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.69374Z","iopub.status.idle":"2023-04-05T21:23:15.694709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras.utils.vis_utils import plot_model\nplot_model(densenet_model, to_file='densenet169.png', show_shapes=True, show_layer_names=True)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.695965Z","iopub.status.idle":"2023-04-05T21:23:15.696867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_gen, val_gen = gen()\n\noptm = Adam(lr=0.0001)\ndensenet_model.compile(loss='categorical_crossentropy', optimizer=optm, \n                  metrics=['accuracy'])\n\nEarlyStopping = EarlyStopping(monitor='val_loss',\n                              min_delta=.0001,\n                              patience=5,\n                              verbose=1,\n                              mode='auto',\n                              baseline=None,\n                              restore_best_weights=True)\n\nmodel_save = ModelCheckpoint('./densenet.h5',\n                             save_best_only = True,\n                             save_weights_only = False,\n                             monitor = 'val_loss', \n                             mode = 'min', verbose = 1)\n\n\ndense_history = densenet_model.fit_generator(train_gen,\n                              steps_per_epoch = train_gen.samples // BATCH_SIZE,\n                              epochs = 10,\n                              validation_data = val_gen,\n                              validation_steps = val_gen.samples // BATCH_SIZE,\n                              callbacks=[EarlyStopping, model_save])","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:15.800376Z","iopub.execute_input":"2023-04-05T21:23:15.800662Z","iopub.status.idle":"2023-04-05T21:23:16.033074Z","shell.execute_reply.started":"2023-04-05T21:23:15.800635Z","shell.execute_reply":"2023-04-05T21:23:16.031694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot(dense_history)","metadata":{"execution":{"iopub.status.busy":"2023-04-05T21:23:16.157037Z","iopub.execute_input":"2023-04-05T21:23:16.157312Z","iopub.status.idle":"2023-04-05T21:23:16.174689Z","shell.execute_reply.started":"2023-04-05T21:23:16.157286Z","shell.execute_reply":"2023-04-05T21:23:16.172828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(dense_history.history['val_accuracy'][-5])\nprint(dense_history.history['val_loss'][-5])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_images = os.listdir(test_path)    \nfor image in test_images:\n    densenet_pred = predict(os.path.join(test_path, image) , densenet_model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"densenet_pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.argmax(densenet_pred)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dense_preds = densenet_model.predict(val_gen)\ndense_preds = np.argmax(dense_preds, axis=-1)\norg_label = val['label'].astype('int')\n\nmatrix=confusion_matrix(org_label, dense_preds)\nsns.heatmap(matrix,square=True, annot=True, fmt='d', cbar=False,\n            xticklabels=['0', '1', '2', '3', '4'],\n            yticklabels=['0', '1', '2', '3', '4'])\nplt.xlabel('Predicted label')\nplt.ylabel('True label');","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ensemble","metadata":{}},{"cell_type":"code","source":"mobilenet_model = tf.keras.models.load_model(\"../input/cassava-models/mobilenetV2.h5\")\nvgg_model = tf.keras.models.load_model(\"../input/cassava-models/vgg16.h5\")\ndensenet_model = tf.keras.models.load_model(\"../input/cassava-models/densenet.h5\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1_list=[]\nmodel2_list=[]\nmodel3_list = []\npredicted_label_list = []\nactual_labels=[]\n\nval_images = val.image_id\nfor i in val_images:\n    actual_labels.append(int(val[val.image_id == i].label))   \nactual_labels = pd.Series(actual_labels)\n\nfor image in val_images:\n    model1_list.append(predict(os.path.join(train_path, image), densenet_model))\n    model2_list.append(predict(os.path.join(train_path, image), mobilenet_model))\n    model3_list.append(predict(os.path.join(train_path, image), vgg_model))\n\nfor dense, mob, vgg in zip(model1_list, model2_list, model3_list):\n    predicted_label_list.append(np.argmax(dense/np.linalg.norm(dense) + mob/np.linalg.norm(mob) + vgg/np.linalg.norm(vgg)))\n    \nprint(classification_report(actual_labels, predicted_label_list))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"matrix=confusion_matrix(actual_labels, predicted_label_list)\nsns.heatmap(matrix,square=True, annot=True, fmt='d', cbar=False,\n            xticklabels=['0', '1', '2', '3', '4'],\n            yticklabels=['0', '1', '2', '3', '4'])\nplt.xlabel('Predicted label')\nplt.ylabel('True label')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}