{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Intro\nWelcome to the Cassava Leaf Disease Classification competition.\n\nThere are 5 classifications (click for further informations):\n* 0: [Cassava Bacterial Blight (CBB)](https://en.wikipedia.org/wiki/Bacterial_blight_of_cassava)\n* 1: [Cassava Brown Streak Disease (CBSD)](https://en.wikipedia.org/wiki/Cassava_brown_streak_virus_disease)\n* 2: [Cassava Green Mottle (CGM)](https://en.wikipedia.org/wiki/Cassava_green_mottle_virus)\n* 3: [Cassava Mosaic Disease (CMD)](https://en.wikipedia.org/wiki/Cassava_mosaic_virus)\n* 4: Healthy\"\n\nWe will give a simple starter notebook based on a CNN."},{"metadata":{},"cell_type":"markdown","source":"# Libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport cv2\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.utils import to_categorical, Sequence\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D, BatchNormalization\nfrom keras.optimizers import RMSprop,Adam","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Path"},{"metadata":{"trusted":true},"cell_type":"code","source":"path = '/kaggle/input/cassava-leaf-disease-classification/'\nos.listdir(path)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","collapsed":true,"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":false},"cell_type":"markdown","source":"# Load Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data = pd.read_csv(path+'train.csv')\nsamp_subm = pd.read_csv(path+'sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# EDA"},{"metadata":{"trusted":true},"cell_type":"code","source":"print('number of train data:', len(train_data))\nprint('number of train images:', len(os.listdir(path+'train_images/')))\nprint('number of test images:', len(os.listdir(path+'test_images/')))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Distribution of the labels:"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data['label'].hist(bins=4)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Plot an image:"},{"metadata":{"trusted":true},"cell_type":"code","source":"img = cv2.imread(path+'train_images/'+'1000015157.jpg')\nplt.imshow(img)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Prepare Data For Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 64\nimg_size = 64\nimg_channel = 3","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Train Labels And Class Weights"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train = to_categorical(train_data['label'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#class_weight = dict(zip(range(0, 7), (train_data['label'].value_counts()/len(train_data))))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Image Data Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"class DataGenerator(Sequence):\n    def __init__(self, path, list_IDs, labels, batch_size, img_size, img_channel):\n        self.path = path\n        self.list_IDs = list_IDs\n        self.labels = labels\n        self.batch_size = batch_size\n        self.img_size = img_size\n        self.img_channel = img_channel\n        self.indexes = np.arange(len(self.list_IDs))\n        \n    def __len__(self):\n        return int(np.floor(len(self.list_IDs)/self.batch_size))\n    \n    \n    def __getitem__(self, index):\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        list_IDs_temp = [self.list_IDs[k] for k in indexes]\n        X, y = self.__data_generation(list_IDs_temp)\n        return X, y\n\n    \n    def __data_generation(self, list_IDs_temp):\n        X = np.empty((self.batch_size, self.img_size, self.img_size, self.img_channel))\n        y = np.empty((self.batch_size, 5), dtype=int)\n        for i, ID in enumerate(list_IDs_temp):\n            data_file = cv2.imread(self.path+ID)\n            img = cv2.resize(data_file, (self.img_size, self.img_size))\n            X[i, ] = img\n            y[i, ] = self.labels[i]\n        X = X.astype('float32')\n        X -= X.mean()\n        X /= X.std()\n        return X, y","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Define Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential()\nmodel.add(Conv2D(128, input_shape=(img_size,img_size,img_channel), kernel_size=5, strides=4, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPool2D(pool_size=(4)))\nmodel.add(Flatten())\nmodel.add(Dense(64, activation='relu'))\nmodel.add(Dense(64, activation='relu'))\nmodel.add(Dropout(0.3))\nmodel.add(Dense(5, activation='softmax'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=1e-3), loss='categorical_crossentropy', metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Logistic Regression"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.linear_model import LogisticRegression","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"clf_log = LogisticRegression(n_jobs=-1, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator = DataGenerator(path+'train_images/', train_data['image_id'], y_train, batch_size, img_size, img_channel)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Hyperparameter tuning"},{"metadata":{"trusted":true},"cell_type":"code","source":"#@title K-fold, 10 splits, Shuffle=True and random_state = 42. The distribution of Training and Val data in each fold is now:\nfrom sklearn.model_selection import StratifiedKFold\nfolds = list(StratifiedKFold(n_splits=40, shuffle=True, random_state=42).split(train_data['image_id'],train_data['label']))\nprint(\"Training split: {}\".format(len(folds[0][0])))\nprint(\"Validation split: {}\".format(len(folds[0][1])))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = np.empty((len(y_train[folds[0][1]]), 64, 64, 3))\ny = np.empty((len(y_train[folds[0][1]]), 5), dtype=int)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = 0\nfor i, ID in enumerate(train_data['image_id'][folds[0][1]]):\n    data_file = cv2.imread(path+\"train_images/\"+ID)\n    img = cv2.resize(data_file, (64,64), interpolation = cv2.INTER_AREA)\n    X[i, ] = img\n    y[i, ] = y_train[folds[0][1]][i]\nX = X.astype('float32')\nX -= X.mean()\nX /= X.std()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from kerastuner.applications import HyperResNet\nfrom kerastuner.tuners import Hyperband\nfrom kerastuner.tuners import BayesianOptimization\n\nhypermodel = HyperResNet(input_shape=(64, 64, 3), classes = 5)\n\ntuner = BayesianOptimization(\n    hypermodel,\n    objective='val_accuracy',\n    directory='/kaggle/working/my_dir',\n    executions_per_trial=3,\n    max_trials = 50,\n    project_name='tuning')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tuner.search(X,y,validation_split=0.2, verbose=1, epochs=10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"   # Show a summary of the search\ntuner.results_summary()\n\n# Retrieve the best model.\nbest_model = tuner.get_best_models(num_models=1)[0]\n\n# Evaluate the best model.\n#results = best_model.evaluate(X_combined_test_gridsearch, y_test_gridsearch)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = best_model.fit_generator(generator=train_generator,\n                              #class_weight = class_weight,\n                              workers=4, verbose = 0, epochs=10\n                             )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predict Test Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"test_generator = DataGenerator(path+'test_images/', samp_subm['image_id'], samp_subm['label'], 1, img_size, img_channel)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predict = best_model.predict_generator(test_generator, verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"samp_subm['label'] = predict.argmax(axis=1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Export Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"samp_subm.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}