{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n\nimport os\nimport cv2\nimport time\nimport random\nimport itertools\nimport tensorflow as tf\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport matplotlib.style as style\nimport tensorflow_hub as hub\n\nfrom PIL import Image\nfrom datetime import datetime\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.preprocessing import image\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import MultiLabelBinarizer\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\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_images_path ='../input/plant-pathology-2021-fgvc8/train_images/'\ntest_images_path = '../input/plant-pathology-2021-fgvc8/test_images/'\ntrain = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv', dtype=str)\ntrain.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Get label frequencies in descending order\nlabel_freq = train['labels'].apply(lambda s: str(s)).explode().value_counts().sort_values(ascending=False)\n\n# Bar plot\nstyle.use(\"fivethirtyeight\")\nplt.figure(figsize=(12,10))\nsns.barplot(y=label_freq.index.values, x=label_freq, order=label_freq.index)\nplt.title(\"Label frequency\", fontsize=14)\nplt.xlabel(\"\")\nplt.xticks(fontsize=12)\nplt.yticks(fontsize=12)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_freq","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Transform labels into a list of labels\ntrain['new_labels'] = train['labels'].apply(lambda s: [l for l in str(s).split()])\ntrain.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_paths = [os.path.join(train_images_path, str(f)) for f in train['image']]\ncorresponding_labels = [f for f in train['new_labels']]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"nobs = 14 # Maximum number of images to display\nncols = 4 # Number of columns in display\nnrows = nobs//ncols # Number of rows in display\n\nstyle.use(\"default\")\nplt.figure(figsize=(12,2*nrows))\nfor i in range(nrows*ncols):\n    ax = plt.subplot(nrows, ncols, i+1)\n    plt.imshow(Image.open(train_paths[i]))\n    plt.title(corresponding_labels[i], size=10)\n    plt.axis('off')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Label Encoding\n# Fit the multi-label binarizer on the training set\nprint(\"Labels:\")\nmlb = MultiLabelBinarizer()\nmlb.fit(train['new_labels'])\n\n# Loop over all labels and show them\nN_LABELS = len(mlb.classes_)\nfor (i, label) in enumerate(mlb.classes_):\n    print(\"{}. {}\".format(i, label))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# transform the new_labels to one-hot encoding \ndf = pd.DataFrame(mlb.fit_transform(train['new_labels']),columns=mlb.classes_)\n# Place the DataFrames side by side\nnew_df = pd.concat([train,df],axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"columns = list(mlb.classes_)\ncolumns","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMG_SIZE = 224 # Specify height and width of image to match the input format of the model\nCHANNELS = 3 # Keep RGB color channels to match the input format of the model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255.,\n                                                           validation_split=0.2,\n                                                           samplewise_center=True,\n                                                           samplewise_std_normalization=True,\n                                                           horizontal_flip=True, \n                                                           vertical_flip=False,\n                                                           height_shift_range=0.05,\n                                                           width_shift_range=0.1,\n                                                           #rotation_range=20,\n                                                           shear_range=0.1,\n                                                           fill_mode='reflect',\n                                                           zoom_range=0.15)\n\ntrain_gen=base_gen.flow_from_dataframe(dataframe=new_df,\n                                             directory=train_images_path,\n                                             x_col='image',\n                                             y_col='new_labels',\n                                             batch_size=32,\n                                             seed=42,\n                                             shuffle=True,\n                                             #class_mode='raw',\n                                             class_mode='categorical',\n                                             classes=columns,\n                                             target_size=(IMG_SIZE,IMG_SIZE),\n                                             subset='training')\n\n\nvalid_gen=base_gen.flow_from_dataframe(dataframe=new_df,\n                                             directory=train_images_path,\n                                             x_col='image',\n                                             y_col='new_labels',\n                                             batch_size=32,\n                                             seed=42,\n                                             shuffle=True,\n                                             #class_mode='raw',\n                                             class_mode='categorical',\n                                             classes=columns,\n                                             target_size=(IMG_SIZE,IMG_SIZE),\n                                             subset='validation')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# feature_extractor_url ='https://tfhub.dev/google/imagenet/resnet_v2_50/feature_vector/4'\n# feature_extractor_layer = hub.KerasLayer(feature_extractor_url,\n#                                          input_shape=(IMG_SIZE,IMG_SIZE,CHANNELS),\n#                                         trainable=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# model = tf.keras.Sequential([\n#     feature_extractor_layer,\n#     layers.Dense(1024, activation='relu', name='hidden_layer'),\n#     layers.Dense(N_LABELS, activation='sigmoid', name='output')\n# ])\n\n# model.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# #our custom model starts here (sequential)\n# model =tf.keras.Sequential(\n#     [\n#         layers.Conv2D(filters=64, kernel_size=(5, 5), activation='relu', \n#                       input_shape=(IMG_SIZE,IMG_SIZE,CHANNELS)),\n#         layers.BatchNormalization(axis=3),\n#         layers.Conv2D(filters=64, kernel_size=(5, 5), activation='relu'),\n#         layers.MaxPooling2D(pool_size=(2, 2)),\n#         layers.BatchNormalization(axis=3),\n#         layers.Dropout(0.25),\n        \n#         layers.Conv2D(filters=128, kernel_size=(5, 5), activation='relu'),\n#         layers.BatchNormalization(axis=3),\n#         layers.Conv2D(filters=128, kernel_size=(5, 5), activation='relu'),\n#         layers.MaxPooling2D(pool_size=(2, 2)),\n#         layers.BatchNormalization(axis=3),\n#         layers.Dropout(0.25),\n        \n#         layers.Conv2D(filters=256, kernel_size=(5, 5), activation='relu'),\n#         layers.BatchNormalization(axis=3),\n#         layers.Conv2D(filters=256, kernel_size=(5, 5), activation='relu'),\n#         layers.MaxPooling2D(pool_size=(2, 2)),\n#         layers.BatchNormalization(axis=3),\n#         layers.Dropout(0.5),\n        \n#         layers.Flatten(),\n        \n#         layers.Dense(512), # Fully connected layer\n#         layers.BatchNormalization(),\n#         layers.Dropout(0.5),\n        \n# #         layers.Dense(60, activation=\"relu\"),  # Fully connected layer\n# #         layers.BatchNormalization(),\n# #         layers.Dropout(0.5),\n        \n#         layers.Dense(N_LABELS, activation=\"sigmoid\")  # Classification layer or output layer\n#     ]\n# )\n\n# # model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.0005), \n# #               loss=tf.keras.metrics.binary_crossentropy,\n# #               metrics=['binary_accuracy', 'mae'])\n\n# model.summary()\n\n\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### Toy ResNet Model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Toy ResNet Model","metadata":{}},{"cell_type":"code","source":"inputs = tf.keras.Input(shape=(224, 224, 3), name=\"img\")\nx = layers.Conv2D(256, 3, activation=\"relu\")(inputs)\nx = layers.Conv2D(256, 3, activation=\"relu\")(x)\nblock_1_output = layers.MaxPooling2D(3)(x)\n\nx = layers.Conv2D(128, 3, activation=\"relu\", padding=\"same\")(block_1_output)\nx = layers.Conv2D(256, 3, activation=\"relu\", padding=\"same\")(x)\nblock_2_output = layers.add([x, block_1_output])\n\nx = layers.Conv2D(64, 3, activation=\"relu\", padding=\"same\")(block_2_output)\nx = layers.Conv2D(256, 3, activation=\"relu\", padding=\"same\")(x)\nblock_3_output = layers.add([x, block_2_output])\n\nx = layers.Conv2D(32, 3, activation=\"relu\")(block_3_output)\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(256, activation=\"relu\")(x)\nx = layers.Dropout(0.5)(x)\noutputs = layers.Dense(N_LABELS)(x)\n\nmodel = tf.keras.Model(inputs, outputs)\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Learning rate & loss specified in Base paper\noptimizer = [tf.keras.optimizers.Adam(learning_rate=1e-3,beta_1=0.9, beta_2=0.999), \n             tf.keras.optimizers.Adagrad(),\n             tf.keras.optimizers.SGD(learning_rate=1e-3, momentum=0.9),\n             tf.keras.optimizers.Adadelta(),\n             tf.keras.optimizers.RMSprop(),\n             tf.keras.optimizers.Nadam()]\n\nmodel.compile(optimizer=optimizer[0], loss=\"binary_crossentropy\", metrics=['binary_accuracy'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set up a checkpoint for model training\n# https://keras.io/callbacks/\ncheckpointer = tf.keras.callbacks.ModelCheckpoint(filepath='weights.best.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_best_only = True)\nreduce = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',factor=0.1,patience=2,mode='auto') \nearly = tf.keras.callbacks.EarlyStopping(monitor='val_loss',min_delta=1e-4,patience=4,mode='auto')\n\ncallbacks_list = [checkpointer,reduce,early]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_X, valid_Y = next(valid_gen)\nhistory = model.fit(train_gen,validation_data=(valid_X,valid_Y),callbacks=callbacks_list,epochs=2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def  prediction(image_name, model):\n    \n    img_path = os.path.join(test_images_path, image_name)\n\n    # Read and prepare image\n    img = image.load_img(img_path, target_size=(IMG_SIZE,IMG_SIZE,CHANNELS))\n    img = image.img_to_array(img)\n    #img = img/255\n    img = np.expand_dims(img, axis=0)\n\n    # Generate prediction\n    prediction = (model.predict(img) > 0.5).astype('int')\n    print(model.predict(img))\n    prediction = pd.Series(prediction[0])\n    prediction.index = mlb.classes_\n    prediction = prediction[prediction==1].index.values\n    predicted_labels = ' '.join(prediction)\n    \n    return predicted_labels\n    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))\nt = f.suptitle('Model Perfomance', fontsize=12)\nf.subplots_adjust(top=0.85, wspace=0.3)\nprint(\"plotting started\")\nmax_epoch = len(history.history['binary_accuracy']) + 1\nepoch_list = list(range(1, max_epoch))\nax1.plot(epoch_list, history.history['binary_accuracy'], label='Train Accuracy')\nax1.plot(epoch_list, history.history['val_binary_accuracy'], label='Validation Accuracy')\nax1.set_xticks(np.arange(1, max_epoch, 5))\nax1.set_ylabel('Accuracy Value')\nax1.set_xlabel('Epoch')\nax1.set_title('Accuracy')\nl1 = ax1.legend(loc=\"best\")\nax1.figure.savefig(\"Accuracy.png\")\n\nprint(\"still ploting\")\n\nax2.plot(epoch_list, history.history['loss'], label='Train Loss')\nax2.plot(epoch_list, history.history['val_loss'], label='Validation Loss')\nax2.set_xticks(np.arange(1, max_epoch, 5))\nax2.set_ylabel('Loss Value')\nax2.set_xlabel('Epoch')\nax2.set_title('Loss')\nl2 = ax2.legend(loc=\"best\")\nax2.figure.savefig(\"plot.png\")\n\nprint(\"plotting finishing\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = pd.DataFrame(columns=['image','labels'])\n\nfor image_name in os.listdir(test_images_path):\n    predicted_labels = prediction(image_name,model)\n    submission_df=submission_df.append(pd.DataFrame({'image':[image_name],'labels':[predicted_labels]}))\nsubmission_df","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}