{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport torch\nfrom torch import optim\nimport torch.nn as nn\nimport cv2\nimport matplotlib.pyplot as plt\nimport torchvision\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nfrom torchvision import datasets, models, transforms\nimport copy\nimport tqdm\nfrom PIL import Image\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Data augmentation and normalization for training\n# Just normalization for validation\ndata_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    'test': transforms.Compose([\n        transforms.Resize(256),\n        transforms.CenterCrop(224),\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n    ]),\n}\n\ndata_dir = '../input'\nimage_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),\n                                          data_transforms[x])\n                  for x in ['train', 'test']}\ndataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,\n                                             shuffle=True, num_workers=4)\n              for x in ['train', 'test']}\ndataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'test']}\nclass_names = image_datasets['train'].classes\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def imshow(inp, title=None):\n    \"\"\"Imshow for Tensor.\"\"\"\n    inp = inp.numpy().transpose((1, 2, 0))\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    inp = std * inp + mean\n    inp = np.clip(inp, 0, 1)\n    plt.imshow(inp)\n    if title is not None:\n        plt.title(title)\n    plt.pause(0.001)  # pause a bit so that plots are updated\n\n\n# Get a batch of training data\ninputs, classes = next(iter(dataloaders['train']))\n\n# Make a grid from batch\nout = torchvision.utils.make_grid(inputs)\n\nimshow(out, title=[class_names[x] for x in classes])\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data_dir = '../input'\n\ntrain_transforms = transforms.Compose([transforms.RandomRotation(30),\n                                       transforms.RandomResizedCrop(224),\n                                       transforms.RandomHorizontalFlip(),\n                                       transforms.ToTensor(),\n                                       transforms.Normalize([0.485, 0.456, 0.406],\n                                                            [0.229, 0.224, 0.225])])\n\ntest_transforms = transforms.Compose([transforms.Resize(255),\n                                      transforms.CenterCrop(224),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize([0.485, 0.456, 0.406],\n                                                           [0.229, 0.224, 0.225])])\n\n# Pass transforms in here, then run the next cell to see how the transforms look\ntrain_data = datasets.ImageFolder(data_dir + '/train', transform=train_transforms)\ntest_data = datasets.ImageFolder(data_dir + '/test', transform=test_transforms)\n\ntrainloader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)\ntestloader = torch.utils.data.DataLoader(test_data, batch_size=64)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = models.densenet121(pretrained=True)\nmodel\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nmodel = models.densenet121(pretrained=True)\n\n# Freeze parameters so we don't backprop through them\nfor param in model.parameters():\n    param.requires_grad = False\n    \nmodel.classifier = nn.Sequential(nn.Linear(1024, 256),\n                                 nn.ReLU(),\n                                 nn.Dropout(0.2),\n                                 nn.Linear(256, 2),\n                                 nn.LogSoftmax(dim=1))\n\ncriterion = nn.NLLLoss()\n\n# Only train the classifier parameters, feature parameters are frozen\noptimizer = optim.Adam(model.classifier.parameters(), lr=0.003)\n\nmodel.to(device);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 1\nsteps = 0\nrunning_loss = 0\nprint_every = 5\nfor epoch in range(epochs):\n    for inputs, labels in trainloader:\n        steps += 1\n        # Move input and label tensors to the default device\n        inputs, labels = inputs.to(device), labels.to(device)\n        \n        optimizer.zero_grad()\n        \n        logps = model.forward(inputs)\n        loss = criterion(logps, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        \n        if steps % print_every == 0:\n            test_loss = 0\n            accuracy = 0\n            model.eval()\n            with torch.no_grad():\n                for inputs, labels in testloader:\n                    inputs, labels = inputs.to(device), labels.to(device)\n                    logps = model.forward(inputs)\n                    batch_loss = criterion(logps, labels)\n                    \n                    test_loss += batch_loss.item()\n                    \n                    # Calculate accuracy\n                    ps = torch.exp(logps)\n                    top_p, top_class = ps.topk(1, dim=1)\n                    equals = top_class == labels.view(*top_class.shape)\n                    accuracy += torch.mean(equals.type(torch.FloatTensor)).item()\n                    \n            print(f\"Epoch {epoch+1}/{epochs}.. \"\n                  f\"Train loss: {running_loss/print_every:.3f}.. \"\n                  f\"Test loss: {test_loss/len(testloader):.3f}.. \"\n                  f\"Test accuracy: {accuracy/len(testloader):.3f}\")\n            running_loss = 0\n            model.train()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_names = image_datasets['test'].classes\n\n# Get a batch of test data\ninputs, classes = next(iter(dataloaders['test']))\n\n# Make a grid from batch\nout = torchvision.utils.make_grid(inputs)\n\nimshow(out, title=[class_names[x] for x in classes])","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}