{"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":"!pip install timm\n!pip install torch-summary\n!pip uninstall -y pillow\n!pip install pillow-simd","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:38:21.340601Z","iopub.execute_input":"2021-05-27T11:38:21.341023Z","iopub.status.idle":"2021-05-27T11:39:13.716087Z","shell.execute_reply.started":"2021-05-27T11:38:21.340927Z","shell.execute_reply":"2021-05-27T11:39:13.714989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json \nimport collections\nfrom tqdm import tqdm\nimport pickle\n\nfrom PIL import Image\nimport numpy as np\nimport pandas as pd\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\n\nimport timm\nimport torchvision\nimport torchvision.transforms as transforms\nimport torchvision.transforms.functional as F\n\ndevice = 'cuda:0' if torch.cuda.is_available() else 'cpu'","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:13.719143Z","iopub.execute_input":"2021-05-27T11:39:13.719481Z","iopub.status.idle":"2021-05-27T11:39:15.744062Z","shell.execute_reply.started":"2021-05-27T11:39:13.719447Z","shell.execute_reply":"2021-05-27T11:39:15.742956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset Preprocessing","metadata":{}},{"cell_type":"code","source":"# Read files having for training annotation data\nwith open('../input/iwildcam2021-fgvc8/metadata/iwildcam2021_megadetector_results.json', encoding='utf-8') as json_file:\n    detections = json.load(json_file)\n\nwith open('../input/iwildcam2021-fgvc8/metadata/iwildcam2021_test_information.json', encoding='utf-8') as json_file:\n    test_anno = json.load(json_file)\n\nconf_thresh = 0.7\nquick_lookup_detections = collections.defaultdict(lambda: [])\n\nfor detection in tqdm(detections['images']):\n    all_dets = []\n    for det in detection['detections']:\n        if det['conf'] < conf_thresh or det['category'] != '1':\n            continue        \n        all_dets.append(det['bbox'])\n    quick_lookup_detections[detection['id']] = all_dets    \n\ntest_detections = collections.defaultdict(lambda: {})\n\nfor t_anno in tqdm(test_anno['images']):\n    test_detections[t_anno['seq_id']][t_anno['file_name']] = quick_lookup_detections[t_anno['file_name'][:-4]]","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:15.74621Z","iopub.execute_input":"2021-05-27T11:39:15.746608Z","iopub.status.idle":"2021-05-27T11:39:20.668279Z","shell.execute_reply.started":"2021-05-27T11:39:15.746566Z","shell.execute_reply":"2021-05-27T11:39:20.667257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model","metadata":{}},{"cell_type":"code","source":"class Cnn_model(nn.Module):\n    def __init__(self, backbone, out_dim, pretrained=False):\n        super(Cnn_model, self).__init__()\n        self.bnet = timm.create_model(backbone, pretrained=pretrained)\n        in_ch = self.bnet.classifier.in_features\n        self.myfc = nn.Linear(in_ch, out_dim)\n        self.bnet.classifier = nn.Identity()\n\n    def forward(self, x):\n        x = self.bnet(x)\n        x = self.myfc(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:20.669832Z","iopub.execute_input":"2021-05-27T11:39:20.670135Z","iopub.status.idle":"2021-05-27T11:39:20.676531Z","shell.execute_reply.started":"2021-05-27T11:39:20.670107Z","shell.execute_reply":"2021-05-27T11:39:20.67549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataloader pipelines","metadata":{}},{"cell_type":"code","source":"size = 456\n\n# Custom transform\nclass SquarePad:\n    def __call__(self, image):\n        w, h = image.size\n        max_wh = np.max([w, h])\n        hp = int((max_wh - w) / 2)\n        vp = int((max_wh - h) / 2)\n        return F.pad(image,(hp, vp, hp, vp),0,'symmetric')\n\ntransform = transforms.Compose([\n        SquarePad(),\n        transforms.Resize((size,size)),\n#         transforms.RandomHorizontalFlip(p=0.5),\n        transforms.ToTensor(),\n        transforms.Normalize(mean = [0.35318278, 0.35319862, 0.35318562],\n                                 std = [0.21479782, 0.21479183, 0.21479116])\n    ])\n\ndef get_crop_area(bbox, image_size):\n    x1, y1,w_box, h_box = bbox\n    ymin,xmin,ymax, xmax = y1, x1, y1 + h_box, x1 + w_box\n    area = (xmin * image_size[0], ymin * image_size[1], \n            xmax * image_size[0], ymax * image_size[1])\n    return area\n\ndef preprocess_transform(im_name, detections):\n    im_path = '../input/iwildcam2021-fgvc8/test/' + im_name\n    img = Image.open(im_path)\n    res_dets = []\n    for detection in detections:\n        cropped_img = img.crop(get_crop_area(detection,img.size))\n        res_dets.append(transform(cropped_img))\n    return res_dets","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:20.677969Z","iopub.execute_input":"2021-05-27T11:39:20.678589Z","iopub.status.idle":"2021-05-27T11:39:20.690929Z","shell.execute_reply.started":"2021-05-27T11:39:20.678537Z","shell.execute_reply":"2021-05-27T11:39:20.69015Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Model\n# model = torch.load(\"../input/iwildcam2021-weighted-loss/play_weigh_effnet_b2_ns_8_0.4882.pth\").to(device)\n# model = torch.load(\"../input/iwildcam2021-weighted-loss/play_weigh_effnet_b2_ns_8_0.4882.pth\",map_location=torch.device('cpu'))\nmodel = Cnn_model(backbone=\"tf_efficientnet_b5_ns\", out_dim=200).to(device) \ncheckpoint = torch.load(\"../input/iwildcam2021-final-weighted-loss/EffnetB5Ns_34_0.7826.tar\",map_location=torch.device(device))\nmodel.load_state_dict(checkpoint[\"model_state_dict\"])\nmodel.eval()\n\n# Label encoder\nfile = open('../input/iwildcam2021-final-weighted-loss/target_encoder.pkl','rb')\nle = pickle.load(file)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:20.692194Z","iopub.execute_input":"2021-05-27T11:39:20.693149Z","iopub.status.idle":"2021-05-27T11:39:25.905171Z","shell.execute_reply.started":"2021-05-27T11:39:20.693103Z","shell.execute_reply":"2021-05-27T11:39:25.904264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize the preprocessing\n\nfrom matplotlib import pyplot as plt\n\n# Test data processing\ninvTrans = transforms.Compose([ transforms.Normalize(mean = [ 0., 0., 0. ],\n                                                     std = [1/0.21487217, 1/0.21486713, 1/0.21486738]),\n                                transforms.Normalize(mean = [-0.36073838, -0.36075481, -0.36074335],\n                                                     std = [ 1., 1., 1. ]),\n                               ])\n\ndef show_img(img):\n    plt.figure(figsize=(18,15))\n    # unnormalize\n    img = invTrans(img)\n    npimg = img.cpu().numpy()\n    npimg = np.clip(npimg, 0., 1.)\n    plt.imshow(np.transpose(npimg, (1, 2, 0)))\n    plt.show()\n\n# for idx, (sequence, images) in tqdm(enumerate(test_detections.items())):\n#     grid_images = []\n#     for image_name, detections in images.items():\n#         ips = preprocess_transform(image_name, detections) # get all preprocessed detections for an image\n#         if len(ips) == 0:\n#             continue\n\n#         grid_images.extend(ips)\n#     # show images\n#     if len(grid_images) == 0:\n#         continue\n#     grid_images = torch.stack(grid_images).to(device)\n#     show_img(torchvision.utils.make_grid(grid_images))\n#     if idx>10:\n#         break","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:25.90642Z","iopub.execute_input":"2021-05-27T11:39:25.906696Z","iopub.status.idle":"2021-05-27T11:39:25.91482Z","shell.execute_reply.started":"2021-05-27T11:39:25.906669Z","shell.execute_reply":"2021-05-27T11:39:25.913536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samp_submission = pd.read_csv(\"../input/iwildcam2021-fgvc8/sample_submission.csv\")\nsubmission = pd.DataFrame(columns=samp_submission.columns)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:25.91767Z","iopub.execute_input":"2021-05-27T11:39:25.918157Z","iopub.status.idle":"2021-05-27T11:39:26.209755Z","shell.execute_reply.started":"2021-05-27T11:39:25.918098Z","shell.execute_reply":"2021-05-27T11:39:26.208739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def update_freq(output_labels,frq_pred):\n    # maintain frequencies\n    if len(output_labels) != 0:\n        is_present = 0\n        for pred in frq_pred:\n            if pred[0] == output_labels:\n                pred[1] += 1\n                is_present = 1\n                break\n        if not is_present:\n            frq_pred.append([output_labels,1])\n    return frq_pred\n\nfor sequence, images in tqdm(test_detections.items()):\n    preds = []\n    frq_pred = []\n    new_row = {key:0 for key in samp_submission.columns}\n    \n    for image_name, detections in images.items():\n        ips = preprocess_transform(image_name, detections) # get all preprocessed detections for an image\n        if len(ips) == 0:\n            continue\n        \n        # perform model predictions\n        with torch.no_grad(): \n            ips = torch.stack(ips).to(device)\n            outputs = model(ips)\n            pred_labels = torch.argmax(outputs, dim=1).tolist()\n            output_labels = le.inverse_transform(pred_labels)\n        \n        frq_pred = update_freq(output_labels.tolist(),frq_pred)\n    \n    # get final output on the basis of max count and max frequency\n    max_pred_freq = max(frq_pred, key=lambda x:x[1])[0] if len(frq_pred) > 0 else []\n    max_pred_len = max(frq_pred, key=lambda x:len(x[0]))[0] if len(frq_pred) > 0 else []\n    preds = max_pred_freq if len(max_pred_freq) == len(max_pred_len) else max_pred_len\n            \n    # write to submission file\n    new_row['Id'] = sequence\n    for pred in preds:\n        if pred == 0:\n            continue\n        new_row[f'Predicted{pred}']+=1\n    submission = submission.append(new_row, ignore_index = True)","metadata":{"execution":{"iopub.status.busy":"2021-05-27T11:39:26.211539Z","iopub.execute_input":"2021-05-27T11:39:26.211948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(submission))\nprint(len(samp_submission))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(\"submission.csv\",index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}