From 4004af12271915d1049dfc3e2beaf2daae3ca972 Mon Sep 17 00:00:00 2001 From: Shreyas Joshi Date: Sun, 12 Jun 2022 23:45:54 +0530 Subject: [PATCH] commit --- ED20B060.ipynb | 866 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 866 insertions(+) create mode 100644 ED20B060.ipynb diff --git a/ED20B060.ipynb b/ED20B060.ipynb new file mode 100644 index 0000000..116e77b --- /dev/null +++ b/ED20B060.ipynb @@ -0,0 +1,866 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "ED20B060.ipynb", + "provenance": [], + "collapsed_sections": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "accelerator": "GPU" + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Imports" + ], + "metadata": { + "id": "D_uk0N0CuCJu" + } + }, + { + "cell_type": "code", + "source": [ + "from IPython.display import clear_output\n", + "\n", + "!pip install pyprind\n", + "\n", + "clear_output()" + ], + "metadata": { + "id": "uJ72toZAuJv9" + }, + "execution_count": 1, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "from google.colab.patches import cv2_imshow\n", + "import cv2\n", + "from PIL import Image\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "import sklearn\n", + "from sklearn import preprocessing\n", + "from sklearn.model_selection import train_test_split\n", + "import numpy as np\n", + "import pandas as pd\n", + "import gzip\n", + "\n", + "import os\n", + "import glob\n", + "import time\n", + "import random\n", + "import gc\n", + "import json\n", + "import copy\n", + "import pyprind\n", + "import tqdm\n", + "from dataclasses import dataclass, field\n", + "from typing import Union, List, Dict, Any, Optional, cast\n", + "\n", + "import torch\n", + "import torchvision\n", + "import torchtext\n", + "\n", + "from torchvision import transforms\n", + "from torch.utils.data import DataLoader\n", + "import torch.nn as nn\n", + "import torch.nn.functional as F\n", + "import torch.optim as optim\n", + "from torchsummary import summary" + ], + "metadata": { + "id": "kJkjypzhuEsz" + }, + "execution_count": 2, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Data Processing" + ], + "metadata": { + "id": "6xdFH0S-tOe5" + } + }, + { + "cell_type": "code", + "source": [ + "# !wget" + ], + "metadata": { + "id": "OmqvhyWMV-7X" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "!gdown --id 1oYnD7Izl3LVVzjEMyLxLklX30TKWHgGG\n", + "!unzip /content/cifar-10.zip\n", + "!rm -rf /content/cifar-10.zip\n", + "!mv /content/cifar-10/sample_submission.csv /content/cifar-10/test_labels.csv\n", + "\n", + "clear_output()" + ], + "metadata": { + "id": "rk-72wvstOEd" + }, + "execution_count": 3, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "def process():\n", + " data = pd.read_csv(os.path.join('/content/cifar-10', 'train_labels.csv'))\n", + " encoder = preprocessing.LabelEncoder()\n", + " encoder.fit(data['label'])\n", + " return encoder\n", + "\n", + "encoder = process()" + ], + "metadata": { + "id": "My1DLmX6xUFw" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "data = pd.read_csv(os.path.join('/content/cifar-10', 'train_labels.csv'))\n", + "files = data['id']\n", + "labels = encoder.transform(data['label'])\n", + "\n", + "train_data_files, valid_data_files, train_data_label, valid_data_label = train_test_split(files, labels, test_size=0.1, shuffle=True, stratify=labels)\n", + "\n", + "train_data = pd.DataFrame({'id': train_data_files, 'label': train_data_label})\n", + "valid_data = pd.DataFrame({'id': valid_data_files, 'label': valid_data_label})\n", + "\n", + "unique, counts = np.unique(labels, return_counts=True)\n", + "weights = torch.Tensor(sklearn.utils.class_weight.compute_class_weight(class_weight=\"balanced\", classes=unique, y=np.asarray(labels)))" + ], + "metadata": { + "id": "ak2lfBubwugU" + }, + "execution_count": 5, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "data = pd.read_csv(os.path.join('/content/cifar-10', 'test_labels.csv'))\n", + "test_data_files = data['id']\n", + "test_data_label = encoder.transform(data['label'])\n", + "\n", + "test_data = pd.DataFrame({'id': test_data_files, 'label': test_data_label})" + ], + "metadata": { + "id": "fDWZKkfJwud6" + }, + "execution_count": 6, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Training Parameters" + ], + "metadata": { + "id": "B3HPjiIszKMb" + } + }, + { + "cell_type": "code", + "source": [ + "@dataclass\n", + "class TrainingArgs():\n", + "\n", + " seed: int = 17\n", + " lr: float = 3e-4\n", + " batch_size: int = 64\n", + " num_workers: int = os.cpu_count()\n", + " max_epochs: str = 10\n", + " device: torch.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "\n", + " img_size: int = 32\n", + "\n", + " root_dir: str = '/content/cifar-10'\n", + " train_file: dict = train_data\n", + " valid_file: dict = valid_data\n", + " test_file: dict = test_data\n", + " data: tuple = ()\n", + " checkpoint: str = '/content/'\n", + "\n", + " project_name: str = 'CIFAR10'\n", + "\n", + "args = TrainingArgs()" + ], + "metadata": { + "id": "AMo4bQJezJui" + }, + "execution_count": 7, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Data Loading" + ], + "metadata": { + "id": "0jKwtSnczNmN" + } + }, + { + "cell_type": "code", + "source": [ + "class CreateDataset(torch.utils.data.Dataset):\n", + " def __init__(self, args, mode='train'):\n", + " self.args = args\n", + " self.mode = mode\n", + "\n", + " if mode=='train':\n", + " self.entry = self.args.train_file\n", + " elif mode=='valid':\n", + " self.entry = self.args.valid_file\n", + " self.mode = 'train'\n", + " elif mode=='test':\n", + " self.entry = self.args.test_file \n", + "\n", + " self.transform = torchvision.transforms.Compose(\n", + " [\n", + " transforms.ToTensor(),\n", + " transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n", + " ]\n", + " )\n", + "\n", + " def __getitem__(self, index):\n", + " data = self.entry.iloc[index]\n", + " file_name = os.path.join(self.args.root_dir, self.mode, str(data['id'])+'.png')\n", + " image = Image.open(file_name)\n", + " image = self.transform(image)\n", + " label = data['label']\n", + " return image, label\n", + "\n", + " def __len__(self):\n", + " return len(self.entry)" + ], + "metadata": { + "id": "UCGrSq1NttOq" + }, + "execution_count": 8, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": { + "id": "huC57aPyvpA_" + } + }, + { + "cell_type": "code", + "source": [ + "train_dataset = CreateDataset(args, mode='train')\n", + "valid_dataset = CreateDataset(args, mode='valid')\n", + "test_dataset = CreateDataset(args, mode='test')\n", + "\n", + "args.data = (train_dataset, valid_dataset, test_dataset)" + ], + "metadata": { + "id": "gyf8b7t0uRq5" + }, + "execution_count": 9, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "trainloader = DataLoader(train_dataset, batch_size=32, shuffle=True)\n", + "validloader = DataLoader(valid_dataset, batch_size=32, shuffle=False)\n", + "testloader = DataLoader(test_dataset, batch_size=32, shuffle=False)" + ], + "metadata": { + "id": "NH15A3gHuYeB" + }, + "execution_count": 10, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "---" + ], + "metadata": { + "id": "vdoUtdT8vta6" + } + }, + { + "cell_type": "code", + "source": [ + "data = next(iter(trainloader))" + ], + "metadata": { + "id": "H7QNEGjA1-PL" + }, + "execution_count": 11, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "data[0].shape, data[1].shape" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "w8XBPxmq1_66", + "outputId": "ddc67443-1cd1-4ac0-b5f9-0072e8704246" + }, + "execution_count": 12, + "outputs": [ + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "(torch.Size([32, 3, 32, 32]), torch.Size([32]))" + ] + }, + "metadata": {}, + "execution_count": 12 + } + ] + }, + { + "cell_type": "code", + "source": [ + "index = 0\n", + "\n", + "image = cv2.resize(data[0][index].permute(1, 2, 0).numpy()*255, (224, 224))\n", + "label = encoder.inverse_transform(data[1])[index]\n", + "\n", + "cv2_imshow(image)\n", + "print(label)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 258 + }, + "id": "k8JSTlRG1MNz", + "outputId": "8b14355b-3e15-406a-e556-c71e0387a365" + }, + "execution_count": 13, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "image/png": "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\n" + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "cat\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "Resnet 18" + ], + "metadata": { + "id": "npzpxkA_ksOO" + } + }, + { + "cell_type": "code", + "source": [ + "class block(nn.Module):\n", + " def __init__(self,in_channels,out_channels,identity_downsample = None,stride = 1):\n", + " super(block, self).__init__()\n", + " self.conv1 = nn. Conv2d(in_channels,out_channels,kernel_size=3,padding = 1,stride = stride)\n", + " self.bn1 = nn.BatchNorm2d(out_channels)\n", + " self.conv2 = nn. Conv2d(out_channels,out_channels,kernel_size=3,padding = 1,stride = 1)\n", + " self.bn2 = nn.BatchNorm2d(out_channels)\n", + " self.relu =nn.ReLU()\n", + " self.downsample = identity_downsample\n", + "\n", + " def forward(self,x):\n", + " identity = x\n", + " x = self.conv1(x)\n", + " x = self.bn1(x)\n", + " x = self.conv2(x)\n", + " x = self.bn2(x)\n", + " if self.downsample is not None:\n", + " identity = self.downsample(identity)\n", + " x += identity\n", + " x = self.relu(x)\n", + " return x\n", + "\n", + "class Res18(nn.Module):\n", + " def __init__(self,block,img_channels,args):\n", + " super(Res18, self).__init__()\n", + " self.args = args\n", + " self.conv1 = nn.Conv2d(img_channels,64,kernel_size=7,stride=1,padding=3)\n", + " self.bn1 = nn.BatchNorm2d(64)\n", + " self.relu = nn.ReLU()\n", + " self.maxpool = nn.MaxPool2d(kernel_size= 3,stride=1,padding =1)\n", + " self.in_channels = 64\n", + " self.layer1 = self._make_layer(block,64,1)\n", + " self.layer2 = self._make_layer(block,128,2)\n", + " self.layer3 = self._make_layer(block,256,2)\n", + " self.layer4 = self._make_layer(block,512,2)\n", + " self.avgpool = nn.AdaptiveAvgPool2d((1,1))\n", + " self.fc = nn.Linear(512,10)\n", + "\n", + " def _make_layer(self,block,out_channels,stride=1):\n", + " layers = []\n", + " identity_downsample = None\n", + " if (stride != 1) or (self.in_channels != out_channels):\n", + " identity_downsample = nn.Sequential(nn.Conv2d(self.in_channels,out_channels,kernel_size=1,stride=stride),nn.BatchNorm2d(out_channels))\n", + " layers.append(block(self.in_channels,out_channels,identity_downsample,stride))\n", + " self.in_channels = out_channels\n", + " layers.append(block(self.in_channels,out_channels))\n", + " return nn.Sequential(*layers)\n", + " def forward(self,x):\n", + " x = self.conv1(x)\n", + " x = self.bn1(x)\n", + " x = self.relu(x)\n", + " #print(x.shape)\n", + " x = self.maxpool(x)\n", + " x = self.layer1(x)\n", + " #print(x.shape)\n", + " x = self.layer2(x)\n", + " #print(x.shape)\n", + " x = self.layer3(x)\n", + " \n", + " x = self.layer4(x)\n", + " #print(x.shape)\n", + " x = self.avgpool(x)\n", + " x = torch.flatten(x,1)\n", + " #print(x.shape)\n", + " x = self.fc(x)\n", + " return x" + ], + "metadata": { + "id": "guAOA44DPn3A" + }, + "execution_count": 43, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Trainer" + ], + "metadata": { + "id": "jiPMx_3YG9tb" + } + }, + { + "cell_type": "code", + "source": [ + "class Trainer():\n", + " def __init__(self, args, architecture):\n", + "\n", + " self.args = args\n", + "\n", + " random.seed(self.args.seed)\n", + " np.random.seed(self.args.seed)\n", + " torch.manual_seed(self.args.seed)\n", + " torch.cuda.manual_seed(self.args.seed)\n", + " torch.cuda.manual_seed_all(self.args.seed)\n", + "\n", + " self.trainloader, self.validloader, self.testloader = self.get_iterator(self.args.data)\n", + " \n", + " self.model = architecture.to(self.args.device) # self.get_model()\n", + " self.criterion = self.get_criterion()\n", + " self.optimizer = self.get_optimizer()\n", + " self.scheduler = self.get_scheduler()\n", + "\n", + " self.train_loss = []\n", + " self.train_metrics = {'accuracy': []}\n", + " self.valid_loss = []\n", + " self.valid_metrics = {'accuracy': []}\n", + "\n", + " self.start_epoch = 0\n", + "\n", + " def get_iterator(self, data):\n", + " train, valid, test = data\n", + " trainloader = DataLoader(train, batch_size=self.args.batch_size, shuffle=True, num_workers=self.args.num_workers, pin_memory=True, drop_last=True)\n", + " validloader = DataLoader(valid, batch_size=self.args.batch_size, shuffle=False, num_workers=self.args.num_workers, pin_memory=True, drop_last=True)\n", + " testloader = DataLoader(test, batch_size=self.args.batch_size, shuffle=False, num_workers=self.args.num_workers, pin_memory=True, drop_last=False)\n", + " return trainloader, validloader, testloader\n", + "\n", + " def get_criterion(self):\n", + " return nn.CrossEntropyLoss(weight=weights).to(self.args.device)\n", + " \n", + " def get_optimizer(self):\n", + " return torch.optim.Adam(self.model.parameters(), lr=self.args.lr)\n", + "\n", + " def get_scheduler(self):\n", + " return torch.optim.lr_scheduler.CosineAnnealingLR(self.optimizer, self.args.max_epochs, eta_min=1e-12, last_epoch=-1, verbose=False)\n", + "\n", + " def get_model(self, architecture):\n", + " model = Convolutional_Network(args).to(self.args.device)\n", + " return model\n", + "\n", + " def get_model_params(self):\n", + " return sum(p.numel() for p in self.model.parameters())/1e6\n", + "\n", + " def get_accuracy(self, output, label):\n", + " return (torch.argmax(output, dim=1)==label).float().sum().item()\n", + "\n", + " def save(self, epoch):\n", + " torch.save({\n", + " 'model_state_dict': self.model.state_dict(),\n", + " 'optimizer_state_dict': self.optimizer.state_dict(),\n", + " }, os.path.join(self.args.checkpoint, \"model.pth\"))\n", + " torch.save({\n", + " 'epoch': epoch,\n", + " 'args': args,\n", + " 'loss': (self.train_loss, self.valid_loss),\n", + " 'metrics': (self.train_metrics, self.valid_metrics)\n", + " }, os.path.join(self.args.checkpoint, \"metrics.pth\"))\n", + " \n", + " def load(self):\n", + " if os.path.exists(os.path.join(self.args.checkpoint, \"model.pth\")):\n", + " checkpoints = torch.load(os.path.join(self.args.checkpoint, \"model.pth\"), map_location=self.args.device)\n", + " self.model.load_state_dict(checkpoints['model_state_dict'])\n", + " self.optimizer.load_state_dict(checkpoints['optimizer_state_dict'])\n", + "\n", + " if os.path.exists(os.path.join(self.args.checkpoint, \"metrics.pth\")):\n", + " checkpoints = torch.load(os.path.join(self.args.checkpoint, \"metrics.pth\"), map_location=self.args.device)\n", + " self.args = checkpoints['args']\n", + " self.train_loss, self.valid_loss = checkpoints['loss']\n", + " self.train_metrics, self.valid_metrics = checkpoints['metrics']\n", + " return checkpoints['epoch']\n", + " return 0\n", + "\n", + " def train(self):\n", + " epoch_loss = 0\n", + " epoch_metrics = {'accuracy': 0}\n", + "\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + " self.model.train()\n", + "\n", + " with torch.autograd.set_detect_anomaly(True):\n", + " bar = pyprind.ProgBar(len(self.trainloader), bar_char='█')\n", + " for index, (data, label) in enumerate(self.trainloader):\n", + " data = data.to(self.args.device).float()\n", + " label = label.long().to(self.args.device)\n", + "\n", + " self.optimizer.zero_grad()\n", + " \n", + " output = self.model(data)\n", + "\n", + " loss = self.criterion(output, label)\n", + "\n", + " loss.backward()\n", + "\n", + " self.optimizer.step()\n", + "\n", + " epoch_loss += loss.item()/len(self.trainloader)\n", + "\n", + " epoch_metrics['accuracy'] += self.get_accuracy(output, label)/len(self.args.data[0])\n", + "\n", + " bar.update()\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + "\n", + " return epoch_loss, epoch_metrics\n", + "\n", + " def evaluate(self):\n", + " epoch_loss = 0\n", + " epoch_metrics = {'accuracy': 0}\n", + "\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + " self.model.eval()\n", + "\n", + " with torch.autograd.set_detect_anomaly(True):\n", + " with torch.no_grad():\n", + " bar = pyprind.ProgBar(len(self.validloader), bar_char='█')\n", + " for index, (data, label) in enumerate(self.validloader):\n", + " data = data.to(self.args.device).float()\n", + " label = label.long().to(self.args.device)\n", + "\n", + " output = self.model(data)\n", + "\n", + " loss = self.criterion(output, label)\n", + "\n", + " epoch_loss += loss.item()/len(self.validloader)\n", + " epoch_metrics['accuracy'] += self.get_accuracy(output, label)/len(self.args.data[1])\n", + "\n", + " bar.update()\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + "\n", + " return epoch_loss, epoch_metrics\n", + "\n", + " def test(self):\n", + "\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + " self.model.eval()\n", + "\n", + " outputs = torch.empty([0,])\n", + "\n", + " with torch.autograd.set_detect_anomaly(True):\n", + " with torch.no_grad():\n", + " bar = pyprind.ProgBar(len(self.testloader), bar_char='█')\n", + " for index, (data, label) in enumerate(self.testloader):\n", + " data = data.to(self.args.device)\n", + "\n", + " output = torch.argmax(self.model(data)).detach().cpu()\n", + " outputs = torch.cat((outputs, output), dim=0)\n", + "\n", + " bar.update()\n", + " gc.collect()\n", + " torch.cuda.empty_cache()\n", + "\n", + " return outputs\n", + " \n", + " def fit(self, next=True):\n", + " if next:\n", + " self.start_epoch = self.load()\n", + "\n", + " for epoch in range(self.start_epoch+1, self.args.max_epochs+1, 1):\n", + "\n", + " epoch_train_loss, epoch_train_metrics = self.train()\n", + " epoch_train_accuracy = epoch_train_metrics['accuracy']\n", + "\n", + " self.train_loss.append(epoch_train_loss)\n", + " self.train_metrics['accuracy'].append(epoch_train_metrics['accuracy'])\n", + "\n", + " epoch_valid_loss, epoch_valid_metrics = self.evaluate()\n", + " epoch_valid_accuracy = epoch_valid_metrics['accuracy']\n", + "\n", + " \n", + " self.valid_loss.append(epoch_valid_loss)\n", + " self.valid_metrics['accuracy'].append(epoch_valid_metrics['accuracy']) \n", + "\n", + " self.scheduler.step()\n", + " for param_group in self.optimizer.param_groups:\n", + " self.args.lr = param_group['lr']\n", + " if epoch_valid_metrics['accuracy'] >= max(self.valid_metrics['accuracy']):\n", + " self.save(epoch)\n", + "\n", + " time.sleep(1)\n", + " print(f'Epoch {epoch}/{self.args.max_epochs} | Training: Loss = {round(epoch_train_loss, 4)} Accuracy = {round(epoch_train_accuracy, 4)} | Validation: Loss = {round(epoch_valid_loss, 4)} Accuracy = {round(epoch_valid_accuracy, 4)}')" + ], + "metadata": { + "id": "U9sm8odkGgMz" + }, + "execution_count": 20, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# Training" + ], + "metadata": { + "id": "jPrxVsc1IsX1" + } + }, + { + "cell_type": "code", + "source": [ + "models = {\n", + " 'Res18': Res18(block,3,args),\n", + "}" + ], + "metadata": { + "id": "BJjzEDsWLB83" + }, + "execution_count": 44, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "trainer = Trainer(args, architecture=models['Res18'])" + ], + "metadata": { + "id": "ka3HRNorHKhu" + }, + "execution_count": 45, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "trainer.fit()" + ], + "metadata": { + "id": "hp6TOW0iHcpt", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 831 + }, + "outputId": "59203c49-a579-43ff-beb8-51a8deb58fa8" + }, + "execution_count": 46, + "outputs": [ + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:15\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/10 | Training: Loss = 1.2649 Accuracy = 0.5425 | Validation: Loss = 1.0881 Accuracy = 0.6216\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:13\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 2/10 | Training: Loss = 0.8874 Accuracy = 0.688 | Validation: Loss = 0.9412 Accuracy = 0.6788\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:13\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 3/10 | Training: Loss = 0.7119 Accuracy = 0.7507 | Validation: Loss = 0.7386 Accuracy = 0.7424\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:13\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 4/10 | Training: Loss = 0.5802 Accuracy = 0.7994 | Validation: Loss = 0.6894 Accuracy = 0.7532\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:13\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 5/10 | Training: Loss = 0.4719 Accuracy = 0.8358 | Validation: Loss = 0.6563 Accuracy = 0.7788\n" + ] + }, + { + "output_type": "stream", + "name": "stderr", + "text": [ + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:02:13\n", + "0% [██████████████████████████████] 100% | ETA: 00:00:00\n", + "Total time elapsed: 00:00:07\n" + ] + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 6/10 | Training: Loss = 0.3484 Accuracy = 0.8783 | Validation: Loss = 0.6789 Accuracy = 0.7792\n" + ] + }, + { + "output_type": "error", + "ename": "KeyboardInterrupt", + "evalue": "ignored", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mtrainer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, next)\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mepoch\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstart_epoch\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmax_epochs\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 169\u001b[0;31m \u001b[0mepoch_train_loss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mepoch_train_metrics\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 170\u001b[0m \u001b[0mepoch_train_accuracy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mepoch_train_metrics\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'accuracy'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 171\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mtrain\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 92\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 94\u001b[0;31m \u001b[0moutput\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 95\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcriterion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0moutput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlabel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlayer3\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 59\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 60\u001b[0;31m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlayer4\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 61\u001b[0m \u001b[0;31m#print(x.shape)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mavgpool\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/container.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mmodule\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0minput\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, x)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbn2\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdownsample\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0midentity\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdownsample\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0midentity\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 19\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m+=\u001b[0m \u001b[0midentity\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0mx\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrelu\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/container.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mforward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 140\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mmodule\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0minput\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmodule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0minput\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, *input, **kwargs)\u001b[0m\n\u001b[1;32m 1108\u001b[0m if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks\n\u001b[1;32m 1109\u001b[0m or _global_forward_hooks or _global_forward_pre_hooks):\n\u001b[0;32m-> 1110\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mforward_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1111\u001b[0m \u001b[0;31m# Do not call functions when jit is used\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1112\u001b[0m \u001b[0mfull_backward_hooks\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnon_full_backward_hooks\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/modules/batchnorm.py\u001b[0m in \u001b[0;36mforward\u001b[0;34m(self, input)\u001b[0m\n\u001b[1;32m 177\u001b[0m \u001b[0mbn_training\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 178\u001b[0m \u001b[0mexponential_average_factor\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 179\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 180\u001b[0m )\n\u001b[1;32m 181\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/nn/functional.py\u001b[0m in \u001b[0;36mbatch_norm\u001b[0;34m(input, running_mean, running_var, weight, bias, training, momentum, eps)\u001b[0m\n\u001b[1;32m 2420\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2421\u001b[0m return torch.batch_norm(\n\u001b[0;32m-> 2422\u001b[0;31m \u001b[0minput\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mweight\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbias\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrunning_mean\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrunning_var\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtraining\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmomentum\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0meps\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackends\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcudnn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0menabled\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2423\u001b[0m )\n\u001b[1;32m 2424\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.7/traceback.py\u001b[0m in \u001b[0;36mformat_stack\u001b[0;34m(f, limit)\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 196\u001b[0m \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getframe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf_back\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 197\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mformat_list\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mextract_stack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlimit\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlimit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 198\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 199\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.7/traceback.py\u001b[0m in \u001b[0;36mextract_stack\u001b[0;34m(f, limit)\u001b[0m\n\u001b[1;32m 209\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 210\u001b[0m \u001b[0mf\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_getframe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mf_back\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 211\u001b[0;31m \u001b[0mstack\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mStackSummary\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextract\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mwalk_stack\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlimit\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlimit\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 212\u001b[0m \u001b[0mstack\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreverse\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 213\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mstack\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.7/traceback.py\u001b[0m in \u001b[0;36mextract\u001b[0;34m(klass, frame_gen, limit, lookup_lines, capture_locals)\u001b[0m\n\u001b[1;32m 357\u001b[0m filename, lineno, name, lookup_line=False, locals=f_locals))\n\u001b[1;32m 358\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mfilename\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfnames\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 359\u001b[0;31m \u001b[0mlinecache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheckcache\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 360\u001b[0m \u001b[0;31m# If immediate lookup was desired, trigger lookups now.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 361\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlookup_lines\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/IPython/core/compilerop.py\u001b[0m in \u001b[0;36mcheck_linecache_ipython\u001b[0;34m(*args)\u001b[0m\n\u001b[1;32m 139\u001b[0m \"\"\"\n\u001b[1;32m 140\u001b[0m \u001b[0;31m# First call the orignal checkcache as intended\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 141\u001b[0;31m \u001b[0mlinecache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_checkcache_ori\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 142\u001b[0m \u001b[0;31m# Then, update back the cache with our data, so that tracebacks related\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 143\u001b[0m \u001b[0;31m# to our compiled codes can be produced.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.7/linecache.py\u001b[0m in \u001b[0;36mcheckcache\u001b[0;34m(filename)\u001b[0m\n\u001b[1;32m 72\u001b[0m \u001b[0;32mcontinue\u001b[0m \u001b[0;31m# no-op for files loaded via a __loader__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 74\u001b[0;31m \u001b[0mstat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mos\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfullname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 75\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mOSError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0mcache\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfilename\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ] + } + ] +} \ No newline at end of file