{"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":"# 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 20GB 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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-08-18T22:43:41.401848Z","iopub.execute_input":"2022-08-18T22:43:41.402357Z","iopub.status.idle":"2022-08-18T22:43:41.417708Z","shell.execute_reply.started":"2022-08-18T22:43:41.402298Z","shell.execute_reply":"2022-08-18T22:43:41.415467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CIFAR-10 image classfication with CNN models\nfollowing https://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torchvision\nimport torch.optim as optim\nfrom torchvision import transforms, models\n\nimport copy\nimport time\nimport matplotlib.pyplot as plt","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:02:05.046435Z","iopub.execute_input":"2022-08-18T22:02:05.046854Z","iopub.status.idle":"2022-08-18T22:02:05.053275Z","shell.execute_reply.started":"2022-08-18T22:02:05.046817Z","shell.execute_reply":"2022-08-18T22:02:05.052140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Detect if we have a GPU available\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2022-08-18T21:51:07.303592Z","iopub.execute_input":"2022-08-18T21:51:07.304028Z","iopub.status.idle":"2022-08-18T21:51:07.310000Z","shell.execute_reply.started":"2022-08-18T21:51:07.303986Z","shell.execute_reply":"2022-08-18T21:51:07.308749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load CIFAR10\nChange the transform functions if want to use **data augmentation**, see for example:\nhttps://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html#load-data","metadata":{}},{"cell_type":"code","source":"# Set the transformations of the image\ntransform = transforms.Compose([\n                 transforms.ToTensor(), # Move from image array to pytorch tensor\n                 transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # Normalize the Images\n                 # transforms.Resize(224) # Resize the image to fit into pretrained models (use only for pretrained models)\n            ])\n\n\n# Load the train dataset\ntrainset = torchvision.datasets.CIFAR10(root='./data', train=True,\n                                        download=True, transform=transform)\n\n# Load the test dataset\ntestset = torchvision.datasets.CIFAR10(root='./data', train=False,\n                                       download=True, transform=transform)\n\nlabels = ['airplane', 'automobile', 'bird', 'cat',\n           'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n\nprint(f\"Number of training examples: {len(trainset)}\")\nprint(f\"Number of testing examples: {len(testset)}\")\nprint(f\"Shape of input tensor: {trainset[0][0].shape}\")","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:32:29.936167Z","iopub.execute_input":"2022-08-18T22:32:29.936769Z","iopub.status.idle":"2022-08-18T22:32:32.158121Z","shell.execute_reply.started":"2022-08-18T22:32:29.936729Z","shell.execute_reply":"2022-08-18T22:32:32.156674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize dataset (processed images with transforms)","metadata":{}},{"cell_type":"code","source":"# Let's view more images in a grid format\n# Define the dimensions of the plot grid \nW_grid = 5\nL_grid = 5\n\n# fig, axes = plt.subplots(L_grid, W_grid)\n# subplot return the figure object and axes object\n# we can use the axes object to plot specific figures at various locations\n\nfig, axes = plt.subplots(L_grid, W_grid, figsize = (17,17))\n\naxes = axes.ravel() # flaten the 15 x 15 matrix into 225 array\n\nn_train = len(trainset) # get the length of the train dataset\n\n# Select a random number from 0 to n_train\nfor i in np.arange(0, W_grid * L_grid): # create evenly spaces variables \n\n    # Select a random number\n    index = np.random.randint(0, n_train)\n    # read and display an image with the selected index    \n    image_tensor, label_index = trainset[index]\n    axes[i].imshow(image_tensor.permute(1,2,0))\n    axes[i].set_title(labels[label_index], fontsize = 20)\n    axes[i].axis('off')\n\nplt.subplots_adjust(hspace=0.4)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:32:35.176448Z","iopub.execute_input":"2022-08-18T22:32:35.176904Z","iopub.status.idle":"2022-08-18T22:32:37.373690Z","shell.execute_reply.started":"2022-08-18T22:32:35.176854Z","shell.execute_reply":"2022-08-18T22:32:37.372256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create a simple CNN model","metadata":{}},{"cell_type":"code","source":"class MyCNN(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.conv1 = nn.Conv2d(3, 6, 5)\n        self.pool = nn.MaxPool2d(2, 2)\n        self.conv2 = nn.Conv2d(6, 16, 5)\n        self.fc1 = nn.Linear(16 * 5 * 5, 120)\n        self.fc2 = nn.Linear(120, 84)\n        self.fc3 = nn.Linear(84, 10)\n\n    def forward(self, x):\n        x = self.pool(nn.functional.relu(self.conv1(x)))\n        x = self.pool(nn.functional.relu(self.conv2(x)))\n        x = torch.flatten(x, 1) # flatten all dimensions except batch\n        x = nn.functional.relu(self.fc1(x))\n        x = nn.functional.relu(self.fc2(x))\n        x = self.fc3(x)\n        return x\nmodel = MyCNN()\n\n# Print the model we just instantiated\nprint(model)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:40:07.050556Z","iopub.execute_input":"2022-08-18T22:40:07.050996Z","iopub.status.idle":"2022-08-18T22:40:07.066811Z","shell.execute_reply.started":"2022-08-18T22:40:07.050960Z","shell.execute_reply":"2022-08-18T22:40:07.065486Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load pretrained CNN models ","metadata":{}},{"cell_type":"code","source":"##https://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html\ndef set_parameter_requires_grad(model, feature_extracting):\n    \"\"\"\n    Whether to freeze the model params \n    \"\"\"\n    if feature_extracting:\n        for param in model.parameters():\n            param.requires_grad = False\ndef initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):\n    # Initialize these variables which will be set in this if statement. Each of these\n    #   variables is model specific.\n    model_ft = None\n    input_size = 0\n\n    if model_name == \"resnet\":\n        \"\"\" Resnet18\n        \"\"\"\n        model_ft = models.resnet18(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n\n    elif model_name == \"alexnet\":\n        \"\"\" Alexnet\n        \"\"\"\n        model_ft = models.alexnet(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier[6].in_features\n        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)\n        input_size = 224\n\n    elif model_name == \"vgg\":\n        \"\"\" VGG11_bn\n        \"\"\"\n        model_ft = models.vgg11_bn(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier[6].in_features\n        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)\n        input_size = 224\n\n    elif model_name == \"squeezenet\":\n        \"\"\" Squeezenet\n        \"\"\"\n        model_ft = models.squeezenet1_0(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        model_ft.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))\n        model_ft.num_classes = num_classes\n        input_size = 224\n\n    elif model_name == \"densenet\":\n        \"\"\" Densenet\n        \"\"\"\n        model_ft = models.densenet121(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier.in_features\n        model_ft.classifier = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n\n    elif model_name == \"inception\":\n        \"\"\" Inception v3\n        Be careful, expects (299,299) sized images and has auxiliary output\n        \"\"\"\n        model_ft = models.inception_v3(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        # Handle the auxilary net\n        num_ftrs = model_ft.AuxLogits.fc.in_features\n        model_ft.AuxLogits.fc = nn.Linear(num_ftrs, num_classes)\n        # Handle the primary net\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs,num_classes)\n        input_size = 299\n\n    else:\n        print(\"Invalid model name, exiting...\")\n        exit()\n\n    return model_ft, input_size","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:33:34.465897Z","iopub.execute_input":"2022-08-18T22:33:34.466467Z","iopub.status.idle":"2022-08-18T22:33:34.485305Z","shell.execute_reply.started":"2022-08-18T22:33:34.466420Z","shell.execute_reply":"2022-08-18T22:33:34.484150Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Uncomment this section to use pretrained models\n**(uncomment the line transforms.Resize(224) in the transform functions above (in the data download) if use pretrained models from Imagenet)**","metadata":{}},{"cell_type":"code","source":"# model_name = 'alexnet'\n# num_classes = len(labels)\n# use_pretrained = True\n# freeze_pretrained_weights = True\n# if use_pretrained == False:\n#     assert freeze_pretrained_weights == False, 'Only freeze weights if use pretrained model.'\n\n# # Initialize the model for this run\n# model, input_size = initialize_model(model_name, num_classes, freeze_pretrained_weights, use_pretrained=use_pretrained)\n\n# # Print the model we just instantiated\n# print(model)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:10:23.913734Z","iopub.execute_input":"2022-08-18T22:10:23.917232Z","iopub.status.idle":"2022-08-18T22:10:35.945306Z","shell.execute_reply.started":"2022-08-18T22:10:23.917180Z","shell.execute_reply":"2022-08-18T22:10:35.943885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define training function","metadata":{}},{"cell_type":"code","source":"# based on https://pytorch.org/tutorials/beginner/finetuning_torchvision_models_tutorial.html\ndef train_model(model, dataloaders, criterion, optimizer, num_epochs=25, is_inception=False):\n    since = time.time()\n\n    training_history = {\n        'train': {\n            'loss': [],\n            'acc': [],\n        },\n        'val': {\n            'loss': [],\n            'acc': [],\n        },\n    }\n\n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_acc = 0.0\n\n    for epoch in range(num_epochs):\n        print('Epoch {}/{}'.format(epoch, num_epochs - 1))\n        print('-' * 10)\n\n        # Each epoch has a training and validation phase\n        for phase in ['train', 'val']:\n            if phase == 'train':\n                model.train()  # Set model to training mode\n            else:\n                model.eval()   # Set model to evaluate mode\n\n            running_loss = 0.0\n            running_corrects = 0\n            num_batches = len(dataloaders[phase])\n            start_time = time.time()\n\n            # Iterate over data.\n            for i, (inputs, labels) in enumerate(dataloaders[phase]):\n                inputs = inputs.to(device)\n                labels = labels.to(device)\n\n                # zero the parameter gradients\n                optimizer.zero_grad()\n\n                # forward\n                # track history if only in train\n                with torch.set_grad_enabled(phase == 'train'):\n                    # Get model outputs and calculate loss\n                    # Special case for inception because in training it has an auxiliary output. In train\n                    #   mode we calculate the loss by summing the final output and the auxiliary output\n                    #   but in testing we only consider the final output.\n                    if is_inception and phase == 'train':\n                        # From https://discuss.pytorch.org/t/how-to-optimize-inception-model-with-auxiliary-classifiers/7958\n                        outputs, aux_outputs = model(inputs)\n                        loss1 = criterion(outputs, labels)\n                        loss2 = criterion(aux_outputs, labels)\n                        loss = loss1 + 0.4*loss2\n                    else:\n                        outputs = model(inputs)\n                        loss = criterion(outputs, labels)\n\n                    _, preds = torch.max(outputs, 1)\n\n                    # backward + optimize only if in training phase\n                    if phase == 'train':\n                        loss.backward()\n                        optimizer.step()\n\n                # statistics\n                batch_loss = loss.item()\n                batch_corrects = torch.sum(preds == labels.data)\n                running_loss += batch_loss * inputs.size(0)\n                running_corrects += batch_corrects\n                \n                # Print statistics\n                if phase == 'train':\n                    print('Batch {:d}/{:d} - Loss: {:.4f} Acc: {:.4f} - Run Time : {:.2f}s'.format(i+1, num_batches,\n                             batch_loss, float(batch_corrects)/len(labels), time.time() - start_time),end='\\r')\n\n            epoch_loss = running_loss / len(dataloaders[phase].dataset)\n            epoch_acc = running_corrects.double() / len(dataloaders[phase].dataset)\n\n            print('\\n{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))\n            training_history[phase]['loss'].append(epoch_loss)\n            training_history[phase]['acc'].append(epoch_acc)\n\n            # deep copy the model\n            if phase == 'val' and epoch_acc > best_acc:\n                best_acc = epoch_acc\n                best_model_wts = copy.deepcopy(model.state_dict())\n\n        print()\n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))\n    print('Best val Acc: {:4f}'.format(best_acc))\n\n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    return model, training_history","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:38:25.274917Z","iopub.execute_input":"2022-08-18T22:38:25.276036Z","iopub.status.idle":"2022-08-18T22:38:25.296637Z","shell.execute_reply.started":"2022-08-18T22:38:25.275990Z","shell.execute_reply":"2022-08-18T22:38:25.294953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create optimizer (re-run everytime define a new model)","metadata":{}},{"cell_type":"code","source":"# Send the model to GPU\nmodel = model.to(device)\n\n# Gather the parameters to be optimized/updated in this run. If we are\n#  finetuning we will be updating all parameters. However, if we are\n#  doing feature extract method, we will only update the parameters\n#  that we have just initialized, i.e. the parameters with requires_grad\n#  is True.\nparams_to_update = model.parameters()\nprint(\"Params to learn:\")\nif freeze_pretrained_weights:\n    params_to_update = []\n    for name,param in model.named_parameters():\n        if param.requires_grad == True:\n            params_to_update.append(param)\n            print(\"\\t\",name)\nelse:\n    for name,param in model.named_parameters():\n        if param.requires_grad == True:\n            print(\"\\t\",name)\n\n# Observe that all parameters are being optimized\noptimizer_ft = optim.SGD(params_to_update, lr=0.001, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:40:13.363893Z","iopub.execute_input":"2022-08-18T22:40:13.365064Z","iopub.status.idle":"2022-08-18T22:40:13.378066Z","shell.execute_reply.started":"2022-08-18T22:40:13.365014Z","shell.execute_reply":"2022-08-18T22:40:13.376349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train the model","metadata":{}},{"cell_type":"code","source":"# Define the batch size and the dataloaders\nbatch_size = 128\ntrainloader = torch.utils.data.DataLoader(trainset, batch_size=batch_size,\n                                          shuffle=True, num_workers=2)\n\ntestloader = torch.utils.data.DataLoader(testset, batch_size=batch_size,\n                                         shuffle=False, num_workers=2)\n\ndataloaders_dict = {'train': trainloader, 'val': testloader}\n","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:40:16.309745Z","iopub.execute_input":"2022-08-18T22:40:16.310281Z","iopub.status.idle":"2022-08-18T22:40:16.325372Z","shell.execute_reply.started":"2022-08-18T22:40:16.310220Z","shell.execute_reply":"2022-08-18T22:40:16.322655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Setup the loss fxn\ncriterion = nn.CrossEntropyLoss()\n\n# Set the number of epochs\nnum_epochs = 5\n\n# Train and evaluate\nmodel, statistics_history = train_model(model, dataloaders_dict, criterion, optimizer_ft, num_epochs=num_epochs, is_inception=(model_name==\"inception\"))","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:40:18.009524Z","iopub.execute_input":"2022-08-18T22:40:18.010743Z","iopub.status.idle":"2022-08-18T22:41:28.028324Z","shell.execute_reply.started":"2022-08-18T22:40:18.010666Z","shell.execute_reply":"2022-08-18T22:41:28.026649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Plot the train and valid loss & accuracy\nfig = plt.figure(figsize=(15,5))\nsubfig = fig.add_subplot(122)\nsubfig.plot(statistics_history['train']['acc'], label=\"training\")\nsubfig.plot(statistics_history['val']['acc'], label=\"validation\")\nsubfig.set_title('Model Accuracy')\nsubfig.set_xlabel('Epoch')\nsubfig.legend(loc='upper left')\nsubfig = fig.add_subplot(121)\nsubfig.plot(statistics_history['train']['loss'], label=\"training\")\nsubfig.plot(statistics_history['val']['loss'], label=\"validation\")\nsubfig.set_title('Model Loss')\nsubfig.set_xlabel('Epoch')\nsubfig.legend(loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:41:38.180737Z","iopub.execute_input":"2022-08-18T22:41:38.182070Z","iopub.status.idle":"2022-08-18T22:41:38.531950Z","shell.execute_reply.started":"2022-08-18T22:41:38.182015Z","shell.execute_reply":"2022-08-18T22:41:38.530349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submit to kaggle\nfollowing https://www.kaggle.com/code/nataliakhol/cifar10-transfer-learning","metadata":{}},{"cell_type":"code","source":"!pip install py7zr","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:45:38.674212Z","iopub.execute_input":"2022-08-18T22:45:38.674649Z","iopub.status.idle":"2022-08-18T22:45:56.399663Z","shell.execute_reply.started":"2022-08-18T22:45:38.674616Z","shell.execute_reply":"2022-08-18T22:45:56.398488Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Unpack the test dataset\n###\nfrom py7zr import unpack_7zarchive\nimport shutil\nshutil.register_unpack_format('7zip', ['.7z'], unpack_7zarchive)\nshutil.unpack_archive('/kaggle/input/cifar-10/test.7z','/kaggle/temp/test')\nshutil.unregister_unpack_format('7zip')","metadata":{"execution":{"iopub.status.busy":"2022-08-18T22:47:01.458551Z","iopub.execute_input":"2022-08-18T22:47:01.459632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"############################# CUSTOM DATASET CLASS #############################\n\nclass CifarLoader(Dataset):\n    def __init__(self, root_dir, csv_file = None, transform = None):\n\n        # images directory \n        self.root_dir = root_dir\n        # transformations if any\n        self.transform = transform\n\n        if csv_file:\n            # read csv file\n            self.df = pd.read_csv(csv_file)\n\n            # {class: lbl}\n            self.annot_dict = {}\n\n            for i, lbl in enumerate(self.df['label'].unique()):\n            self.annot_dict[lbl] = i\n\n            # {lbl: class}\n            self.annot_dict_reversed = {v:k for k,v in self.annot_dict.items()}\n\n            # add a column with decoded labels\n            self.df['encoded'] = self.df['label'].map(self.annot_dict)\n\n        else: \n            # if no csv file provided -> create a df, fill labels with 0's\n            self.df = pd.DataFrame({\n              'id': list(range(1, len(os.listdir(self.root_dir)) + 1)),\n              'label': np.zeros(len(os.listdir(self.root_dir))),\n              'encoded': np.zeros(len(os.listdir(self.root_dir)))\n            })\n\n\n    def __len__(self):\n        # num of records in the df\n        return len(self.df)\n\n    def __getitem__(self, index):\n        # path to the image\n        img_path = os.path.join(self.root_dir, str(self.df.iloc[index, 0]) + '.png')\n        # read image\n        image = np.array(Image.open(img_path).convert('RGB'))\n        # get label\n        y_label = torch.tensor(int(self.df.iloc[index, 2]))\n\n        # apply transformations\n        if self.transform:\n            image = self.transform(image)\n\n        return (image, y_label)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_test_kaggle = CifarLoader(root_dir = './test',\n                      transform = transform)\n\ndataloader_test_kaggle = torch.utils.data.DataLoader(dataset = dataset_test_kaggle, \n                             batch_size = batch_size, shuffle=False)\n\nprint(f\"Kaggle Test Set Size: {len(dataset_test_kaggle)}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"################################### PREDICT ####################################\n\npredictions = np.array([])\n\nwith torch.no_grad():\n    model.eval()\n\n    for images, _ in dataloader_test_kaggle:\n        images = images.to(device)\n\n        outputs = model(images)\n\n        # value, index\n        v, pred = torch.max(outputs, 1)\n\n        pred = pred.cpu().numpy()\n\n        predictions = np.concatenate((predictions, pred), axis = None)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_test_kaggle.df['encoded'] = predictions.astype(int)\ndataset_test_kaggle.df['label'] = dataset_test.df['encoded'].map(dataset.annot_dict_reversed)\ndataset_test_kaggle.df.head()\ndataset_test_kaggle.df.drop(columns ='encoded', inplace=True)\ndataset_test_kaggle.df.to_csv('submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]}]}