{"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# 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":"import glob\nimport os.path as osp\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport pickle\n\nimport torch\nimport torch.nn as nn\nfrom torch.optim import Adam, SGD\nfrom torch.utils.data import DataLoader, Dataset\n\nfrom torchvision import datasets, models\nfrom torchvision.utils import make_grid\n\nimport os\nfrom PIL import Image\nfrom IPython.display import display\nimport tqdm\n\nimport warnings\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nnum_classes = 12\npretrained = False\ncriterion = nn.CrossEntropyLoss()\n        \nclass Config:\n    ep1= {\n        \"img_size\" : 224,\n        \"batch_size\" : 64,\n        \"epoch\": 20,\n        \"optimizer\": Adam\n    }\n    ep2 = {\n        \"img_size\" : 224,\n        \"batch_size\" : 64,\n        \"epoch\" : 20,\n        \"optimizer\": SGD\n    }    \n\nimg_size, batch_size, epoch, optimizer = Config.ep2.values()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train = pd.read_csv(\"/kaggle/input/plant-pathology-2021-fgvc8/train.csv\")\ndf_sub = pd.read_csv(\"/kaggle/input/plant-pathology-2021-fgvc8/sample_submission.csv\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The number of labels\nlen(df_train.labels.unique())\n\n#The no.values per label\ndf_train.labels.value_counts()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\n\nle = LabelEncoder()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def encode_label(df):\n    df['encoded_label'] = le.fit_transform(df.labels.values)\n    return df\n\nencode_label(df_train)\n    \ndf_labels_idx = df_train.loc[df_train.duplicated([\"labels\", \"encoded_label\"])==False]\\\n                [[\"encoded_label\", \"labels\"]].set_index(\"encoded_label\").sort_index()\ndisplay(df_labels_idx)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_datapath_list(phase='train', val_size=0.25):\n    if phase in [\"train\", \"val\"]:\n        phase_path = \"train_images\"\n    elif phase in [\"test\"]:\n        phase_path = \"test_images\"\n    else:\n        print(f\"{phase} not in path\")    \n        \n    if phase == 'train' or phase == 'val':\n        rootpath = \"/kaggle/input/resized-plant2021/img_sz_640/\"\n    else:\n        rootpath = \"/kaggle/input/plant-pathology-2021-fgvc8/test_images/\"\n    \n    target_path = osp.join(rootpath+\"/*.jpg\")\n    path_list = []\n    \n    for path in glob.glob(target_path):\n        path_list.append(path)\n        \n    if phase in [\"train\", \"val\"]:\n        train, val = train_test_split(path_list, test_size=val_size, random_state=0, shuffle=True)\n        if phase == \"train\":\n            path_list = train\n        else:\n            path_list = val\n    \n    return path_list","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_list = make_datapath_list(phase='train')\n# print(f'The length of training set: {len(train_list)}')\n# val_list = make_datapath_list(phase='val')\n# print(f'The length of valuation set: {len(val_list)}')\ntest_list = make_datapath_list(phase='test')\nprint(f'The length of testing set: {len(test_list)}')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import albumentations as A\nfrom albumentations import Compose\nfrom albumentations.pytorch import ToTensorV2\nimport cv2","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = {\n    'train': Compose([\n        A.Rotate(\n            always_apply=False, \n            p=0.1, \n            limit=(-68, 178), \n            interpolation=1, \n            border_mode=0, \n            value=(0, 0, 0), \n            mask_value=None\n        ),\n        A.RandomShadow(\n            num_shadows_lower=1, \n            num_shadows_upper=1, \n            shadow_dimension=3, \n            shadow_roi=(0, 0.6, 1, 1), \n            p=0.4\n        ),\n        A.ShiftScaleRotate(\n            shift_limit=0.05, \n            scale_limit=0.05, \n            rotate_limit=15, \n            p=0.6\n        ),\n        A.RandomFog(\n            fog_coef_lower=0.2, \n            fog_coef_upper=0.2, \n            alpha_coef=0.2, \n            p=0.3\n        ),\n        A.RGBShift(\n            r_shift_limit=15, \n            g_shift_limit=15, \n            b_shift_limit=15, \n            p=0.3\n        ),\n        A.RandomBrightnessContrast(\n            p=0.3\n        ),\n        A.GaussNoise(\n            var_limit=(50, 70),  \n            always_apply=False, \n            p=0.3\n        ),\n        A.Resize(\n            height=img_size,\n            width=img_size,\n        ),\n        A.CoarseDropout(\n            max_holes=5, \n            max_height=5, \n            max_width=5, \n            min_holes=3, \n            min_height=5, \n            min_width=5,\n            always_apply=False, \n            p=0.2\n        ),\n        A.Normalize(\n            mean=(0.485, 0.456, 0.406), \n            std=(0.229, 0.224, 0.225)\n        ),\n        ToTensorV2()\n    ]),\n    'val': Compose([\n        A.Resize(img_size, img_size),\n        A.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),            \n        ToTensorV2()\n    ]),\n    'test': Compose([\n        A.Resize(img_size, img_size),\n        A.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),\n        ToTensorV2()\n    ])\n}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PlantDataset(Dataset):\n    \"\"\"\n    Class to create a Dataset\n    \n    Attributes\n    ----------\n    df_train : DataFrame\n        DataFrame containing the image labels.\n    file_list : list\n        A list containing the paths to the images\n    transform : object\n        Instance of the preprocessing class (ImageTransform)\n    phase : 'train' or 'val' or 'test'\n        Specify whether to use train, validation, or test\n    \"\"\"\n    def __init__(self, df_train, file_list, transform=None, phase='train'):\n        self.df_train = df_train\n        self.df_labels_idx = df_labels_idx\n        self.file_list = file_list\n        self.transform = transform[phase]\n        self.phase = phase\n        \n    def __len__(self):\n        \"\"\"\n        Returns the number of images.\n        \"\"\"\n        return len(self.file_list)\n    \n    def __getitem__(self, index):\n        \"\"\"\n        Get data in Tensor format and labels of preprocessed images.\n        \"\"\"\n        \n        # Load the index number image.\n        img_path = self.file_list[index]\n        img = Image.open(img_path)\n        \n        # Preprocessing images\n        img = cv2.imread(img_path)\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        img_transformed = self.transform(image=img)\n        \n        # image name\n        image_name = img_path[-20:]\n        \n        # Extract the labels\n        if self.phase in [\"train\", \"val\"]:\n            label = df_train.loc[df_train[\"image\"]==image_name][\"encoded_label\"].values[0]\n        elif self.phase in [\"test\"]:\n            label = -1\n        \n        return img_transformed, label, image_name","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataset = PlantDataset(df_train, train_list, transform=transform, phase='train')\n# val_dataset = PlantDataset(df_train, val_list, transform=transform, phase='val')\ntest_dataset = PlantDataset(df_train, test_list, transform=transform, phase='test')\n\nindex = 0\n\n# print(\"【train dataset】\")\n# print(f\"img num : {train_dataset.__len__()}\")\n# # print(f\"img : {train_dataset.__getitem__(index)[0].size()}\")\n# print(f\"label : {train_dataset.__getitem__(index)[1]}\")\n# print(f\"image name : {train_dataset.__getitem__(index)[2]}\")\n\n# print(\"\\n【validation dataset】\")\n# print(f\"img num : {val_dataset.__len__()}\")\n# # print(f\"img : {val_dataset.__getitem__(index)[0].size()}\")\n# print(f\"label : {val_dataset.__getitem__(index)[1]}\")\n# print(f\"image name : {val_dataset.__getitem__(index)[2]}\")\n\nprint(\"\\n【test dataset】\")\nprint(f\"img num : {test_dataset.__len__()}\")\n# print(f\"img : {test_dataset.__getitem__(index)[0].size()}\")\nprint(f\"label : {test_dataset.__getitem__(index)[1]}\")\nprint(f\"image name : {test_dataset.__getitem__(index)[2]}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train_dataloader = DataLoader(train_dataset, batch_size=batch_size, num_workers=2,shuffle=True)\n# val_dataloader = DataLoader(val_dataset, batch_size=batch_size, num_workers=2, shuffle=False)\ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size, num_workers=2, shuffle=False)\n\n# to Dictionary\ndataloaders_dict = {\"test\": test_dataloader}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Pkl_Filename = '../input/nh-m-1-chuy-n-c-ng-ngh/2 FCs, 0.0001 Lr, 30 Epochs.pkl'\nwith open(Pkl_Filename, 'rb') as file:  \n    model = pickle.load(file)\n    \n# class CPU_Unpickler(pickle.Unpickler):\n#     def find_class(self, module, name):\n#         if module == 'torch.storage' and name == '_load_from_bytes':\n#             return lambda b: torch.load(io.BytesIO(b), map_location='cpu')\n#         else: return super().find_class(module, name)\n        \n# model = CPU_Unpickler(\"../input/final2/Resmodel50_trained_1fc.pkl\").load()\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PlantPredictor():\n    \"\"\"\n    Class for predicting labels from output results\n    \n    Attributes\n    ----------\n    df_labels_idx: DataFrame\n        DataFrame that associates INDEX with a label name\n    \"\"\"\n    \n    def __init__(self, model, df_labels_idx, dataloaders_dict):\n        self.model = model\n        self.df_labels_idx = df_labels_idx\n        self.dataloaders_dict = dataloaders_dict\n        self.df_submit = pd.DataFrame()\n        \n    \n    def __predict_max(self, out):\n        \"\"\"\n        Get the label name with the highest probability.\n        \n        Parameters\n        ----------\n        predicted_label_name: str\n            Name of the label with the highest prediction probability\n        \"\"\"\n        maxid = np.argmax(out.detach().numpy(), axis=1)\n        df_predicted_label_name = self.df_labels_idx.iloc[maxid]\n        \n        return df_predicted_label_name\n    \n    def inference(self):\n        device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\n        print(f\"Devices to be used : {device}\")\n        df_pred_list = []\n        for i, data in enumerate(self.dataloaders_dict['test']):\n            image_name = data[2]\n            self.model.to(device)\n            inputs = data[0]['image']\n            inputs = inputs.to(device)\n            out = self.model(inputs)\n            device = torch.device(\"cpu\")\n            out = out.to(device)\n            df_pred = self.__predict_max(out).reset_index(drop=True)\n            df_pred[\"image\"] = image_name\n            df_pred_list.append(df_pred)\n            \n        self.df_submit = pd.concat(df_pred_list, axis=0)\n        self.df_submit = self.df_submit[[\"image\", \"labels\"]].reset_index(drop=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictor = PlantPredictor(model, df_labels_idx, dataloaders_dict)\npredictor.inference()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_submit = predictor.df_submit.copy()\n\ndf_submit.to_csv('submission.csv', index=False)\ndf_submit","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}