{"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":"# The Xception model architecture\n![Xception Model](https://vitalab.github.io/article/images/xception/architecture.png)\n1. Xception is a depthwise separable convolution network\n2. Consists of 3 flows entry, middle and exit flows\n3. There are shortcuts between the many separable Conv layers\n4. Default **input shape is 299x299x3**\n\n> Original paper introducing Xception\n[Original Paper](https://arxiv.org/abs/1610.02357)","metadata":{}},{"cell_type":"markdown","source":"# Importing packages","metadata":{}},{"cell_type":"code","source":"import numpy as np \nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nimport os\nimport shutil\nimport keras\nimport skimage.io\nimport keras.backend as K\nimport tensorflow as tf\nfrom tensorflow.keras import Input, Model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.layers import Dense, Flatten, Dropout,BatchNormalization ,Activation,add\nfrom tensorflow.keras.models import Model, Sequential\nfrom keras.applications.xception import Xception\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.utils import to_categorical\nfrom keras.layers.experimental.preprocessing import RandomFlip, RandomRotation, RandomCrop, Rescaling, RandomTranslation\nfrom keras import Sequential\nfrom tqdm import tqdm\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras.optimizers import Adam\n\nimport tensorflow_addons as tfa","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:19:26.374354Z","iopub.execute_input":"2021-06-04T21:19:26.374681Z","iopub.status.idle":"2021-06-04T21:19:26.382339Z","shell.execute_reply.started":"2021-06-04T21:19:26.374648Z","shell.execute_reply":"2021-06-04T21:19:26.381355Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading data","metadata":{}},{"cell_type":"code","source":"root_dir = '../input/cassava-leaf-disease-classification'\n\ntrain_df = pd.read_csv(os.path.join(root_dir, 'train.csv'))\n\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:08:43.739425Z","iopub.execute_input":"2021-06-04T21:08:43.739736Z","iopub.status.idle":"2021-06-04T21:08:43.784715Z","shell.execute_reply.started":"2021-06-04T21:08:43.739707Z","shell.execute_reply":"2021-06-04T21:08:43.783631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preprocessing data","metadata":{}},{"cell_type":"code","source":"image_preprocessor = Sequential([\n    RandomFlip(\"horizontal_and_vertical\"),\n    RandomCrop(150,150),\n    RandomTranslation(0.3, 0.3),\n    RandomRotation(0.5),\n    Rescaling(1./255)])\n\ndef custom_gen(batch_size, image_dir, h = 150, w = 150):\n    \n    start = 0\n    end = batch_size\n    images = train_df['image_id']\n    labels = train_df['label']\n    while 1:\n        \n        if end >= train_df.shape[0]:\n            start = 0\n            end = batch_size \n            continue\n        else:\n        \n            batch = []\n\n            if start == 0:\n                names = images[:end]\n                y = to_categorical(labels[:end], num_classes = 5)\n            else:\n                names = images[start:end]\n                y = to_categorical(labels[start:end], num_classes = 5)\n\n            for name in names:\n\n                img = cv2.imread(os.path.join(image_dir,name))\n                img = np.expand_dims(img, axis = 0)\n                img = image_preprocessor(img)\n                img = np.squeeze(img, axis = 0)\n                batch.append(img)\n\n\n\n            end = end + batch_size\n            start = start +  batch_size\n\n\n            yield np.array(batch), y","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:08:46.653237Z","iopub.execute_input":"2021-06-04T21:08:46.653559Z","iopub.status.idle":"2021-06-04T21:08:48.813326Z","shell.execute_reply.started":"2021-06-04T21:08:46.653530Z","shell.execute_reply":"2021-06-04T21:08:48.812503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading VGG19","metadata":{}},{"cell_type":"code","source":"os.makedirs('/tmp/.keras/datasets')","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:09:05.163779Z","iopub.execute_input":"2021-06-04T21:09:05.164187Z","iopub.status.idle":"2021-06-04T21:09:05.170319Z","shell.execute_reply.started":"2021-06-04T21:09:05.164156Z","shell.execute_reply":"2021-06-04T21:09:05.169480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.copytree(\"../input/keras-pretrained-models\", \"/tmp/.keras/models\")","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:10:02.118194Z","iopub.execute_input":"2021-06-04T21:10:02.118538Z","iopub.status.idle":"2021-06-04T21:10:14.083542Z","shell.execute_reply.started":"2021-06-04T21:10:02.118501Z","shell.execute_reply":"2021-06-04T21:10:14.082765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"weights_path = '../input/keras-pretrained-models/xception_weights_tf_dim_ordering_tf_kernels_notop.h5'\nmodel_xception = Xception(weights = weights_path, input_shape=(150,150,3),include_top=False)\n\nmodel_xception.trainable = False","metadata":{"execution":{"iopub.status.busy":"2021-06-04T21:22:09.902383Z","iopub.execute_input":"2021-06-04T21:22:09.902702Z","iopub.status.idle":"2021-06-04T21:22:13.073858Z","shell.execute_reply.started":"2021-06-04T21:22:09.902672Z","shell.execute_reply":"2021-06-04T21:22:13.072995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"model=Sequential()\n\nmodel.add(model_xception)\nmodel.add(Dropout(0.3))\nmodel.add(Flatten())\nmodel.add(BatchNormalization())\nmodel.add(Dense(256))\nmodel.add(BatchNormalization())\nmodel.add(tf.keras.layers.PReLU(alpha_initializer='zeros', alpha_regularizer=None))\nmodel.add(Dropout(0.3))\nmodel.add(Dense(128))\nmodel.add(BatchNormalization())\nmodel.add(tf.keras.layers.PReLU(alpha_initializer='zeros', alpha_regularizer=None))\nmodel.add(Dropout(0.3))\nmodel.add(Dense(64))\nmodel.add(BatchNormalization())\nmodel.add(tf.keras.layers.PReLU(alpha_initializer='zeros', alpha_regularizer=None))\nmodel.add(Dense(5, activation = 'softmax'))\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2021-06-04T17:04:21.794758Z","iopub.execute_input":"2021-06-04T17:04:21.795033Z","iopub.status.idle":"2021-06-04T17:04:21.959697Z","shell.execute_reply.started":"2021-06-04T17:04:21.795006Z","shell.execute_reply":"2021-06-04T17:04:21.958982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lrd = ReduceLROnPlateau(monitor = 'val_loss',verbose = 1,factor = 0.75, min_lr = 0.00001)","metadata":{"execution":{"iopub.status.busy":"2021-06-04T17:04:22.110962Z","iopub.execute_input":"2021-06-04T17:04:22.111257Z","iopub.status.idle":"2021-06-04T17:04:22.115364Z","shell.execute_reply.started":"2021-06-04T17:04:22.111229Z","shell.execute_reply":"2021-06-04T17:04:22.114297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer = 'adam', loss = 'categorical_crossentropy',metrics=['accuracy', tfa.metrics.F1Score(num_classes = 5)])","metadata":{"execution":{"iopub.status.busy":"2021-06-04T17:04:24.630309Z","iopub.execute_input":"2021-06-04T17:04:24.630646Z","iopub.status.idle":"2021-06-04T17:04:24.655073Z","shell.execute_reply.started":"2021-06-04T17:04:24.630616Z","shell.execute_reply":"2021-06-04T17:04:24.654205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training model","metadata":{}},{"cell_type":"code","source":"batch_size = 512\nepochs = 20\nsteps_per_epoch = train_df.shape[0] // batch_size\ntrain_img_dir = os.path.join(root_dir, 'train_images')\ntrain_gen = custom_gen(batch_size, train_img_dir)\n  \nhistory = model.fit(train_gen, epochs = epochs, steps_per_epoch = steps_per_epoch,verbose = 1,callbacks=[lrd])","metadata":{"execution":{"iopub.status.busy":"2021-06-04T17:12:39.944218Z","iopub.execute_input":"2021-06-04T17:12:39.944581Z","iopub.status.idle":"2021-06-04T19:36:59.698841Z","shell.execute_reply.started":"2021-06-04T17:12:39.94454Z","shell.execute_reply":"2021-06-04T19:36:59.698013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predictions and submission","metadata":{}},{"cell_type":"code","source":"test_leaf = \"../input/cassava-leaf-disease-classification/test_images\"\n\ntest_names = pd.Series(os.listdir(test_leaf))\n\n\nfor j in range(3):\n\n    for i in tqdm(range(len(test_names))):\n\n        image = cv2.imread(os.path.join(test_leaf, test_names[i]))\n        image = np.expand_dims(image, axis = 0)\n        image = image_preprocessor(image)\n        if i ==0:\n\n            pred = model.predict(image)\n        else:\n            pred = np.concatenate([pred, model.predict(image)])\n            \n    if j ==0:\n        final = pred\n    else:\n        final = final +pred\n     \npred = pd.Series(np.argmax(final, axis = 1))\n\n\ntest_df = pd.concat([test_names, pred], axis = 1)\ntest_df = test_df.rename(columns = {0: 'image_id', 1: 'label'})\n\ntest_df.to_csv('submission.csv', index = False)","metadata":{"execution":{"iopub.status.busy":"2021-06-04T19:36:59.702567Z","iopub.execute_input":"2021-06-04T19:36:59.702846Z","iopub.status.idle":"2021-06-04T19:37:00.452207Z","shell.execute_reply.started":"2021-06-04T19:36:59.702819Z","shell.execute_reply":"2021-06-04T19:37:00.451471Z"},"trusted":true},"execution_count":null,"outputs":[]}]}