{"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":"import os\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"load_dir = \"../input/plant-pathology-2021-fgvc8/\"\ntrain = pd.read_csv(load_dir + \"train.csv\")\n\ntrain_image_dir = \"/kaggle/input/plant-pathology-2021-fgvc8/train_images/\"\ntrain_df = pd.DataFrame(train, columns = [\"image\", \"labels\"])\ntrain_df[\"labels\"] = train['labels'].apply(lambda s: s.split(' '))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\n\ndef visualizeImage(idx):\n  fd = train_df.iloc[idx]\n  img = fd.image\n  img = Image.open(\"/kaggle/input/plant-pathology-2021-fgvc8/train_images/\" + img)\n  fig,ax = plt.subplots(figsize = (15, 7))\n  ax.imshow(img)\n  ax.grid(False)\n  plt.show()\n  print(f\"labels: {train_df.iloc[idx][1]}\")\n  \nvisualizeImage(1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocessing the data\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\nimageSize = 227\nbatchSize = 16\nNUM_CLASSES = 6\n\ntrainGen = ImageDataGenerator(preprocessing_function = tf.keras.applications.resnet50.preprocess_input, \n                             rescale = 1./255,\n                             shear_range = 0.2,\n                             zoom_range = 0.2,\n                             horizontal_flip = True,\n                             validation_split = 0.2)\n\ntrain_generator = trainGen.flow_from_dataframe(dataframe = train_df,\n                                             directory = train_image_dir,\n                                             x_col = \"image\",\n                                             y_col = \"labels\",\n                                             class_mode= \"categorical\", \n                                               subset = \"training\", \n                                               target_size = (imageSize, imageSize),\n                                               batch_size = batchSize,\n                                              seed = 672502037)\n\nvalid_generator = trainGen.flow_from_dataframe(dataframe = train_df,\n                                             directory = train_image_dir,\n                                             x_col = \"image\",\n                                             y_col = \"labels\",\n                                             class_mode= \"categorical\", \n                                               subset = \"validation\", \n                                               target_size = (imageSize, imageSize),\n                                               batch_size = batchSize,\n                                              seed = 672502037)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras\nfrom tensorflow.keras.optimizers import Adam, SGD\nfrom keras.models import Model\nfrom tensorflow.keras.layers import Dense, Dropout\n\nbaseNet = tf.keras.applications.ResNet50(weights = \"imagenet\", include_top = False, pooling = \"avg\")\n\nx = baseNet.output\nx = Dense(1024, activation='relu')(x)\nx = Dense(64, activation='relu')(x)\npredictions = Dense(NUM_CLASSES, activation='sigmoid')(x)\n\n# this is the model we will train\nmodel = Model(inputs=baseNet.input, outputs=predictions)\n\n#for layer in baseNet.layers:\n#    layer.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from keras import backend as K\n\ndef recall(y_true, y_pred):\n    tp = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n    recall = tp / (possible_positives + K.epsilon())\n    return recall\n\ndef precision(y_true, y_pred):\n    tp = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n    precision = tp / (predicted_positives + K.epsilon())\n    return precision\n\ndef f1(y_true, y_pred):\n    precision = precision(y_true, y_pred)\n    recall = recall(y_true, y_pred)\n    return 2*((precision * recall) / (precision + recall + K.epsilon()))\n\nearlystop = keras.callbacks.EarlyStopping(\n    monitor='val_loss',\n    # threshold to consider as no change\n    min_delta=0.02,\n    # stop if  epochs with no change\n    patience=2,\n    verbose=1,\n    mode='min',\n    restore_best_weights= True\n)\n\nopt = keras.optimizers.Adam(lr=0.001, decay=1e-4)\nmodel.compile(optimizer = opt, loss = \"binary_crossentropy\", metrics = [\"accuracy\", f1, recall, precision])\nhistory = model.fit(train_generator, steps_per_epoch = 932, epochs=10, validation_data=valid_generator, verbose=True,\n         validation_steps = 187, callbacks = earlystop)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.save(\"trainedModel.h5\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, layer in enumerate(baseNet.layers):\n   print(i, layer.name)","metadata":{"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(history.history.keys())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# summarize history for accuracy\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('model accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\nplt.show()\n\n# summarize history for accuracy\nplt.plot(history.history['f1_m'])\nplt.plot(history.history['val_f1_m'])\nplt.title('model f1_m')\nplt.ylabel('f1_m')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\nplt.show()\n\n# summarize history for accuracy\nplt.plot(history.history['recall_m'])\nplt.plot(history.history['val_recall_m'])\nplt.title('model recall_m')\nplt.ylabel('recall_m')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\nplt.show()\n\n# summarize history for accuracy\nplt.plot(history.history['precision_m'])\nplt.plot(history.history['val_precision_m'])\nplt.title('model precision_m')\nplt.ylabel('precision_m')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\nplt.show()\n\n# summarize history for loss\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('model loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'validation'], loc='upper right')\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"THRESHOLD = 0.5\n\nfrom tqdm import tqdm\nimport PIL\n\ntest_df = pd.read_csv('../input/plant-pathology-2021-fgvc8/sample_submission.csv')\n\nfor img in tqdm(test_df['image']):\n    path = '../input/plant-pathology-2021-fgvc8/test_images/' + str(img_name)\n    with PIL.Image.open(path) as img:\n        img = img.resize((imageSize, imageSize))\n        img.save(f'./{img}')\n        \ntest_generator = trainGen.flow_from_dataframe(\n    dataframe = test_df,\n    directory = './',\n    x_col = \"image\",\n    y_col = \"labels\",\n    class_mode = \"categorical\",\n    target_size = (imageSize, imageSize),\n    batch_size = batchSize,\n    seed = 672502037,\n)\n\npredResult = []\nprediction = model.predict(test_generator).tolist()\nfor img in prediction:\n    predictionLabels = []\n    index = 0\n    for categoryScore in img:\n        if categoryScore > THRESHOLD:\n            predictionLabels.append(index)\n        index += 1\n    if not predictionLabels:\n        predResult.append(np.argmax(prediction))\n    else:\n        predResult.append(predictionLabels)\n\nprint(predResult)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_map = (train_generator.class_indices)\nfinal_label_map = dict((v,k) for k,v in label_map.items())\nprint(final_label_map)\n\nfor i in range(len(test_df)):\n    labels = \"\"\n    for idx in predResult[i]:\n        labels += final_label_map[idx] + \" \"\n    test_df.iloc[i, 1] = labels.strip()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}