{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Imports","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset\nfrom torchvision import datasets\nfrom torchvision.transforms import ToTensor , Lambda\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nfrom torch.utils.data import SubsetRandomSampler\nfrom torch.utils.data import SubsetRandomSampler\nfrom sklearn.model_selection import train_test_split\nfrom torchvision import models\nimport matplotlib.pyplot as plt\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nimport time\nfrom tempfile import TemporaryDirectory\nimport torch.utils\nimport git\nimport sys\nimport datetime","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:15:52.533891Z","iopub.execute_input":"2023-12-19T19:15:52.534746Z","iopub.status.idle":"2023-12-19T19:15:59.391671Z","shell.execute_reply.started":"2023-12-19T19:15:52.534711Z","shell.execute_reply":"2023-12-19T19:15:59.390719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Clone classification utils from pytorch vision and add to system**","metadata":{}},{"cell_type":"code","source":"git.Repo.clone_from('https://github.com/pytorch/vision.git', '/kaggle/working/extra')","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:15:59.393399Z","iopub.execute_input":"2023-12-19T19:15:59.393913Z","iopub.status.idle":"2023-12-19T19:17:15.136376Z","shell.execute_reply.started":"2023-12-19T19:15:59.393863Z","shell.execute_reply":"2023-12-19T19:17:15.135387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp /kaggle/working/extra/references/classification/utils.py /kaggle/working/\nimport utils","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:15.137650Z","iopub.execute_input":"2023-12-19T19:17:15.137975Z","iopub.status.idle":"2023-12-19T19:17:16.096856Z","shell.execute_reply.started":"2023-12-19T19:17:15.137948Z","shell.execute_reply":"2023-12-19T19:17:16.095644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntest_df = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\nprint(train_df.shape , test_df.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:16.099262Z","iopub.execute_input":"2023-12-19T19:17:16.099563Z","iopub.status.idle":"2023-12-19T19:17:21.457826Z","shell.execute_reply.started":"2023-12-19T19:17:16.099537Z","shell.execute_reply":"2023-12-19T19:17:21.456926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomMNISTDataset(Dataset):\n    def __init__(self, csv_name, img_dir, transform=None, target_transform=None , label_name = \"label\"):\n        \n        self.img_filename = csv_name\n        self.img_dir = img_dir\n        self.transform = transform\n        self.target_transform = target_transform\n        self.label_name = label_name\n        \n        img_path = os.path.join(self.img_dir, self.img_filename)\n        self.img_df = pd.read_csv(img_path)\n\n    def __len__(self):\n        return len(self.img_df)\n\n    def __getitem__(self, idx):\n        \n        # Extracting all the other columns except label_name\n        img_cols = [ i for i in self.img_df.columns if i not in self.label_name]\n        \n        image = self.img_df.iloc[[idx]][img_cols].values\n\n        # Reshaping the array from 1*784 to 28*28\n        image = image.reshape(28,28)\n        \n        image = np.expand_dims(image, -1)\n        image = image.repeat(3, axis=-1)\n\n        # Scaling the image so that the values only range between 0 and 1\n        image = image/255.0\n        \n        if self.transform:\n            image = self.transform(image)\n    \n        image = image.to(torch.float)    \n        \n        if self.label_name in self.img_df.columns:\n            \n            if self.target_transform:\n                label = self.target_transform(label)\n            label = int(self.img_df.iloc[[idx]][self.label_name].values)\n            return image, label\n        \n        # Exceptions for test where labels are absent\n        else :\n            return image","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:21.459155Z","iopub.execute_input":"2023-12-19T19:17:21.459590Z","iopub.status.idle":"2023-12-19T19:17:21.470993Z","shell.execute_reply.started":"2023-12-19T19:17:21.459550Z","shell.execute_reply":"2023-12-19T19:17:21.470017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nindices = list(range(len(train_df)))\n\ntrain_indices , test_indices = train_test_split(indices, test_size=0.1, stratify=train_df['label'])\n\nlen(train_indices) , len(test_indices) , len(train_df)\n\ntrain_subset = train_df.loc[train_indices]\nval_subset = train_df.loc[test_indices]","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:21.472467Z","iopub.execute_input":"2023-12-19T19:17:21.472809Z","iopub.status.idle":"2023-12-19T19:17:21.728221Z","shell.execute_reply.started":"2023-12-19T19:17:21.472769Z","shell.execute_reply":"2023-12-19T19:17:21.727066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Crerating a temp dataset\ntrain_csv_name = \"train.csv\"\ntest_csv_name = \"test.csv\"\nimg_dir = \"/kaggle/input/digit-recognizer/\"\n\n# Converting X variables to Tensors\n# transforms = transforms.Compose( [transforms.ToTensor(), transforms.Grayscale(num_output_channels=3), transforms.Normalize((0.5,), (0.5,)), ] )\ntransforms = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,)), ] )\n\nlabel_name = \"label\"\n\ntrain_dataset = CustomMNISTDataset(csv_name = train_csv_name , img_dir = img_dir , transform = transforms , target_transform = None , label_name = label_name)\n\n# Inspecting the fist line item under dataset\nx0 , y0 = train_dataset[3]\nprint(x0.shape , y0)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:21.729847Z","iopub.execute_input":"2023-12-19T19:17:21.730168Z","iopub.status.idle":"2023-12-19T19:17:24.296585Z","shell.execute_reply.started":"2023-12-19T19:17:21.730143Z","shell.execute_reply":"2023-12-19T19:17:24.295561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## Checking if the GPU is being used properly . \n\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nprint('Using device:', device)\ntorch.cuda.is_available()\nx0 = x0.to(device)\nprint(\"x0\" , x0.is_cuda)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:24.297674Z","iopub.execute_input":"2023-12-19T19:17:24.297968Z","iopub.status.idle":"2023-12-19T19:17:29.021606Z","shell.execute_reply.started":"2023-12-19T19:17:24.297945Z","shell.execute_reply":"2023-12-19T19:17:29.020486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"indices = list(range(len(train_df)))\nprint(len(indices))\ntrain_indices , valid_indices = train_test_split(indices, test_size=0.1, stratify=train_df['label'])\n\n# Creating PT data samplers and loaders:\ntrain_sampler = SubsetRandomSampler(train_indices)\nvalid_sampler = SubsetRandomSampler(valid_indices)\n\ntrain_dataloader = torch.utils.data.DataLoader(train_dataset , batch_size=64, sampler=train_sampler, num_workers=4)\nvalid_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=64, sampler=valid_sampler, num_workers=4)\n\nx0 , y0 = next(iter(train_dataloader))\nx0.shape , y0.shape\n\nclasses = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9')","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:29.023122Z","iopub.execute_input":"2023-12-19T19:17:29.023988Z","iopub.status.idle":"2023-12-19T19:17:29.639635Z","shell.execute_reply.started":"2023-12-19T19:17:29.023948Z","shell.execute_reply":"2023-12-19T19:17:29.638394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_one_epoch(model, criterion, optimizer, data_loader, device, epoch, print_freq, apex=False):\n    model.train()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    metric_logger.add_meter('lr', utils.SmoothedValue(window_size=1, fmt='{value}'))\n    metric_logger.add_meter('img/s', utils.SmoothedValue(window_size=10, fmt='{value}'))\n\n    header = 'Epoch: [{}]'.format(epoch)\n    for image, target in metric_logger.log_every(data_loader, print_freq, header):\n        start_time = time.time()\n        image, target = image.to(device), target.to(device)\n        output = model(image)\n        loss = criterion(output, target)\n\n        optimizer.zero_grad()\n        if apex:\n            with amp.scale_loss(loss, optimizer) as scaled_loss:\n                scaled_loss.backward()\n        else:\n            loss.backward()\n        optimizer.step()\n\n        acc1, acc5 = utils.accuracy(output, target, topk=(1, 5))\n        batch_size = image.shape[0]\n        metric_logger.update(loss=loss.item(), lr=optimizer.param_groups[0][\"lr\"])\n        metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n        metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n        metric_logger.meters['img/s'].update(batch_size / (time.time() - start_time))","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:29.643055Z","iopub.execute_input":"2023-12-19T19:17:29.643370Z","iopub.status.idle":"2023-12-19T19:17:29.653797Z","shell.execute_reply.started":"2023-12-19T19:17:29.643343Z","shell.execute_reply":"2023-12-19T19:17:29.652874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def evaluate(model, criterion, data_loader, device, print_freq=100):\n    model.eval()\n    metric_logger = utils.MetricLogger(delimiter=\"  \")\n    header = 'Test:'\n    with torch.no_grad():\n        for image, target in metric_logger.log_every(data_loader, print_freq, header):\n            image = image.to(device, non_blocking=True)\n            target = target.to(device, non_blocking=True)\n            output = model(image)\n            loss = criterion(output, target)\n\n            acc1, acc5 = utils.accuracy(output, target, topk=(1, 5))\n            # FIXME need to take into account that the datasets\n            # could have been padded in distributed setup\n            batch_size = image.shape[0]\n            metric_logger.update(loss=loss.item())\n            metric_logger.meters['acc1'].update(acc1.item(), n=batch_size)\n            metric_logger.meters['acc5'].update(acc5.item(), n=batch_size)\n    # gather the stats from all processes\n    metric_logger.synchronize_between_processes()\n\n    print(' * Acc@1 {top1.global_avg:.3f} Acc@5 {top5.global_avg:.3f}'\n          .format(top1=metric_logger.acc1, top5=metric_logger.acc5))\n    return metric_logger.acc1.global_avg","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:29.655076Z","iopub.execute_input":"2023-12-19T19:17:29.655663Z","iopub.status.idle":"2023-12-19T19:17:29.670821Z","shell.execute_reply.started":"2023-12-19T19:17:29.655630Z","shell.execute_reply":"2023-12-19T19:17:29.670035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _get_cache_path(filepath):\n    import hashlib\n    h = hashlib.sha1(filepath.encode()).hexdigest()\n    cache_path = os.path.join(\"~\", \".torch\", \"vision\", \"datasets\", \"imagefolder\", h[:10] + \".pt\")\n    cache_path = os.path.expanduser(cache_path)\n    return cache_path","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:29.671976Z","iopub.execute_input":"2023-12-19T19:17:29.672237Z","iopub.status.idle":"2023-12-19T19:17:29.685602Z","shell.execute_reply.started":"2023-12-19T19:17:29.672214Z","shell.execute_reply":"2023-12-19T19:17:29.684693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.resnet50(pretrained=True)\nnum_ftrs = model.fc.in_features\n# Here the size of each output sample is set to 2.\n# Alternatively, it can be generalized to ``nn.Linear(num_ftrs, len(class_names))``.\nmodel.fc = nn.Linear(num_ftrs, len(classes))\n\nmodel = model.to(device)\n\ncriterion = nn.CrossEntropyLoss()\n\n# Observe that all parameters are being optimized\noptimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n\n# Decay LR by a factor of 0.1 every 7 epochs\nexp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:29.686536Z","iopub.execute_input":"2023-12-19T19:17:29.687092Z","iopub.status.idle":"2023-12-19T19:17:30.879454Z","shell.execute_reply.started":"2023-12-19T19:17:29.687066Z","shell.execute_reply":"2023-12-19T19:17:30.878187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"    output_dir = 'outputs'\n    utils.mkdir(output_dir)\n    start_epoch = 0 \n    epochs = 10\n    print(\"Start training\")\n    start_time = time.time()\n    for epoch in range(start_epoch, epochs):\n        train_one_epoch(model, criterion, optimizer, train_dataloader, device, epoch, 300)\n#         lr_scheduler.step()\n        evaluate(model, criterion, valid_dataloader, device=device)\n        if output_dir:\n            checkpoint = {\n                'model': model.state_dict(),\n                'optimizer': optimizer.state_dict(),\n#                 'lr_scheduler': lr_scheduler.state_dict(),\n#                 'lr_scheduler': lr_scheduler,\n                'epoch': epoch}\n            utils.save_on_master(\n                checkpoint,\n                os.path.join(output_dir, 'model_{}.pth'.format(epoch)))\n            utils.save_on_master(\n                checkpoint,\n                os.path.join(output_dir, 'checkpoint.pth'))\n\n    total_time = time.time() - start_time\n    total_time_str = str(datetime.timedelta(seconds=int(total_time)))\n    print('Training time {}'.format(total_time_str))","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:17:30.880898Z","iopub.execute_input":"2023-12-19T19:17:30.881380Z","iopub.status.idle":"2023-12-19T19:23:29.474144Z","shell.execute_reply.started":"2023-12-19T19:17:30.881344Z","shell.execute_reply":"2023-12-19T19:23:29.473030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision.transforms as transforms\ntest_csv_name = \"test.csv\"\nimg_dir = \"/kaggle/input/digit-recognizer/\"\n\n# Converting X variables to Tensors\ntransforms = transforms.Compose( [transforms.ToTensor() , transforms.Normalize((0.5,), (0.5,)) , ] )\nlabel_name = \"label\"\n\ntest_dataset = CustomMNISTDataset(csv_name = test_csv_name , img_dir = img_dir , transform = transforms , target_transform = None , label_name = label_name)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:23:29.475701Z","iopub.execute_input":"2023-12-19T19:23:29.476109Z","iopub.status.idle":"2023-12-19T19:23:31.197627Z","shell.execute_reply.started":"2023-12-19T19:23:29.476078Z","shell.execute_reply":"2023-12-19T19:23:31.196603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = test_dataset[100]\nprint(x.shape)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:23:31.199092Z","iopub.execute_input":"2023-12-19T19:23:31.199482Z","iopub.status.idle":"2023-12-19T19:23:31.208655Z","shell.execute_reply.started":"2023-12-19T19:23:31.199447Z","shell.execute_reply":"2023-12-19T19:23:31.207696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probas = []\npredictions = []\nwith torch.no_grad():\n    for i in range(len(test_dataset)):\n        image = test_dataset[i].to(device)\n        output = model(image.unsqueeze(0))\n        probas.append(output)\n        predictions.append(output.argmax(1).item())\n        torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:23:31.209792Z","iopub.execute_input":"2023-12-19T19:23:31.210446Z","iopub.status.idle":"2023-12-19T19:27:52.690354Z","shell.execute_reply.started":"2023-12-19T19:23:31.210413Z","shell.execute_reply":"2023-12-19T19:27:52.689180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv(\"/kaggle/input/digit-recognizer/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:27:52.692098Z","iopub.execute_input":"2023-12-19T19:27:52.692475Z","iopub.status.idle":"2023-12-19T19:27:52.731448Z","shell.execute_reply.started":"2023-12-19T19:27:52.692441Z","shell.execute_reply":"2023-12-19T19:27:52.730620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Saving the dataframe for submission\ndf = pd.DataFrame({'ImageId':range(1,len(predictions)+1),'Label':predictions})\ndf.to_csv(\"submission.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2023-12-19T19:27:52.732515Z","iopub.execute_input":"2023-12-19T19:27:52.732762Z","iopub.status.idle":"2023-12-19T19:27:52.804530Z","shell.execute_reply.started":"2023-12-19T19:27:52.732740Z","shell.execute_reply":"2023-12-19T19:27:52.803870Z"},"trusted":true},"execution_count":null,"outputs":[]}]}