{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# # This Python 3 environment comes with many helpful analytics libraries installed\n# # It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# # For example, here's several helpful packages to load\n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# # Input data files are available in the read-only \"../input/\" directory\n# # For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# # You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# # You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install tensorflow-gpu==2.0.0-alpha0\n# !pip install tensorflow-gpu==2.4.1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# %tensorflow_version 2.x\nimport tensorflow as tf\ndevice_name = tf.test.gpu_device_name()\nprint(device_name)\nif device_name != '/device:GPU:0':\n  raise SystemError('GPU device not found')\nprint('Found GPU at: {}'.format(device_name))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.__version__","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from tensorflow.python.client import device_lib\n# device_lib.list_local_devices()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !cat /proc/meminfo","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> # Include packages and libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport tensorflow as tf\n\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\n\nfrom keras_preprocessing.image import ImageDataGenerator\n\nfrom sklearn.metrics import classification_report, accuracy_score\nfrom sklearn.preprocessing import MultiLabelBinarizer","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> # About the data","metadata":{}},{"cell_type":"markdown","source":"## Read file data ","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')\ndf.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.info()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The data contains 2 columns.  \nThe first column is the *images' names* named '**image**', another column is the '**labels**' of all the images in the dataset.  \nThere are 18632 images and 18632 labels so that there are no null data in this dataset.","metadata":{}},{"cell_type":"markdown","source":"> # Process the data","metadata":{}},{"cell_type":"markdown","source":"## Visualize the data","metadata":{}},{"cell_type":"code","source":"print(df['labels'].value_counts().plot.bar())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **NOTE:**  \n### As we can see here, there are 12 labels but some labels are the combine other labels.  \n### So that, there actually are 5 diseases which are:  \n* rust\n* scab\n* complex\n* frog_eye_leaf_spot\n* powdery_mildew\n\n### And another label is:  \n* healthy","metadata":{}},{"cell_type":"markdown","source":"In the description of the challenge, it is said that \"**Unhealthy leaves with too many diseases to classify visually will have the complex class, and may also have a subset of the diseases identified.**\"  \nBut in the visualization of data above, there label 'complex' also goes with 'rust', 'frog_eye_leaf_spot', 'powdery_mildew'.  \nSo i suppose the 'complex' label is not the combination of the remaining labels and it's still an independent label, but can combine with other labels. ","metadata":{}},{"cell_type":"markdown","source":"### Because one image (leaf) can have multiple diseases so that this task is a multi-label classification problem!!!","metadata":{}},{"cell_type":"markdown","source":"Reform the type of column 'labels' in the dataset from String to Lists in which all labels of all images are contained. ","metadata":{}},{"cell_type":"code","source":"df['labels'] = df['labels'].apply(lambda string: string.split(' '))\ndf.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Keep on processing the data, i'm using MultiLabelBinarizer to convert all the labels to the type of a pandas DataFrame named '**data**'.  \nThis '**data**' table represents each disease label as a column and if an image, or leaf, has that disease, the value of it's cell in that column will be 1, otherwise 0.   ","metadata":{}},{"cell_type":"code","source":"_labels = list(df['labels'])\nmlb = MultiLabelBinarizer()\ndata = pd.DataFrame(mlb.fit_transform(_labels), columns=mlb.classes_, index=df.index)\nprint(data.sum())\n\nlabels = list(data.sum().keys())\nprint(labels)\nlabel_counts = data.sum().values.tolist()\n\nfig, ax = plt.subplots(1,1, figsize=(20,6))\n\nsns.barplot(x= labels, y= label_counts, ax=ax)\n\nfor p in ax.patches:\n    ax.text(p.get_x() + p.get_width()/2, p.get_height(), int(p.get_height()), ha='center')\n    \nplt.title('THE AMOUNT OF EACH LABEL')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.insert(0, 'image', df['image'], True)\ndata","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now we have a table of images' names and their diseases index.  \nLet's get the target of all image in the dataset.","metadata":{}},{"cell_type":"code","source":"target = []\nfor row in range(len(data)):\n    target.append(list((data.iloc[row])[1:]))\n    \nlen(target), target[:5]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"target = np.array(target)\ntarget[:5]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Using Image Data Generator to load the image data from directory","metadata":{}},{"cell_type":"markdown","source":"Call an ImageDataGenerator","metadata":{}},{"cell_type":"code","source":"image_generator = ImageDataGenerator(rescale=1/255.0, validation_split=0.2)\n#                                      preprocessing_function=tf.keras.applications.vgg16.preprocess_input)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Define important arguments","metadata":{}},{"cell_type":"code","source":"HEIGHT = 32 #128 64\nWIDTH = 32 #128 64\nSEED = 42\nBATCH_SIZE = 32","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Create a train_generator, validation_generator to get the image from file train_images for training and validating.","metadata":{}},{"cell_type":"code","source":"type(df), df['labels'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with tf.device('/GPU:0'):\n    train_generator = image_generator.flow_from_dataframe(\n        dataframe=df,\n        directory='../input/plant-pathology-2021-fgvc8/train_images',\n        x_col='image',\n        y_col='labels',\n        subset='training',\n        batch_size=BATCH_SIZE, \n        seed=SEED,\n        class_mode='categorical',\n        target_size=(HEIGHT, WIDTH),\n        shuffle=True,\n    )\n    validation_generator = image_generator.flow_from_dataframe(\n        dataframe=df,\n        directory='../input/plant-pathology-2021-fgvc8/train_images',\n        x_col='image',\n        y_col='labels',\n        subset='validation',\n        batch_size=BATCH_SIZE, \n        seed=SEED,\n        class_mode='categorical',\n        target_size=(HEIGHT, WIDTH),\n        shuffle=True,\n    )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Create a CNN model","metadata":{}},{"cell_type":"code","source":"# instantiating the model in the strategy scope creates the model on the TPU\n# with tpu_strategy.scope():\n# print(tpu, tpu_strategy)\n# run_opts = tf.RunOptions(report_tensor_allocations_upon_oom = True)\nwith tf.device('/GPU:0'):\n    model=Sequential()\n    model.add(Conv2D(64,kernel_size=4,activation='relu',input_shape=(HEIGHT,WIDTH,3)))\n    model.add(MaxPooling2D(2,2))\n    model.add(Conv2D(64,(3,3),activation='relu'))\n    model.add(MaxPooling2D(2,2))\n#     model.add(Conv2D(64,(3,3),activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n    model.add(Conv2D(128,(3,3),activation='relu'))\n    model.add(MaxPooling2D(2,2))\n    model.add(Flatten())\n    model.add(Dropout(0.5))\n    model.add(Dense(12,activation='softmax'))\n\n    model.compile(\n        optimizer='adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy'],\n    #     options=run_opts\n    )\n\n# with tf.device('/gpu:0'):\n#     model = Sequential()\n#     model.add(Conv2D(64, kernel_size=4, activation='relu', input_shape=(HEIGHT, WIDTH, 3)))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Conv2D(64, kernel_size=4, activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Dropout(0.5))\n#     model.add(Conv2D(128, kernel_size=4, activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Conv2D(128, kernel_size=4, activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Dropout(0.5))\n#     model.add(Conv2D(256, kernel_size=4, activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Conv2D(256, kernel_size=4, activation='relu'))\n#     model.add(MaxPooling2D(2,2))\n#     model.add(Flatten())\n#     model.add(Dropout(0.5))\n# #     model.add(Dense(512, activation='relu'))\n#     model.add(Dense(6, activation='softmax'))\n\n#     model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=[\"accuracy\"])\n\nmodel.summary()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Compile the model","metadata":{}},{"cell_type":"code","source":"# model.compile(\n#     optimizer='adam',\n#     loss='categorical_crossentropy',\n#     metrics=['accuracy'])\n# model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Define arguments ","metadata":{}},{"cell_type":"code","source":"TRAIN_STEP_SIZE = train_generator.samples/train_generator.batch_size\nVALIDATION_STEP_SIZE = validation_generator.samples/validation_generator.batch_size","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# tf.test.is_gpu_available(), tf.test.gpu_device_name()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Fit the model","metadata":{}},{"cell_type":"code","source":"with tf.device('/gpu:0'):\n    model_history=model.fit_generator(train_generator, validation_data=validation_generator, epochs=5)\n\n#                              steps_per_epoch=TRAIN_STEP_SIZE,\n#                              validation_steps=VALIDATION_STEP_SIZE\n                                \n            ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.__version__","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}