{"cells":[{"metadata":{"id":"lilHL8z7LXEe"},"cell_type":"markdown","source":"##**1. SETTING UP & KAGGLE API**"},{"metadata":{"id":"dFKdGvUg2leT","executionInfo":{"status":"ok","timestamp":1615856029148,"user_tz":240,"elapsed":278,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"a1862992-dd01-4eb5-e675-ef616c920158","trusted":false},"cell_type":"code","source":"# set up libraries and environment\nimport math, re, os\nimport tensorflow as tf\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tensorflow import keras\nfrom functools import partial\nfrom sklearn.model_selection import train_test_split\nimport numpy as np \nimport pandas as pd\nimport gc\nimport random\nfrom sklearn.model_selection import train_test_split\nfrom keras.utils import to_categorical\nfrom tqdm import tqdm\nfrom keras.preprocessing import image\nfrom keras.preprocessing.image import img_to_array, load_img, ImageDataGenerator\nimport cv2\nfrom random import shuffle\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization, ReLU\nimport keras\nfrom keras.layers import Dense, Dropout, Input, MaxPooling2D, ZeroPadding2D, Conv2D, Flatten\nfrom keras.models import Sequential, Model\nfrom keras.losses import categorical_crossentropy\nfrom keras.optimizers import Adam, SGD\nfrom keras.preprocessing.image import img_to_array, load_img, ImageDataGenerator\nfrom keras.utils import to_categorical\nfrom tensorflow.keras import regularizers\nimport pandas as pd\nimport json\nfrom keras.callbacks import EarlyStopping\nfrom tensorflow.keras.layers import MaxPool2D, AveragePooling2D, GlobalAveragePooling2D\nimport numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom keras.callbacks import ReduceLROnPlateau\nfrom tensorflow.keras.layers import LeakyReLU\nfrom tensorflow.keras.regularizers import l2\nfrom tensorflow.keras.layers.experimental import preprocessing\nfrom tensorflow.keras.optimizers.schedules import ExponentialDecay\n\nimport matplotlib.pyplot as plt\nfrom mpl_toolkits.axes_grid1 import ImageGrid\n\nfrom zipfile import ZipFile\nimport time\nfrom datetime import timedelta\nfrom io import BytesIO\n\n# image manipulation.\nimport PIL.Image\nimport seaborn as sns\nimport plotly.express as px\n\nimport pickle\nimport os\n\nimport random\nprint(\"Tensorflow version \" + tf.__version__)","execution_count":null,"outputs":[]},{"metadata":{"id":"ykfSRfyJXNnN","executionInfo":{"status":"ok","timestamp":1615842136524,"user_tz":240,"elapsed":3387,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f7e50d53-2aa4-4275-ddfa-ca35cd222862","trusted":false},"cell_type":"code","source":"# uninstall and reinstall kaggle\n!pip uninstall -y kaggle\n!pip install -q kaggle","execution_count":null,"outputs":[]},{"metadata":{"id":"SZs5F9DUXY-P","executionInfo":{"status":"ok","timestamp":1615842137428,"user_tz":240,"elapsed":2010,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"6d1af1d0-0c38-4f13-e46a-4a2bb3f58a49","trusted":false},"cell_type":"code","source":"# set Kaggle username and API key\nos.environ[\"KAGGLE_USERNAME\"] = 'drewsolomon'\nos.environ[\"KAGGLE_KEY\"] = '394c2e9f24d40740b88dbd424a87235f'\n\n# download the data from the kaggle competition\nraw_data_dir = \"input/raw\"\n!kaggle competitions download -c cassava-leaf-disease-classification -p {raw_data_dir}\n'done'","execution_count":null,"outputs":[]},{"metadata":{"id":"CeZGMlcoZ4Ry","executionInfo":{"status":"ok","timestamp":1615842141019,"user_tz":240,"elapsed":462,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"059b9b08-aa81-44fc-c99c-12c3855e5533","trusted":false},"cell_type":"code","source":"# check zip file download\n!ls {raw_data_dir}","execution_count":null,"outputs":[]},{"metadata":{"id":"azNcpRzcaALh","executionInfo":{"status":"ok","timestamp":1615842147438,"user_tz":240,"elapsed":4709,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"653dd8ec-bf00-4fda-817c-7aff1b6eaacf","trusted":false},"cell_type":"code","source":"# access zipped folders using Fuze zip #Nice, did not know of this :)\n!apt-get install -y fuse-zip\n\n# set input directory\ninput_dir = \"/tmp/kaggle-data\"\n!mkdir {input_dir}\n# fuze zip\n!fuse-zip input/raw/cassava-leaf-disease-classification.zip {input_dir}\n# check directory\n!ls {input_dir}","execution_count":null,"outputs":[]},{"metadata":{"id":"Q07ElpzFa1mz","executionInfo":{"status":"ok","timestamp":1615842150183,"user_tz":240,"elapsed":215,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"9bf15ca6-066e-4e4e-c937-6b750cd8f0f2","trusted":false},"cell_type":"code","source":"# Use this path to access the downloaded folders\nbase_path = '/tmp/kaggle-data/'\n\nos.listdir(base_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"aA9xSPPtqBvM","executionInfo":{"status":"ok","timestamp":1615850537097,"user_tz":240,"elapsed":268,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"d031d0fd-b159-44c0-99c6-9c604c003190","trusted":false},"cell_type":"code","source":"# See the files inside train and test tfrecordds\nprint('files in train tfrecords:')\nprint(os.listdir(base_path + 'train_tfrecords'))\nprint('files in test tfrecords:')\nprint(os.listdir(base_path + 'test_tfrecords'))","execution_count":null,"outputs":[]},{"metadata":{"id":"nm4OcgwRq4R4","executionInfo":{"status":"ok","timestamp":1615850540078,"user_tz":240,"elapsed":217,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f950993d-2276-492e-d690-fd87030f1181","trusted":false},"cell_type":"code","source":"# See the lenght of train and test tfrecordds\nprint(len(os.listdir(base_path + 'train_tfrecords')))\nprint(len(os.listdir(base_path + 'test_tfrecords')))\n","execution_count":null,"outputs":[]},{"metadata":{"id":"iNLesnj_Mv2I"},"cell_type":"markdown","source":"##**2. LOADING AND PREPROCESSING TFRECORDS**"},{"metadata":{"id":"x9hxDMzPZ6Xj"},"cell_type":"markdown","source":"**Loading tfrecords**"},{"metadata":{"id":"toKqGY7Qt2Rh","executionInfo":{"status":"ok","timestamp":1615850552980,"user_tz":240,"elapsed":277,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"AUTOTUNE = tf.data.experimental.AUTOTUNE\nBATCH_SIZE = 64\nIMAGE_SIZE = [224, 224]","execution_count":null,"outputs":[]},{"metadata":{"id":"W8cXb6eErW2w","executionInfo":{"status":"ok","timestamp":1615850557333,"user_tz":240,"elapsed":202,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"3c9a8430-8b72-4625-bdf0-1d7c5737138f","trusted":false},"cell_type":"code","source":"FILENAMES = tf.io.gfile.glob(base_path + \"train_tfrecords/ld_train*.tfrec\")\nTEST_FILENAMES = tf.io.gfile.glob(base_path + \"test_tfrecords/ld_test*.tfrec\")\nsplit_ind = int(0.9 * len(FILENAMES))\nTRAINING_FILENAMES, VALID_FILENAMES = FILENAMES[:split_ind], FILENAMES[split_ind:]\n\nprint(\"Train TFRecord Files:\", len(TRAINING_FILENAMES))\nprint(\"Validation TFRecord Files:\", len(VALID_FILENAMES))\nprint(\"Test TFRecord Files:\", len(TEST_FILENAMES))","execution_count":null,"outputs":[]},{"metadata":{"id":"hiSOhOc-tsyQ","executionInfo":{"status":"ok","timestamp":1615842195614,"user_tz":240,"elapsed":235,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to decode image\ndef decode_image(image):\n    image = tf.image.decode_jpeg(image, channels=3)\n    image = tf.image.resize(image, size=IMAGE_SIZE) \n    image = tf.cast(image/255.0, tf.float32) \n    return image","execution_count":null,"outputs":[]},{"metadata":{"id":"1zwtZ-9-teD0","executionInfo":{"status":"ok","timestamp":1615842197273,"user_tz":240,"elapsed":258,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to read tf_records\ndef read_tfrecord(example, labeled):\n    tfrecord_format = (\n        {\n            \"image\": tf.io.FixedLenFeature([], tf.string),\n            \"target\": tf.io.FixedLenFeature([], tf.int64),\n        }\n        if labeled\n        else {\"image\": tf.io.FixedLenFeature([], tf.string),}\n    )\n    example = tf.io.parse_single_example(example, tfrecord_format)\n    image = decode_image(example[\"image\"])\n    if labeled:\n        label = tf.cast(example[\"target\"], tf.float32) \n        return image, label\n    return image","execution_count":null,"outputs":[]},{"metadata":{"id":"q7cMTNg9tHPq","executionInfo":{"status":"ok","timestamp":1615842202929,"user_tz":240,"elapsed":216,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to load dataset\ndef load_dataset(filenames, labeled=True):\n    ignore_order = tf.data.Options()\n    ignore_order.experimental_deterministic = False  # disable order, increase speed\n    dataset = tf.data.TFRecordDataset(\n        filenames\n    )  # automatically interleaves reads from multiple files\n    dataset = dataset.with_options(\n        ignore_order\n    )  # uses data as soon as it streams in, rather than in its original order\n    dataset = dataset.map(\n        partial(read_tfrecord, labeled=labeled), num_parallel_calls=AUTOTUNE\n    )\n    # returns a dataset of (image, label) pairs if labeled=True or just images if labeled=False\n    return dataset\n\n# source: https://keras.io/examples/keras_recipes/tfrecord/","execution_count":null,"outputs":[]},{"metadata":{"id":"4u1dTKdjiIIj","executionInfo":{"status":"ok","timestamp":1615842205658,"user_tz":240,"elapsed":226,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to load dataset, shuffle data, prefetch data, and set batch size\ndef get_dataset(filenames, labeled=True):\n    dataset = load_dataset(filenames, labeled=labeled)\n    # set shuffle buffer size to length of filenames, for full shuffle\n    dataset = dataset.shuffle(384) \n    dataset = dataset.prefetch(buffer_size=AUTOTUNE)\n    dataset = dataset.batch(BATCH_SIZE)\n    return dataset\n\n# source: https://keras.io/examples/keras_recipes/tfrecord/","execution_count":null,"outputs":[]},{"metadata":{"id":"iqwOwp3Dj2Lg","executionInfo":{"status":"ok","timestamp":1615842208354,"user_tz":240,"elapsed":336,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"train_dataset = get_dataset(TRAINING_FILENAMES)\nvalid_dataset = get_dataset(VALID_FILENAMES)\ntest_dataset = get_dataset(TEST_FILENAMES, labeled=False)","execution_count":null,"outputs":[]},{"metadata":{"id":"Eo5AzkGtZts6"},"cell_type":"markdown","source":"**Displaying Images from tfrecords**"},{"metadata":{"id":"qpshka4wuZbr","executionInfo":{"status":"ok","timestamp":1615842210400,"user_tz":240,"elapsed":1303,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"image_batch, label_batch = next(iter(train_dataset))","execution_count":null,"outputs":[]},{"metadata":{"id":"dX7KxOSajAyn","executionInfo":{"status":"ok","timestamp":1615842211510,"user_tz":240,"elapsed":215,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"77a4906c-54c5-44f5-817f-8356cb03a557","trusted":false},"cell_type":"code","source":"# load the labels map json file\nwith open(base_path + 'label_num_to_disease_map.json', 'rb') as f:\n    jsonlabels = json.load(f)\n    \n# add labels from json file into dictionary\nlabels_dict = {}\nlabels_dict[0] = jsonlabels['0']\nlabels_dict[1] = jsonlabels['1']\nlabels_dict[2] = jsonlabels['2']\nlabels_dict[3] = jsonlabels['3']\nlabels_dict[4] = jsonlabels['4']\n\n# print labels dictionary\nlabels_dict","execution_count":null,"outputs":[]},{"metadata":{"id":"E6QCXRh4uz-g","executionInfo":{"status":"ok","timestamp":1615842215652,"user_tz":240,"elapsed":2633,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f0b117a9-b64c-46d9-844b-d9d7246ae070","trusted":false},"cell_type":"code","source":"def show_batch(image_batch, label_batch):\n    plt.figure(figsize=(10, 10))\n    for n in range(25):\n        ax = plt.subplot(5, 5, n + 1)\n        plt.imshow(image_batch[n])\n        plt.title(labels_dict[label_batch[n]], size=6)           \n        plt.axis(\"off\")\n\n\n# show batch with labels\nshow_batch(image_batch.numpy(), label_batch.numpy())","execution_count":null,"outputs":[]},{"metadata":{"id":"GhIzVpouZ-r2"},"cell_type":"markdown","source":"**Displaying Augmented Images from tfrecords**"},{"metadata":{"id":"Nm93fZBE6bHC","executionInfo":{"status":"ok","timestamp":1615842219608,"user_tz":240,"elapsed":213,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# data augmentation\nimg_augmentation = Sequential(\n    [\n        preprocessing.RandomCrop(height=224, width=224),\n        preprocessing.RandomFlip(\"horizontal_and_vertical\"),\n        preprocessing.RandomRotation(0.25),\n        preprocessing.RandomZoom((-0.7, -0.2)),\n        preprocessing.RandomContrast(factor=0.1)\n    ],\n    name=\"img_augmentation\"\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"hUbzyd6OEk4S","executionInfo":{"status":"ok","timestamp":1615842226683,"user_tz":240,"elapsed":2039,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"cb4e309a-b3a3-4343-f514-26d262131aca","trusted":false},"cell_type":"code","source":"# show augmented image\nfor image,label in train_dataset.take(1):\n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        aug_img = img_augmentation(image)\n        plt.imshow(aug_img[0])\n        #plt.title(\"{}\".format(format_label(label)))\n        #plt.title(labels_dict[label_batch[n]], size=6)  \n        plt.axis(\"off\")\n","execution_count":null,"outputs":[]},{"metadata":{"id":"G7cS4LtbDqll"},"cell_type":"markdown","source":"##**3.Exploratory Data Analysis**"},{"metadata":{"id":"neRJ2Q2yeW5i","executionInfo":{"status":"ok","timestamp":1615842227393,"user_tz":240,"elapsed":455,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"train_data = pd.read_csv(base_path + '/train.csv')","execution_count":null,"outputs":[]},{"metadata":{"id":"3IE99bTMfS39","executionInfo":{"status":"ok","timestamp":1615842228206,"user_tz":240,"elapsed":238,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"340cc78b-faed-4d67-9ff8-eb745923981d","trusted":false},"cell_type":"code","source":"# show head of training data\ntrain_data.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"1ecl_zIY1VVq","executionInfo":{"status":"ok","timestamp":1615842229776,"user_tz":240,"elapsed":233,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# add class names to dataframe in new column\ntrain_data[\"disease\"] = train_data[\"label\"].map(labels_dict)","execution_count":null,"outputs":[]},{"metadata":{"id":"VlVbZMCuummQ","executionInfo":{"status":"ok","timestamp":1615842230747,"user_tz":240,"elapsed":281,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"68f9a6a2-0f0a-426a-ffe2-29d121c7c6f7","trusted":false},"cell_type":"code","source":"# print head\ntrain_data.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"3eGsJj1stT2u","executionInfo":{"status":"ok","timestamp":1615842232226,"user_tz":240,"elapsed":232,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"32e3d3ff-1ce1-4844-d395-eba0be9f9cc0","trusted":false},"cell_type":"code","source":"# get value counts by label\ntrain_data['label'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"id":"sxRhuUvXD_HV","executionInfo":{"status":"ok","timestamp":1615842234173,"user_tz":240,"elapsed":227,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"TARGET_SIZE = 224 ","execution_count":null,"outputs":[]},{"metadata":{"id":"N-G44lo3rvII","executionInfo":{"status":"ok","timestamp":1615842235722,"user_tz":240,"elapsed":418,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"fb2c68e7-a0fb-4cf9-df4f-aa996e92f2a6","trusted":false},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\n\n# plot count by class\npd.value_counts(train_data['label']).plot.bar(color=['red', 'lightgreen', 'purple', 'pink', 'orange'])\nplt.title('Cassava disease class balance', fontsize=16)\nplt.xlabel('Class', fontsize=13)\nplt.ylabel('Count', fontsize=13)\ny_pos = np.arange(5)\nplt.xticks(y_pos, rotation=0)\nplt.savefig(base_path + 'cassava_disease_class_balance.jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"4jpygwQgv-Kh","executionInfo":{"status":"ok","timestamp":1615842238742,"user_tz":240,"elapsed":418,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"8b564b5c-b41c-45c0-c5f8-935b3d55c4f7","trusted":false},"cell_type":"code","source":"# plot class balance\npd.value_counts(train_data['label'], normalize=True).plot.bar(color=['red', 'lightgreen', 'purple', 'pink', 'orange'])\nplt.title('Cassava disease class balance (normalized)', fontsize=16)\nplt.xlabel('Class', fontsize=13)\nplt.ylabel('Proportion', fontsize=13)\ny_pos = np.arange(5)\nplt.xticks(y_pos, rotation=0)\nplt.savefig(base_path + 'cassava_disease_class_balance(normalized).jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"TnychY4765AV","executionInfo":{"status":"ok","timestamp":1615842240204,"user_tz":240,"elapsed":444,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"8d208f8c-1258-4a2d-f2d9-f0dd20e69a1e","trusted":false},"cell_type":"code","source":"#import seaborn as sns\nplt.figure(figsize=(10, 6))\nplt.title('Cassava Disease Class Balance', fontsize=16)\nsns.countplot(y=\"disease\", data=train_data, palette=\"pastel\");\nplt.savefig(base_path + 'cassava_disease_class_balance(horizontal).jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"v9Le0Hmo8iu8","executionInfo":{"status":"ok","timestamp":1615842241936,"user_tz":240,"elapsed":568,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"d328a5ac-fff1-4b0f-94de-edd7a3fa7073","trusted":false},"cell_type":"code","source":"#import plotly.express as px\n# Counting the Number of Training Samples for each Label\nlabelCounts = train_data['disease'].value_counts().reset_index()\nlabelCounts.columns = ['Label', 'Number of Observations']\n\n# Plot Pie to show Proportions\nfig = px.pie(labelCounts, \n             names = 'Label',values='Number of Observations', \n             labels = train_data['disease'], \n             title = 'Cassava Disease Class Balance (Normalized)')\nplt.savefig(base_path + 'cassava_disease_class_balance(normalized)pie.jpg',bbox_inches='tight')\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"xRmFoRD7SCYN","executionInfo":{"status":"ok","timestamp":1615842243798,"user_tz":240,"elapsed":313,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"5a6b6d97-ddac-4c32-cfbe-fe80ea67d1cd","trusted":false},"cell_type":"code","source":"# print class balances\npd.value_counts(train_data['disease'], normalize=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"eFQoLAhtfY_J","executionInfo":{"status":"ok","timestamp":1615842244836,"user_tz":240,"elapsed":331,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"sample_submission = pd.read_csv(base_path + 'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"id":"t3Z-QhRUf4oF","executionInfo":{"status":"ok","timestamp":1615842245566,"user_tz":240,"elapsed":301,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"729732e8-ab4e-4dfb-86f6-d38ae1cb87d4","trusted":false},"cell_type":"code","source":"sample_submission.head()","execution_count":null,"outputs":[]},{"metadata":{"id":"CDFyJORyxBbW","executionInfo":{"status":"ok","timestamp":1615842251741,"user_tz":240,"elapsed":4896,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"87acdc49-753c-4958-e9a9-721756e9e2e7","trusted":false},"cell_type":"code","source":"# set random seed\nnp.random.seed(2020)\n# plot 5 random samples for each class, by leaf disease\nfor class_name in train_data['disease'].unique():\n    plt.figure(figsize=(20,50))\n    for idx,img_name in enumerate(np.random.choice(train_data[train_data['disease'] == class_name]['image_id'].values,\n                                                   size=5,replace=False)):\n        plt.subplot(1,5,idx+1)\n        #read the image and convert BGR color space to RGB\n        img = cv2.cvtColor(cv2.imread(base_path+'train_images/'+img_name), cv2.COLOR_BGR2RGB)\n        plt.imshow(img)\n        plt.axis('off')\n        # add title to center plot\n        if idx ==2:\n          plt.title(str(class_name), fontsize=20, pad=30)\n          plt.subplots_adjust(hspace=1)\n    # save figure\n    plt.savefig(base_path + 'example_images_for_each_class.jpg',bbox_inches='tight')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"KbvakdPm9aro","executionInfo":{"status":"ok","timestamp":1615842251742,"user_tz":240,"elapsed":747,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"59f44ad8-50bd-4804-a555-de03ecd2b46f","trusted":false},"cell_type":"code","source":"for class_name in train_data['disease'].unique():\n  print(class_name)","execution_count":null,"outputs":[]},{"metadata":{"id":"q6GP7KyXbgRf","executionInfo":{"status":"ok","timestamp":1615842252824,"user_tz":240,"elapsed":287,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"8643cb93-3eee-490c-b351-f7e5116d83b8","trusted":false},"cell_type":"code","source":"train_data.label","execution_count":null,"outputs":[]},{"metadata":{"id":"U7GfiHtKbZSr","executionInfo":{"status":"ok","timestamp":1615842255260,"user_tz":240,"elapsed":1030,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"a8254091-2474-4ce6-8f2e-45c3032611f0","trusted":false},"cell_type":"code","source":"# convert labels to strings for sparse class mode\ntrain_data.label = train_data.label.astype('str')\n\n# separate and augment training images\ntrain_generator = ImageDataGenerator(validation_split = 0.2,\n                                     rotation_range = 20,\n                                     preprocessing_function = None,\n                                     zoom_range = 0.2,\n                                     cval = 0.2,\n                                     horizontal_flip = True,\n                                     vertical_flip = True,\n                                     fill_mode = 'nearest',\n                                     shear_range = 0.3,\n                                     height_shift_range = 0.3,\n                                     width_shift_range = 0.3) \\\n    .flow_from_dataframe(train_data,\n                         directory = os.path.join(base_path, \"train_images\"),\n                         subset = \"training\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n\n# separate and augment validation images\nvalidation_generator = ImageDataGenerator(validation_split = 0.2) \\\n    .flow_from_dataframe(train_data,\n                         directory = os.path.join(base_path, \"train_images\"),\n                         subset = \"validation\",\n                         x_col = \"image_id\",\n                         y_col = \"label\",\n                         target_size = (TARGET_SIZE, TARGET_SIZE),\n                         batch_size = BATCH_SIZE,\n                         class_mode = \"sparse\")\n'done'","execution_count":null,"outputs":[]},{"metadata":{"id":"yZM0wRzefItY","executionInfo":{"status":"ok","timestamp":1615842256867,"user_tz":240,"elapsed":199,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"66b90215-aad2-4aca-837f-cdc017933214","trusted":false},"cell_type":"code","source":"# print images in training set\nprint(\"images in training set: \", train_generator.n)\n\n# printing images in validation set\nprint(\"images in validation set: \", validation_generator.n)","execution_count":null,"outputs":[]},{"metadata":{"id":"FXm4Zsr1gA5_","executionInfo":{"status":"ok","timestamp":1615842258312,"user_tz":240,"elapsed":216,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"0fd4e142-c595-42d5-aec5-2c4792f26b7f","trusted":false},"cell_type":"code","source":"# training set balance\npd.value_counts(train_generator.classes, normalize=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"rWYBum7dhiRz","executionInfo":{"status":"ok","timestamp":1615842259876,"user_tz":240,"elapsed":297,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"9f7b62e9-8ecf-4c3d-fc91-1638b03531ab","trusted":false},"cell_type":"code","source":"# validation set balance\npd.value_counts(validation_generator.classes, normalize=True)","execution_count":null,"outputs":[]},{"metadata":{"id":"au-hCU2cLTLw"},"cell_type":"markdown","source":"##**4. TRANSFER LEARNING/ FINE TUNING CNN MODELS**"},{"metadata":{"id":"3rdOL5CDdalg"},"cell_type":"markdown","source":"**Set up for CNN models**"},{"metadata":{"id":"0LcGkU6CBrgE","executionInfo":{"status":"ok","timestamp":1615859509258,"user_tz":240,"elapsed":4009,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"3e3ecf08-8adc-4e8d-f56e-bc520cf50bad","trusted":false},"cell_type":"code","source":"# setup tensorboard, directories\n!rm -rf ./logs\n!mkdir ./logs/\n!mkdir ./logs/midterm\n\nlog_dir=\"./logs/midterm/\"\ndef tensorboard_callback(exp_name):\n  return tf.keras.callbacks.TensorBoard(log_dir= log_dir + exp_name, profile_batch=0, histogram_freq=1)\n# launch tensorboard with specific directory\n%reload_ext tensorboard\n%tensorboard --logdir logs/midterm","execution_count":null,"outputs":[]},{"metadata":{"id":"Wx0B37POo3av","executionInfo":{"status":"ok","timestamp":1615859528332,"user_tz":240,"elapsed":258,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# set hyperparameters\nBATCH = 64\nEPOCHS = 20","execution_count":null,"outputs":[]},{"metadata":{"id":"RDnVjBWZiP41","executionInfo":{"status":"ok","timestamp":1615859529739,"user_tz":240,"elapsed":300,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# Early Stopping\nearly_stopping_callback = tf.keras.callbacks.EarlyStopping(\n    monitor = 'acc',\n    min_delta=0,\n    patience=10,\n    verbose=0,\n    mode=\"auto\",\n    baseline=None,\n    restore_best_weights=True,\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"HyJ9miMUDlLX"},"cell_type":"markdown","source":"**Baseline Model**"},{"metadata":{"id":"FBJ-TD8EHCRz","executionInfo":{"status":"ok","timestamp":1615850748362,"user_tz":240,"elapsed":246,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"from keras.applications.vgg16 import VGG16\ndef create_base_model():\n    vgg_model = VGG16(include_top = False, weights = 'imagenet', input_tensor = Input(shape=(224, 224, 3)))\n\n    # freeze the model\n    for layer in vgg_model.layers:\n      layer.trainable = False\n    # check frozen layers\n    for i, layer in enumerate(vgg_model.layers):\n      print(i, layer.name, layer.trainable)\n    \n    # define inputs\n    inputs = tf.keras.layers.Input(shape=(224, 224, 3))\n    # do data augmentation on inputs\n    x = img_augmentation(inputs)\n    # call the base model on inputs\n    x = vgg_model(x)\n    \n    # Fine-tuning\n    x = tf.keras.layers.GlobalAveragePooling2D()(x) # add global average pooling layer - color \n\n    # Output layer - output dimension=5 because we have 5 classes\n    outputs = tf.keras.layers.Dense(5, activation = \"softmax\")(x)\n\n    # putting the model together\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n\n    # compile model with Adam, sparse_categorical_crossentropy loss, and accuracy metric\n    model.compile(optimizer = Adam(lr = 0.001),\n                  loss = \"sparse_categorical_crossentropy\",\n                  metrics = [\"acc\"])\n \n    return model","execution_count":null,"outputs":[]},{"metadata":{"id":"7ixukzmYjXXl","executionInfo":{"status":"ok","timestamp":1615850751982,"user_tz":240,"elapsed":655,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f2d01d9c-a83a-4820-c51f-f1aa81203e69","trusted":false},"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\n\n# create baseline model\nbaseline_model = create_base_model()\nbaseline_model.summary()","execution_count":null,"outputs":[]},{"metadata":{"id":"0Hm6W4THjd33","executionInfo":{"status":"ok","timestamp":1615851868628,"user_tz":240,"elapsed":1066259,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"bc584d64-6d58-4a43-ebaf-ea2e5c3a250b","trusted":false},"cell_type":"code","source":"history = baseline_model.fit(\n    train_dataset, \n    epochs = EPOCHS,\n    validation_data=valid_dataset,\n    verbose=1, \n    batch_size=BATCH,\n    callbacks = [early_stopping_callback, tensorboard_callback('vgg_baseline_history')]\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"430Us9R0kUih","executionInfo":{"status":"ok","timestamp":1615851931957,"user_tz":240,"elapsed":245,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to save the model just trained\ndef save_model(model):\n  import os\n  model_name = 'vgg_baseline_model.h5'\n  save_dir = os.path.join(base_path, 'saved_models')\n  \n  # Save model and weights\n  if not os.path.isdir(save_dir):\n      os.makedirs(save_dir)\n  model_path = os.path.join(save_dir, model_name)\n  model.save(model_path)\n  print('Saved trained model at %s ' % model_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"hOekRRovsEdX","executionInfo":{"status":"ok","timestamp":1615851933440,"user_tz":240,"elapsed":597,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"b2e8107e-dbf5-45c2-d1db-8e26540c9476","trusted":false},"cell_type":"code","source":"# save the model\nsave_model(baseline_model)","execution_count":null,"outputs":[]},{"metadata":{"id":"sSM9oEpF77JH","executionInfo":{"status":"ok","timestamp":1615851934654,"user_tz":240,"elapsed":730,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"27ae431e-14c8-4b73-b312-44af0bc95260","trusted":false},"cell_type":"code","source":"# load the model\nfrom keras.models import load_model\nbaseline_model = load_model('/tmp/kaggle-data/saved_models/vgg_baseline_model.h5')\n'done !'","execution_count":null,"outputs":[]},{"metadata":{"id":"v3gKWd4rR7MF","executionInfo":{"status":"error","timestamp":1615852170479,"user_tz":240,"elapsed":234299,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f085d52c-0f71-443c-8f15-7902e7d14cdc","trusted":false},"cell_type":"code","source":"# save tensorboard\n!tensorboard dev upload \\\n--logdir logs \\\n--name \"midterm_project_baseline\" \\\n--description \"Tensorboard of baseline model for Cassava Leaf Disease Classification\"\n--one_shot","execution_count":null,"outputs":[]},{"metadata":{"id":"Oo0ySyD6P930"},"cell_type":"markdown","source":"**Link to TensorBoard for Baseline Model**\nhttps://tensorboard.dev/experiment/IgYfRGC2SqS5ekT9sOdW7Q/#scalars"},{"metadata":{"id":"N01mGgrAwC6w","executionInfo":{"status":"ok","timestamp":1615852174476,"user_tz":240,"elapsed":893,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"f687bde7-5bff-4c34-dfaf-a3c797961e90","trusted":false},"cell_type":"code","source":"# baseline model accuracy plot\nplt.plot(history.history['val_acc'], label=\"val accuracy\")\nplt.plot(history.history['acc'],  label=\"train accuracy\")\nplt.title('Baseline VGG16 model accuracy', fontweight='bold')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend()\nplt.savefig(base_path + 'Baseline VGG16 model accuracy.jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"5aiC3-2jvXFG","executionInfo":{"status":"ok","timestamp":1615852220799,"user_tz":240,"elapsed":292,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# save history as dataframe\nbaseline_history_df = pd.DataFrame(history.history)\n\n# save training history\npickle.dump(history.history, open( 'vgg_baseline_history' + '.pickle', \"wb\"))","execution_count":null,"outputs":[]},{"metadata":{"id":"20vQ5_nTx1ks","executionInfo":{"status":"ok","timestamp":1615852222207,"user_tz":240,"elapsed":289,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# load baseline training data\nbaseline_history = open('vgg_baseline_history' + '.pickle', \"rb\")","execution_count":null,"outputs":[]},{"metadata":{"id":"xS_7dBV6yH0O","executionInfo":{"status":"ok","timestamp":1615852223752,"user_tz":240,"elapsed":448,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"65640e9d-4959-4827-98ed-f78c563b177f","trusted":false},"cell_type":"code","source":"# show baseline training history\nbaseline_history_df","execution_count":null,"outputs":[]},{"metadata":{"id":"-qHpoLfzBr_m"},"cell_type":"markdown","source":"**Model 1: Fine-tuned VGG**"},{"metadata":{"id":"-fF-tzGP7eXO","executionInfo":{"status":"ok","timestamp":1615858186440,"user_tz":240,"elapsed":243,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# Fine Tuning Model 1 VGG\ndef create_frozen_vgg_model():\n\n    # import vgg model\n    vgg_model = VGG16(include_top = False, weights = 'imagenet', input_tensor = Input(shape=(224, 224, 3)))\n    # freeze four convolution blocks\n    for layer in vgg_model.layers:\n      layer.trainable = False\n    # check frozen layers\n    for i, layer in enumerate(vgg_model.layers):\n      print(i, layer.name, layer.trainable)\n    \n    # define inputs\n    inputs = tf.keras.layers.Input(shape=(224, 224, 3))\n    # do data augmentation on inputs\n    x = img_augmentation(inputs)\n    # call the base model on x\n    x = vgg_model(x)\n\n\n    # Fine-tuning\n      # Combos\n    x = tf.keras.layers.GlobalAveragePooling2D()(x) #add global average pooling layer - color \n    x = Dense(128, kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #l2(1e-3) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n      # Combos\n    x = Dense(64, activation = \"relu\", kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n\n    # Output layer - output dimension=5 because we have 5 classes\n    outputs = tf.keras.layers.Dense(5, activation = \"softmax\")(x)\n\n    # Put the model together\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n    \n    # compile model with Adam, sparse_categorical_crossentropy loss, and accuracy metric\n    model.compile(optimizer = Adam(0.0001), #0.001 #learning_rate=expo_decay_lr_schedule\n                  loss = \"sparse_categorical_crossentropy\",\n                  metrics = [\"acc\"])\n \n    return model","execution_count":null,"outputs":[]},{"metadata":{"id":"vU8On4Ax7XOZ","executionInfo":{"status":"ok","timestamp":1615858190087,"user_tz":240,"elapsed":974,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"5100ac27-7e81-443a-c519-d8687be64926","trusted":false},"cell_type":"code","source":"frozen_vgg = create_frozen_vgg_model() \nfrozen_vgg.summary() ","execution_count":null,"outputs":[]},{"metadata":{"id":"KI9Fome-niac","executionInfo":{"status":"ok","timestamp":1615859395709,"user_tz":240,"elapsed":1201393,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"2b5215c6-d143-4e1a-a920-5fae939ddd7e","trusted":false},"cell_type":"code","source":"# fit VGG model and track history \nvgg_history = frozen_vgg.fit(\n    train_dataset,\n    epochs = EPOCHS,\n    validation_data = valid_dataset,\n    verbose = 1, \n    batch_size=BATCH,\n    callbacks=[early_stopping_callback, tensorboard_callback('vgg_finetuned_history')]\n)","execution_count":null,"outputs":[]},{"metadata":{"id":"kQll89gZIm0j","executionInfo":{"status":"ok","timestamp":1615859402144,"user_tz":240,"elapsed":228,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to save the model just trained\ndef save_model(model):\n  import os\n  model_name = 'vgg_finetuned_model.h5'\n  save_dir = os.path.join(base_path, 'saved_models')\n  \n  # Save model and weights\n  if not os.path.isdir(save_dir):\n      os.makedirs(save_dir)\n  model_path = os.path.join(save_dir, model_name)\n  model.save(model_path)\n  print('Saved trained model at %s ' % model_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"t-QjUCU-Im0k","executionInfo":{"status":"ok","timestamp":1615859404446,"user_tz":240,"elapsed":682,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"c21181ec-60dd-463c-8228-b39e0982b68e","trusted":false},"cell_type":"code","source":"# save the model\nsave_model(frozen_vgg)","execution_count":null,"outputs":[]},{"metadata":{"id":"dgZJZvZKIm0k","executionInfo":{"status":"ok","timestamp":1615859406751,"user_tz":240,"elapsed":1215,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"79dc5db3-145e-4668-e2b6-583e3c3a43bd","trusted":false},"cell_type":"code","source":"# load the model\nfrom keras.models import load_model\nfrozen_vgg = load_model('/tmp/kaggle-data/saved_models/vgg_finetuned_model.h5')\n'done !'","execution_count":null,"outputs":[]},{"metadata":{"id":"64bVekIwIm0k","executionInfo":{"status":"error","timestamp":1615859447565,"user_tz":240,"elapsed":23307,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"ef4f2d2e-6043-4595-d4b5-ce0c3dbaeb08","trusted":false},"cell_type":"code","source":"# save tensorboard\n!tensorboard dev upload \\\n--logdir logs \\\n--name \"midterm_project_vgg_finetuned\" \\\n--description \"Tensorboard of VGG model for Cassava Leaf Disease Classification\"\n--one_shot","execution_count":null,"outputs":[]},{"metadata":{"id":"V3x3OQa58u-4"},"cell_type":"markdown","source":"**# Link to Tensorboard for Fine-tuned VGG Model**"},{"metadata":{"id":"WM67k_c6Im0k","executionInfo":{"status":"ok","timestamp":1615859453281,"user_tz":240,"elapsed":631,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"de422649-4650-4372-e32a-1c735a476bb9","trusted":false},"cell_type":"code","source":"# baseline model accuracy plot\nplt.plot(vgg_history.history['val_acc'], label=\"val. accuracy\")\nplt.plot(vgg_history.history['acc'],  label=\"train accuracy\")\nplt.title('Fine-tuned VGG16 model accuracy', fontweight='bold')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend()\nplt.savefig(base_path + 'Fine-tuned VGG16 model accuracy.jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"wEj1UrIFIm0l","executionInfo":{"status":"ok","timestamp":1615855668732,"user_tz":240,"elapsed":264,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# save history as dataframe\nVGG_finetuned_history_df= pd.DataFrame(vgg_history.history)\n\n# save training history\npickle.dump(vgg_history.history, open( 'vgg_finetuned_history' + '.pickle', \"wb\"))","execution_count":null,"outputs":[]},{"metadata":{"id":"rf0btSXbIm0l","executionInfo":{"status":"ok","timestamp":1615855669763,"user_tz":240,"elapsed":295,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# load baseline training data\nVGG_finetuned_history = open('vgg_finetuned_history' + '.pickle', \"rb\")","execution_count":null,"outputs":[]},{"metadata":{"id":"pZ11zIaSIm0l","executionInfo":{"status":"ok","timestamp":1615855670676,"user_tz":240,"elapsed":280,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"74d39db4-d134-4bb6-f33f-8494839ef397","trusted":false},"cell_type":"code","source":"# show baseline training history\nVGG_finetuned_history_df","execution_count":null,"outputs":[]},{"metadata":{"id":"YS9XwsI9ECqq"},"cell_type":"markdown","source":"**Model 2: Fine-tuned ResNet**"},{"metadata":{"id":"Ig5a6gOUEP-7","executionInfo":{"status":"ok","timestamp":1615860186762,"user_tz":240,"elapsed":260,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# Fine Tuning Model 2 ResNet\nfrom keras.applications.resnet50 import ResNet50\ndef create_frozen_resnet_model():\n  \n    # import resnet model\n    resnet_model = ResNet50(include_top = False, weights = 'imagenet', input_tensor = Input(shape=(224, 224, 3)))    \n    # freeze the model\n    for layer in resnet_model.layers:\n      layer.trainable = False\n    # check frozen layers\n    for i, layer in enumerate(resnet_model.layers):\n      print(i, layer.name, layer.trainable)\n \n    # define inputs\n    inputs = tf.keras.layers.Input(shape=(224, 224, 3))\n    # do data augmentation on inputs\n    x = img_augmentation(inputs)\n    # call the base model on x\n    x = resnet_model(x)\n\n    # Fine-tuning\n      # Combos\n    x = tf.keras.layers.GlobalAveragePooling2D()(x) #add global average pooling layer - color \n    x = Dense(128, kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #l2(1e-3) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n      # Combos\n    x = Dense(64, activation = \"relu\", kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n\n    # Output layer - output dimension=5 because we have 5 classes\n    outputs = tf.keras.layers.Dense(5, activation = \"softmax\")(x)\n\n    # Putting the model together\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n\n    # compile model with Adam, sparse_categorical_crossentropy loss, and accuracy metric\n    model.compile(optimizer = Adam(lr=0.0001), #learning_rate=expo_decay_lr_schedule\n                  loss = \"sparse_categorical_crossentropy\",\n                  metrics = [\"acc\"])\n  \n    return model","execution_count":null,"outputs":[]},{"metadata":{"id":"2deg7Jk5FvMH","executionInfo":{"status":"ok","timestamp":1615860191948,"user_tz":240,"elapsed":3494,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"48aa7603-8232-4d0d-ffdd-a84351d44286","trusted":false},"cell_type":"code","source":"frozen_resnet = create_frozen_resnet_model() \nfrozen_resnet.summary() ","execution_count":null,"outputs":[]},{"metadata":{"id":"sEyIf3QFIp8g","executionInfo":{"status":"ok","timestamp":1615861236244,"user_tz":240,"elapsed":1041918,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"008ce53c-e1f0-48cc-962b-17bd6210eff1","trusted":false},"cell_type":"code","source":"# fit ResNet model and track history\nresnet_history = frozen_resnet.fit(\n    train_dataset,\n    epochs = EPOCHS,\n    validation_data = valid_dataset,\n    verbose = 1, \n    batch_size=BATCH, \n    callbacks=[early_stopping_callback, tensorboard_callback('resnet_finetuned_history')]\n)\n","execution_count":null,"outputs":[]},{"metadata":{"id":"MhoMnIiMIp8h","executionInfo":{"status":"ok","timestamp":1615861242939,"user_tz":240,"elapsed":697,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to save the model just trained\ndef save_model(model):\n  import os\n  model_name = 'resnet_finetuned_model.h5'\n  save_dir = os.path.join(base_path, 'saved_models')\n  \n  # Save model and weights\n  if not os.path.isdir(save_dir):\n      os.makedirs(save_dir)\n  model_path = os.path.join(save_dir, model_name)\n  model.save(model_path)\n  print('Saved trained model at %s ' % model_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"xjNrenX7Ip8h","executionInfo":{"status":"ok","timestamp":1615861245922,"user_tz":240,"elapsed":1100,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"2ec0d17e-0152-4ccf-9b85-079f4d912f41","trusted":false},"cell_type":"code","source":"# save the model\nsave_model(frozen_resnet)","execution_count":null,"outputs":[]},{"metadata":{"id":"XmYKPyWmIp8i","executionInfo":{"status":"ok","timestamp":1615861249330,"user_tz":240,"elapsed":2296,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"5c1cef35-d0ca-4e54-91be-e66ff9385f84","trusted":false},"cell_type":"code","source":"# load the model\nfrom keras.models import load_model\nfrozen_resnet = load_model('/tmp/kaggle-data/saved_models/resnet_finetuned_model.h5')\n'done !'","execution_count":null,"outputs":[]},{"metadata":{"id":"aiVfUdAWIp8i","executionInfo":{"status":"error","timestamp":1615861307704,"user_tz":240,"elapsed":40267,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"3fe04b46-c0cc-4639-c1a7-03212d56930a","trusted":false},"cell_type":"code","source":"# save tensorboard\n!tensorboard dev upload \\\n--logdir logs \\\n--name \"midterm_project_resnet_finetuned\" \\\n--description \"Tensorboard of ResNet model for Cassava Leaf Disease Classification\"\n--one_shot","execution_count":null,"outputs":[]},{"metadata":{"id":"Qntwnd1X718A"},"cell_type":"markdown","source":"**Link to TensoBoard for ResNet**"},{"metadata":{"id":"UCEjsMYpIp8i","executionInfo":{"status":"ok","timestamp":1615861312335,"user_tz":240,"elapsed":629,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"12728fea-60fb-44ac-e8f9-dc6bc8492f85","trusted":false},"cell_type":"code","source":"# baseline model accuracy plot\nplt.plot(resnet_history.history['val_acc'], label=\"val. accuracy\")\nplt.plot(resnet_history.history['acc'],  label=\"train accuracy\")\nplt.title('Finetuned ResNet model accuracy', fontweight='bold')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend()\nplt.savefig(base_path + 'Finetuned ResNet model accuracy.jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"KecBHREbIp8i","executionInfo":{"status":"ok","timestamp":1615861318065,"user_tz":240,"elapsed":214,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# save history as dataframe\nResNet_finetuned_history_df = pd.DataFrame(resnet_history.history)\n\n# save training history\npickle.dump(resnet_history.history, open('resnet_finetuned_history' + '.pickle', \"wb\"))","execution_count":null,"outputs":[]},{"metadata":{"id":"N_o3saAjIp8j","executionInfo":{"status":"ok","timestamp":1615861319355,"user_tz":240,"elapsed":254,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# load baseline training data\nResNet_finetuned_history = open('resnet_finetuned_history' + '.pickle', \"rb\")","execution_count":null,"outputs":[]},{"metadata":{"id":"TH5DfAZ-Ip8j","executionInfo":{"status":"ok","timestamp":1615861320454,"user_tz":240,"elapsed":368,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"18a32d78-f930-4049-b374-19a170e24c6e","trusted":false},"cell_type":"code","source":"# show baseline training history\nResNet_finetuned_history_df","execution_count":null,"outputs":[]},{"metadata":{"id":"IHk7sas1ELhw"},"cell_type":"markdown","source":"**Model 3: Fine-tuned DenseNet**"},{"metadata":{"id":"2e0dJAh7GIhw","executionInfo":{"status":"ok","timestamp":1615861374691,"user_tz":240,"elapsed":374,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# Fine Tuning Model 3 DenseNet\nfrom keras.applications.densenet import DenseNet121\ndef create_frozen_densenet_model():\n\n    # import densenet model\n    densenet_model = DenseNet121(include_top = False, weights = 'imagenet', input_tensor = Input(shape=(224, 224, 3)))\n    # freeze four convolution blocks\n    for layer in densenet_model.layers:\n      layer.trainable = False\n    # check frozen layers\n    for i, layer in enumerate(densenet_model.layers):\n      print(i, layer.name, layer.trainable)\n    \n    # define inputs\n    inputs = tf.keras.layers.Input(shape=(224, 224, 3))\n    # do data augmentation on inputs\n    x = img_augmentation(inputs)\n    # call the base model on x\n    x =  densenet_model(x)\n\n    # Fine-tuning\n      # Combos\n    x = tf.keras.layers.GlobalAveragePooling2D()(x) #add global average pooling layer - color \n    x = Dense(128, kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #l2(1e-3) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n      # Combos\n    x = Dense(64, activation = \"relu\", kernel_initializer = 'he_normal', kernel_regularizer='l2')(x) #activation = \"relu\",\n    x = BatchNormalization()(x)\n    x = Dropout(rate = 0.5)(x)\n    x = ReLU()(x)\n\n    # Output layer - output dimension=5 because we have 5 classes\n    outputs = tf.keras.layers.Dense(5, activation = \"softmax\")(x)\n\n    # Put the model together\n    model = tf.keras.Model(inputs=inputs, outputs=outputs)\n\n    # compile model with Adam, sparse_categorical_crossentropy loss, and accuracy metric\n    model.compile(optimizer = Adam(lr=0.0001), #learning_rate=expo_decay_lr_schedule\n                  loss = \"sparse_categorical_crossentropy\",\n                  metrics = [\"acc\"])\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"id":"W8PFFiATGIh6","executionInfo":{"status":"ok","timestamp":1615861381450,"user_tz":240,"elapsed":3957,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"2e640d6a-9b27-4b80-a15a-49fb2e4e9255","trusted":false},"cell_type":"code","source":"frozen_densenet = create_frozen_densenet_model() \nfrozen_densenet.summary() ","execution_count":null,"outputs":[]},{"metadata":{"id":"QXZ69jSeIrgp","executionInfo":{"status":"ok","timestamp":1615862393660,"user_tz":240,"elapsed":1000839,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"8af1dbdb-c5f0-4fca-fb94-492e9f2fe0fa","trusted":false},"cell_type":"code","source":"# fit model and track history\ndensenet_history = frozen_densenet.fit(\n    train_dataset,\n    epochs = EPOCHS,\n    validation_data = valid_dataset,\n    verbose = 1, \n    batch_size=BATCH, \n    callbacks=[early_stopping_callback, tensorboard_callback('densenet_finetuned_history')]\n)\n","execution_count":null,"outputs":[]},{"metadata":{"id":"PXeUA00GIrgq","executionInfo":{"status":"ok","timestamp":1615862396919,"user_tz":240,"elapsed":214,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# function to save the model just trained\ndef save_model(model):\n  import os\n  model_name = 'densenet_finetuned_model.h5'\n  save_dir = os.path.join(base_path, 'saved_models')\n  \n  # Save model and weights\n  if not os.path.isdir(save_dir):\n      os.makedirs(save_dir)\n  model_path = os.path.join(save_dir, model_name)\n  model.save(model_path)\n  print('Saved trained model at %s ' % model_path)","execution_count":null,"outputs":[]},{"metadata":{"id":"D6zxZ-N0Irgr","executionInfo":{"status":"ok","timestamp":1615862399201,"user_tz":240,"elapsed":878,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"e0c80a9b-2e0e-4a56-b10b-040bc7916395","trusted":false},"cell_type":"code","source":"# save the model\nsave_model(frozen_densenet)","execution_count":null,"outputs":[]},{"metadata":{"id":"7mVSCGlDIrgr","executionInfo":{"status":"ok","timestamp":1615862404576,"user_tz":240,"elapsed":3641,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"96bc4013-709d-44f9-995a-3a6ffdd107bf","trusted":false},"cell_type":"code","source":"# load the model\nfrom keras.models import load_model\nfrozen_densenet= load_model('/tmp/kaggle-data/saved_models/densenet_finetuned_model.h5')\n'done !'","execution_count":null,"outputs":[]},{"metadata":{"id":"SQ5SAHszIrgs","trusted":false},"cell_type":"code","source":"# save tensorboard\n!tensorboard dev upload \\\n--logdir logs \\\n--name \"midterm_project_densenet_finetuned\" \\\n--description \"Tensorboard of DenseNet model for Cassava Leaf Disease Classification\"\n--one_shot","execution_count":null,"outputs":[]},{"metadata":{"id":"rw4WyWoNalhZ"},"cell_type":"markdown","source":"**Link to TensorBoard for DenseNet**"},{"metadata":{"id":"hWd_JaTAIrgs","executionInfo":{"status":"ok","timestamp":1615862407848,"user_tz":240,"elapsed":548,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"45db709d-2b6d-4dd5-a58a-cccb745ba1c6","trusted":false},"cell_type":"code","source":"# baseline model accuracy plot\nplt.plot(densenet_history.history['val_acc'], label=\"val. accuracy\")\nplt.plot(densenet_history.history['acc'],  label=\"train accuracy\")\nplt.title('Finetuned DenseNet model accuracy', fontweight='bold')\nplt.ylabel('accuracy')\nplt.xlabel('epochs')\nplt.legend()\nplt.savefig(base_path + 'Finetuned DenseNet model accuracy.jpg',bbox_inches='tight')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"id":"QiBAJu9AIrgs","executionInfo":{"status":"ok","timestamp":1615862454191,"user_tz":240,"elapsed":235,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# save history as dataframe\ndensenet_finetuned_history_df = pd.DataFrame(densenet_history.history)\n\n# save training history\npickle.dump(densenet_history.history, open( 'densenet_finetuned_history' + '.pickle', \"wb\"))","execution_count":null,"outputs":[]},{"metadata":{"id":"IUVpTPfyIrgt","executionInfo":{"status":"ok","timestamp":1615862455432,"user_tz":240,"elapsed":210,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"trusted":false},"cell_type":"code","source":"# load baseline training data\ndensenet_finetuned_history = open('densenet_finetuned_history' + '.pickle', \"rb\")","execution_count":null,"outputs":[]},{"metadata":{"id":"-xpJ2kGUIrgt","executionInfo":{"status":"ok","timestamp":1615862456616,"user_tz":240,"elapsed":234,"user":{"displayName":"Annie Phan","photoUrl":"https://lh3.googleusercontent.com/a-/AOh14GiYl_tqOFZ5W2cE-YU8KG1J1TwyYbIywmPedKYmNQ=s64","userId":"14394843052745211035"}},"outputId":"b7326641-9d27-42bd-a9a9-48b0396a3620","trusted":true},"cell_type":"code","source":"# show baseline training history\ndensenet_finetuned_history_df","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}