{"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 pandas as pd\nimport numpy as np\nimport cv2\nimport os\nimport re\nfrom PIL import Image\nfrom matplotlib import pyplot as plt\nimport matplotlib.patches as patches\nimport seaborn as sns # plotting\nimport random","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Future works\n* Labeling bias correction (using augmentation)\n* Augmentation (gray scale)\n* Image resize efficiently (not using Keras package)\n* Cutmix code adjustment\n* Using latest model archiecture","metadata":{}},{"cell_type":"markdown","source":"## Data loading","metadata":{}},{"cell_type":"code","source":"path = '../input/plant-pathology-2021-fgvc8'\ndir_train = os.path.join(path,'train_images')\ntrain_df=pd.read_csv(os.path.join(path,'train.csv'))\ntrain_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Number of images: {}'.format(train_df['image'].shape))\nprint('Number of labels: {}'.format(train_df['labels'].shape))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The number of images is well matched with labels.<br>\nThere is no missing lables.","metadata":{}},{"cell_type":"code","source":"print('Label of image: {}'.format(train_df['labels'][3]))\nfig, ax = plt.subplots(1)\nax.imshow(plt.imread(os.path.join(dir_train,(train_df['image'][3]))))\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Label Check","metadata":{}},{"cell_type":"code","source":"image_ids = train_df['labels'].unique()\nprint(\"Total number of images = \",len(train_df['labels']))\nprint(\"Number of Unique labels = \",len(image_ids))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['labels'].value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#fig, ax = plt.subplots(1,1, figsize=(8,30))\n#categories = train_df['labels'].unique()\n#plt.pie(train_df['labels'].value_counts())\n#plt.legend(categories, loc='best')\n#plt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Encoding the labels","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nencoder = LabelEncoder() # Create label encoder\n\nencoder.fit(train_df['labels'])\ntrain_df['label'] = encoder.transform(train_df['labels'])\ntrain_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1,1, figsize=(10,8))\nlabel_x = train_df['label'].value_counts()\nsns.barplot(label_x.index, label_x)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_num = train_df['labels'].value_counts()\nprint('Number of label: \\n{}'.format(labels_num))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_num = train_df['label'].value_counts()\nprint('Number of label: \\n{}'.format(label_num))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Check image size\nI've already checked the image size.<br>\nThe size of images are same with 2672x4000.","metadata":{}},{"cell_type":"code","source":"#sample_img = (os.path.join(dir_train,(train_df['image'][3])))\n#image = cv2.imread(sample_img, cv2.IMREAD_COLOR)\n## convert imreaded image BGR to RGB\n#image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n#image /= 255.0","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Setting","metadata":{}},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\n\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection import FasterRCNN\nfrom torchvision.models.detection.rpn import AnchorGenerator\n\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.utils.data.sampler import SequentialSampler","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Cutmix (Ongoing)","metadata":{}},{"cell_type":"code","source":"def generate_cutmix(df, img_dir, beta, n_label):\n    im1, im2 = random.sample(range(0,n_label),2)\n    img1 = cv2.cvtColor(cv2.imread(os.path.join(img_dir,(df['image'][int(im1)]))), cv2.COLOR_BGR2RGB)\n    img2 = cv2.cvtColor(cv2.imread(os.path.join(img_dir,(df['image'][int(im2)]))), cv2.COLOR_BGR2RGB)\n    lam1 = int(beta*img1.shape[0])\n    lam2 = int(beta*img1.shape[1])\n    img2 = cv2.resize(img2, dsize=(lam2, lam1), interpolation=cv2.INTER_AREA)\n    img1[:lam1, :lam2,:] = img2\n    return img1\nnew_img = generate_cutmix(train_df, dir_train, 0.4, label_num[1])\nfig, ax = plt.subplots(1)\nax.imshow(new_img)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prepare data","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ndfs = train_df[['image','label']]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\ntrain_datagen = ImageDataGenerator(horizontal_flip = True,\n                                  rescale = 1./255,\n                                  zoom_range = 0.2,\n                                  validation_split = 0.2)\ntest_datagen = ImageDataGenerator(rescale = 1./255,\n                                 validation_split = 0.2)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dir_train = '../input/resized-plant2021/img_sz_256'\ndfs = train_df[['image','labels']]\ndfs","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator = train_datagen.flow_from_dataframe(dataframe = dfs,\n                                                   directory = dir_train,\n                                                   target_size = (256,256),\n                                                   x_col = 'image',\n                                                   y_col = 'labels',\n                                                   batch_size = 128,\n                                                   color_mode = 'rgb',\n                                                   class_mode = 'categorical',\n                                                   subset = 'training')\n\ntest_generator = test_datagen.flow_from_dataframe(dataframe = dfs,\n                                                 directory = dir_train,\n                                                 target_size = (256,256),\n                                                 x_col = 'image',\n                                                 y_col = 'labels',\n                                                 batch_size = 128,\n                                                 color_mode = 'rgb',\n                                                 class_mode = 'categorical',\n                                                 subset = 'validation')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build model (Keras)","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, BatchNormalization, Dropout\nfrom tqdm import tqdm\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = tf.keras.Sequential([\n    Conv2D(32, (3,3), activation = 'relu', input_shape = [256, 256, 3]), # 2672x4000 -> resize to 1/16 167x250\n    BatchNormalization(),\n    MaxPooling2D(2,2),\n    Dropout(0.3),\n    \n    Conv2D(32, (3,3), activation = 'relu'),\n    BatchNormalization(),\n    MaxPooling2D(2,2),\n    Dropout(0.3),\n    \n    #Conv2D(32, (3,3), activation = 'relu'),\n    #BatchNormalization(),\n    #MaxPooling2D(2,2),\n    #Dropout(0.2),\n    \n    Flatten(),\n    Dense(32, activation = 'relu'),\n    BatchNormalization(),\n    #Dropout(0.5),\n    Dense(12, activation='softmax')\n])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"earlystop = EarlyStopping(patience=3)\nlr_schedule = ReduceLROnPlateau(monitor='val_acc', patience=2, verbose=1, factor=0.5, min_lr = 0.0001)\ncallbacks = [earlystop, lr_schedule]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_generator,epochs = 10, validation_data = test_generator, callbacks=callbacks)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test and Predict","metadata":{}},{"cell_type":"code","source":"import os\npath = '../input/plant-pathology-2021-fgvc8'\ndir_test = os.path.join(path,'test_images')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_datagen = ImageDataGenerator(rescale = 1./255)\ntest_set = test_datagen.flow_from_directory(path,\n                                            classes=['test_images'])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output = model.predict(test_set)\nnp.set_printoptions(formatter={'float': lambda x: \"{0:0.3f}\".format(x)})\nprint(test_generator.class_indices)\ny_output = np.argmax(output, axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lbs = test_generator.class_indices\nlbs = dict((v,k) for k, v in lbs.items())\nprint(lbs)\n\npreds = [lbs[k] for k in y_output]\nprint(preds[:10])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Export to csv","metadata":{}},{"cell_type":"code","source":"path = '../input/plant-pathology-2021-fgvc8'\ntest_df=pd.read_csv(os.path.join(path,'sample_submission.csv'))\npred_df = test_df.copy()\npred_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df['labels'] = preds\npred_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df.to_csv('submission.csv',index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}