{"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":"markdown","source":"## Import Package","metadata":{}},{"cell_type":"code","source":"# model\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom torchvision import models\n\n# dataset\nimport os\nimport math\nimport glob\nimport pandas as pd\nfrom PIL import Image\nfrom sklearn.model_selection import train_test_split\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset, Subset, DataLoader\nimport matplotlib.pyplot as plt\n\n# save result\nimport pickle","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-02T00:30:28.465213Z","iopub.execute_input":"2022-07-02T00:30:28.466211Z","iopub.status.idle":"2022-07-02T00:30:31.576382Z","shell.execute_reply.started":"2022-07-02T00:30:28.466101Z","shell.execute_reply":"2022-07-02T00:30:31.574186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(2022)\ntry:\n    device = torch.device(\"mps\")\nexcept:\n    device = torch.device(\"cuda\") if torch.cuda.is_available() else torch.device(\"cpu\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:30:31.582412Z","iopub.execute_input":"2022-07-02T00:30:31.585176Z","iopub.status.idle":"2022-07-02T00:30:31.669592Z","shell.execute_reply.started":"2022-07-02T00:30:31.585133Z","shell.execute_reply":"2022-07-02T00:30:31.668486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:30:35.505936Z","iopub.execute_input":"2022-07-02T00:30:35.506574Z","iopub.status.idle":"2022-07-02T00:30:35.518183Z","shell.execute_reply.started":"2022-07-02T00:30:35.506489Z","shell.execute_reply":"2022-07-02T00:30:35.516893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prepare Dataset","metadata":{}},{"cell_type":"markdown","source":"### Get All Training Image","metadata":{}},{"cell_type":"code","source":"img_names = glob.glob(\"../input/dog-breed-identification/train/*.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:31:52.658166Z","iopub.execute_input":"2022-07-02T00:31:52.659080Z","iopub.status.idle":"2022-07-02T00:31:53.033509Z","shell.execute_reply.started":"2022-07-02T00:31:52.659043Z","shell.execute_reply":"2022-07-02T00:31:53.032512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(img_names)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:31:57.844668Z","iopub.execute_input":"2022-07-02T00:31:57.845586Z","iopub.status.idle":"2022-07-02T00:31:57.851647Z","shell.execute_reply.started":"2022-07-02T00:31:57.845548Z","shell.execute_reply":"2022-07-02T00:31:57.850588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_names[0:10]","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:32:03.968757Z","iopub.execute_input":"2022-07-02T00:32:03.969098Z","iopub.status.idle":"2022-07-02T00:32:03.976505Z","shell.execute_reply.started":"2022-07-02T00:32:03.969069Z","shell.execute_reply":"2022-07-02T00:32:03.975451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create Custom Dataset","metadata":{}},{"cell_type":"code","source":"class DogDataset(Dataset):\n\n    def __init__(self, img_path, csv_path):\n        self.csv_path = csv_path\n        self.transform = None\n\n        self.img_names = glob.glob(f\"{img_path}/*.jpg\")\n\n        if csv_path:\n            label_df = pd.read_csv(csv_path)\n            self.label_idx2name = label_df['breed'].unique()\n            self.label_name2idx = {}\n            for i in range(len(self.label_idx2name)):\n                self.label_name2idx[self.label_idx2name[i]] = i\n            self.img2label = {}\n            for _, row in label_df.iterrows():\n                self.img2label[f\"{img_path}/{row['id']}.jpg\"] = self.label_name2idx[row['breed']]\n    \n    def __len__(self):\n        return len(self.img_names)\n    \n    def __getitem__(self, index):\n        img = self.img_names[index]\n\n        if self.csv_path:\n            label = self.img2label[img]\n            label = torch.tensor(label)\n        else:\n            label = -1\n        \n        img = Image.open(img).convert(\"RGB\")\n        img = self.transform(img)\n        return (img, label)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:32:19.716969Z","iopub.execute_input":"2022-07-02T00:32:19.717533Z","iopub.status.idle":"2022-07-02T00:32:19.728325Z","shell.execute_reply.started":"2022-07-02T00:32:19.717497Z","shell.execute_reply":"2022-07-02T00:32:19.727343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# transform_fn for pretrained ViT\nchannel_mean = torch.Tensor([0.485, 0.456, 0.406])\nchannel_std = torch.Tensor([0.229, 0.224, 0.225])\n\nvit_train_transform_fn = transforms.Compose([\n    transforms.Resize(256),\n    transforms.CenterCrop(224),\n\n    transforms.RandomHorizontalFlip(p=0.6),\n    transforms.RandomRotation(degrees=(30)),\n\n    transforms.ToTensor(),\n    transforms.Normalize(mean=channel_mean, std=channel_std),\n])\n\nvit_valid_transform_fn = transforms.Compose([\n    transforms.Resize(256),\n    transforms.CenterCrop(224),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=channel_mean, std=channel_std),\n])","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:32:28.729443Z","iopub.execute_input":"2022-07-02T00:32:28.729796Z","iopub.status.idle":"2022-07-02T00:32:28.739587Z","shell.execute_reply.started":"2022-07-02T00:32:28.729768Z","shell.execute_reply":"2022-07-02T00:32:28.737068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = DogDataset(\n    img_path=\"../input/dog-breed-identification/train\",\n    csv_path=\"../input/dog-breed-identification/labels.csv\",\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:33:03.553929Z","iopub.execute_input":"2022-07-02T00:33:03.554319Z","iopub.status.idle":"2022-07-02T00:33:04.128325Z","shell.execute_reply.started":"2022-07-02T00:33:03.554259Z","shell.execute_reply":"2022-07-02T00:33:04.127204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Split `dataset` into `train_dataset` and `valid_dataset`","metadata":{}},{"cell_type":"code","source":"indexes = list(range(len(dataset)))\ntrain_indexes, valid_indexes = train_test_split(indexes, test_size=0.1)\ntrain_dataset = Subset(dataset, train_indexes)\nvalid_dataset = Subset(dataset, valid_indexes)\n\nprint(f\"number of samples in train_dataset: {len(train_dataset)}\")\nprint(f\"number of samples in valid_dataset: {len(valid_dataset)}\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:33:20.293742Z","iopub.execute_input":"2022-07-02T00:33:20.294099Z","iopub.status.idle":"2022-07-02T00:33:20.306182Z","shell.execute_reply.started":"2022-07-02T00:33:20.294068Z","shell.execute_reply":"2022-07-02T00:33:20.305156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset.transform = vit_train_transform_fn\ntrain_dataset.transform = vit_train_transform_fn\nvalid_dataset.transform = vit_valid_transform_fn","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:33:41.510005Z","iopub.execute_input":"2022-07-02T00:33:41.510483Z","iopub.status.idle":"2022-07-02T00:33:41.515471Z","shell.execute_reply.started":"2022-07-02T00:33:41.510448Z","shell.execute_reply":"2022-07-02T00:33:41.514573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create DataLoader","metadata":{}},{"cell_type":"code","source":"train_valid_dataloader = DataLoader(\n    dataset,\n    batch_size=8,\n    shuffle=True\n)\n\ntrain_dataloader = DataLoader(\n    train_dataset,\n    batch_size=8,\n    shuffle=True\n)\n\nvalid_dataloader = DataLoader(\n    valid_dataset,\n    batch_size=32,\n    shuffle=True\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:33:49.771889Z","iopub.execute_input":"2022-07-02T00:33:49.772958Z","iopub.status.idle":"2022-07-02T00:33:49.779801Z","shell.execute_reply.started":"2022-07-02T00:33:49.772906Z","shell.execute_reply":"2022-07-02T00:33:49.778673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Show Some Samples in Batch","metadata":{}},{"cell_type":"code","source":"def show_samples(batch_img, batch_label=None, num_samples=16):\n\n    sample_idx = 0\n    total_col = 4\n    total_row = math.ceil(num_samples / 4)\n    col_idx = 0\n    row_idx = 0\n\n    fig, axs = plt.subplots(total_row, total_col, figsize=(15, 15))\n\n    while sample_idx < num_samples:\n        img = batch_img[sample_idx]\n        img = img.view(3, -1) * channel_std.view(3, -1) + channel_mean.view(3, -1)\n        img = img.view(3, 224, 224)\n        img = img.permute(1, 2, 0)\n        axs[row_idx, col_idx].imshow(img)\n\n        if batch_label != None:\n            axs[row_idx, col_idx].set_title(dataset.label_idx2name[(batch_label[sample_idx])])\n\n        sample_idx += 1\n        col_idx += 1\n        if col_idx == 4:\n            col_idx = 0\n            row_idx += 1","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:35:37.846191Z","iopub.execute_input":"2022-07-02T00:35:37.847009Z","iopub.status.idle":"2022-07-02T00:35:37.856368Z","shell.execute_reply.started":"2022-07-02T00:35:37.846971Z","shell.execute_reply":"2022-07-02T00:35:37.855227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_img, batch_label = next(iter(train_dataloader))","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:35:43.643728Z","iopub.execute_input":"2022-07-02T00:35:43.644127Z","iopub.status.idle":"2022-07-02T00:35:43.773284Z","shell.execute_reply.started":"2022-07-02T00:35:43.644094Z","shell.execute_reply":"2022-07-02T00:35:43.772329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_samples(batch_img, batch_label, 8)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:35:50.466251Z","iopub.execute_input":"2022-07-02T00:35:50.466935Z","iopub.status.idle":"2022-07-02T00:35:51.659590Z","shell.execute_reply.started":"2022-07-02T00:35:50.466896Z","shell.execute_reply":"2022-07-02T00:35:51.658636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build Model","metadata":{}},{"cell_type":"code","source":"class PretrainViT(nn.Module):\n\n    def __init__(self):\n        super(PretrainViT, self).__init__()\n        model = models.vit_b_16(pretrained=True)\n        num_classifier_feature = model.heads.head.in_features\n        model.heads.head = nn.Sequential(\n            nn.Linear(num_classifier_feature, 120)\n        )\n        self.model = model\n\n        for param in self.model.named_parameters():\n            if \"heads\" not in param[0]:\n                param[1].requires_grad = False\n\n    def forward(self, x):\n        return self.model(x)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:36:13.802196Z","iopub.execute_input":"2022-07-02T00:36:13.802908Z","iopub.status.idle":"2022-07-02T00:36:13.810660Z","shell.execute_reply.started":"2022-07-02T00:36:13.802871Z","shell.execute_reply":"2022-07-02T00:36:13.809332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"net = PretrainViT()\nnet.to(device)\nprint(f\"number of paramaters: {sum([param.numel() for param in net.parameters() if param.requires_grad])}\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:36:22.301186Z","iopub.execute_input":"2022-07-02T00:36:22.301795Z","iopub.status.idle":"2022-07-02T00:36:30.634399Z","shell.execute_reply.started":"2022-07-02T00:36:22.301756Z","shell.execute_reply":"2022-07-02T00:36:30.632607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train Model","metadata":{}},{"cell_type":"markdown","source":"### Loss Function and Optimizer","metadata":{}},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(net.parameters(), lr=0.003, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:36:46.247921Z","iopub.execute_input":"2022-07-02T00:36:46.248303Z","iopub.status.idle":"2022-07-02T00:36:46.254619Z","shell.execute_reply.started":"2022-07-02T00:36:46.248250Z","shell.execute_reply":"2022-07-02T00:36:46.253554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Training Loop ","metadata":{}},{"cell_type":"code","source":"def get_accuracy(output, label):\n    output = output.to(\"cpu\")\n    label = label.to(\"cpu\")\n\n    sm = F.softmax(output, dim=1)\n    _, index = torch.max(sm, dim=1)\n    return torch.sum((label == index)) / label.size()[0]","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:37:02.881547Z","iopub.execute_input":"2022-07-02T00:37:02.881916Z","iopub.status.idle":"2022-07-02T00:37:02.888293Z","shell.execute_reply.started":"2022-07-02T00:37:02.881885Z","shell.execute_reply":"2022-07-02T00:37:02.886420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, dataloader):\n    model.train()\n    running_loss = 0.0\n    total_loss = 0.0\n    running_acc = 0.0\n    total_acc = 0.0\n\n    for batch_idx, (batch_img, batch_label) in enumerate(dataloader):\n\n        batch_img = batch_img.to(device)\n        batch_label = batch_label.to(device)\n\n        optimizer.zero_grad()\n        output = net(batch_img)\n        loss = criterion(output, batch_label)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        total_loss += loss.item()\n\n        acc = get_accuracy(output, batch_label)\n        running_acc += acc\n        total_acc += acc\n\n        if batch_idx % 100 == 0 and batch_idx != 0:\n            print(f\"[step: {batch_idx:4d}/{len(dataloader)}] loss: {running_loss / 100:.3f}\")\n            running_loss = 0.0\n            running_acc = 0.0\n    \n    return total_loss / len(dataloader), total_acc / len(dataloader)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:37:07.321722Z","iopub.execute_input":"2022-07-02T00:37:07.322082Z","iopub.status.idle":"2022-07-02T00:37:07.330538Z","shell.execute_reply.started":"2022-07-02T00:37:07.322051Z","shell.execute_reply":"2022-07-02T00:37:07.329233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def validate(model, dataloader):\n    model.eval()\n    total_loss = 0.0\n    total_acc = 0.0\n\n    for batch_idx, (batch_img, batch_label) in enumerate(dataloader):\n\n        batch_img = batch_img.to(device)\n        batch_label = batch_label.to(device)\n\n        # optimizer.zero_grad()\n        output = net(batch_img)\n        loss = criterion(output, batch_label)\n        # loss.backward()\n        # optimizer.step()\n\n        total_loss += loss.item()\n        acc = get_accuracy(output, batch_label)\n        total_acc += acc\n    \n    return total_loss / len(dataloader), total_acc / len(dataloader)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:37:12.387951Z","iopub.execute_input":"2022-07-02T00:37:12.388337Z","iopub.status.idle":"2022-07-02T00:37:12.398659Z","shell.execute_reply.started":"2022-07-02T00:37:12.388299Z","shell.execute_reply":"2022-07-02T00:37:12.397323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"EPOCHS = 3\ntrain_loss_history = []\nvalid_loss_history = []\n\ntrain_acc_history = []\nvalid_acc_history = []\n\nfor epoch in range(EPOCHS):\n    train_loss, train_acc = train(net, train_dataloader)\n    valid_loss, valid_acc = validate(net, valid_dataloader)\n    print(f\"Epoch: {epoch:2d}, training loss: {train_loss:.3f}, training acc: {train_acc:.3f} validation loss: {valid_loss:.3f}, validation acc: {valid_acc:.3f}\")\n\n    train_loss_history.append(train_loss)\n    valid_loss_history.append(valid_loss)\n\n    train_acc_history.append(train_acc)\n    valid_acc_history.append(valid_acc)\n\n    if valid_loss <= min(valid_loss_history):\n        torch.save(net.state_dict(), \"net.pt\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:37:53.155920Z","iopub.execute_input":"2022-07-02T00:37:53.156890Z","iopub.status.idle":"2022-07-02T00:45:49.094640Z","shell.execute_reply.started":"2022-07-02T00:37:53.156843Z","shell.execute_reply":"2022-07-02T00:45:49.093566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predict on Test Dataset and Submit to Kaggle","metadata":{}},{"cell_type":"code","source":"net = PretrainViT()\nnet.load_state_dict(torch.load(\"./net.pt\", map_location=\"cpu\"))\nnet.to(device)\nnet.eval()","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:18.785717Z","iopub.execute_input":"2022-07-02T00:46:18.786065Z","iopub.status.idle":"2022-07-02T00:46:20.566264Z","shell.execute_reply.started":"2022-07-02T00:46:18.786035Z","shell.execute_reply":"2022-07-02T00:46:20.565311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit_df = pd.read_csv(\"../input/dog-breed-identification/sample_submission.csv\")\ntest_names = submit_df[\"id\"].values\ncolumns = list(dataset.label_idx2name)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:28.744892Z","iopub.execute_input":"2022-07-02T00:46:28.745513Z","iopub.status.idle":"2022-07-02T00:46:29.492941Z","shell.execute_reply.started":"2022-07-02T00:46:28.745463Z","shell.execute_reply":"2022-07-02T00:46:29.491333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(Dataset):\n\n    def __init__(self, test_names, transform_fn):\n        self.test_names = test_names\n        self.transform = transform_fn\n    \n    def __len__(self):\n        return len(self.test_names)\n\n    def __getitem__(self, idx):\n        name = self.test_names[idx]\n        path = os.path.join(\"../input/dog-breed-identification/test\", name + \".jpg\")\n        img = Image.open(path)\n        img = self.transform(img)\n        return (img, name)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:38.999678Z","iopub.execute_input":"2022-07-02T00:46:39.000021Z","iopub.status.idle":"2022-07-02T00:46:39.007528Z","shell.execute_reply.started":"2022-07-02T00:46:38.999990Z","shell.execute_reply":"2022-07-02T00:46:39.006439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = TestDataset(\n    test_names = test_names,\n    transform_fn = vit_valid_transform_fn\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:40.185297Z","iopub.execute_input":"2022-07-02T00:46:40.185946Z","iopub.status.idle":"2022-07-02T00:46:40.191699Z","shell.execute_reply.started":"2022-07-02T00:46:40.185908Z","shell.execute_reply":"2022-07-02T00:46:40.189719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataloader = DataLoader(\n    dataset=dataset,\n    batch_size=64,\n    shuffle=False\n)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:41.041133Z","iopub.execute_input":"2022-07-02T00:46:41.041947Z","iopub.status.idle":"2022-07-02T00:46:41.047352Z","shell.execute_reply.started":"2022-07-02T00:46:41.041907Z","shell.execute_reply":"2022-07-02T00:46:41.045944Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n\n    dfs = []\n\n    for batch_idx, (batch_img, batch_name) in enumerate(test_dataloader):\n        df = pd.DataFrame(columns=[\"id\"] + columns)\n        df[\"id\"] = batch_name\n\n        batch_img = batch_img.to(device)\n        output = net(batch_img)\n        sm = F.softmax(output, dim=1)\n        df[columns] = sm.cpu().numpy()\n        dfs.append(df)\n\n        print(f\"step: {batch_idx}/{len(test_dataloader)}\")","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:46:49.853342Z","iopub.execute_input":"2022-07-02T00:46:49.853987Z","iopub.status.idle":"2022-07-02T00:50:27.963158Z","shell.execute_reply.started":"2022-07-02T00:46:49.853947Z","shell.execute_reply":"2022-07-02T00:50:27.962061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_submit = pd.concat(dfs)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:50:27.965251Z","iopub.execute_input":"2022-07-02T00:50:27.965848Z","iopub.status.idle":"2022-07-02T00:50:28.574546Z","shell.execute_reply.started":"2022-07-02T00:50:27.965808Z","shell.execute_reply":"2022-07-02T00:50:28.573551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_submit","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:50:28.575965Z","iopub.execute_input":"2022-07-02T00:50:28.576568Z","iopub.status.idle":"2022-07-02T00:50:28.620616Z","shell.execute_reply.started":"2022-07-02T00:50:28.576526Z","shell.execute_reply":"2022-07-02T00:50:28.619801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_submit.to_csv(\"submit.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-02T00:50:28.622698Z","iopub.execute_input":"2022-07-02T00:50:28.623090Z","iopub.status.idle":"2022-07-02T00:50:30.231415Z","shell.execute_reply.started":"2022-07-02T00:50:28.623048Z","shell.execute_reply":"2022-07-02T00:50:30.230438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}