{"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 numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport tensorflow as tf\nfrom tqdm.auto import tqdm\n\nsns.set_style('darkgrid')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset Exploration","metadata":{}},{"cell_type":"code","source":"train = pd.read_csv('../input/plant-pathology-2021-fgvc8/train.csv')\nprint(train.shape)\ntrain.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import MultiLabelBinarizer\n\nmlb = MultiLabelBinarizer().fit(train.labels.apply(lambda x: x.split()))\nlabels = pd.DataFrame(mlb.transform(train.labels.apply(lambda x: x.split())), columns=mlb.classes_)\n\nfig, ax = plt.subplots(figsize=(20, 6))\nlabels.sum().plot.bar(title='Target Class Distribution');","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(20, 6))\nlabels.sum(axis=1).value_counts().plot.bar(title='Distribution of Number of Labels per Image');","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(3, 4, figsize=(20, 10))\nfor i, img in enumerate(train.groupby('labels').first().reset_index().values):\n    ax[i//4][i%4].imshow(plt.imread(f\"../input/plant-pathology-2021-fgvc8/train_images/{img[1]}\"))\n    ax[i//4][i%4].set_title(img[0])\n    ax[i//4][i%4].axis('off')\nfig.suptitle('Image Samples', fontsize=18); ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preprocessing and Augmentation","metadata":{}},{"cell_type":"code","source":"labels = pd.concat([train['image'], labels], axis=1).drop('healthy', axis=1)\nlabels.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size=128\nimage_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, validation_split=0.1)\n\ntrain_generator = image_data_generator.flow_from_dataframe(\n    dataframe=labels,\n    directory='../input/plant-pathology-2021-fgvc8/train_images',\n    x_col='image',\n    y_col=labels.columns.tolist()[1:],\n    class_mode='raw',\n    color_mode=\"rgb\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    subset='training'\n)\n\nvalid_generator = image_data_generator.flow_from_dataframe(\n    dataframe=labels,\n    directory='../input/plant-pathology-2021-fgvc8/train_images',\n    x_col='image',\n    y_col=labels.columns.tolist()[1:],\n    class_mode='raw',\n    color_mode=\"rgb\",\n    target_size=(224, 224),\n    batch_size=batch_size,\n    subset='validation'\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modelling","metadata":{}},{"cell_type":"code","source":"inputs = tf.keras.Input(shape=(224, 224, 3))\nx = tf.keras.applications.InceptionV3(include_top=False)(inputs)\nx = tf.keras.layers.GlobalAveragePooling2D()(x)\noutputs = tf.keras.layers.Dense(5, activation='sigmoid')(x)\n\nmodel = tf.keras.models.Model(inputs, outputs)\nmodel.compile(loss='binary_crossentropy', optimizer=tf.keras.optimizers.Adam(lr=1e-4))\n\nmodel.summary()\ntf.keras.utils.plot_model(model, show_shapes=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rlp = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', patience=1, verbose=1, factor=0.01)\nes = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, verbose=1, restore_best_weights=True)\n\nhistory = model.fit(train_generator, validation_data=valid_generator, epochs=10, callbacks=[rlp, es])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fix, ax = plt.subplots(figsize=(20, 6))\npd.DataFrame(history.history)[['loss', 'val_loss']].plot(ax=ax, title='Model Loss Curve')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('InceptionV3.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submission","metadata":{}},{"cell_type":"code","source":"submissions = pd.read_csv('../input/plant-pathology-2021-fgvc8/sample_submission.csv')\nsubmissions.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data_generator = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255)\n\ntest_generator = test_data_generator.flow_from_dataframe(\n    submissions,\n    directory = '../input/plant-pathology-2021-fgvc8/test_images',\n    x_col=\"image\",\n    y_col=None,\n    target_size=(224, 224),\n    color_mode=\"rgb\",\n    classes=None,\n    class_mode=None,\n    shuffle=False,\n    batch_size=1\n)\n\npredictions = model.predict(test_generator,steps=len(test_generator.filenames))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"thresh = 0.5\nfor i in range(3):\n    pred = ' '.join(labels.columns[1:][predictions[i] >= thresh])\n    pred = 'healthy' if pred == '' else pred\n    submissions.iloc[i, 1] = pred\n    \nsubmissions.to_csv('submission.csv', index=False)    ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}