{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport keras\nimport csv\nfrom PIL import Image\nimport os\nimport librosa\nfrom sklearn.model_selection import train_test_split\nfrom skimage.transform import resize\nimport cv2\nimport json\nfrom keras import layers\nfrom keras.layers import Input, Add, Dense, Activation, Dropout, ZeroPadding2D, BatchNormalization, Flatten, Conv2D, AveragePooling2D, MaxPooling2D, GlobalMaxPooling2D\nfrom keras.models import Model, Sequential\nfrom keras.callbacks import LearningRateScheduler, EarlyStopping, ReduceLROnPlateau, ModelCheckpoint, History\nfrom keras.utils import layer_utils\nfrom keras.utils.np_utils import to_categorical\nfrom keras.utils.data_utils import get_file\nfrom keras.applications.imagenet_utils import preprocess_input\nfrom keras.optimizers import RMSprop,Adam\nfrom tensorflow.keras.applications import EfficientNetB4\nimport pydot\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.preprocessing import image_dataset_from_directory\nfrom sklearn.model_selection import train_test_split\nfrom IPython.display import SVG\nfrom keras.utils.vis_utils import model_to_dot\nfrom keras.utils import plot_model\nfrom keras.initializers import glorot_uniform\nimport scipy.misc\nfrom matplotlib.pyplot import imshow\n%matplotlib inline\n\nimport keras.backend as K\nK.set_image_data_format('channels_last')\nK.set_learning_phase(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f = open('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json')\nreal_labels = json.load(f)\nreal_labels = {int(k):v for k,v in real_labels.items()}\nreal_labels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv('../input/cassava-leaf-disease-classification/train.csv')\ntrain_df['class_name'] = train_df.label.map(real_labels)\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train,valid = train_test_split(train_df, test_size = 0.1, random_state = 42, stratify = train_df['class_name'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(len(train))\nprint(len(valid))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classes = len(train_df.label.unique())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset_gen = ImageDataGenerator(\n    featurewise_center=False,\n    samplewise_center=False,\n    featurewise_std_normalization=False,\n    samplewise_std_normalization=False,\n    zca_whitening=False,\n    zca_epsilon=1e-06,\n    rotation_range=0,\n    width_shift_range=0.0,\n    height_shift_range=0.0,\n    brightness_range=None,\n    shear_range=0.0,\n    zoom_range=0.0,\n    channel_shift_range=0.0,\n    fill_mode=\"nearest\",\n    cval=0.0,\n    horizontal_flip=False,\n    vertical_flip=False,\n    rescale=None,\n    preprocessing_function=None,\n    data_format=None,\n    validation_split=0.0,\n    dtype=None,\n)\n\ntrain_data = dataset_gen.flow_from_dataframe(train,\n                             directory = '../input/cassava-leaf-disease-classification/train_images',\n                             seed=42,\n                             x_col = 'image_id',\n                             y_col = 'class_name',\n                             target_size = (512, 512),\n                             color_mode= 'rgb',\n                             class_mode = 'categorical',\n                             interpolation = 'nearest',\n                             shuffle = True,\n                             batch_size = 32)\n\nvalid_data = dataset_gen.flow_from_dataframe(valid,\n                             directory = '../input/cassava-leaf-disease-classification/train_images',\n                             seed=42,\n                             x_col = 'image_id',\n                             y_col = 'class_name',\n                             target_size = (512, 512),\n                             color_mode= 'rgb',\n                             class_mode = 'categorical',\n                             interpolation = 'nearest',\n                             shuffle = True,\n                             batch_size = 32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def identity_block(X, f, filters, stage, block):\n    \"\"\"\n    Implementation of the identity block as defined in Figure 3\n\n    Arguments:\n    X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)\n    f -- integer, specifying the shape of the middle CONV's window for the main path\n    filters -- python list of integers, defining the number of filters in the CONV layers of the main path\n    stage -- integer, used to name the layers, depending on their position in the network\n    block -- string/character, used to name the layers, depending on their position in the network\n\n    Returns:\n    X -- output of the identity block, tensor of shape (n_H, n_W, n_C)\n    \"\"\"\n\n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n    # Retrieve Filters\n    F1, F2, F3 = filters\n\n    # Save the input value. You'll need this later to add back to the main path. \n    X_shortcut = X\n\n    # First component of main path\n    X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(1, 1), padding='valid', name=conv_name_base + '2a')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)\n    X = Activation('relu')(X)\n\n    # Second component of main path (≈3 lines)\n    X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same', name=conv_name_base + '2b')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n    # Third component of main path (≈2 lines)\n    X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding='valid', name=conv_name_base + '2c')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)\n\n    # Final step: Add shortcut value to main path, and pass it through a RELU activation (≈2 lines)\n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n\n    return X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def convolutional_block(X, f, filters, stage, block, s=2):\n    \"\"\"\n    Implementation of the convolutional block as defined in Figure 4\n\n    Arguments:\n    X -- input tensor of shape (m, n_H_prev, n_W_prev, n_C_prev)\n    f -- integer, specifying the shape of the middle CONV's window for the main path\n    filters -- python list of integers, defining the number of filters in the CONV layers of the main path\n    stage -- integer, used to name the layers, depending on their position in the network\n    block -- string/character, used to name the layers, depending on their position in the network\n    s -- Integer, specifying the stride to be used\n\n    Returns:\n    X -- output of the convolutional block, tensor of shape (n_H, n_W, n_C)\n    \"\"\"\n\n    # defining name basis\n    conv_name_base = 'res' + str(stage) + block + '_branch'\n    bn_name_base = 'bn' + str(stage) + block + '_branch'\n\n    # Retrieve Filters\n    F1, F2, F3 = filters\n\n    # Save the input value\n    X_shortcut = X\n\n    ##### MAIN PATH #####\n    # First component of main path \n    X = Conv2D(filters=F1, kernel_size=(1, 1), strides=(s, s), padding='valid', name=conv_name_base + '2a')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2a')(X)\n    X = Activation('relu')(X)\n\n    # Second component of main path\n    X = Conv2D(filters=F2, kernel_size=(f, f), strides=(1, 1), padding='same', name=conv_name_base + '2b')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2b')(X)\n    X = Activation('relu')(X)\n\n    # Third component of main path\n    X = Conv2D(filters=F3, kernel_size=(1, 1), strides=(1, 1), padding='valid', name=conv_name_base + '2c')(X)\n    X = BatchNormalization(axis=3, name=bn_name_base + '2c')(X)\n\n    ##### SHORTCUT PATH ####\n    X_shortcut = Conv2D(filters=F3, kernel_size=(1, 1),strides=(s, s),padding='valid', name=conv_name_base + '1')(X_shortcut)\n    X_shortcut = BatchNormalization(axis=3, name=bn_name_base + '1')(X_shortcut)\n\n    # Final step: Add shortcut value to main path, and pass it through a RELU activation (≈2 lines)\n    X = Add()([X, X_shortcut])\n    X = Activation('relu')(X)\n\n    return X","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def ResNet50(input_shape=(512, 512, 3), classes=5):\n    \"\"\"\n    Implementation of the popular ResNet50 the following architecture:\n    CONV2D -> BATCHNORM -> RELU -> MAXPOOL -> CONVBLOCK -> IDBLOCK*2 -> CONVBLOCK -> IDBLOCK*3\n    -> CONVBLOCK -> IDBLOCK*5 -> CONVBLOCK -> IDBLOCK*2 -> AVGPOOL -> TOPLAYER\n\n    Arguments:\n    input_shape -- shape of the images of the dataset\n    classes -- integer, number of classes\n\n    Returns:\n    model -- a Model() instance in Keras\n    \"\"\"\n\n    # Define the input as a tensor with shape input_shape\n    X_input = Input(input_shape)\n\n    # Zero-Padding\n    X = ZeroPadding2D((3, 3))(X_input)\n\n    # Stage 1\n    X = Conv2D(64, (7, 7), strides=(2, 2), name='conv1')(X)\n    X = BatchNormalization(axis=3, name='bn_conv1')(X)\n    X = Activation('relu')(X)\n    X = MaxPooling2D((3, 3), strides=(2, 2))(X)\n\n    # Stage 2\n    X = convolutional_block(X, f=3, filters=[64, 64, 256], stage=2, block='a', s=1)\n    X = identity_block(X, 3, [64, 64, 256], stage=2, block='b')\n    X = identity_block(X, 3, [64, 64, 256], stage=2, block='c')\n\n    ### START CODE HERE ###\n\n    # Stage 3 (≈4 lines)\n    X = convolutional_block(X, f=3, filters=[128, 128, 512], stage=3, block='a', s=2)\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='b')\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='c')\n    X = identity_block(X, 3, [128, 128, 512], stage=3, block='d')\n\n    # Stage 4 (≈6 lines)\n    X = convolutional_block(X, f=3, filters=[256, 256, 1024], stage=4, block='a', s=2)\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='b')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='c')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='d')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='e')\n    X = identity_block(X, 3, [256, 256, 1024], stage=4, block='f')\n\n    # Stage 5 (≈3 lines)\n    X = X = convolutional_block(X, f=3, filters=[512, 512, 2048], stage=5, block='a', s=2)\n    X = identity_block(X, 3, [512, 512, 2048], stage=5, block='b')\n    X = identity_block(X, 3, [512, 512, 2048], stage=5, block='c')\n\n    # AVGPOOL (≈1 line). Use \"X = AveragePooling2D(...)(X)\"\n    X = AveragePooling2D(pool_size=(2, 2), padding='same')(X)\n\n    ### END CODE HERE ###\n\n    # output layer\n    X = Flatten()(X)\n    X = Dense(classes, activation='softmax', name='fc' + str(classes))(X)\n\n    # Create model\n    model = Model(inputs=X_input, outputs=X, name='ResNet50')\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = ResNet50(input_shape=(512, 512, 3), classes=5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def model_fit():\n    training_model = ResNet50(input_shape=(512, 512, 3), classes=5)\n    \n    optimizer = Adam(learning_rate=0.0001, beta_1=0.9, beta_2=0.999, epsilon=1e-07, amsgrad=False)\n    \n    training_model.compile(optimizer = optimizer, loss = 'categorical_crossentropy', metrics=['categorical_accuracy'])\n    \n    SPE = train_data.n // train_data.batch_size\n    VS = valid_data.n // valid_data.batch_size\n\n    early_stopping = EarlyStopping(monitor='val_loss', mode='min', patience=3, restore_best_weights=True, verbose=1)\n\n    checkpoint = ModelCheckpoint(\"Trained_Best_Model.h5\", save_best_only=True, monitor = 'val_loss', mode= 'min')\n\n    reduce_lr = ReduceLROnPlateau(monitor = 'val_loss', factor = 0.3, patience = 2, min_lr = 1e-6, mode = 'min', verbose = 1)\n\n    training = training_model.fit(train_data, validation_data = valid_data , epochs = 25, \n          batch_size = 32,\n          steps_per_epoch = SPE,\n          validation_steps = VS,                                          \n          callbacks=[early_stopping, checkpoint, reduce_lr] )\n\n    training_model.save('Trained_Final_Model.h5')\n    \n    return training\n\n\nresult = model_fit()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Training Accuracy: ' + str(max(result.history['categorical_accuracy'])))\nprint('Validation Accuracy: ' + str(max(result.history['val_categorical_accuracy'])))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Predictions**"},{"metadata":{"trusted":true},"cell_type":"code","source":"img = cv2.imread('../input/cassava-leaf-disease-classification/test_images/2216849948.jpg')\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nimg = resize(img, (512, 512, 3))\nimg = img.reshape(1, 512, 512, 3)\npred_model = keras.models.load_model('/kaggle/working/Trained_Best_Model.h5')\ny = model.predict(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y = np.argmax(y)\ny","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dir = '../input/cassava-leaf-disease-classification/test_images/'\npreds = [('image_id', 'label')]\nfor img in os.listdir(test_dir):\n    path = test_dir + img\n    image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = resize(image, (512,512,3))\n    image = image.reshape(1, 512, 512, 3)\n    y = model.predict(image)\n    y = np.argmax(y)\n    tup = (img, y)\n    preds.append(tup)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"csvfile = open('submission.csv','w',newline='')\nobj = csv.writer(csvfile)\nfor pred in preds:\n    obj.writerow(pred)\ncsvfile.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"output1 = pd.read_csv('/kaggle/working/submission.csv')\noutput1","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}