{"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 torch\nfrom torch import nn\nfrom torch.autograd import Variable\nimport torchvision\nfrom torchvision import datasets, transforms, models\nimport matplotlib.pyplot as plt\nimport time\nfrom sklearn.model_selection import train_test_split\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"39756d889fe6f1dcccf53d800a2bc32a2b5673b5"},"cell_type":"code","source":"%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"82121e7e4c9e57674336db0e11a32f3e33e0212a"},"cell_type":"code","source":"data_dir = \"/kaggle/input/train/train\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"394009eb83e78f1a0f60a8bc424d52ccd2d7f8d4"},"cell_type":"code","source":"class myDataset(torch.utils.data.Dataset):\n    def __init__(self, prefix, files, transform, img_loader):\n        self.imgs = files\n        self.transform = transform\n        self.loader = img_loader\n        self.prefix = prefix\n    \n    def __len__(self):\n        return len(self.imgs)\n    \n    def __getitem__(self, idx):\n        img = self.imgs[idx]\n        label = 0 if 'cat' in img else 1\n        img = self.loader(f\"{self.prefix}/{img}\")\n        return self.transform(img), label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b1f98da9a40462c7e8a16c931ad6433e42e016bb"},"cell_type":"code","source":"img_train, img_test = train_test_split(os.listdir(data_dir), test_size=0.1, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d797b552993290aa6575b4d73fc27be785fc6979"},"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize([224, 224]),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])\n])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"edcf65532e0ebd34958c377e42a66f2dfd33ed06"},"cell_type":"code","source":"train_data = myDataset(data_dir, img_train, transform, lambda file: Image.open(file).convert('RGB'))\ntest_data = myDataset(data_dir, img_test, transform, lambda file: Image.open(file).convert('RGB'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6da821dfe41e248f125bc067ecf58cafd97fa342"},"cell_type":"code","source":"train_data_loader = torch.utils.data.DataLoader(train_data, batch_size=64, shuffle=True)\ntest_data_loader = torch.utils.data.DataLoader(test_data, batch_size=64)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7d3f02d03b814f483d4949d6f8ffb43083aa162e"},"cell_type":"markdown","source":"# **View the data**"},{"metadata":{"trusted":true,"_uuid":"8ff77260d4cb16de68ec28b3b36386ea59d1b70f"},"cell_type":"code","source":"x_exp, y_exp = next(iter(test_data_loader))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8ea0de11388f7a1ffdc4aa475bea21b0b43c2e5c"},"cell_type":"code","source":"y_exp","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9b735f0425ea6581135a3e7fde6df067ef0f27e6"},"cell_type":"code","source":"img = torchvision.utils.make_grid(x_exp)\nimg = img.numpy().transpose([1,2,0])\nplt.imshow(img)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6bf973552e90637c6d4ccf738fee09d0eaf3c304"},"cell_type":"markdown","source":"# Transfer from VGG16"},{"metadata":{"trusted":true,"_uuid":"1556ce7c36925e4b59da6d6f9b84d1b611f70b4d"},"cell_type":"code","source":"model = models.vgg16(pretrained=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"582e8fdfc990879cf97b84a1d5705a091da58373"},"cell_type":"code","source":"print(model)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0fc1c5a0cb5efd7a97c89b0a5c53da5e9b9e2bb5"},"cell_type":"code","source":"# 模型中的参数不需要更新\nfor parma in model.parameters():\n    parma.requires_grad = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d3e41ad9c17546409773bdd4d6aca60abdef12e4"},"cell_type":"code","source":"model.classifier = nn.Sequential(\n    nn.Linear(25088, 4096),\n    nn.ReLU(),\n    nn.Dropout(),\n    nn.Linear(4096, 4096),\n    nn.ReLU(),\n    nn.Dropout(),\n    nn.Linear(4096, 2)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d558bad09407e7e281b4b9fb40d76b5591363960"},"cell_type":"code","source":"if torch.cuda.is_available():\n    model = model.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"12d4d223017afd88079bc4eaa8e9cda59b7d3692"},"cell_type":"code","source":"loss = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.classifier.parameters(), lr=1e-5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7f6caf62c88b37037eb242df9b1bf58a542b2e5b"},"cell_type":"code","source":"from tqdm import tqdm_notebook as tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8d6008fa6f5ab469f69f361d104f865b142f0949"},"cell_type":"code","source":"epoch_n = 5\ntime_s = time.time()\n\nfor epoch in range(epoch_n):\n    print(f\"Epoch {epoch+1}/{epoch_n}\")\n    print(\"-\"*10)\n    \n    for phase in [\"train\", \"valid\"]:\n        if phase == 'train':\n            print(\"Training...\")\n            model.train(True)\n            dataloader = train_data_loader\n            img_datasets = train_data\n        else:\n            print(\"Validing...\")\n            model.eval()\n            dataloader = test_data_loader\n            img_datasets = test_data\n        \n        running_loss = 0.0\n        running_acc = 0.0\n        \n        for batch, data in tqdm(enumerate(dataloader, 1), total=len(dataloader)):\n            X, y = data\n            X, y = Variable(X.cuda()), Variable(y.cuda())\n            y_pred = model(X)\n            _, pred = torch.max(y_pred.data, 1)\n    \n            optimizer.zero_grad()\n            batch_loss = loss(y_pred, y)\n\n            if phase == \"train\":\n                batch_loss.backward()\n                optimizer.step()\n            \n            running_loss += batch_loss.data\n            running_acc += torch.sum(pred == y.data)\n            \n            if batch%100 == 0 and phase == \"train\":\n                print(f\"Batch {batch}, Train Loss {running_loss/(batch):.4f}, Train Acc {100*running_acc/(64*(batch))}\")\n        \n        epoch_loss = running_loss*64/len(img_datasets)\n        epoch_acc = 100*running_acc/(len(img_datasets) + 0.0)\n        \n        print(f\"{phase} Loss {epoch_loss:.4f} Acc {epoch_acc:.4f}\")\ntime_e = time.time()\nprint(f\"Spend {(time_e-time_s)/60:.3f} mins\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"00e3cc44dd1d7ea0784887fc45c52f10cdda12b9"},"cell_type":"code","source":"torch.save(model, './transfer_vgg16.pth')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b1478bc3e4b4ee6c7ccbbcb081af916d6e1b4163"},"cell_type":"markdown","source":"# Predict on the Test data"},{"metadata":{"trusted":true,"_uuid":"fb424ee1abb889b667259418690801e7903b4ad8"},"cell_type":"code","source":"class resultDataset(torch.utils.data.Dataset):\n    def __init__(self, prefix, transform, img_loader):\n        self.imgs = os.listdir(prefix)\n        self.transform = transform\n        self.loader = img_loader\n        self.prefix = prefix\n    \n    def __len__(self):\n        return len(self.imgs)\n    \n    def __getitem__(self, idx):\n        name = self.imgs[idx]\n        img = self.loader(f\"{self.prefix}/{name}\")\n        return self.transform(img), name","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e49790f368171954e15a2a006596376653bd0780"},"cell_type":"code","source":"T_data = resultDataset(\"/kaggle/input/test1/test1\", transform, lambda file: Image.open(file).convert('RGB'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bb1c0ded95cc9ee5598f5467ea4ba6824a6c65d7"},"cell_type":"code","source":"T_dataloader = torch.utils.data.DataLoader(T_data)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d37e3bb9b4440d818004935dba0d5872b5755703"},"cell_type":"code","source":"model.eval()\n \nresult = {\n    name[0]: torch.max(model(Variable(X_test.cuda())) ,1)[1].data.cpu().numpy() \n    for X_test, name in tqdm(T_dataloader, total=len(T_data))\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cb5a8ded45c92a8b12dca1c003be84b35a408533"},"cell_type":"code","source":"res_sample = np.random.choice([k for k in result.keys()], 18, replace=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"200511531e26f1c054ed2eebc77f8d5b4a563e84"},"cell_type":"code","source":"result[res_sample[0]]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"127e0e72d971b2ad7ed038aeffa7c940f2bdff56"},"cell_type":"code","source":"model.eval()\ny_pred = model(x_exp.cuda())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fb75a46023e99a5a14f9d9d7b521e718cbcdf568"},"cell_type":"code","source":"pred = torch.max(y_pred,1)[1].data.cpu().numpy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3195ec6090cd4a61ffc776aa586fc03fcc7e3113"},"cell_type":"code","source":"img = torchvision.utils.make_grid(x_exp)\nimg = img.numpy().transpose([1,2,0])\nplt.imshow(img)\nplt.title(\"Cat\" if pred == 0 else \"dog\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b600c6eb987c73a66602ea3427525717f0b4e01f"},"cell_type":"code","source":"from keras.preprocessing.image import load_img\nprefix = \"/kaggle/input/test1/test1\"\nIMAGE_SIZE = (224, 224)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4765043cce8f6fec3218f3c91d4d250e27892e8"},"cell_type":"code","source":"plt.figure(figsize=(12, 24))\nfor i, name in enumerate(res_sample, 1):\n    img = load_img(f\"{prefix}/{name}\", target_size=IMAGE_SIZE)\n    plt.subplot(6, 3, i)\n    plt.imshow(img)\n    plt.xlabel(\"cat\" if result[name] == 0 else \"dog\")\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a6525b239314b1d493d2d87a3a8f2084ec63d27"},"cell_type":"code","source":"result_df = pd.DataFrame.from_dict(result, orient='index', columns=[\"label\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c2bcef862738eb91d7e1a654db577e18c0a2b58b"},"cell_type":"code","source":"result_df['id'] = result_df.index.str.split(\".\").str[0].astype(int)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a0c74cc9ee088d7d55d2bfa9ce800cec7617f98"},"cell_type":"code","source":"result_df = result_df[['id', 'label']]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2d9c32667312e97f4f6981407a0f2b95d3d1b5b0"},"cell_type":"code","source":"result_df = result_df.sort_values(by=[\"id\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c42de92d4d3577a259578fc8dc956b7f51ea90c1"},"cell_type":"code","source":"result_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"36edc2c96b0a7aaad04987fe5a98f4445df74dc0"},"cell_type":"markdown","source":"# Transfer from ResNet50"},{"metadata":{"trusted":true,"_uuid":"d4161e639f7e51b9d73118b6133f7f90671d6698"},"cell_type":"code","source":"model = models.resnet50(pretrained=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e0feb354a44ca9ae0e9329e1c9b3dc6521de6c73"},"cell_type":"code","source":"for parma in model.parameters():\n    parma.requires_grad = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cd8c604aee4e2ac5b7efb7521760b08e873a34da"},"cell_type":"code","source":"model.fc = nn.Linear(2048, 2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"94e6cf801db6b36678655cc0f3eca44bcb4d8f85"},"cell_type":"code","source":"loss = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.fc.parameters(), lr=1e-5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"06ce37713f0ed70689e534378fd57037428b55ba"},"cell_type":"code","source":"model = model.cuda()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7c84ebf6a61a3b640af5de0d1c6c5ead3ba4b91f"},"cell_type":"code","source":"epoch_n = 5\ntime_s = time.time()\n\nfor epoch in range(epoch_n):\n    print(f\"Epoch {epoch+1}/{epoch_n}\")\n    print(\"-\"*10)\n    \n    for phase in [\"train\", \"valid\"]:\n        if phase == 'train':\n            print(\"Training...\")\n            model.train(True)\n            dataloader = train_data_loader\n            img_datasets = train_data\n        else:\n            print(\"Validing...\")\n            model.eval()\n            dataloader = test_data_loader\n            img_datasets = test_data\n        \n        running_loss = 0.0\n        running_acc = 0.0\n        \n        for batch, data in tqdm(enumerate(dataloader, 1), total=len(dataloader)):\n            X, y = data\n            X, y = Variable(X.cuda()), Variable(y.cuda())\n            y_pred = model(X)\n            _, pred = torch.max(y_pred.data, 1)\n    \n            optimizer.zero_grad()\n            batch_loss = loss(y_pred, y)\n\n            if phase == \"train\":\n                batch_loss.backward()\n                optimizer.step()\n            \n            running_loss += batch_loss.data\n            running_acc += torch.sum(pred == y.data)\n            \n            if batch%100 == 0 and phase == \"train\":\n                print(f\"Batch {batch}, Train Loss {running_loss/(batch):.4f}, Train Acc {100*running_acc/(64*(batch))}\")\n        \n        epoch_loss = running_loss*64/len(img_datasets)\n        epoch_acc = 100*running_acc/(len(img_datasets) + 0.0)\n        \n        print(f\"{phase} Loss {epoch_loss:.4f} Acc {epoch_acc:.4f}\")\ntime_e = time.time()\nprint(f\"Spend {(time_e-time_s)/60:.3f} mins\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"90b86695b68323125bcfad02f3a85604582d38ad"},"cell_type":"code","source":"torch.save(model, './transfer_resnet50.pth')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ab49f9c8ca82ae3385a895400b9443e1b057de75"},"cell_type":"code","source":"model.eval()\nresult_resnet = {\n    name[0]: torch.max(model(Variable(X_test.cuda())) ,1)[1].data.cpu().numpy() \n    for X_test, name in tqdm(T_dataloader, total=len(T_data))\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6334ff9b679cda4676c57030b58b5149150202bb"},"cell_type":"code","source":"result_df_r = pd.DataFrame.from_dict(result_resnet, orient='index', columns=[\"label\"])\nresult_df_r['id'] = result_df_r.index.str.split(\".\").str[0].astype(int)\nresult_df_r = result_df_r[['id', 'label']]\nresult_df_r = result_df_r.sort_values(by=[\"id\"])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cb8648bc61c4e93eaaf5ee6735a6bcbfe68f2255"},"cell_type":"markdown","source":"# Compare the two models with different prediction"},{"metadata":{"trusted":true,"_uuid":"6c35e6e667b317d38a94b6416132fb53a2eff403"},"cell_type":"code","source":"a = result_df[result_df_r.label != result_df.label]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee62f0b912e8a5fd3a275b5554fc6abc799320d1"},"cell_type":"code","source":"b = result_df_r[result_df_r.label != result_df.label]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a444a4e9f95414ba118a4811ab5b280944a7636c"},"cell_type":"code","source":"from keras.preprocessing.image import load_img\nprefix = \"/kaggle/input/test1/test1\"\nIMAGE_SIZE = (224, 224)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e5326101892a2f942b8a870cdfa5bd9781d2dc47"},"cell_type":"code","source":"plt.figure(figsize=(12, 24))\nfor i, name in enumerate(a.index[105:123], 1):\n    img = load_img(f\"{prefix}/{name}\", target_size=IMAGE_SIZE)\n    plt.subplot(6, 3, i)\n    plt.imshow(img)\n    plt.xlabel(\"cat\" if a.at[name, 'label'] == 0 else \"dog\")\nplt.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c867a874dd08f63a16cfe4892009391ff6b8021"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}