{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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)\nfrom matplotlib import pyplot as plt\nimport os\nimport ast\nimport matplotlib.patches as patches\nfrom matplotlib.image import imsave\nfrom tqdm import tqdm\nfrom PIL import Image\nimport re\nimport keras\nfrom torchvision import transforms\nfrom keras.layers import Dense\nfrom keras import Model\nfrom keras import optimizers\nfrom keras.applications import DenseNet121\n\nimport joblib\nfrom joblib import Parallel, delayed\nimport cv2\nimport tensorflow as tf\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom albumentations.core.transforms_interface import DualTransform\nfrom albumentations.augmentations.bbox_utils import denormalize_bbox, normalize_bbox\n\nfrom PIL import Image\n#importing libraries for validation and training set generation\nfrom sklearn import datasets, linear_model\nfrom sklearn.model_selection import train_test_split\n\nfrom sklearn.model_selection import StratifiedKFold\nfrom glob import glob\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\nimport torch\nfrom torch.utils.data import DataLoader, Dataset\nimport torch.utils.data as data_utils\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\nimport time\nfrom torch.utils.data import SubsetRandomSampler\nimport torchvision \nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection.rpn import AnchorGenerator\nfrom torchvision.models.detection import FasterRCNN\nimport torch.nn as nn\nfrom torchvision.models.detection.backbone_utils import resnet_fpn_backbone\nfrom itertools import islice\nimport albumentations as alb\nimport sys\nfrom keras.preprocessing.image import ImageDataGenerator\nimport json\nimport warnings\nfrom torch.utils.data import SubsetRandomSampler\nimport torch.nn as nn\nfrom pathlib import Path\n#from detectron2.engine import DefaultPredictor, DefaultTrainer\nfrom torch.utils.data.sampler import SequentialSampler\nwarnings.filterwarnings('ignore')\n# You can write up to 5GB 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","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* Setting up paths for training and test images \n* creating lists of training and testing images","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"# setting up paths for training and test images\ntrain_dir = '../input/global-wheat-detection/train/'\ntest_dir = '../input/global-wheat-detection/test/'\ntrain_csv_path = '../input/global-wheat-detection/train.csv'\nimage_folder_path = \"/kaggle/input/global-wheat-detection/train/\"\ntest_folder_path = \"/kaggle/input/global-wheat-detection/test/\"\nDATA_DIR = \"/kaggle/input/global-wheat-detection\"\n\nWEIGHTS_FILE = \"../input/densenet169/densenet169.pth\"\n# printing completion of setup\nprint ('setup complete')\n\n# the lists of train and test images\ntrain_list = glob(train_dir + '*')\ntest_list = glob(test_dir + '*')\n\nprint('Number of train images is ',len(train_list))\nprint('Number of test images is ',len(test_list))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Read train data and store in dataframe","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# read train data and store in dataframe\ntrain_data=pd.read_csv(train_csv_path)\n\n# printing summary of data\n## train_data.describe()\ntrain_data.head()\n\n#read test data and store in dataframe\ntest_df = pd.read_csv(f'{DATA_DIR}/sample_submission.csv')\ntest_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# storing dataframe as train\ntrain = train_data\ntrain_pascal = train_data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#append .jpg to image ids for easier handling\ntrain['image_id'] = train['image_id'].apply(lambda x: str(x) + '.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n# Let's expand the bounding box coordinates and calculate the area of all the bboxes\n#i have used train in the next line as train pascal gets editted and no longer has bbox as a parameter\ntrain_pascal[['x_min','y_min', 'width', 'height']] = pd.DataFrame([ast.literal_eval(x) for x in train.bbox.tolist()], index= train_pascal.index)\ntrain_pascal = train[['image_id', 'bbox', 'source', 'x_min', 'y_min', 'width', 'height']]\ntrain_pascal['area'] = train_pascal['width'] * train_pascal['height']\ntrain_pascal['x_max'] = train_pascal['x_min'] + train_pascal['width']\ntrain_pascal['y_max'] = train_pascal['y_min'] + train_pascal['height']\ntrain_pascal = train_pascal.drop(['bbox'], axis=1)\n#following parameters are recorded for all images\ntrain_pascal = train_pascal[['image_id', 'x_min', 'y_min', 'x_max', 'y_max', 'width', 'height', 'area', 'source']]\n\n#removing these bboxes was there in a lot of notebooks\n#if you wanna include them you can just comment the next line\ntrain_pascal = train_pascal[(train_pascal['area'] < 100000) & (train_pascal['area'] > 40)]\n\ntrain_pascal.head()\n\n#this train_pascal will be saved as a new csv file.\n#i didnt directly do these operations on train because it would disrupt the code you have written\n#the below warning is because of that\n#i will get to that later","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#printing total number of images in csv file by identifying unique image ids\n#this also gives us the number of images without bbox\nimage_ids = train_pascal['image_id'].unique()\nprint(f'Total number of training images: {len(image_ids)}')\nprint(f'Images without bboxes: {len(train_list)-len(image_ids)}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"plot sample images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#displaying 8 random images from the training set\n\nsample_indices = np.random.choice(np.unique(train[\"image_id\"].tolist()), 8)\nfig, ax = plt.subplots(nrows=2, ncols=4, figsize=(20, 10))\ncount=0\n\nfor row in ax:\n    for col in row:\n        img = plt.imread(\"/kaggle/input/global-wheat-detection/train/\" + sample_indices[count])\n        col.grid(False)\n        col.set_xticks([])\n        col.set_yticks([])\n        col.imshow(img)\n        count = count +  1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#creating function for forming bounding boxes for all images\n\ndef get_bbox_1(image_id, df, color='white'):\n    bboxes = df[df['image_id'] == image_id]\n    \n    for i in range(len(bboxes)):\n        # Create a Rectangle patch\n        rect = patches.Rectangle(\n            (bboxes['x_min'].iloc[i], bboxes['y_min'].iloc[i]),\n            bboxes['width'].iloc[i], \n            bboxes['height'].iloc[i], \n            linewidth=2, \n            edgecolor=color, \n            facecolor='none')\n\n        # Add the patch to the Axes\n        col.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# displaying 6 random training images with bounding boxes\n\nfig, ax = plt.subplots(nrows=2, ncols=3, figsize=(20, 10))\ncount=0\nfor row in ax:\n    for col in row:\n        img = plt.imread(\"/kaggle/input/global-wheat-detection/train/\" + sample_indices[count])\n        col.grid(False)\n        col.set_xticks([])\n        col.set_yticks([])\n        get_bbox_1(sample_indices[count], train, color='red')\n        col.imshow(img)\n        count += 1\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_bbox(bboxes, col, color='white', bbox_format='pascal_voc'):\n    \n    for i in range(len(bboxes)):\n        # Create a Rectangle patch\n        if bbox_format == 'pascal_voc':\n            rect = patches.Rectangle(\n                (bboxes[i][0], bboxes[i][1]),\n                bboxes[i][2] - bboxes[i][0], \n                bboxes[i][3] - bboxes[i][1], \n                linewidth=2, \n                edgecolor=color, \n                facecolor='none')\n        else:\n            rect = patches.Rectangle(\n                (bboxes[i][0], bboxes[i][1]),\n                bboxes[i][2], \n                bboxes[i][3], \n                linewidth=2, \n                edgecolor=color, \n                facecolor='none')\n\n        # Add the patch to the Axes\n        col.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"generate training and validation batches","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# get a df with just image and source columns\n# such that dropping duplicates will only keep unique image_ids\nimage_source = train_data[['image_id', 'source']].drop_duplicates()\n\n# get lists for image_ids and sources\nimage_ids = image_source['image_id'].to_numpy()\nsources = image_source['source'].to_numpy()\n\n\n\n# do the split\n# in other words:\n# split up our data into 10 buckets making sure that each bucket\n#  has a more or less even distribution of sources\n# Note the use of random_state=1 to ensure the split is the same each time we run this code\nskf = StratifiedKFold(n_splits=10, shuffle=True, random_state=1)\nsplit = skf.split(image_ids, sources) # second arguement is what we are stratifying by\n\n# so now `split` is an iterator\n# each iteration gives us a set of indices pointing to the train rows of the df \n#  (in this case 90% of all the data)\n#  and a set of indices pointing to the val rows of the df\n#  (in this case 10% of the data)\n# we can use islice to control which split we select\nselect = 0\ntrain_ix, val_ix = next(islice(split, select, select+1))\n\n# translate indices to ids\ntrain_ids = image_ids[train_ix]\nval_ids = image_ids[val_ix]\n\n# create corresponding dfs\nprint('Length of training ids', len(train_ids))\nprint('Length of validation ids', len(val_ids))\ntrain_df = train_data[train_data['image_id'].isin(train_ids)]\nvalid_df = train_data[train_data['image_id'].isin(val_ids)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train[\"bbox_area\"]=  train_pascal['area']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class WheatDataset(Dataset):\n    def __init__(self, df, image_dir,transform = None):\n        super().__init__()\n        self.df = df\n        self.img_ids = df['image_id'].unique()\n        self.image_dir = image_dir\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.img_ids)\n    \n    def __getitem__(self, idx: int):\n        image_id = self.img_ids[idx]\n        pts = self.df[self.df['image_id'] == image_id]\n        \n        image = cv2.imread(os.path.join(self.image_dir, image_id), cv2.IMREAD_COLOR)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image = image/255.0\n        \n        boxes = pts[['x_min', 'y_min', 'width', 'height']].values\n        \n        #convert boxes to x1,y1,x2,y2 format because that is what resnet50 faster cnn in pytorch expects\n        boxes[:, 2] = boxes[:, 0] + boxes[:, 2]\n        boxes[:, 3] = boxes[:, 1] + boxes[:, 3]\n        \n        area = (boxes[:, 3] - boxes[:, 1]) * (boxes[:, 2] - boxes[:, 0]) #width times height\n        area = torch.as_tensor(area, dtype = torch.float32)\n        \n        # there is only one class\n        labels = torch.ones((pts.shape[0],), dtype=torch.int64)\n        \n        # suppose all instances are not crowd\n        iscrowd = torch.zeros((pts.shape[0],), dtype=torch.int32)\n        \n        target = {}\n        target[\"boxes\"] = boxes\n        target[\"labels\"] = labels\n        target[\"image_id\"] = torch.tensor(idx)\n        target[\"area\"] = area\n        target[\"iscrowd\"] = iscrowd\n\n        if self.transform:\n            sample = {\n                'image': image,\n                'bboxes': target['boxes'],\n                'labels': target['labels']\n            }\n            sample = self.transform(**sample)\n            image = sample['image']\n            \n            if len(sample['bboxes']) > 0:\n                target['boxes'] = torch.as_tensor(sample['bboxes'], dtype=torch.float32)\n            else:\n                target['boxes'] = torch.linspace(0,3, steps = 4, dtype = torch.float32)\n                target['boxes'] = target['boxes'].reshape(-1,4)\n            \n            #target['boxes'] = torch.stack(tuple(map(torch.tensor, zip(*sample['bboxes'])))).permute(1, 0)\n            #target['boxes'] = torch.as_tensor(sample['bboxes'], dtype=torch.float32)\n            #target['boxes'] = torch.tensor(sample['bboxes'], dtype = torch.float32)\n            \n        return image, target, image_id","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_training_transforms():\n    return alb.Compose([\n        alb.VerticalFlip(p = 0.5),\n        alb.HorizontalFlip(p = 0.5),\n        alb.RandomBrightness(p = 0.5),\n        alb.RandomContrast(p = 0.5),\n        #alb.RandomSunFlare(p=1),\n        #alb.RandomFog(p=1),\n        #alb.Rotate(p=1, limit=90),\n        #alb.RandomSnow(p=1),\n        alb.RandomContrast(limit = 0.5,p = 1),\n        #alb.HueSaturationValue(p=1,hue_shift_limit=20, sat_shift_limit=30, val_shift_limit=50),\n    ToTensorV2(p = 1.0)],\n    p=1.0, bbox_params=alb.BboxParams(format='pascal_voc', label_fields=['labels']))\n\ndef get_validation_transforms():\n    return alb.Compose([ToTensorV2(p = 1.0)], p = 1.0, bbox_params = alb.BboxParams(format='pascal_voc', label_fields=['labels']))\n\ndef get_test_transforms():\n    return alb.Compose([\n                ToTensorV2(p=1.0)\n            ])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def format_prediction_string(boxes, scores):\n    pred_strings = []\n    for j in zip(scores, boxes):\n        pred_strings.append(\"{0:.4f} {1} {2} {3} {4}\".format(j[0], j[1][0], j[1][1], j[1][2], j[1][3]))\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False,pretrained_backbone=False)\nnum_classes = 2\nin_features = model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\nmodel.roi_heads.box_predictor\ndevice = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.to(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.load_state_dict(torch.load('../input/global-wheat-detection-public/fasterrcnn_resnet50_fpn_best.pth'))\nmodel.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.train()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"densenet_net = DenseNet121(\n    weights='../input/densenet-keras/DenseNet-BC-121-32-no-top.h5',\n    include_top=False\n)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"markdown","source":"densenet_net = torchvision.models.densenet169(pretrained=False)\n# so we need to add it here\nmodules = list(densenet_net.children())[:-1]\nbackbone = nn.Sequential(*modules)\nbackbone.out_channels = 1664\n# aspect ratios\nanchor_generator = AnchorGenerator(sizes=((32, 64, 128,256, 512),),\n                                   aspect_ratios=((0.5, 1.0, 2.0),))\n# feature maps to use.\nroi_pooler = torchvision.ops.MultiScaleRoIAlign(featmap_names=[\"0\"],\n                                                output_size=7,\n                                                sampling_ratio=2)\n\n# Load the trained weights\ndensenet_net.load_state_dict(torch.load(WEIGHTS_FILE))\n\n# put the pieces together inside a FasterRCNN model\nmodel = FasterRCNN(backbone,\n                   num_classes=2,\n                   rpn_anchor_generator=anchor_generator,\n                   box_roi_pool=roi_pooler)\n","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def collate_fn(batch):\n    return tuple(zip(*batch))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#setting up dataloaders \ntraining_dataset = WheatDataset(train_df, image_folder_path, get_training_transforms())\nvalidation_dataset = WheatDataset(valid_df, image_folder_path, get_validation_transforms())\n\ntest_dataset = WheatDataset(pd.read_csv(os.path.join(DATA_DIR, \"sample_submission.csv\")), os.path.join(DATA_DIR, \"test\"), get_test_transforms())\n\n\ntrain_dataloader = DataLoader(\n        training_dataset, batch_size=2, shuffle= True, num_workers=4,\n        collate_fn= collate_fn)\n\nvalid_dataloader = DataLoader(\n        validation_dataset, batch_size=2, shuffle=False, num_workers=4,\n        collate_fn=collate_fn)\n\ntest_data_loader = DataLoader(\n    test_dataset,\n    batch_size=4,\n    shuffle=False,\n    num_workers=4,\n    drop_last=False,\n    collate_fn=collate_fn\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.to(device)\n\n# construct an optimizer\nparams = [p for p in model.parameters() if p.requires_grad]\n\noptimizer = torch.optim.SGD(params, lr= 0.01, momentum=0, dampening=0, weight_decay=0, nesterov=False)\n\n# and a learning rate scheduler\nlr_scheduler =  torch.optim.lr_scheduler.StepLR(optimizer, 2, gamma=0.1, last_epoch=-1)\n# let's train it for 12 epochs\nnum_epochs = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"total_train_loss = []\ntotal_test_loss = []\n#itr = 1\n\nfor epoch in range(num_epochs):\n    model.train()\n\n    print('Epoch: ', epoch + 1)\n    train_loss = []\n    \n    for images, targets, image_ids in tqdm(train_dataloader):\n        images = list(image.to(device) for image in images)\n        targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n        \n        loss_dict = model(images, targets)  \n        losses = sum(loss for loss in loss_dict.values())\n        loss_value = losses.item()\n        train_loss.append(loss_value)\n        \n        optimizer.zero_grad()\n        losses.backward()\n        optimizer.step()\n        \n        #if itr%50 == 0:\n            #print('Iteration: ' + str(itr) + '\\n' + 'Loss: '+ str(loss_value))\n            \n        #itr += 1\n        \n    epoch_loss = np.mean(train_loss)\n    print('Epoch Loss is: ' , epoch_loss)\n    total_train_loss.append(epoch_loss)\n    \n    with torch.no_grad():\n        test_losses = []\n        for images, targets, image_ids in tqdm(valid_dataloader):\n            images = list(image.to(device) for image in images)\n            targets = [{k: v.to(device) for k, v in t.items()} for t in targets]\n            \n            loss_dict = model(images, targets)\n\n            losses = sum(loss for loss in loss_dict.values())\n            test_loss = losses.item()\n            if lr_scheduler is not None:\n                lr_scheduler.step()\n            test_losses.append(test_loss)\n            \n    test_losses_epoch = np.mean(test_losses)\n    print('Test Loss: ' ,test_losses_epoch)\n    total_test_loss.append(test_losses_epoch)\n    \n        \ntorch.save(model.state_dict(), 'fasterrcnn.pth')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(np.arange(num_epochs),total_train_loss ,label = 'train')\nplt.plot(np.arange(num_epochs),total_test_loss, label = 'test')\nplt.title('Loss over epochs')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"images, targets, image_ids in next(iter(valid_dataloader))\nimages = list(image.to(device) for image in images)\ntargets = [{k: v.to(device) for k, v in t.items()} for t in targets]\nimages\n\nprediction = model(images)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(1,2, figsize = (20,10))\nboxes = targets[0]['boxes'].cpu().numpy().astype(np.int32)\nimg = images[0].permute(1,2,0).cpu().numpy()\n\nfor box in boxes:\n    rect = patches.Rectangle((box[0],box[1]),box[2] - box[0],box[3] - box[1],linewidth=2,edgecolor='r',facecolor='none')\n    ax[0].add_patch(rect)\nax[0].set_title('Actual')\nax[0].set_axis_off()\nax[0].imshow(img)\n\nthresh = 0.5\nbox_preds = prediction[0]['boxes'].cpu().detach().numpy()\nscore_preds = prediction[0]['scores'].cpu().detach().numpy()\nbox_preds = box_preds[score_preds >= thresh].astype(np.int32)\nfor box in box_preds:\n    rect = patches.Rectangle((box[0],box[1]),box[2] - box[0],box[3] - box[1],linewidth=2,edgecolor='r',facecolor='none')\n    ax[1].add_patch(rect)\nax[1].set_title('Predicted')\nax[1].set_axis_off()\nax[1].imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detection_threshold= 0.5\nimages = list(image.to(device) for image in images)\noutputs = model(images)\nresults=[]\nfor i, image in enumerate(images):\n\n    boxes = outputs[i]['boxes'].data.cpu().numpy()\n    scores = outputs[i]['scores'].data.cpu().numpy()\n\n    boxes = boxes[scores >= detection_threshold].astype(np.int32)\n    scores = scores[scores >= detection_threshold]\n    image_id = image_ids[i]\n\n    boxes[:, 2] = boxes[:, 2] - boxes[:, 0]\n    boxes[:, 3] = boxes[:, 3] - boxes[:, 1]\n\n\n\n    result = {\n        'image_id': image_id,\n        'PredictionString': format_prediction_string(boxes, scores)\n    }\n\n\n    results.append(result)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from glob import glob","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"origin_list = glob('../input/global-wheat-detection/test/*.jpg')\nprint(origin_list)\n\npreds = []\n\nfor i, img_name in enumerate(origin_list):\n    # load image\n    original_img = Image.open(img_name)\n\n    # from pil image to tensor, do not normalize image\n    data_transform = transforms.Compose([transforms.ToTensor()])\n    img = data_transform(original_img)\n    # expand batch dimension\n    img = torch.unsqueeze(img, dim=0)\n\n\n    model.eval()\n    with torch.no_grad():\n        since = time.time()\n        predictions = model(img.to(device))[0]\n        print('{} Time:{}s'.format(i, time.time() - since))\n        predict_boxes = predictions[\"boxes\"].to(\"cpu\").numpy()\n        predict_classes = predictions[\"labels\"].to(\"cpu\").numpy()\n        predict_scores = predictions[\"scores\"].to(\"cpu\").numpy()\n\n       \n\n        predict = \"\"\n        for box, score in zip(predict_boxes, predict_scores):\n            str_box = \"\"\n            box[2] = box[2] - box[0]\n            box[3] = box[3] - box[1]\n            for b in box:\n                str_box += str(b) + ' '\n            predict += '1.0' + ' ' + str_box\n        preds.append(predict)\n\nname_list = [name.split('/')[-1].split('.')[0] for name in origin_list]\nprint(name_list)\ndataframe = pd.DataFrame({\"image_id\": name_list, \"PredictionString\": preds})\ndataframe.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"test_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\ntest_df.head()","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"test_df.to_csv('submission.csv', index=False)","execution_count":null}],"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":4,"nbformat_minor":4}