{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"###Importing the necessary libraries###\nimport numpy as np\nimport random\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport os\nimport torch\nfrom torchvision import models, datasets, transforms\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.optim import lr_scheduler\nimport time\nimport copy\nimport glob\nfrom PIL import Image\nfrom sklearn.metrics import classification_report","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"class DogDS(Dataset):\n    def __init__(self, root, phase, transforms, label_file = None):\n        self.root = root\n        self.phase = phase\n        self.transforms = transforms\n        self.filenames = glob.glob(os.path.join(os.path.join(root, phase),'*'))\n        \n        self.len = len(self.filenames)\n        if (self.phase == \"train\"):\n            self.labels = pd.read_csv(label_file)\n            self.classes = self.labels['breed'].unique().tolist()\n    def __getitem__(self, index):\n        image = Image.open(self.filenames[index])\n        image = self.transforms(image)\n        filename = self.filenames[index].split('/')[-1]\n        filename_no_ext = filename.split('.')[0]\n        breed = str(self.labels[self.labels['id'] == filename_no_ext].breed.values[0])\n        label = self.classes.index(breed)\n        if (self.phase == 'train'):\n            return image, label\n        return image\n    def __len__(self):\n        return self.len","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_TRANSFORMS = {\n    'train': transforms.Compose([\n        transforms.RandomResizedCrop(224),\n        transforms.RandomHorizontalFlip(),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n    'valid': transforms.Compose([\n        transforms.RandomResizedCrop(224),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dataset = DogDS('../input/train', 'train', DATA_TRANSFORMS['train'], '../input/labels.csv')\ndataset.classes","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUM_CLASSES = len(dataset.classes)\nDEVICE = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ntrain_size = int(0.8 * len(dataset))\nvalid_size = len(dataset) - train_size\ndataset_sizes = {'train': train_size, 'valid': valid_size}\ntrain_dataset, valid_dataset = torch.utils.data.random_split(dataset, [train_size, valid_size])\ndataloaders = {'train': DataLoader(train_dataset, batch_size = 64, shuffle = True),\n              'valid': DataLoader(valid_dataset, batch_size = valid_size, shuffle = False)}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_count_lis = [0]*len(dataset.classes)\nfor index, row in dataset.labels.iterrows():\n    label = dataset.classes.index(row['breed'])\n    label_count_lis[label] += 1\nprint (\"Minimum samples per class : {0}\".format(min(label_count_lis)))\nprint (\"Maximum samples per class : {0}\".format(max(label_count_lis)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure()\nf, ax = plt.subplots(figsize=(25,10))\nplt.bar(np.arange(len(dataset.classes)), label_count_lis)\nplt.xticks(np.arange(len(dataset.classes)), np.arange(len(dataset.classes)))\nplt.ylabel(\"No. of samples\")\nplt.xlabel(\"Classes\")\nplt.title('train')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_model(dataloaders, model, criterion, optimizer, scheduler, num_epochs=25):\n    since = time.time()\n\n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_acc = 0.0\n    losses = {'train': [], 'valid':[]}\n    acc = {'train': [], 'valid': []}\n\n    for epoch in range(num_epochs):\n        print('Epoch {}/{}'.format(epoch, num_epochs - 1))\n        print('-' * 10)\n        scheduler.step()\n        \n        # Each epoch has a training and validation phase\n        for phase in ['train', 'valid']:\n            if phase == 'train':\n                scheduler.step()\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\n            # Iterate over data.\n            for inputs, labels in 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                    outputs = model(inputs)\n                    _, preds = torch.max(outputs, 1)\n                    loss = criterion(outputs, labels)\n\n                    # backward + optimize only if in training phase\n                    if phase == 'train':\n                        loss.backward()\n                        optimizer.step()\n\n                running_loss += loss.item() * inputs.size(0)\n                running_corrects += torch.sum(preds == labels.data)\n\n            epoch_loss = running_loss / dataset_sizes[phase]\n            epoch_acc = running_corrects.double() / dataset_sizes[phase]\n            losses[phase].append(epoch_loss)\n            acc[phase].append(epoch_acc)\n\n            print('{} Loss: {:.4f} Acc: {:.4f}'.format(\n                phase, epoch_loss, epoch_acc))\n\n            # deep copy the model\n            if phase == 'valid' and epoch_acc > best_acc:\n                best_acc = epoch_acc\n                best_model_wts = copy.deepcopy(model.state_dict())\n                \n            if (phase == 'valid' and epoch + 1 == num_epochs):\n                print (\"--------------\")\n                print (\"Final Classification Report\")\n                print (\"--------------\")\n                print (classification_report(preds.cpu(), labels.cpu()))\n\n        print()\n        scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max = len(dataloaders['train']))\n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(\n        time_elapsed // 60, time_elapsed % 60))\n    print('Best val Acc: {:4f}'.format(best_acc))\n    \n    plot_xy(np.arange(num_epochs), [losses['train'], losses['valid']], xlabel = 'Epochs', ylabel = 'Loss', title = 'Loss Plot')\n    plot_xy(np.arange(num_epochs), [acc['train'], acc['valid']], xlabel = 'Epochs', ylabel = 'Accuracy', title = 'Accuracy Plot')\n\n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    return model\n\ndef plot_xy(x, y, title=\"\", xlabel=\"\", ylabel=\"\"):\n    plt.figure()\n    plt.xlabel(xlabel)\n    plt.ylabel(ylabel)\n    plt.title(title)\n    for i in range(len(y)):\n        plt.plot(x, y[i], label = str(i))\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = models.resnet34(pretrained=True)\nnum_ftrs = model.fc.in_features\nmodel.fc = nn.Linear(num_ftrs, NUM_CLASSES)\nmodel = model.to(DEVICE)\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.0001, weight_decay=1e-5)\nexp_lr_scheduler = lr_scheduler.CosineAnnealingLR(optimizer, T_max = len(dataloaders['train']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = train_model(dataloaders, model, criterion, optimizer, exp_lr_scheduler, num_epochs=10)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}