{"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)\nimport matplotlib.pyplot as plt\n\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.optim as optim\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\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\n# import os\n# for 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":"2023-05-30T02:49:25.561354Z","iopub.execute_input":"2023-05-30T02:49:25.561701Z","iopub.status.idle":"2023-05-30T02:49:25.572871Z","shell.execute_reply.started":"2023-05-30T02:49:25.561672Z","shell.execute_reply":"2023-05-30T02:49:25.572007Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n# read given csv and familiarize with input\nlabels = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nunique_breeds = np.unique(labels['breed'])\nlabels.head()\nlabels.describe()","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:49:36.314609Z","iopub.execute_input":"2023-05-30T02:49:36.314970Z","iopub.status.idle":"2023-05-30T02:49:36.383397Z","shell.execute_reply.started":"2023-05-30T02:49:36.314941Z","shell.execute_reply":"2023-05-30T02:49:36.382497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# visualize frequencies of labels.csv\n\nimport matplotlib.pyplot as plt\n\n# Count the occurrences of each breed\nbreed_counts = labels['breed'].value_counts()\n\n# Plot the data\nplt.figure(figsize=(15, 8))\nbreed_counts.plot(kind='bar')\nplt.xlabel('Breed', fontsize=12)\nplt.ylabel('Count', fontsize=12)\nplt.title('Dog Breed Counts', fontsize=14)\nplt.xticks(rotation=90)\nplt.show()\n\nlabels['breed'].nunique()","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:49:38.546726Z","iopub.execute_input":"2023-05-30T02:49:38.547798Z","iopub.status.idle":"2023-05-30T02:49:39.782471Z","shell.execute_reply.started":"2023-05-30T02:49:38.547757Z","shell.execute_reply":"2023-05-30T02:49:39.781503Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"From this, we can see the different frequencies of the breeds and see that we have 120 unique breeds and at least 50 images of each breed. This is good information about our dataset.","metadata":{}},{"cell_type":"code","source":"# map dog breeds to their positions in the csv file, used to turn ids to ints\nlabel_breed_id = dict()\nfor index, value in enumerate(pd.read_csv('../input/dog-breed-identification/sample_submission.csv').columns[1:]):\n    label_breed_id[value] = index","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:49:53.547700Z","iopub.execute_input":"2023-05-30T02:49:53.548597Z","iopub.status.idle":"2023-05-30T02:49:53.848533Z","shell.execute_reply.started":"2023-05-30T02:49:53.548564Z","shell.execute_reply":"2023-05-30T02:49:53.847518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import DataLoader, Dataset\nimport pandas as pd\n\nclass build_data(Dataset):\n    def __init__(self, csv_file, root_dir, transform=None, is_training=True):\n        self.is_training = is_training\n        if self.is_training:\n            self.labels = pd.read_csv(csv_file)\n        else:\n            self.labels = pd.read_csv(csv_file)['id'].values\n        self.root_dir = root_dir\n        self.transform = transform\n        \n    def __len__(self):\n        return self.labels.shape[0]\n    \n    def __getitem__(self, index):\n        \n        if self.is_training:\n            img_path = os.path.join(self.root_dir, self.labels.iloc[index, 0] + '.jpg')\n            image = Image.open(img_path).convert('RGB')\n            if self.transform:\n                image = self.transform(image)\n            torch_label = torch.tensor(int(label_breed_id[self.labels.iloc[index, 1]]))\n            return (image, self.labels.iloc[index, 1], torch_label)\n        else:\n            img_path = os.path.join(self.root_dir, self.labels[index] + '.jpg')\n            image = Image.open(img_path).convert('RGB')\n            if self.transform:\n                image = self.transform(image)\n            torch_label = torch.tensor(int(label_breed_id[self.labels.iloc[index]]))\n            return (image, torch_label)\n        ","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:50:01.540956Z","iopub.execute_input":"2023-05-30T02:50:01.541302Z","iopub.status.idle":"2023-05-30T02:50:01.552750Z","shell.execute_reply.started":"2023-05-30T02:50:01.541275Z","shell.execute_reply":"2023-05-30T02:50:01.550398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torchvision.transforms as transforms\nfrom torchvision.datasets import ImageFolder\n\ndef get_dog_data(augmentation=0):\n    transform_train = transforms.Compose([\n        transforms.Resize((256, 256)),\n        transforms.RandomCrop(256, padding=8, padding_mode='edge'), # Take 256x256 crops from padded images\n        transforms.RandomHorizontalFlip(),    # 50% of time flip image along y-axis\n        transforms.ToTensor(), # convert to pytorch sensor\n        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]), # use the mean and std of Imagenet\n    ])\n    \n    transform_test = transforms.Compose([\n        transforms.Resize((256, 256)),\n        transforms.ToTensor(),\n    ])\n    # Create the trainset object by specifying the train data directory and the transformations\n    trainset = build_data('../input/dog-breed-identification/labels.csv', '../input/dog-breed-identification/train', transform=transform_train, is_training=True)\n    trainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)\n\n    testset = build_data('../input/dog-breed-identification/sample_submission.csv', '../input/dog-breed-identification/test', transform=transform_test, is_training=False)\n    testloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=False, num_workers=2)\n    classes = open(\"/kaggle/input/dog-breed-identification/labels.csv\").read().strip().split(\"\\n\")\n    return {'train': trainloader, 'test': testloader}\n\ndata = get_dog_data()","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:50:03.907738Z","iopub.execute_input":"2023-05-30T02:50:03.910088Z","iopub.status.idle":"2023-05-30T02:50:04.235958Z","shell.execute_reply.started":"2023-05-30T02:50:03.910049Z","shell.execute_reply":"2023-05-30T02:50:04.235020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport torchvision\nfrom PIL import Image\nimport matplotlib.pyplot as plt\nimport numpy as np # linear algebra\n\ndataiter = iter(data['train'])\nimages, labels, torch_label = next(dataiter)\nimages = images[:8]\nprint(images.size())\n\ndef imshow(img):\n    npimg = img.numpy()\n    plt.imshow(np.transpose(npimg, (1, 2, 0)))\n    plt.show()\n\n# show images\nimshow(torchvision.utils.make_grid(images))\n# print labels\nprint(\"Labels:\" + ', '.join('%9s' % labels[j] for j in range(8)))","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:50:06.150393Z","iopub.execute_input":"2023-05-30T02:50:06.150740Z","iopub.status.idle":"2023-05-30T02:50:08.923730Z","shell.execute_reply.started":"2023-05-30T02:50:06.150711Z","shell.execute_reply":"2023-05-30T02:50:08.922655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nimport torch.optim as optim\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\ndef accuracy(net, dataloader):\n  net.to(device)\n  net.eval()\n  correct = 0\n  total = 0\n  with torch.no_grad():\n      for batch in dataloader:\n          images, labels = batch[0].to(device), batch[2].to(device)\n          outputs = net(images)\n          _, predicted = torch.max(outputs.data, 1)\n          total += labels.size(0)\n          correct += (predicted == labels).sum().item()\n  return correct/total\n\ndef train(net, dataloader, epochs=5, start_epoch=0, lr=0.01, momentum=0.9, decay=0.0005, \n          verbose=1, print_every=10, state=None, schedule={}, checkpoint_path=None):\n    net.to(device)\n    net.train()\n    losses = []\n    criterion = nn.CrossEntropyLoss() # loss function\n    optimizer = optim.SGD(net.parameters(), lr=lr, momentum=momentum, weight_decay=decay)\n    label_encoder = LabelEncoder()\n    \n    # Load previous training state\n    if state:\n        net.load_state_dict(state['net'])\n        optimizer.load_state_dict(state['optimizer'])\n        start_epoch = state['epoch']\n        losses = state['losses']\n\n    # Fast forward lr schedule through already trained epochs\n    for epoch in range(start_epoch):\n        if epoch in schedule:\n            print (\"Learning rate: %f\"% schedule[epoch])\n            for g in optimizer.param_groups:\n                g['lr'] = schedule[epoch]\n\n    for epoch in range(start_epoch, epochs):\n        sum_loss = 0.0\n        total_loss = 0.0\n        correct = 0\n        # Update learning rate when scheduled\n        if epoch in schedule:\n            print (\"Learning rate: %f\"% schedule[epoch])\n            for g in optimizer.param_groups:\n                g['lr'] = schedule[epoch]\n\n        for i, datapoint in enumerate(dataloader, 0):\n            \n            inputs = datapoint[0].to(device)\n            labels = datapoint[2].to(device)\n\n            optimizer.zero_grad()\n\n            outputs = net(inputs)\n            loss = criterion(outputs, labels)\n            loss.backward()  # autograd magic, computes all the partial derivatives\n            optimizer.step() # takes a step in gradient direction\n            \n            _, predicted = torch.max(outputs.data, 1)\n            total_loss += labels.size(0)\n            correct += (predicted == labels).sum().item()\n            \n            losses.append(loss.item())\n            sum_loss += loss.item()\n            \n            \n\n            if i % print_every == print_every-1:    # print every 10 mini-batches\n                if verbose:\n                  print('[%d, %5d] loss: %.3f' % (epoch, i + 1, sum_loss / print_every))\n                sum_loss = 0.0\n\n        training_accuracy = correct / total_loss\n        print('Epoch: ', epoch)\n        print('Training accuracy: ', training_accuracy)\n    # plot the losses from this training\n    plt.plot(smooth(losses,50))\n    return net\n\ndef smooth(x, size):\n  return np.convolve(x, np.ones(size)/size, mode='valid')","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:50:12.228543Z","iopub.execute_input":"2023-05-30T02:50:12.231419Z","iopub.status.idle":"2023-05-30T02:50:13.186258Z","shell.execute_reply.started":"2023-05-30T02:50:12.231372Z","shell.execute_reply":"2023-05-30T02:50:13.185168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.nn as nn\n\nresnet = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True)\nresnet.fc = nn.Linear(512, 555) # This will reinitialize the layer as well\nresnet = train(resnet, data['train'], epochs=5, lr=.01, print_every=10)","metadata":{"execution":{"iopub.status.busy":"2023-05-30T02:50:17.890931Z","iopub.execute_input":"2023-05-30T02:50:17.892328Z","iopub.status.idle":"2023-05-30T02:55:20.522767Z","shell.execute_reply.started":"2023-05-30T02:50:17.892280Z","shell.execute_reply":"2023-05-30T02:55:20.521714Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resnet","metadata":{"execution":{"iopub.status.busy":"2023-05-30T03:31:40.875110Z","iopub.execute_input":"2023-05-30T03:31:40.875497Z","iopub.status.idle":"2023-05-30T03:31:40.884275Z","shell.execute_reply.started":"2023-05-30T03:31:40.875464Z","shell.execute_reply":"2023-05-30T03:31:40.883266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train again with more epochs\nresnet = torch.hub.load('pytorch/vision:v0.6.0', 'resnet18', pretrained=True)\nresnet.fc = nn.Linear(512, 555) # This will reinitialize the layer as well\nresnet = train(resnet, data['train'], epochs=10, schedule={0:.01, 4:.001}, lr=.01, print_every=10)","metadata":{"execution":{"iopub.status.busy":"2023-05-30T03:44:05.338902Z","iopub.execute_input":"2023-05-30T03:44:05.339277Z","iopub.status.idle":"2023-05-30T03:51:00.731756Z","shell.execute_reply.started":"2023-05-30T03:44:05.339247Z","shell.execute_reply":"2023-05-30T03:51:00.730679Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\n\n\nresnet.eval()\n\ntest_dir = '/kaggle/input/dog-breed-identification/test'\ntest_data=[]\nids=[]\n\nfor image in os.listdir(test_dir):\n    ids.append(image.split('.')[0])\n    test_data.append(test_dir+'/'+image)\n\ntest_df=pd.DataFrame({'file_name':test_data})\n\ntest_predictions = []\n\nfor image_path in test_data:\n    test_image = Image.open(image_path)\n    # Convert the image to a PyTorch tensor\n    transform_tensor = transforms.ToTensor()\n    input_image = transform_tensor(test_image)\n\n    # Perform forward pass to get the predictions\n    with torch.no_grad():\n        input_image = input_image.to(device)  # Move input to the appropriate device if needed\n        input_image = input_image.unsqueeze(0)\n        output = resnet(input_image)\n\n    # Process the output to get the predicted class\n    _, predicted = torch.max(output, 1)\n    predicted_class = predicted.item()\n    # add the prediction for image to list of predictions\n    test_predictions.append(unique_breeds[predicted_class])","metadata":{"execution":{"iopub.status.busy":"2023-05-30T03:51:47.567777Z","iopub.execute_input":"2023-05-30T03:51:47.568834Z","iopub.status.idle":"2023-05-30T03:54:16.547999Z","shell.execute_reply.started":"2023-05-30T03:51:47.568771Z","shell.execute_reply":"2023-05-30T03:54:16.546950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions[:10]","metadata":{"execution":{"iopub.status.busy":"2023-05-30T04:03:14.486015Z","iopub.execute_input":"2023-05-30T04:03:14.486381Z","iopub.status.idle":"2023-05-30T04:03:14.493229Z","shell.execute_reply.started":"2023-05-30T04:03:14.486350Z","shell.execute_reply":"2023-05-30T04:03:14.492181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import cv2\ntest_df['breed'] = test_predictions\n\nplt.figure(figsize=(6,6))\n\nfor index, data in test_df[:10].iterrows():\n    img = data['file_name']\n    label = data['breed']\n    img = cv2.imread(img)\n    plt.imshow(img)\n    plt.xlabel(label,fontsize = (15))\n    plt.tight_layout()\n    plt.show()    ","metadata":{"execution":{"iopub.status.busy":"2023-05-30T04:05:33.479467Z","iopub.execute_input":"2023-05-30T04:05:33.479851Z","iopub.status.idle":"2023-05-30T04:05:37.718564Z","shell.execute_reply.started":"2023-05-30T04:05:33.479800Z","shell.execute_reply":"2023-05-30T04:05:37.717724Z"},"trusted":true},"execution_count":null,"outputs":[]}]}