{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"#Importing relevant libraries\nimport numpy as np\nimport pandas as pd\nfrom tensorflow.keras.layers import Dense, Dropout\nfrom tensorflow.keras.applications import EfficientNetB2\nfrom tensorflow.keras.applications import EfficientNetB4\n\n#from tensorflow.keras.applications.resnet101 import ResNet101\nfrom tensorflow.keras.applications.vgg16 import VGG16\nfrom keras.callbacks import EarlyStopping\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras.optimizers import SGD\nfrom keras.callbacks import EarlyStopping\nimport tensorflow as tf\nfrom PIL import Image\nimport os\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#%% IMPORTING DATA\ngeneral_path = '../input/cassava-leaf-disease-classification/'\ntrain = pd.read_csv(general_path + 'train.csv')\ntrain['label'] = train['label'].astype('string')\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"names_of_disease = pd.read_json(general_path + 'label_num_to_disease_map.json', typ='series')\nnames_of_disease","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plotting count to see the count of labels\nax = train['label'].value_counts().plot(kind='bar',\n                                    figsize=(14,8),\n                                    title=\"Count of disease\",color='r')\nax.set_xlabel(\"Count\")\nax.set_ylabel(\"Frequency\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Sample Images\nplt.figure(figsize=(20,16))\nfor i in range(9):\n    plt.subplot(3, 3, i + 1)\n    image = Image.open(general_path + 'train_images/' + train.iloc[i]['image_id'])\n    array = np.array(image)\n    plt.imshow(array)\n    label=train.iloc[i]['label']\n    plt.title(f'{names_of_disease[int(label)]}')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sizes = []\nfor i in range(1, len(train), 250):\n    image = Image.open(general_path + 'train_images/' + train.iloc[i]['image_id'])\n    array = np.array(image)\n    sizes.append(array.shape)\nprint('Picture size', set(sizes))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_width, img_height = 256,256","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Training\ndatagen = ImageDataGenerator(validation_split=0.2,\n                              rotation_range = 40,\n                    width_shift_range = 0.2,\n                    height_shift_range = 0.2,\n                    shear_range = 0.2,\n                    zoom_range = 0.2,\n                    horizontal_flip = True,\n                    vertical_flip = False,\n                    fill_mode = 'nearest')\ntrain_datagen_flow = datagen.flow_from_dataframe(\n    dataframe=train,\n    directory=general_path + 'train_images',\n    x_col='image_id',\n    y_col='label',\n    target_size=(img_width, img_height),\n    batch_size=20,\n    subset='training',\n    seed=12345)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_datagen_flow = datagen.flow_from_dataframe(\n    dataframe=train,\n    directory=general_path + 'train_images',\n    x_col='image_id',\n    y_col='label',\n    target_size=(img_width, img_height),\n    batch_size=20,\n    subset='validation',\n    seed=12345)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"current_balance = train['label'].value_counts(normalize=True)\ncurrent_balance","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weight = {0: (1 - current_balance[0]) / (1 - current_balance.min()),\n                1: (1 - current_balance[1]) / (1 - current_balance.min()),\n                2: (1 - current_balance[2]) / (1 - current_balance.min()),\n                3: (1 - current_balance[3]) / (1 - current_balance.min()),\n                4: (1 - current_balance[4]) / (1 - current_balance.min())}\n\nclass_weight","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Custom Loss\nimport numpy as np\nfrom keras import backend as K\n\nsigma \t  = 0.05\nlamda_mmd = 0.1\ndef mmd(x1, x2, beta):\n    x1x1 = gaussian_kernel(x1, x1, beta)\n    x1x2 = gaussian_kernel(x1, x2, beta)\n    x2x2 = gaussian_kernel(x2, x2, beta)\n    diff = x1x1.mean() - 2 * x1x2.mean() + x2x2.mean()\n    return diff\n\ndef gaussian_kernel(x1, x2, beta = 1.0):\n    r = x1.dimshuffle(0,'x',1)\n    return K.exp( -beta * K.square(r - x2).sum(axis=-1))\n\ndef our_MMD(features, labels):\n\t## I am assuming both features and labels to numpy arrays.\n\t## But with Keras, the functions such as (np.unique, np.where) will be different.\n\t## features will be batch_size x embedding_size in size; and labels will be batch_size in size.\n\tloss  = 0.0\n\tcount = 0\n\tunique_labels \t  = np.unique(labels) ## Find the unique labels.\n\tnum_unique_labels = unique_labels.size ## Number of unique labels.\n\tfor i in range(num_unique_labels-1):\n\t\tlabel_i    = unique_labels[i] ## i^{th} label\n\t\tidx_i \t   = np.where(labels==label_i)[0] ## indices of i^{th} label.\n\t\tfeatures_i = features[idx_i] ## features belonging to i^{th} label.\n\t\tfor j in range(i+1, num_unique_labels): \n\t\t\tlabel_j    = unique_labels[j] ## j^{th} label\n\t\t\tidx_j      = np.where(labels==label_j)[0]  ## indices of j^{th} label.\n\t\t\tfeatures_j = features[idx_j] ## features belonging to j^{th} label.\n\t\t\tloss_ij    = mmd(x1=features_i, x2=features_j, beta=1.0/sigma) ## Calculate \n\t\t\tcount     += 1\n\t\t\tloss      += loss_ij\n\tloss = lamda_mmd * loss / float(count)\n\treturn loss\n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"es= EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=5)\nmodel = Sequential()\noptimizer = RMSprop(lr=0.001)\nbackbone = EfficientNetB4(include_top=False, \n                          weights='imagenet', \n                          pooling='avg')\nfeatures=[]\nlabels=[]\nmodel.add(backbone)\nmodel.add(Dropout(0.3))\n#model.add(Dense(512))\nmodel.add(Dense(256))\n\nmodel.add(Dropout(0.3))\n#model.add(Dense(128))\n#model.add(Dense(32))\nmodel.add(Dense(5, activation='softmax'))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for layer in model.layers:\n    print(layer.name)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#layer_output = model.get_layer('dropout_9').output\n#features.append(layer_output)\n#labels.append[y_col]\nmodel.compile(loss='categorical_crossentropy', \n             optimizer=optimizer, \n              metrics=[\"accuracy\"])\nhistory=model.fit_generator(train_datagen_flow,\n                    validation_data=valid_datagen_flow, \n                    epochs=50, \n                    verbose=1,class_weight=class_weight,callbacks=[es])\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Training_Cat-Acc: ', max(history.history['accuracy']))\nprint('Validation_Cat-Acc: ',max(history.history['val_accuracy']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def Plot(acc,val_acc,loss,val_loss):\n    \n    fig, (ax1, ax2) = plt.subplots(1,2, figsize= (15,10))\n    fig.suptitle(\" MODEL'S METRICS VISUALIZATION \", fontsize=20)\n\n    ax1.plot(range(1, len(acc) + 1), acc)\n    ax1.plot(range(1, len(val_acc) + 1), val_acc)\n    ax1.set_title('History of Accuracy', fontsize=15)\n    ax1.set_xlabel('Epochs', fontsize=15)\n    ax1.set_ylabel('Accuracy', fontsize=15)\n    ax1.legend(['training', 'validation'])\n\n\n    ax2.plot(range(1, len(loss) + 1), loss)\n    ax2.plot(range(1, len(val_loss) + 1), val_loss)\n    ax2.set_title('History of Loss', fontsize=15)\n    ax2.set_xlabel('Epochs', fontsize=15)\n    ax2.set_ylabel('Loss', fontsize=15)\n    ax2.legend(['training', 'validation'])\n    plt.show()\n\nPlot(history.history['accuracy'],history.history['val_accuracy'],\n               history.history['loss'],history.history['val_loss'])\n    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.DataFrame(columns=['image_id','label'])\nfor image_name in os.listdir(general_path + 'test_images'):\n    image_path = os.path.join(general_path + 'test_images', image_name)\n    image = tf.keras.preprocessing.image.load_img(image_path)\n    resized_image = image.resize((img_width, img_height))\n    numpied_image = np.expand_dims(resized_image, 0)\n    tensored_image = tf.cast(numpied_image, tf.float32)\n    submission = submission.append(pd.DataFrame({'image_id': image_name,\n                                                 'label': model.predict_classes(tensored_image)}))\n\nsubmission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index = False)","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}