{"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 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.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-14T13:24:14.244622Z","iopub.execute_input":"2023-04-14T13:24:14.245131Z","iopub.status.idle":"2023-04-14T13:24:14.253028Z","shell.execute_reply.started":"2023-04-14T13:24:14.245023Z","shell.execute_reply":"2023-04-14T13:24:14.252001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from os import walk\nfor (dirpath, dirnames, filenames) in walk(\"../input/dogs-vs-cats\"):\n    print(\"Directory path: \", dirpath)\n    print(\"Folder name: \", dirnames)\n    print(\"File name: \", filenames)","metadata":{"_uuid":"3cf897a2116c4eae7bb3dafeeb4405075e848038","execution":{"iopub.status.busy":"2023-04-14T13:24:14.254461Z","iopub.execute_input":"2023-04-14T13:24:14.254954Z","iopub.status.idle":"2023-04-14T13:24:14.265243Z","shell.execute_reply.started":"2023-04-14T13:24:14.254885Z","shell.execute_reply":"2023-04-14T13:24:14.264211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from os import walk\nfor (dirpath, dirnames, filenames) in walk(\"../input/dogs-vs-cats-for-pytorch\"):\n    print(\"Directory path: \", dirpath)\n    print(\"Folder name: \", dirnames)\n    print(\"File name: \", filenames)","metadata":{"_uuid":"f6b13bf258e80d5829434fb23b8db40ca08054d8","execution":{"iopub.status.busy":"2023-04-14T13:24:14.266665Z","iopub.execute_input":"2023-04-14T13:24:14.267307Z","iopub.status.idle":"2023-04-14T13:24:42.711106Z","shell.execute_reply.started":"2023-04-14T13:24:14.267254Z","shell.execute_reply":"2023-04-14T13:24:42.710411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Implementation","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a"}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nfrom torchvision import datasets ,models,transforms\nfrom torch.utils.data.sampler import SubsetRandomSampler\nfrom torch.optim import lr_scheduler\nfrom pathlib import Path\nfrom matplotlib import pyplot as plt\nimport numpy as np","metadata":{"_uuid":"cc0c921c2188b10d3c07d46d5f2d75d25f14f16d","execution":{"iopub.status.busy":"2023-04-14T13:24:42.712121Z","iopub.execute_input":"2023-04-14T13:24:42.712343Z","iopub.status.idle":"2023-04-14T13:24:42.718017Z","shell.execute_reply.started":"2023-04-14T13:24:42.712306Z","shell.execute_reply":"2023-04-14T13:24:42.717297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# check if CUDA is available\ntrain_on_gpu = torch.cuda.is_available()\n\nif not train_on_gpu:\n    print('CUDA is not available.  Training on CPU ...')\nelse:\n    print('CUDA is available!  Training on GPU ...')","metadata":{"_uuid":"8402f92bc655b7aead5de0798f5e37a15dd9dd24","execution":{"iopub.status.busy":"2023-04-14T13:24:42.719162Z","iopub.execute_input":"2023-04-14T13:24:42.719653Z","iopub.status.idle":"2023-04-14T13:24:42.730180Z","shell.execute_reply.started":"2023-04-14T13:24:42.719604Z","shell.execute_reply":"2023-04-14T13:24:42.729378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PATH=Path('../input/dogs-vs-cats-for-pytorch/Cat_Dog_data')\nPATH1=Path('../input/dogs-vs-cats-for-pytorch/Cat_Dog_data/test')","metadata":{"_uuid":"1a603f2e3b87e6987245b06b95076f2177adbc27","execution":{"iopub.status.busy":"2023-04-14T13:26:50.372837Z","iopub.execute_input":"2023-04-14T13:26:50.373164Z","iopub.status.idle":"2023-04-14T13:26:50.377553Z","shell.execute_reply.started":"2023-04-14T13:26:50.373101Z","shell.execute_reply":"2023-04-14T13:26:50.376454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN =Path(PATH/'train')\nVALID = Path(PATH/'test')\nTEST=Path(PATH1)\nprint(TRAIN)\nprint(VALID)\nprint(TEST)","metadata":{"_uuid":"456bf7d2535f3c45d3cf22c72077367962fceda2","execution":{"iopub.status.busy":"2023-04-14T13:26:52.899002Z","iopub.execute_input":"2023-04-14T13:26:52.899309Z","iopub.status.idle":"2023-04-14T13:26:52.905849Z","shell.execute_reply.started":"2023-04-14T13:26:52.899252Z","shell.execute_reply":"2023-04-14T13:26:52.905056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No of dog images for training","metadata":{"_uuid":"3302f270638ea786d60e5a825efe55dd7ff0774a"}},{"cell_type":"code","source":"ls ../input/dogs-vs-cats-for-pytorch/cat_dog_data/Cat_Dog_data/train/dog -1 | wc -l","metadata":{"_uuid":"8b150cb4173e9b1b67416713d63158f463e57f43","execution":{"iopub.status.busy":"2023-04-14T13:24:42.749288Z","iopub.execute_input":"2023-04-14T13:24:42.749727Z","iopub.status.idle":"2023-04-14T13:24:44.717783Z","shell.execute_reply.started":"2023-04-14T13:24:42.749677Z","shell.execute_reply":"2023-04-14T13:24:44.716771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No of Cat images for training","metadata":{"_uuid":"08b576f07f8f7cf37cf949e3af11db6c6f2c4d7c"}},{"cell_type":"code","source":"ls ../input/dogs-vs-cats-for-pytorch/cat_dog_data/Cat_Dog_data/train/cat -1 | wc -l","metadata":{"_uuid":"7de8b754963a1cfbc3695ab12630afd7abf7e0bd","execution":{"iopub.status.busy":"2023-04-14T13:24:44.719375Z","iopub.execute_input":"2023-04-14T13:24:44.719716Z","iopub.status.idle":"2023-04-14T13:24:46.572057Z","shell.execute_reply.started":"2023-04-14T13:24:44.719665Z","shell.execute_reply":"2023-04-14T13:24:46.571183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No of Dog images for validation","metadata":{"_uuid":"033975937d8d283b90bdf42d42a867b6930cceb8"}},{"cell_type":"code","source":"ls ../input/dogs-vs-cats-for-pytorch/cat_dog_data/Cat_Dog_data/test/dog -1 | wc -l","metadata":{"_uuid":"96ba04a79812804f076c0189aaf830b97deb588b","execution":{"iopub.status.busy":"2023-04-14T13:24:46.573603Z","iopub.execute_input":"2023-04-14T13:24:46.573873Z","iopub.status.idle":"2023-04-14T13:24:47.890589Z","shell.execute_reply.started":"2023-04-14T13:24:46.573828Z","shell.execute_reply":"2023-04-14T13:24:47.889708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No of Cat images for validation","metadata":{"_uuid":"d82c1144b6dc797963c2865da07ea5d7ac21da49"}},{"cell_type":"code","source":"ls ../input/dogs-vs-cats-for-pytorch/cat_dog_data/Cat_Dog_data/test/cat -1 | wc -l","metadata":{"_uuid":"4a6fd56718fc65612eb5a87afd24a55346c45ec8","execution":{"iopub.status.busy":"2023-04-14T13:24:47.892183Z","iopub.execute_input":"2023-04-14T13:24:47.892475Z","iopub.status.idle":"2023-04-14T13:24:49.261891Z","shell.execute_reply.started":"2023-04-14T13:24:47.892417Z","shell.execute_reply":"2023-04-14T13:24:49.260969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No of images to predict","metadata":{"_uuid":"dbb6b9a84e23884a5187b268cb2546ec7db2d03b"}},{"cell_type":"code","source":"ls ../input/dogs-vs-cats/test1/test1 -1 | wc -l","metadata":{"_uuid":"5bc776186c5fea776e1283456bfa568bf72e81a2","execution":{"iopub.status.busy":"2023-04-14T13:24:49.264736Z","iopub.execute_input":"2023-04-14T13:24:49.265047Z","iopub.status.idle":"2023-04-14T13:24:50.194559Z","shell.execute_reply.started":"2023-04-14T13:24:49.264995Z","shell.execute_reply":"2023-04-14T13:24:50.193689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# number of subprocesses to use for data loading\nnum_workers = 0\n# how many samples per batch to load\nbatch_size = 32\n\n# convert data to a normalized torch.FloatTensor\ntrain_transforms = transforms.Compose([transforms.Resize((224,224)),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize([0.485, 0.456, 0.406],\n                                                           [0.229, 0.224, 0.225])])\n\nvalid_transforms = transforms.Compose([transforms.Resize((224,224)),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize([0.485, 0.456, 0.406],\n                                                           [0.229, 0.224, 0.225])])\n# choose the training and test datasets\n\ntest_transforms = transforms.Compose([transforms.Resize((224,224)),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize([0.485, 0.456, 0.406],\n                                                           [0.229, 0.224, 0.225])])\n# choose the training and test datasets\ntrain_data = datasets.ImageFolder(TRAIN, transform=train_transforms)\nvalid_data=datasets.ImageFolder(VALID,transform=valid_transforms)\ntest_data = datasets.ImageFolder(PATH1, transform=test_transforms)\n\n# obtain training indices that will be used for validation\n#num_train = len(train_data)\n#indices = list(range(num_train))\n#np.random.shuffle(indices)\n#split = int(np.floor(valid_size * num_train))\n#print(\"Split Index\",split)\n#train_idx, valid_idx = indices[split:], indices[:split]\n#train_idx, valid_idx = indices[split:], indices[:split]\n# define samplers for obtaining training and validation batches\n","metadata":{"_uuid":"f460717dbfd51d925e7e5ee348cb74334aa0301c","execution":{"iopub.status.busy":"2023-04-14T13:26:58.833488Z","iopub.execute_input":"2023-04-14T13:26:58.833773Z","iopub.status.idle":"2023-04-14T13:27:03.312958Z","shell.execute_reply.started":"2023-04-14T13:26:58.833720Z","shell.execute_reply":"2023-04-14T13:27:03.312164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(train_data.class_to_idx)\nprint(valid_data.class_to_idx)","metadata":{"_uuid":"e0cb2a3741f38e633686e711996476324c361bca","execution":{"iopub.status.busy":"2023-04-14T13:27:06.843373Z","iopub.execute_input":"2023-04-14T13:27:06.843668Z","iopub.status.idle":"2023-04-14T13:27:06.848509Z","shell.execute_reply.started":"2023-04-14T13:27:06.843613Z","shell.execute_reply":"2023-04-14T13:27:06.847609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare data loaders (combine dataset and sampler)\ntrain_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=num_workers,shuffle=True)\nvalid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\ntest_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size,  num_workers=num_workers)","metadata":{"_uuid":"b747ff806f4e80734cea0daad42918ac1cb00906","execution":{"iopub.status.busy":"2023-04-14T13:27:10.018855Z","iopub.execute_input":"2023-04-14T13:27:10.019165Z","iopub.status.idle":"2023-04-14T13:27:10.024255Z","shell.execute_reply.started":"2023-04-14T13:27:10.019104Z","shell.execute_reply":"2023-04-14T13:27:10.023143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images,labels=next(iter(train_loader))","metadata":{"_uuid":"3b5b83c42b058a9c46d395723ea014791f1d81cb","execution":{"iopub.status.busy":"2023-04-14T13:27:13.228699Z","iopub.execute_input":"2023-04-14T13:27:13.228996Z","iopub.status.idle":"2023-04-14T13:27:13.674391Z","shell.execute_reply.started":"2023-04-14T13:27:13.228939Z","shell.execute_reply":"2023-04-14T13:27:13.673666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images.shape,labels.shape","metadata":{"_uuid":"4083b460a0eeb10ae81e6e465b59ee0202e2d124","execution":{"iopub.status.busy":"2023-04-14T13:27:15.145662Z","iopub.execute_input":"2023-04-14T13:27:15.145945Z","iopub.status.idle":"2023-04-14T13:27:15.156682Z","shell.execute_reply.started":"2023-04-14T13:27:15.145891Z","shell.execute_reply":"2023-04-14T13:27:15.156001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n%matplotlib inline\nclasses = ['cat','dog']\nmean , std = torch.tensor([0.485, 0.456, 0.406]),torch.tensor([0.229, 0.224, 0.225])\n\n\ndef denormalize(image):\n  image = transforms.Normalize(-mean/std,1/std)(image) #denormalize\n  image = image.permute(1,2,0) #Changing from 3x224x224 to 224x224x3\n  image = torch.clamp(image,0,1)\n  return image\n\n# helper function to un-normalize and display an image\ndef imshow(img):\n    img = denormalize(img) \n    plt.imshow(img)","metadata":{"_uuid":"ec4b972aeedfeca3f931963c0529948bb08b5c62","execution":{"iopub.status.busy":"2023-04-14T13:27:21.400109Z","iopub.execute_input":"2023-04-14T13:27:21.400414Z","iopub.status.idle":"2023-04-14T13:27:21.407981Z","shell.execute_reply.started":"2023-04-14T13:27:21.400353Z","shell.execute_reply":"2023-04-14T13:27:21.407115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# obtain one batch of training images\ndataiter = iter(train_loader)\nimages, labels = dataiter.next()\n # convert images to numpy for display\n\n# plot the images in the batch, along with the corresponding labels\nfig = plt.figure(figsize=(25, 8))\n# display 20 images\nfor idx in np.arange(20):\n    ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])\n    imshow(images[idx])\n    ax.set_title(\"{} \".format( classes[labels[idx]]))","metadata":{"_uuid":"a798a576675154c274dba5173db2505396ca9f51","execution":{"iopub.status.busy":"2023-04-14T13:27:24.707595Z","iopub.execute_input":"2023-04-14T13:27:24.707891Z","iopub.status.idle":"2023-04-14T13:27:26.386295Z","shell.execute_reply.started":"2023-04-14T13:27:24.707833Z","shell.execute_reply":"2023-04-14T13:27:26.385577Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"rgb_img = np.squeeze(images[3])\nchannels = ['red channel', 'green channel', 'blue channel']\n\nfig = plt.figure(figsize = (36, 36)) \nfor idx in np.arange(rgb_img.shape[0]):\n    ax = fig.add_subplot(1, 3, idx + 1)\n    img = rgb_img[idx]\n    ax.imshow(img, cmap='gray')\n    ax.set_title(channels[idx])\n    width, height = img.shape\n    thresh = img.max()/2.5\n    for x in range(width):\n        for y in range(height):\n            val = round(img[x][y],2) if img[x][y] !=0 else 0\n            ax.annotate(str(val), xy=(y,x),\n                    horizontalalignment='center',\n                    verticalalignment='center', size=8,\n                    color='white' if img[x][y]<thresh else 'black')","metadata":{"_uuid":"31c1d36f71044ff88382415cf030c8a29c1d47d1","trusted":true}},{"cell_type":"markdown","source":"![](http://)Load the model VGG -19","metadata":{"_uuid":"af3e9af0992a7228e3c4744fe4a95e9898848b33","trusted":true}},{"cell_type":"code","source":"vgg_19=models.vgg19_bn(pretrained=True)\nvgg_19","metadata":{"_uuid":"4a05bc1f8d54374fbd914011a2f8e0fc85db859d","execution":{"iopub.status.busy":"2023-04-14T13:27:31.304715Z","iopub.execute_input":"2023-04-14T13:27:31.305008Z","iopub.status.idle":"2023-04-14T13:27:48.093145Z","shell.execute_reply.started":"2023-04-14T13:27:31.304953Z","shell.execute_reply":"2023-04-14T13:27:48.092336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Freeze parameters so we don't backprop through them\nfor param in vgg_19.parameters():\n    param.requires_grad = False\n\nfrom collections import OrderedDict\nclassifier = nn.Sequential(OrderedDict([\n                          ('fc1', nn.Linear(25088, 1028)),\n                          ('relu1', nn.ReLU()),\n                          ('dropout1',nn.Dropout(0.5)),\n                          ('fc2', nn.Linear(1028, 512)),\n                          ('relu2', nn.ReLU()), \n                          ('dropout2',nn.Dropout(0.5)),\n                          ('fc3', nn.Linear(512, 2)),\n                          ('output', nn.LogSoftmax(dim=1))\n                          ]))\n    \nvgg_19.classifier = classifier","metadata":{"_uuid":"59d8071adab43cafe88ab43b9cbfd278030b6f4e","execution":{"iopub.status.busy":"2023-04-14T13:24:50.339043Z","iopub.status.idle":"2023-04-14T13:24:50.339749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vgg_19","metadata":{"_uuid":"7fe13f9fdc397b4af13443e25c9d7f6f251a8d4d","execution":{"iopub.status.busy":"2023-04-14T13:24:50.340561Z","iopub.status.idle":"2023-04-14T13:24:50.341245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.NLLLoss()\noptimizer=torch.optim.Adam(vgg_19.parameters(),lr=0.01)","metadata":{"_uuid":"30ef92168a98bdb63e7e41ca1214635b8649fe50","execution":{"iopub.status.busy":"2023-04-14T13:24:50.342020Z","iopub.status.idle":"2023-04-14T13:24:50.342687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare data loaders (combine dataset and sampler)\ntrain_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=num_workers,shuffle=True)\nvalid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\ntest_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size,  num_workers=num_workers)","metadata":{"_uuid":"1daa951c7b757be404d32caa248156d6be907d60","execution":{"iopub.status.busy":"2023-04-14T13:24:50.343487Z","iopub.status.idle":"2023-04-14T13:24:50.344170Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if train_on_gpu:\n    vgg_19.cuda()\n# number of epochs to train the model\nn_epochs = 3\n\nvalid_loss_min = np.Inf # track change in validation loss\n\n#train_losses,valid_losses=[],[]\n\nfor epoch in range(1, n_epochs+1):\n\n    # keep track of training and validation loss\n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    ###################\n    # train the model #\n    ###################\n    vgg_19.train()\n    for data, target in train_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # clear the gradients of all optimized variables\n        optimizer.zero_grad()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # backward pass: compute gradient of the loss with respect to model parameters\n        loss.backward()\n        # perform a single optimization step (parameter update)\n        optimizer.step()\n        # update training loss\n        train_loss += loss.item()*data.size(0)\n        \n    ######################    \n    # validate the model #\n    ######################\n    vgg_19.eval()\n    for data, target in valid_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # update average validation loss \n        valid_loss += loss.item()*data.size(0)\n    \n    # calculate average losses\n    #train_losses.append(train_loss/len(train_loader.dataset))\n    #valid_losses.append(valid_loss.item()/len(valid_loader.dataset)\n    train_loss = train_loss/len(train_loader.dataset)\n    valid_loss = valid_loss/len(valid_loader.dataset)\n        \n    # print training/validation statistics \n    print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(\n        epoch, train_loss, valid_loss))\n    \n    # save model if validation loss has decreased\n    if valid_loss <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n        valid_loss_min,\n        valid_loss))\n        torch.save(vgg_19.state_dict(), 'model_vgg19.pth')\n        valid_loss_min = valid_loss","metadata":{"_uuid":"5ccc71267ca99ab5895408a89cba964729063233","execution":{"iopub.status.busy":"2023-04-14T13:24:50.344982Z","iopub.status.idle":"2023-04-14T13:24:50.345686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nbatch_size=4\n# track test loss\ntest_loss = 0.0\nclass_correct = list(0. for i in range(2))\nclass_total = list(0. for i in range(2))\n\nvgg_19.eval()\n# iterate over valid data\nfor data, target in valid_loader:\n    # move tensors to GPU if CUDA is available\n    if train_on_gpu:\n        data, target = data.cuda(), target.cuda()\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = vgg_19(data)\n    # calculate the batch loss\n    loss = criterion(output, target)\n    # update test loss \n    test_loss += loss.item()*data.size(0)\n    # convert output probabilities to predicted class\n    _, pred = torch.max(output, 1)    \n    # compare predictions to true label\n    correct_tensor = pred.eq(target.data.view_as(pred))\n    correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())\n    # calculate test accuracy for each object class\n    for i in range(batch_size):\n        label = target.data[i]\n        class_correct[label] += correct[i].item()\n        class_total[label] += 1\n\n# average test loss\ntest_loss = test_loss/len(valid_loader.dataset)\nprint('Test Loss: {:.6f}\\n'.format(test_loss))\n\nfor i in range(2):\n    if class_total[i] > 0:\n        print('Test Accuracy of %5s: %2d%% (%2d/%2d)' % (\n            classes[i], 100 * class_correct[i] / class_total[i],\n            np.sum(class_correct[i]), np.sum(class_total[i])))\n    else:\n        print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\nprint('\\nTest Accuracy (Overall): %2d%% (%2d/%2d)' % (\n    100. * np.sum(class_correct) / np.sum(class_total),\n    np.sum(class_correct), np.sum(class_total)))","metadata":{"_uuid":"42f7742549adc8fb0eb34f558ea06d481707182f","execution":{"iopub.status.busy":"2023-04-14T13:24:50.346501Z","iopub.status.idle":"2023-04-14T13:24:50.347192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size=32\nvalid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nvgg_19.cpu()\n# obtain one batch of test images\ndataiter = iter(valid_loader)\nimages, labels = dataiter.next()\n\n# move model inputs to cuda, if GPU available\n#if train_on_gpu:\n    #images = images.cuda()\n\n# get sample outputs\noutput = vgg_19(images)\n# convert output probabilities to predicted class\n_, preds_tensor = torch.max(output, 1)\npreds = np.squeeze(preds_tensor.numpy()) if not train_on_gpu else np.squeeze(preds_tensor.cpu().numpy())\n\n# plot the images in the batch, along with predicted and true labels\nfig = plt.figure(figsize=(25, 4))\nfor idx in np.arange(20):\n    ax = fig.add_subplot(2, 20/2, idx+1, xticks=[], yticks=[])\n    imshow(images[idx])\n    ax.set_title(\"{} ({})\".format(classes[preds[idx]], classes[labels[idx]]),\n                 color=(\"green\" if preds[idx]==labels[idx].item() else \"red\"))","metadata":{"_uuid":"eb6777caef4badba8e3c45b6de56afca5c62cd1a","execution":{"iopub.status.busy":"2023-04-14T13:24:50.348005Z","iopub.status.idle":"2023-04-14T13:24:50.348677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"The state dict keys: \\n\\n\", vgg_19.state_dict().keys())","metadata":{"_uuid":"012bfd6109f073f2656528fba8fecfb17478f68b","execution":{"iopub.status.busy":"2023-04-14T13:24:50.349483Z","iopub.status.idle":"2023-04-14T13:24:50.350160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(vgg_19.state_dict(), 'checkpoint_97.pth')","metadata":{"_uuid":"2f24ddf9aa5ff2a0be93dbbdf3ab2366e0df569c","execution":{"iopub.status.busy":"2023-04-14T13:24:50.350949Z","iopub.status.idle":"2023-04-14T13:24:50.351616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"vgg_19.load_state_dict(state_dict)","metadata":{"_uuid":"9f457e4ae1c1f63969a4c169d417d703af7f181e"}},{"cell_type":"code","source":"# Criteria NLLLoss which is recommended with Softmax final layer\ncriterion = nn.NLLLoss()\n# Observe that all parameters are being optimized\noptimizer = torch.optim.Adam(vgg_19.classifier.parameters(), lr=0.001)\n# Decay LR by a factor of 0.1 every 3 epochs\nscheduler = lr_scheduler.StepLR(optimizer, step_size=3, gamma=0.1)\n# Number of epochs","metadata":{"_uuid":"4135612d5f8f2fa9f3d869a6d027e37dc2a12be2","execution":{"iopub.status.busy":"2023-04-14T13:24:50.352426Z","iopub.status.idle":"2023-04-14T13:24:50.353097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if train_on_gpu:\n    vgg_19.cuda()\n# number of epochs to train the model\nn_epochs = 2\n\nvalid_loss_min = np.Inf # track change in validation loss\n\nfor epoch in range(1, n_epochs+1):\n\n    # keep track of training and validation loss\n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    ###################\n    # train the model #\n    ###################\n    vgg_19.train()\n    \n    for data, target in train_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # clear the gradients of all optimized variables\n        scheduler.step()\n        optimizer.zero_grad()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # backward pass: compute gradient of the loss with respect to model parameters\n        loss.backward()\n        # perform a single optimization step (parameter update)\n        optimizer.step()\n        # update training loss\n        train_loss += loss.item()*data.size(0)\n        \n    ######################    \n    # validate the model #\n    ######################\n    vgg_19.eval()\n    for data, target in valid_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # update average validation loss \n        valid_loss += loss.item()*data.size(0)\n    \n    # calculate average losses\n    train_loss = train_loss/len(train_loader.dataset)\n    valid_loss = valid_loss/len(valid_loader.dataset)\n        \n    # print training/validation statistics \n    print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(\n        epoch, train_loss, valid_loss))\n    \n    # save model if validation loss has decreased\n    if valid_loss <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n        valid_loss_min,\n        valid_loss))\n        torch.save(vgg_19.state_dict(), 'model_vgg19_2.pth')\n        valid_loss_min = valid_loss","metadata":{"_uuid":"cb5d786d934781f1868115a1e812e4dc3f6ab34c","execution":{"iopub.status.busy":"2023-04-14T13:24:50.353897Z","iopub.status.idle":"2023-04-14T13:24:50.354575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size=4\nvalid_loader = torch.utils.data.DataLoader(valid_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\n# track test loss\ntest_loss = 0.0\nclass_correct = list(0. for i in range(2))\nclass_total = list(0. for i in range(2))\n\nvgg_19.eval()\n# iterate over test data\nfor data, target in valid_loader:\n    # move tensors to GPU if CUDA is available\n    if train_on_gpu:\n        data, target = data.cuda(), target.cuda()\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = vgg_19(data)\n    # calculate the batch loss\n    loss = criterion(output, target)\n    # update test loss \n    test_loss += loss.item()*data.size(0)\n    # convert output probabilities to predicted class\n    _, pred = torch.max(output, 1)    \n    # compare predictions to true label\n    correct_tensor = pred.eq(target.data.view_as(pred))\n    correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())\n    # calculate test accuracy for each object class\n    for i in range(batch_size):\n        label = target.data[i]\n        class_correct[label] += correct[i].item()\n        class_total[label] += 1\n\n# average test loss\ntest_loss = test_loss/len(test_loader.dataset)\nprint('Test Loss: {:.6f}\\n'.format(test_loss))\n\nfor i in range(2):\n    if class_total[i] > 0:\n        print('Test Accuracy of %5s: %2d%% (%2d/%2d)' % (\n            classes[i], 100 * class_correct[i] / class_total[i],\n            np.sum(class_correct[i]), np.sum(class_total[i])))\n    else:\n        print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\nprint('\\nTest Accuracy (Overall): %2d%% (%2d/%2d)' % (\n    100. * np.sum(class_correct) / np.sum(class_total),\n    np.sum(class_correct), np.sum(class_total)))","metadata":{"_uuid":"d59caceb43c56bee3afb8d96e56438ed9a83137a","execution":{"iopub.status.busy":"2023-04-14T13:24:50.355389Z","iopub.status.idle":"2023-04-14T13:24:50.356051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"References\n<br>\n[Notebook](https://www.kaggle.com/pocahontas1010/cats-dogs-classifier-with-pytorch/notebook)\n<br>\n[Sorting data into subdirectories](https://www.kaggle.com/c/dog-breed-identification/discussion/48908)\n<br>\n[Model evaluation](https://www.kaggle.com/carloalbertobarbano/vgg16-transfer-learning-pytorch)\n<br>\n[Pytorch Models](https://pytorch.org/docs/stable/torchvision/models.html[Pytorch Models])\n<br>\n[Pytorch Augmetation](https://colab.research.google.com/drive/109vu3F1LTzD1gdVV6cho9fKGx7lzbFll)","metadata":{"_uuid":"f4ed63fd4053efe5ef4110ad05cd913beb1dcdde"}}]}