{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Imports\n\nBuncha imports"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install --quiet efficientnet","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import efficientnet.tfkeras as efn\nfrom tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D\nimport tensorflow.keras\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import TensorBoard, EarlyStopping, ReduceLROnPlateau, ModelCheckpoint, Callback\n# from tensorflow.keras.layers import Batchnorm2D, Conv2D, MaxPooling2D, Dense, Flatten, Activation\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport cv2\nimport os\nfrom tqdm import tqdm as tqdm\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\nimport os","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loading CSV's containing image path stuff"},{"metadata":{},"cell_type":"markdown","source":"Lets make a var for our main directory"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"path = '../input/cassava-leaf-disease-classification/'","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Loading of the train csv"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv = pd.read_csv(path + 'train.csv')\ntrain_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"lets see how many samples do we have"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv.label.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- The image path is not compelete we would like it to be compelete\n\n- The labels are not one hot encoded\n\nSo the plan - \n\n- make a function to compelete the path\n- make a function to convert into one hot arrays\n- use ```train_csv.apply()```"},{"metadata":{"trusted":true},"cell_type":"code","source":"def comp_path(img_name):\n    img_dir = '../input/cassava-leaf-disease-classification/train_images/'\n    return img_dir + img_name\ndef one_hot(label):\n    return str(list(to_categorical(label, num_classes=5, dtype='int32')))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Please run the following cells only once."},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv.image_id = train_csv.image_id.apply(comp_path)\nprint(train_csv.image_id[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_csv.label = train_csv.label.apply(one_hot)\ntrain_csv","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = cv2.imread(train_csv.image_id[0])\nimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\nplt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let us now split our dataframe into train and validation sets"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain,val = train_test_split(train_csv, test_size = 0.1, random_state = 42)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from collections import Counter\nprint(Counter(train.label.apply(str)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(Counter(val.label.apply(str)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"A look at our classes"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = pd.read_json(path + 'label_num_to_disease_map.json', orient='index')\nlabels","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Lets have a sneak peek at the submission file"},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.read_csv('../input/cassava-leaf-disease-classification/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load in Data and Augmentations"},{"metadata":{},"cell_type":"markdown","source":"Will need augmentations to increase amount of data.\n\nGood augmentations for detecting a disease is that does not alters the disease's features.\nSo some ot the good augmentations would be - \n\n**1. Vertical Flip**\n\n**2. Horrizontal Flip**\n\n**3. Rotation**\n\n**4. Zoom the image**\n\n**5. Centre crop**"},{"metadata":{},"cell_type":"markdown","source":"## Parameters for training - "},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 32\nEPOCHS = 15\nIMG_SIZE = 256","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Setting some augmentation parameters in an ImageDataGenerator Object"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_datagen = ImageDataGenerator(horizontal_flip = True, \n                                    vertical_flip = True, \n                                    height_shift_range=0.2, \n                                    width_shift_range=0.2, \n                                    brightness_range=[0.7, 1.5],\n                                    rotation_range=30, \n                                    shear_range=0.2,\n                                    fill_mode='reflect',\n                                    zoom_range=[0.3,0.6],\n                                  )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Making the generator and telling it where to look for the data"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_gen = train_datagen.flow_from_dataframe(dataframe = train,\n                                             directory = None,\n                                             x_col = \"image_id\",\n                                             y_col = \"label\",\n                                             target_size = (IMG_SIZE, IMG_SIZE),\n                                             batch_size = BATCH_SIZE,\n                                             class_mode = \"categorical\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Lets display the images. Here is our function to display images"},{"metadata":{"trusted":true},"cell_type":"code","source":"t_x, t_y = next(train_gen)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, m_axs = plt.subplots(4, 6, figsize = (32, 16))\nfor (c_x, c_y, c_ax) in zip(t_x, t_y, m_axs.flatten()):\n    c_ax.imshow(c_x.astype(np.uint8))\n    c_ax.set_title(np.argmax(c_y))\n    c_ax.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"t_y[0]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The validation generator - "},{"metadata":{"trusted":true},"cell_type":"code","source":"val_datagen = ImageDataGenerator(horizontal_flip = True, \n                                vertical_flip = True, \n                                height_shift_range=0.2, \n                                width_shift_range=0.2, \n                                brightness_range=[0.7, 1.5],\n                                rotation_range=30, \n                                shear_range=0.2,\n                                fill_mode='reflect',\n                                zoom_range=[0.3,0.6],\n                                  )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_gen = train_datagen.flow_from_dataframe(dataframe = val,\n                                             directory = None,\n                                             x_col = \"image_id\",\n                                             y_col = \"label\",\n                                             target_size = (IMG_SIZE, IMG_SIZE),\n                                             batch_size = BATCH_SIZE,\n                                             class_mode = \"categorical\")\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# The Model - \n\nOk so we have made our augmentors and stuff loaded in data and stuff and now making the model and stuff is left.\n\nFirst step lets load in the state of the art Efficientnet B4 model. Well lets see if it turns \nstate of the art in helping us sort out the cassava disease.\n\nThis sure is a wonderful tutorial - \n\nhttps://www.kaggle.com/harveenchadha/effnetb4-tf-data-gpu-aug-5x-speedup-tta?select=best_model.hdf5"},{"metadata":{"trusted":true},"cell_type":"code","source":"import tensorflow as tf\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print(f'Running on TPU {tpu.master()}')\nexcept ValueError:\n    tpu = None\n    print('Not RUNNING on TPU')\n\nif tpu:\n    print('MAKING TPU STRATEGY')\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    print('MAKING CPU STRATEGY')\n    strategy = tf.distribute.get_strategy()\n\nAUTO = tf.data.experimental.AUTOTUNE\nREPLICAS = strategy.num_replicas_in_sync\nprint(f'REPLICAS: {REPLICAS}')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#!wget https://storage.googleapis.com/keras-applications/efficientnetb4_notop.h5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_model():\n    model = Sequential()\n    model.add(efn.EfficientNetB4(include_top = False,\n                                  weights = 'noisy-student',\n                                  pooling = 'avg',\n                                  input_shape = (IMG_SIZE, IMG_SIZE, 3)))\n    model.add(Dense(5, activation = 'softmax'))\n    model.layers[0].trainable = True\n    \n    optimizer = Adam(lr = 0.01)\n    #tpu_optimizer = tf.experimental.contrib.tpu.CrossShardOptimizer(optimizer)\n    model.compile(optimizer=optimizer, \n                  loss='categorical_crossentropy', \n                  metrics=['accuracy'])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = make_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Callbacks\nmodel_path = 'EnetB4_top_trainable/'\ntensorboard = TensorBoard(log_dir = model_path + 'logs/')\nreducelr = ReduceLROnPlateau(patience=1)\nearlystop = EarlyStopping(monitor='val_loss', min_delta=0, patience = 3, mode = 'min')\ncheckpoint_val_loss = ModelCheckpoint(model_path + 'val_loss_checkpoint/{epoch:02d}-{val_loss:.2f}.hdf5', monitor='val_loss', save_best_only=True, mode='min')\ncheckpoint_val_acc = ModelCheckpoint(model_path + 'val_acc_checkpoint/{epoch:02d}-{val_loss:.2f}.hdf5', monitor='val_acc', save_best_only=True, mode='max')\ncheckpoint_all = ModelCheckpoint(model_path + 'all_checkpoint/{epoch:02d}-{val_loss:.2f}.hdf5', monitor='val_loss', save_best_only=False, mode='auto')\nbest = ModelCheckpoint(model_path + 'best_model.hdf5', monitor='val_loss', save_best_only=True, mode='min')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(train_gen,\n                    validation_data = val_gen,\n                    epochs = EPOCHS,\n                    batch_size = BATCH_SIZE,\n                    callbacks = [tensorboard, \n                                 reducelr, earlystop, \n                                 checkpoint_val_loss, checkpoint_val_acc, \n                                 checkpoint_all,\n                                 best])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}