{"cells":[{"metadata":{},"cell_type":"markdown","source":"# STARTER: keras EfficientNet\n\nHello, this is my first computer vision competition notebook. \n\nPlease don't be afraid to ask questions. I hope this notebook helps you. \n\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport tensorflow as tf\nfrom tensorflow.keras import models, layers\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\nfrom tensorflow.keras.applications import ResNet50, DenseNet121, EfficientNetB3\nfrom keras.optimizers import Adam\nfrom keras.losses import CategoricalCrossentropy\nimport os, cv2, json\n\n# ignoring warnings\nimport warnings\nwarnings.simplefilter(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# For easy acces to files\nWORK_DIR = \"../input/cassava-leaf-disease-classification/\"\nos.listdir(WORK_DIR)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with open('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json', 'r') as file:\n    labels = json.load(file)\n    \nlabels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = pd.read_csv(WORK_DIR + \"train.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.dtypes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#change for the ImageDatagen and flow_from_dataframe\ndata.label = data.label.astype(\"str\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.dtypes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.shape[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.label.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### **We have 21397 images for training and don't have an equal number of photos for each class.** \n\n I don't know how to deal with the unbalanced image dataset so I'll leave it to the next version."},{"metadata":{},"cell_type":"markdown","source":"# Image Visualization\n\n\n#### Let's first visualize the general data set. \n#### Visualize by class later"},{"metadata":{"trusted":true},"cell_type":"code","source":"IMG_SIZE = 300","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data.sample(9).reset_index(drop=True)\n\nfor i in range(8):\n    plt.subplot(2,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Cassava Bacterial Blight (CBB)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels.get(\"0\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data[data.label==\"0\"].sample(4).reset_index(drop=True)\nfor i in range(4):\n    plt.subplot(1,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Cassava Brown Streak Disease (CBSD)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels.get(\"1\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data[data.label==\"1\"].sample(4).reset_index(drop=True)\nfor i in range(4):\n    plt.subplot(1,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Cassava Green Mottle (CGM)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels.get(\"2\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data[data.label==\"2\"].sample(4).reset_index(drop=True)\nfor i in range(4):\n    plt.subplot(1,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Cassava Mosaic Disease (CMD)**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels.get(\"3\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data[data.label==\"3\"].sample(4).reset_index(drop=True)\nfor i in range(4):\n    plt.subplot(1,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Healthy**"},{"metadata":{"trusted":true},"cell_type":"code","source":"labels.get(\"4\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15,12))\ndata_sample = data[data.label==\"4\"].sample(4).reset_index(drop=True)\nfor i in range(4):\n    plt.subplot(1,4,i+1)\n    \n    img = cv2.imread(WORK_DIR + \"train_images/\" + data_sample.image_id[i])\n    img = cv2.resize(img, (IMG_SIZE, IMG_SIZE))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    \n    plt.axis(\"off\")\n    plt.imshow(img)\n    plt.title(labels.get(data_sample.label[i]))\n    \nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image Preprocessing, Data Augmentetion\n\n\n**ImageDataGenerator:** Generate batches of tensor image data with real-time data augmentation.\n\n**flow_from_dataframe:** Takes the dataframe and the path to a directory + generates batches.\nThe generated batches contain augmented/normalized data.\n\n\nhttps://keras.io/api/preprocessing/image/"},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\ntrain_generator = ImageDataGenerator(\n                                    featurewise_center=True,                                    \n                                    samplewise_center=True,\n                                    featurewise_std_normalization=True,\n                                    samplewise_std_normalization=True, \n                                    zca_whitening=False,\n                                    zca_epsilon=1e-06,\n                                    rotation_range=180,\n                                    width_shift_range=0.2,\n                                    height_shift_range=0.2,\n                                    brightness_range=[-0.1,0.1],\n                                    shear_range=25,\n                                    zoom_range=0.3,\n                                    channel_shift_range=0.2,\n                                    #fill_mode=\"nearest\",\n                                    #cval=0.0,\n                                    horizontal_flip=True,\n                                    vertical_flip=True,\n                                    #rescale=None,\n                                    #preprocessing_function=None,\n                                    #data_format=None,\n                                    validation_split=0.2,\n                                    #dtype=None,\n) \\\n        .flow_from_dataframe(\n                            data,\n                            directory = WORK_DIR + \"train_images\",\n                            x_col = \"image_id\",\n                            y_col = \"label\",\n                            #weight_col = None,\n                            target_size = (IMG_SIZE, IMG_SIZE),\n                            #color_mode = \"rgb\",\n                            #classes = None,\n                            class_mode = \"categorical\",\n                            batch_size = 32,\n                            shuffle = True,\n                            #seed = 34,\n                            #save_to_dir = None,\n                            #save_prefix = \"\",\n                            #save_format = \"png\",\n                            subset = \"training\",\n                            #interpolation = \"nearest\",\n                            #validate_filenames = True\n)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_generator = ImageDataGenerator(\n                                    validation_split = 0.2\n) \\\n        .flow_from_dataframe(\n                            data,\n                            directory = WORK_DIR + \"train_images\",\n                            x_col = \"image_id\",\n                            y_col = \"label\",\n                            target_size = (IMG_SIZE, IMG_SIZE),\n                            class_mode = \"categorical\",\n                            batch_size = 32,\n                            shuffle = True,\n                            #seed = 34,\n                            subset = \"validation\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"valid_generator.class_indices","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model\n\nActually I can say that this is my first experience in transfer learning. I found a good repo on GitHub for benchmarking. Thats why I used EfficientNet.\n\nhttps://github.com/weiaicunzai/awesome-image-classification"},{"metadata":{"trusted":true},"cell_type":"code","source":"def modelEfficientNetB3():\n    \n    model = models.Sequential()\n    model.add(EfficientNetB3(include_top = False, weights = \"imagenet\",\n                            input_shape=(IMG_SIZE,IMG_SIZE, 3)))\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dense(256, activation = 'relu'))\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(5, activation = \"softmax\"))\n    \n    return model ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = modelEfficientNetB3()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras import utils\n\nutils.plot_model(model)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Callbacks\n\n**ModelCheckpoint**: Callback to save the Keras model or model weights at some frequency.\n\n**EarlyStopping**: Stop training when a monitored metric has stopped improving.\n\n**ReduceLROnPlateau**: Reduce learning rate when a metric has stopped improving.\n\n\nhttps://keras.io/api/callbacks/"},{"metadata":{"trusted":true},"cell_type":"code","source":"model_check = ModelCheckpoint(\n                            \"./firstTry.h5\",\n                            monitor = \"val_loss\",\n                            verbose = 1,\n                            save_best_only = True,\n                            save_weights_only = False,\n                            mode = \"min\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stop= EarlyStopping(\n                                monitor = \"val_loss\",\n                                min_delta=0.001,\n                                patience=5,\n                                verbose=1,\n                                mode=\"min\",\n                                #baseline=None,\n                                restore_best_weights=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"reduce_lr = ReduceLROnPlateau(\n                                monitor=\"val_loss\",\n                                factor=0.1,\n                                patience=2,\n                                verbose=1,\n                                mode=\"min\",\n                                min_delta=0.0001,\n                                #cooldown=0,\n                                #min_lr=0\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer = \"adam\",\n            loss = CategoricalCrossentropy(label_smoothing=0.3,reduction=\"auto\",name=\"categorical_crossentropy\"),\n            metrics = [\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(train_generator,\n                            epochs = 30,\n                            validation_data = valid_generator,\n                            callbacks = [model_check,early_stop,reduce_lr])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nplt.plot(history.history['accuracy'], 'b*-', label=\"train_acc\")\nplt.plot(history.history['val_accuracy'], 'r*-', label=\"val_acc\")\nplt.grid()\nplt.title(\"train_acc vs val_acc\")\nplt.ylabel(\"Accuracy\")\nplt.xlabel(\"Epochs\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(15, 5))\nplt.plot(history.history['loss'], 'b*-', label=\"train_loss\")\nplt.plot(history.history['val_loss'], 'r*-', label=\"val_loss\")\nplt.grid()\nplt.title(\"train_loss - val_loss\")\nplt.ylabel(\"Loss\")\nplt.xlabel(\"Epochs\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Any suggestions are very valuable to me. please share with me**"},{"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}