{"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":"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\nimport torch.nn as nn\nimport matplotlib.pyplot as plt\nimport torchvision\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nfrom torchvision import transforms\nimport copy\nfrom tqdm import tqdm\nfrom PIL import Image","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:55:56.890439Z","iopub.execute_input":"2022-12-03T01:55:56.890975Z","iopub.status.idle":"2022-12-03T01:55:59.495836Z","shell.execute_reply.started":"2022-12-03T01:55:56.890875Z","shell.execute_reply":"2022-12-03T01:55:59.494828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = '/kaggle/working/train'#'/kaggle/input/dogs-vs-cats/train.zip'\ntest_dir  = '/kaggle/working/test1'#'/kaggle/input/dogs-vs-cats/test1.zip'\nbatch_size = 100","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:00.775299Z","iopub.execute_input":"2022-12-03T01:56:00.775835Z","iopub.status.idle":"2022-12-03T01:56:00.781986Z","shell.execute_reply.started":"2022-12-03T01:56:00.775793Z","shell.execute_reply":"2022-12-03T01:56:00.780468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:02.177440Z","iopub.execute_input":"2022-12-03T01:56:02.178100Z","iopub.status.idle":"2022-12-03T01:56:02.301283Z","shell.execute_reply.started":"2022-12-03T01:56:02.178065Z","shell.execute_reply":"2022-12-03T01:56:02.299862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Resize((500, 500))\n])","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:04.078587Z","iopub.execute_input":"2022-12-03T01:56:04.079356Z","iopub.status.idle":"2022-12-03T01:56:04.084911Z","shell.execute_reply.started":"2022-12-03T01:56:04.079315Z","shell.execute_reply":"2022-12-03T01:56:04.083463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Class loading Dataset\nclass CatDogDataset(Dataset):\n    def __init__(self, train_dir, transform = None):\n        super(CatDogDataset, self).__init__()\n        self.train_dir = train_dir\n        self.transform = transform\n        self.images = os.listdir(train_dir)\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, index):\n        image_path = os.path.join(self.train_dir, self.images[index])\n\n        label = self.images[index].split(\".\")[0]\n        label = 0 if label == 'cat' else 1\n        image = np.array(Image.open(image_path))\n        \n        if self.transform:\n            image = self.transform(image)\n        return image, label","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-03T01:56:06.063157Z","iopub.execute_input":"2022-12-03T01:56:06.063924Z","iopub.status.idle":"2022-12-03T01:56:06.072071Z","shell.execute_reply.started":"2022-12-03T01:56:06.063878Z","shell.execute_reply":"2022-12-03T01:56:06.070698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def validate(model, test_data_loader, device=device):\n    total = 0\n    correct = 0\n\n    for (images, labels) in test_data_loader:\n        images  = images.to(device)\n        y       = model(images)\n        _, pred = torch.max(y, 1)\n\n        total   += y.size(0)\n        correct += torch.sum(pred == labels)\n\n    return correct*100/total","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:15.904978Z","iopub.execute_input":"2022-12-03T01:56:15.905387Z","iopub.status.idle":"2022-12-03T01:56:15.912833Z","shell.execute_reply.started":"2022-12-03T01:56:15.905345Z","shell.execute_reply":"2022-12-03T01:56:15.911547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_model(model, train_data_loader, test_data_loader, epoches, lr, device=device):\n    accuracies  = []\n    model       = model.to(device)\n    criterion   = nn.CrossEntropyLoss()\n    optimizer   = torch.optim.Adam(model.parameters(), lr=lr, amsgrad=True)\n\n    max_accuracy = 0\n\n    #Below runs as epoch1->epoch2-> . . .\n    print(\"Using device: \", device)\n    for epoch in range(epoches):\n        print(\"\\rEpoch {}\".format(epoch), end=\"\")\n        #Below runs batch-wise: batch1->batch2-> . . .\n        with tqdm(train_data_loader, unit=\"batch\") as tepoch:\n            for i, (images, labels) in enumerate(tepoch):\n                images = images.to(device)\n                labels = labels.to(device)\n\n                optimizer.zero_grad()\n                pred = model(images)\n                loss = criterion(pred, labels)\n                loss.backward()\n                optimizer.step()\n        accuracy = float(validate(model, test_data_loader))\n        accuracies.append(accuracy)\n        \n        if accuracy > max_accuracy:\n            best_model = copy.deepcopy(model)\n            max_accuracy = accuracy\n            print(\"saving best model with accuracy: \", accuracy)\n        print(\"Epoch: \", epoch+1, \"Accuracy: \", accuracy, \"%\")\n    \n    return best_model","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:23.803116Z","iopub.execute_input":"2022-12-03T01:56:23.803514Z","iopub.status.idle":"2022-12-03T01:56:23.813177Z","shell.execute_reply.started":"2022-12-03T01:56:23.803483Z","shell.execute_reply":"2022-12-03T01:56:23.811856Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def classifier():\n    #Load data into torch DataLoader\n    train_data = CatDogDataset(train_dir, data_transform)\n    test_data  = CatDogDataset(test_dir, data_transform)\n\n    train_data_loader = DataLoader(train_data, batch_size=batch_size)\n    test_data_loader  = DataLoader(test_data, batch_size=batch_size)\n\n    #Transfer learning\n    model       = torchvision.models.resnet18(pretrained=True)\n    model       = model.to(device)\n    \n    for param in model.parameters():\n        param.requires_grad = False\n    \n    num_ftrs    = model.fc.in_features\n    model.fc    = nn.Sequential(\n                    nn.Linear(num_ftrs, 2),\n                    nn.Softmax(dim=1)\n                )\n\n    epoches = 2\n    lr = 1e-4\n\n    model = train_model(model, train_data_loader, test_data_loader, epoches, lr, device).to(device)\n    torch.save(model.state_dict(), \"ResNet18_CatDog.pth\")","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:56:25.456742Z","iopub.execute_input":"2022-12-03T01:56:25.457404Z","iopub.status.idle":"2022-12-03T01:56:25.465859Z","shell.execute_reply.started":"2022-12-03T01:56:25.457364Z","shell.execute_reply":"2022-12-03T01:56:25.464144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! unzip \"/kaggle/input/dogs-vs-cats/test1.zip\"\n\n! unzip \"/kaggle/input/dogs-vs-cats/train.zip\"","metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#ls '/kaggle/working/train'","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-12-02T23:54:36.797543Z","iopub.execute_input":"2022-12-02T23:54:36.797972Z","iopub.status.idle":"2022-12-02T23:54:36.802257Z","shell.execute_reply.started":"2022-12-02T23:54:36.797938Z","shell.execute_reply":"2022-12-02T23:54:36.801359Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls '/kaggle/input/dogs-vs-cats/'","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:58:19.561149Z","iopub.execute_input":"2022-12-03T01:58:19.561551Z","iopub.status.idle":"2022-12-03T01:58:20.610723Z","shell.execute_reply.started":"2022-12-03T01:58:19.561515Z","shell.execute_reply":"2022-12-03T01:58:20.609437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#trains and saves the model\nclassifier()","metadata":{"execution":{"iopub.status.busy":"2022-12-03T01:58:22.059522Z","iopub.execute_input":"2022-12-03T01:58:22.059991Z","iopub.status.idle":"2022-12-03T02:02:33.568107Z","shell.execute_reply.started":"2022-12-03T01:58:22.059951Z","shell.execute_reply":"2022-12-03T02:02:33.566314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference(path, model, device=device):\n    try:\n        resp = requests.get(path, timeout=10)\n        print(\"request sent\")\n    except:\n        return False\n    \n    with torch.no_grad():\n        image = np.array(Image.open(BytesIO(resp.content)))\n        \n        image = transforms(image)\n        \n        image = image.unsqueeze(0)\n        pred = model(image.to(device))\n        return pred","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path = str(input(\"insert the image url: \"))\npred = inference(path, model, \"cuda\")\nif torch.is_tensor(pred):\n    pred_idx = np.argmax(pred)\n\n    pred_label = \"cat\" if pred_idx == 0 else \"dog\"\n    \n    print(f\"Predicted: {pred_label}, Prob: {pred[0][pred_idx]*100}%\")\nelse:\n    print(\"can not get the url!!!\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}