{"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)\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\nimport os\nfor 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 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":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import torch\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport matplotlib.patches as patches\nfrom PIL import Image\nimport numpy as np\nimport torchvision\nimport random\nimport torchvision.transforms as transforms\nfrom tqdm import tqdm\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nimport glob\nfrom torch.utils.data import Dataset, DataLoader\n\nDIR_INPUT = '/kaggle/input/global-wheat-detection'\nDIR_TRAIN = f'{DIR_INPUT}/train'\nDIR_TEST = f'{DIR_INPUT}/test'\n\n# DIR_WEIGHTS = '/kaggle/input/global-wheat-detection-public'\nDIR_WEIGHTS = '/kaggle/input/kernel70d11cc72d'\n\n# WEIGHTS_FILE = f'{DIR_WEIGHTS}/fasterrcnn_resnet50_fpn_best.pth'\nWEIGHTS_FILE = f'{DIR_WEIGHTS}/model_states.pt'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import math\nimport torch\nfrom torch.optim.optimizer import Optimizer, required\n\nclass RAdam(Optimizer):\n\n    def __init__(self, params, lr=1e-3, betas=(0.9, 0.999), eps=1e-8, weight_decay=0, degenerated_to_sgd=True):\n        if not 0.0 <= lr:\n            raise ValueError(\"Invalid learning rate: {}\".format(lr))\n        if not 0.0 <= eps:\n            raise ValueError(\"Invalid epsilon value: {}\".format(eps))\n        if not 0.0 <= betas[0] < 1.0:\n            raise ValueError(\"Invalid beta parameter at index 0: {}\".format(betas[0]))\n        if not 0.0 <= betas[1] < 1.0:\n            raise ValueError(\"Invalid beta parameter at index 1: {}\".format(betas[1]))\n        \n        self.degenerated_to_sgd = degenerated_to_sgd\n        if isinstance(params, (list, tuple)) and len(params) > 0 and isinstance(params[0], dict):\n            for param in params:\n                if 'betas' in param and (param['betas'][0] != betas[0] or param['betas'][1] != betas[1]):\n                    param['buffer'] = [[None, None, None] for _ in range(10)]\n        defaults = dict(lr=lr, betas=betas, eps=eps, weight_decay=weight_decay, buffer=[[None, None, None] for _ in range(10)])\n        super(RAdam, self).__init__(params, defaults)\n\n    def __setstate__(self, state):\n        super(RAdam, self).__setstate__(state)\n\n    def step(self, closure=None):\n\n        loss = None\n        if closure is not None:\n            loss = closure()\n\n        for group in self.param_groups:\n\n            for p in group['params']:\n                if p.grad is None:\n                    continue\n                grad = p.grad.data.float()\n                if grad.is_sparse:\n                    raise RuntimeError('RAdam does not support sparse gradients')\n\n                p_data_fp32 = p.data.float()\n\n                state = self.state[p]\n\n                if len(state) == 0:\n                    state['step'] = 0\n                    state['exp_avg'] = torch.zeros_like(p_data_fp32)\n                    state['exp_avg_sq'] = torch.zeros_like(p_data_fp32)\n                else:\n                    state['exp_avg'] = state['exp_avg'].type_as(p_data_fp32)\n                    state['exp_avg_sq'] = state['exp_avg_sq'].type_as(p_data_fp32)\n\n                exp_avg, exp_avg_sq = state['exp_avg'], state['exp_avg_sq']\n                beta1, beta2 = group['betas']\n\n                exp_avg_sq.mul_(beta2).addcmul_(1 - beta2, grad, grad)\n                exp_avg.mul_(beta1).add_(1 - beta1, grad)\n\n                state['step'] += 1\n                buffered = group['buffer'][int(state['step'] % 10)]\n                if state['step'] == buffered[0]:\n                    N_sma, step_size = buffered[1], buffered[2]\n                else:\n                    buffered[0] = state['step']\n                    beta2_t = beta2 ** state['step']\n                    N_sma_max = 2 / (1 - beta2) - 1\n                    N_sma = N_sma_max - 2 * state['step'] * beta2_t / (1 - beta2_t)\n                    buffered[1] = N_sma\n\n                    # more conservative since it's an approximated value\n                    if N_sma >= 5:\n                        step_size = math.sqrt((1 - beta2_t) * (N_sma - 4) / (N_sma_max - 4) * (N_sma - 2) / N_sma * N_sma_max / (N_sma_max - 2)) / (1 - beta1 ** state['step'])\n                    elif self.degenerated_to_sgd:\n                        step_size = 1.0 / (1 - beta1 ** state['step'])\n                    else:\n                        step_size = -1\n                    buffered[2] = step_size\n\n                # more conservative since it's an approximated value\n                if N_sma >= 5:\n                    if group['weight_decay'] != 0:\n                        p_data_fp32.add_(-group['weight_decay'] * group['lr'], p_data_fp32)\n                    denom = exp_avg_sq.sqrt().add_(group['eps'])\n                    p_data_fp32.addcdiv_(-step_size * group['lr'], exp_avg, denom)\n                    p.data.copy_(p_data_fp32)\n                elif step_size > 0:\n                    if group['weight_decay'] != 0:\n                        p_data_fp32.add_(-group['weight_decay'] * group['lr'], p_data_fp32)\n                    p_data_fp32.add_(-step_size * group['lr'], exp_avg)\n                    p.data.copy_(p_data_fp32)\n\n        return loss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_mat = pd.read_csv('/kaggle/input/global-wheat-detection/train.csv')\ntrain_mat.head()\ntest_df = pd.read_csv('/kaggle/input/global-wheat-detection/sample_submission.csv')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_mat['source'].unique())\ncolor_list = dict()\nfor src in train_mat['source'].unique():\n    color_list[src] = (random.random(), random.random(), random.random())\nprint(color_list)\nprint(color_list['usask_1'])\na = 'usask_1'\nprint(color_list[a])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def red_box(box_df, plt, m_output=False):\n    for i in range(len(box_df)):\n        if isinstance(box_df, torch.Tensor):\n            if m_output:\n                box_df[i][2] -= box_df[i][0]\n                box_df[i][3] -= box_df[i][1]\n            rect = patches.Rectangle(\n                (float(box_df[i][0]), float(box_df[i][1])),\n                float(box_df[i][2]),\n                float(box_df[i][3]),\n                linewidth=2,\n                edgecolor='red',\n                facecolor='none'\n            )\n        else:\n            # Read image, not model output\n            one_bbox = box_df['bbox'].iloc[i].replace(\"[\", \"\").replace(\"]\", \"\").replace(\" \", \"\").split(\",\")\n            source = box_df['source'].iloc[i]\n            rect = patches.Rectangle(\n                (float(one_bbox[0]), float(one_bbox[1])),\n                float(one_bbox[2]),\n                float(one_bbox[3]),\n                linewidth=2,\n                edgecolor=color_list[source],\n                facecolor='none'\n            )\n\n        plt.add_patch(rect)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"one = train_mat.loc[train_mat['image_id'] == '0a3cb453f']\nprint(len(one))\nprint(one.head())\nprint(isinstance(one, pd.core.frame.DataFrame))\nprint(type(one))\nprint(one['bbox'].iloc[0].replace(\"[\", \"\").replace(\"]\",\"\").replace(\" \",\"\").split(','))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"one_image = Image.open('/kaggle/input/global-wheat-detection/train/0a3cb453f.jpg')\nfig = plt.figure(figsize=(8, 8))\nax = fig.add_subplot(1, 1, 1)\nax.imshow(one_image)\ntransform = transforms.ToTensor()\nimg_ten = transform(one_image)\nprint(img_ten.max())\nprint(img_ten.size())\nred_box(one, ax) # Input dataframe and fig subplot(which is plotting image)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class wheatDataset(object):\n    # original bbox = [x_min, y_min, width, height] --> wheatDataset return boxs(list) = [[x_min, y_min, x_max, y_max]]\n    def __init__(self, root_dir, dataframe, transforms, train=True):\n        self.img_ids = dataframe['image_id'].unique()\n        self.df = dataframe\n        self.root_dir = root_dir\n        self.transforms = transforms\n        self.len = len(self.img_ids)\n        self.train = train\n    \n    def __getitem__(self, index):\n        image_id = self.img_ids[index]\n        a, b, c = torch.rand(1).item(), torch.rand(1).item(), torch.rand(1).item()\n        \n        if self.train:\n            bbox = self.df[self.df['image_id'] == image_id]['bbox']\n            box_l = []\n            for i in range(len(bbox)):\n                if a > 0.5 and b > 0.5: # horizontal flip and vertical\n                    one_bbox_t = list(map(float, bbox.iloc[i].replace(\"[\", \"\").replace(\"]\", \"\").replace(\" \", \"\").split(\",\")))\n                    one_bbox = [1024 - one_bbox_t[0]-one_bbox_t[2], 1024-one_bbox_t[1]-one_bbox_t[3], one_bbox_t[2], one_bbox_t[3]]\n                    one_bbox[2] += one_bbox[0]\n                    one_bbox[3] += one_bbox[1]\n                    box_l.append(one_bbox)\n                elif a > 0.5 and b < 0.5: # horizontal flip\n                    one_bbox_t = list(map(float, bbox.iloc[i].replace(\"[\", \"\").replace(\"]\", \"\").replace(\" \", \"\").split(\",\")))\n                    one_bbox = [1024 - one_bbox_t[0]-one_bbox_t[2], one_bbox_t[1], one_bbox_t[2], one_bbox_t[3]]\n                    one_bbox[2] += one_bbox[0]\n                    one_bbox[3] += one_bbox[1]\n                    box_l.append(one_bbox)\n                elif b > 0.5 and a < 0.5: # vertical flip\n                    one_bbox_t = list(map(float, bbox.iloc[i].replace(\"[\", \"\").replace(\"]\", \"\").replace(\" \", \"\").split(\",\")))\n                    one_bbox = [one_bbox_t[0], 1024-one_bbox_t[1]-one_bbox_t[3], one_bbox_t[2], one_bbox_t[3]]\n                    one_bbox[2] += one_bbox[0]\n                    one_bbox[3] += one_bbox[1]\n                    box_l.append(one_bbox)\n                elif a < 0.5 and b < 0.5: # ordinary\n                    one_bbox = list(map(float, bbox.iloc[i].replace(\"[\", \"\").replace(\"]\", \"\").replace(\" \", \"\").split(\",\")))\n                    one_bbox[2] += one_bbox[0]\n                    one_bbox[3] += one_bbox[1]\n                    box_l.append(one_bbox)\n            boxs = torch.tensor(box_l)\n        else:\n            boxs = None\n\n        image = Image.open(\"/kaggle/input/global-wheat-detection\" + self.root_dir + '/' + image_id + '.jpg')\n        \n        if a > 0.5:\n            trans1 = transforms.RandomHorizontalFlip(p=1.0)\n            image = trans1(image)\n        \n        if b > 0.5:\n            trans1 = transforms.RandomVerticalFlip(p=1.0)\n            image = trans1(image)\n        \n        if c > 0.5:\n            trans1 = transforms.ColorJitter(contrast=(0.5, 1.5), brightness=(0.5, 1.5), saturation=(0.5, 1.5))\n            image = trans1(image)\n        \n        if self.transforms:\n            image = self.transforms(image).to(device)\n        \n        return image, image_id, boxs\n\n    def __len__(self):\n        return self.len\n\n    \n    \nclass WheatDataset(Dataset):  # For test phase\n    def __init__(self, dataframe, image_dir, transforms):\n        super().__init__()\n\n        self.image_ids = dataframe['image_id'].unique()\n        self.df = dataframe\n        self.image_dir = image_dir\n        self.transforms = transforms\n\n    def __len__(self) -> int:\n        return len(self.image_ids)\n\n    def __getitem__(self, idx: int):\n        image_id = self.image_ids[idx]\n        image = Image.open(f'{self.image_dir}/{image_id}.jpg')\n        if self.transforms:\n            image = self.transforms(image).to(device)\n\n        records = self.df[self.df['image_id'] == image_id]\n\n        return image, image_id","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Assign dataset and dataloader\n\ndef collate_fn(batch):\n    return tuple(zip(*batch))\n\ntrainset = wheatDataset(root_dir='/train', dataframe=train_mat, transforms=transform)\nset_length = len(trainset)\ntrainset, validset = torch.utils.data.random_split(trainset, [set_length-int(set_length/10), int(set_length/10)])\n\ntrainloader = torch.utils.data.DataLoader(dataset=trainset, batch_size=16, shuffle=False, collate_fn=collate_fn)\nvalidloader = torch.utils.data.DataLoader(dataset=validset, batch_size=16, shuffle=True, collate_fn=collate_fn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test dataset and dataloader\n\ndevice = 'cuda'\ndataiter = iter(trainloader)\nimages, labels, box = dataiter.next()\nimages = list(image for image in images)\nprint('d', labels)\nprint(images[0].size())\nprint(box[0].size())\nprint(len(box))\nprint(box[0][:6,:])\n\n\nfig = plt.figure(figsize=(7, 7))\nax = fig.add_subplot(1, 1, 1)\nwith torch.no_grad():\n    ax.imshow(images[0].permute(1, 2, 0).cpu())\n    red_box(box[0], ax, m_output=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone=False)\n\nnum_classes = 2\nin_features = model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\n\nmodel.load_state_dict(torch.load(WEIGHTS_FILE, map_location=torch.device(\"cuda\")))\n\noptimizer = RAdam([p for p in model.parameters() if p.requires_grad], lr=1e-4, weight_decay=1e-4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\nnum_epoch = 5\n\nmodel.train()\nmodel.to(device)\n\nfor epoch in range(num_epoch):\n    total_loss = 0.0\n    model.train()\n    for i, (images, labels, boxes) in tqdm(enumerate(trainloader)):\n        targets = []\n        for j in range(len(images)):\n            d = {}\n            d['boxes'] = boxes[j].to(device)\n            d['labels'] = torch.ones(boxes[j].size(0), dtype=torch.int64).to(device)\n            targets.append(d)\n        \n        images = list(image for image in images)\n        output = model(images, targets)\n        losses = sum(loss for loss in output.values())\n\n        optimizer.zero_grad()\n        losses.backward()\n        optimizer.step()\n\n        total_loss += losses.item()\n    \n    model.eval()\n    for i, (images, labels, boxes) in tqdm(enumerate(validloader)):\n        targets = []\n        for j in range(len(images)):\n            d = {}\n            d['boxes'] = boxes[j].to(device)\n            d['labels'] = torch.ones(boxes[j].size(0), dtype=torch.int64).to(device)\n            targets.append(d)\n        \n        images = list(image for image in images)\n        output = model(images, targets)\n        losses = sum(loss for loss in output.values())\n    \n    if epoch % 1 == 0:\n        print(f\"{epoch}/{num_epoch} : {total_loss:.4f}\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Test trainset! not testset\ndetection_threshold = 0.5\n\ntrainset = wheatDataset(root_dir='/train', dataframe=train_mat, transforms=transform)\ntrainloader = torch.utils.data.DataLoader(dataset=trainset, batch_size=4, shuffle=True, collate_fn=collate_fn)\ndevice = 'cuda:0'\ndataiter = iter(trainloader)\nimages, labels, box = dataiter.next()\nimages = list(image for image in images)\n\nmodel.eval()\noutput = model(images)\n# print(output[0].values())\n\nfig = plt.figure(figsize=(8, 8))\nax1 = fig.add_subplot(2, 2, 1)\nax2 = fig.add_subplot(2, 2, 2)\nax3 = fig.add_subplot(2, 2, 3)\nax4 = fig.add_subplot(2, 2, 4)\nax = [ax1, ax2, ax3, ax4]\n\nfor i, a in enumerate(ax):\n    # one = train_mat.loc[train_mat['image_id'] == labels[i]]\n    a.imshow(Image.open(\"/kaggle/input/global-wheat-detection/train/\" + labels[i] + '.jpg'))\n    boxes = output[i]['boxes'].data.cpu().numpy()\n    scores = output[i]['scores'].data.cpu().numpy()\n    boxes = torch.from_numpy(boxes[scores >= detection_threshold].astype(np.int32))\n    red_box(boxes, a, m_output=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_submission = pd.read_csv(\"/kaggle/input/global-wheat-detection/sample_submission.csv\")\nsample_submission\nsample_submission.to_csv(\"/kaggle/working/sample_submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_dataset = WheatDataset(test_df, os.path.join(\"/kaggle/input/global-wheat-detection\", \"test\"), transforms=transform)\n\ntest_data_loader = DataLoader(\n    test_dataset,\n    batch_size=4,\n    shuffle=False,\n    drop_last=False,\n    collate_fn=collate_fn\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\n    return \" \".join(pred_strings)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"detection_threshold = 0.5\nresults = []\n\nfor images, image_ids in test_data_loader:\n\n    images = list(image.to(device) for image in images)\n    outputs = model(images)\n\n    for 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        result = {\n            'image_id': image_id,\n            'PredictionString': format_prediction_string(boxes, scores)\n        }\n\n        \n        results.append(result)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"os.chdir(\"/kaggle/working\")\n!pwd\n!ls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"torch.save(model.state_dict(), \"model_states.pt\")\n\ntest_df = pd.DataFrame(results, columns=['image_id', 'PredictionString'])\nprint(test_df)\ntest_df.to_csv('submission.csv', index=False)\nprint(\"saved\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\ndetection_threshold = 0.3\n\ntest_img_list = glob.glob(\"/kaggle/input/global-wheat-detection/test/*.jpg\")\nfig = plt.figure(figsize=(8, 8))\nax = fig.add_subplot(1, 1, 1)\nanswer_list = []\n\ntestset = wheatDataset(root_dir='/test', dataframe=test_df, transforms=transform, train=False)\ntestloader = torch.utils.data.DataLoader(dataset=testset, batch_size=1, shuffle=False, collate_fn=collate_fn)\n\nfor i, (images, labels, _) in tqdm(enumerate(testloader)):\n    targets = []\n    pdstring = \"\"\n\n    output = model(images)\n    for j in range(len(boxes)):\n        if j == len(boxes)-1:\n            pdstring += str(scores[j].item()) + \" \" + str(boxes[j][0].item()) + \" \" + str(boxes[j][1].item()) + \" \" + str(boxes[j][2].item()-boxes[j][0].item()) + \" \" + str(boxes[j][3].item() - boxes[j][1].item())\n        else:\n            pdstring += str(scores[j].item()) + \" \" + str(boxes[j][0].item()) + \" \" + str(boxes[j][1].item()) + \" \" + str(boxes[j][2].item()-boxes[j][0].item()) + \" \" + str(boxes[j][3].item() - boxes[j][1].item()) + \" \"\n    answer_list.append(pdstring)\n   \n   \n   \n   fucnalksdnf;kasjdnfkj;sadnfkjsnadkfasdkhfasldkfhsadjhf;lasjfd \n   \n   \n   \n\"\"\"\n\"\"\"\nfor i in range(10):\n    pdstring = \"\"\n    img = transforms.ToTensor()(Image.open(f\"/kaggle/input/global-wheat-detection/test/{sample_submission.iloc[i, 0]}.jpg\"))\n    model.eval()\n    output = model(img.unsqueeze(0).cuda())\n    \n    ax.imshow(img.permute(1, 2, 0).cpu())\n    boxes = output[0]['boxes'].data.cpu().numpy()\n    scores = output[0]['scores'].data.cpu().numpy()\n    \n    boxes = torch.from_numpy(boxes[scores >= detection_threshold].astype(np.int32))\n    scores = torch.from_numpy(scores[scores >= detection_threshold])\n    \n    for j in range(len(boxes)):\n        if j == len(boxes)-1:\n            print('end')\n            pdstring += str(scores[j].item()) + \" \" + str(boxes[j][0].item()) + \" \" + str(boxes[j][1].item()) + \" \" + str(boxes[j][2].item()-boxes[j][0].item()) + \" \" + str(boxes[j][3].item() - boxes[j][1].item())\n        else:\n            pdstring += str(scores[j].item()) + \" \" + str(boxes[j][0].item()) + \" \" + str(boxes[j][1].item()) + \" \" + str(boxes[j][2].item()-boxes[j][0].item()) + \" \" + str(boxes[j][3].item() - boxes[j][1].item()) + \" \"\n    print(i, f\"{sample_submission.iloc[i, 0]}\", pdstring)\n    answer_list.append(pdstring)\n    red_box(boxes, ax, m_output=True)\n\"\"\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\"\"\"\nprint(sample_submission)\nsample_submission.iloc[:, 1] = answer_list\nos.chdir(\"/kaggle/working/\")\nprint(sample_submission)\nsample_submission.to_csv(\"submission.csv\", index=False)\nprint(\"saved\")\n\"\"\"","execution_count":null,"outputs":[]}],"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}