{"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\nimport pandas as pd\nimport matplotlib.pyplot as plt\n#%matplotlib inline \n\nimport os\nfrom sys import path\nfrom zipfile import ZipFile\n\nfrom tqdm import tqdm\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset , DataLoader\nfrom torchvision import transforms\nfrom torch.optim import Adam\nfrom torch.autograd import Variable","metadata":{"id":"vClSPq3H-N9W","execution":{"iopub.status.busy":"2022-05-05T09:08:36.793466Z","iopub.execute_input":"2022-05-05T09:08:36.794037Z","iopub.status.idle":"2022-05-05T09:08:36.799832Z","shell.execute_reply.started":"2022-05-05T09:08:36.793999Z","shell.execute_reply":"2022-05-05T09:08:36.798725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# config\nLR = 1e-3\nBATCH_SIZE = 20\nEPOCHS = 10\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nTRAIN_PATH = \"./train/\"\nTEST_PATH = \"./test1/\"\nMODEL_PATH = \"./model.pth\"","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:08:36.824658Z","iopub.execute_input":"2022-05-05T09:08:36.824947Z","iopub.status.idle":"2022-05-05T09:08:36.829397Z","shell.execute_reply.started":"2022-05-05T09:08:36.824917Z","shell.execute_reply":"2022-05-05T09:08:36.828618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustDat(Dataset):\n    def __init__(self, imgs, class_to_int, path, mode, transforms):\n        self.imgs = imgs\n        self.class_to_int = class_to_int\n        self.mode = mode\n        self.transforms = transforms\n        self.path = path\n        \n    def __len__(self):\n        return len(self.imgs)\n    \n    def __getitem__(self, idx):\n        img = Image.open(self.path + self.imgs[idx])\n        if self.mode  in [\"train\" , \"test\"]:\n            label = self.class_to_int[self.imgs[idx].split(\".\")[0]]\n            img = self.transforms(img)\n            return img, label\n        elif self.mode == \"pred\":\n            pred_id = self.imgs[idx].split(\".\")[0]\n            img = self.transforms(img)\n            return img, pred_id      ","metadata":{"id":"UNdNyDaD-Ziq","execution":{"iopub.status.busy":"2022-05-05T09:08:36.869013Z","iopub.execute_input":"2022-05-05T09:08:36.869294Z","iopub.status.idle":"2022-05-05T09:08:36.879517Z","shell.execute_reply.started":"2022-05-05T09:08:36.869267Z","shell.execute_reply":"2022-05-05T09:08:36.878687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CatandDogSet(Dataset):\n    def __init__(self, path):\n        self.path = path\n        self.img_name = os.listdir(self.path)\n                \n    def __len__(self):\n        return len(self.img_name)\n    \n    def __getitem__(self, idx):\n        img_idx = self.img_name[idx]\n        img_item_path = os.path.join(self.path, img_idx)\n        img = Image.open(img_item_path)\n        label = img_idx.split(\".\")[0]\n        return img, label, img_item_path","metadata":{"id":"4e6zvd2rXjhT","execution":{"iopub.status.busy":"2022-05-05T09:08:36.903669Z","iopub.execute_input":"2022-05-05T09:08:36.90387Z","iopub.status.idle":"2022-05-05T09:08:36.90951Z","shell.execute_reply.started":"2022-05-05T09:08:36.903846Z","shell.execute_reply":"2022-05-05T09:08:36.908683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with ZipFile('../input/dogs-vs-cats/train.zip', 'r') as zip_ref:\n    zip_ref.extractall('.')\n    \nwith ZipFile('../input/dogs-vs-cats/test1.zip', 'r') as zip_ref:\n    zip_ref.extractall('.') \n    \n!ls","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:08:36.936453Z","iopub.execute_input":"2022-05-05T09:08:36.936858Z","iopub.status.idle":"2022-05-05T09:08:52.253054Z","shell.execute_reply.started":"2022-05-05T09:08:36.93683Z","shell.execute_reply":"2022-05-05T09:08:52.252186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#path = os.listdir(\"./train/\")[100]\n#label = name[:3]\n#img = Image.open(\"./train/\"+ path)\n#print(path, label, plt.imshow(img))","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:08:52.255467Z","iopub.execute_input":"2022-05-05T09:08:52.255774Z","iopub.status.idle":"2022-05-05T09:08:52.259763Z","shell.execute_reply.started":"2022-05-05T09:08:52.255734Z","shell.execute_reply":"2022-05-05T09:08:52.259054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs = os.listdir(TRAIN_PATH)\n\ntrain_imgs = np.random.choice(imgs , 20000, replace=\"False\")\nprint(len(train_imgs))\nprint(len(set(train_imgs)))\n\ntest_imgs = np.setdiff1d(imgs , train_imgs)\nprint(len(test_imgs))\nprint(len(set(test_imgs)))\n\npred_imgs = [f\"{path}.jpg\" for path in range(1,len(os.listdir(TEST_PATH))+1)]","metadata":{"id":"2vOdTEtAk10s","execution":{"iopub.status.busy":"2022-05-05T09:08:52.260993Z","iopub.execute_input":"2022-05-05T09:08:52.261642Z","iopub.status.idle":"2022-05-05T09:08:52.341499Z","shell.execute_reply.started":"2022-05-05T09:08:52.261608Z","shell.execute_reply":"2022-05-05T09:08:52.340809Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_to_int = {\"cat\" : 0 , \"dog\" : 1}\ntrain_transforms = transforms.Compose([\n    transforms.Resize((360 , 360)) , \n    transforms.RandomHorizontalFlip(p = 0.5) , \n    transforms.ToTensor() , \n    transforms.Normalize((0 , 0 , 0) , (1 , 1 , 1))\n])\n\ntest_pred_transforms = transforms.Compose([\n    transforms.Resize((360 , 360)) , \n    transforms.ToTensor() , \n    transforms.Normalize((0 , 0 , 0) , (1 , 1 , 1))\n])","metadata":{"id":"gfqLwXSF-VTy","execution":{"iopub.status.busy":"2022-05-05T09:08:52.343424Z","iopub.execute_input":"2022-05-05T09:08:52.343859Z","iopub.status.idle":"2022-05-05T09:08:52.351211Z","shell.execute_reply.started":"2022-05-05T09:08:52.343824Z","shell.execute_reply":"2022-05-05T09:08:52.350453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = CatandDogSet(TRAIN_PATH)\n\ntrain = DataLoader(CustDat(train_imgs , class_to_int , TRAIN_PATH , \"train\" , train_transforms) , batch_size = BATCH_SIZE , shuffle = True)\ntest = DataLoader(CustDat(test_imgs , class_to_int , TRAIN_PATH , \"test\" , test_pred_transforms) , batch_size = BATCH_SIZE , shuffle = True)\npred = DataLoader(CustDat(pred_imgs , class_to_int , TEST_PATH , \"pred\" , test_pred_transforms))","metadata":{"id":"9f5S6rIt-cZf","outputId":"66edeedc-d800-4402-950c-312990e7338b","execution":{"iopub.status.busy":"2022-05-05T09:08:52.352517Z","iopub.execute_input":"2022-05-05T09:08:52.352824Z","iopub.status.idle":"2022-05-05T09:08:52.375637Z","shell.execute_reply.started":"2022-05-05T09:08:52.352787Z","shell.execute_reply":"2022-05-05T09:08:52.374965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img, label , path = dataset[np.random.randint(len(dataset))]\nplt.imshow(img)","metadata":{"id":"ODTb5WfuUX_G","outputId":"836d9614-d701-4766-9f0b-bc51f2ffa68b","execution":{"iopub.status.busy":"2022-05-05T09:08:52.376863Z","iopub.execute_input":"2022-05-05T09:08:52.377138Z","iopub.status.idle":"2022-05-05T09:08:52.591035Z","shell.execute_reply.started":"2022-05-05T09:08:52.377076Z","shell.execute_reply":"2022-05-05T09:08:52.590401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet34', pretrained=True)","metadata":{"id":"SZOC_i4j-ckD","outputId":"e691c925-17cf-4e94-c446-6e4cc4474977","execution":{"iopub.status.busy":"2022-05-05T09:08:52.592298Z","iopub.execute_input":"2022-05-05T09:08:52.592759Z","iopub.status.idle":"2022-05-05T09:08:53.00197Z","shell.execute_reply.started":"2022-05-05T09:08:52.592723Z","shell.execute_reply":"2022-05-05T09:08:53.00122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_last_features = model.fc.in_features","metadata":{"id":"OZaZiFWQ-ghL","execution":{"iopub.status.busy":"2022-05-05T09:08:53.003399Z","iopub.execute_input":"2022-05-05T09:08:53.003823Z","iopub.status.idle":"2022-05-05T09:08:53.008509Z","shell.execute_reply.started":"2022-05-05T09:08:53.003788Z","shell.execute_reply":"2022-05-05T09:08:53.007745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"new_last_yr = nn.Sequential(\n    nn.Linear(num_last_features , 1) , \n    nn.Sigmoid()\n)","metadata":{"id":"2V0yJj2Z-gxI","execution":{"iopub.status.busy":"2022-05-05T09:08:53.009991Z","iopub.execute_input":"2022-05-05T09:08:53.010463Z","iopub.status.idle":"2022-05-05T09:08:53.018427Z","shell.execute_reply.started":"2022-05-05T09:08:53.010425Z","shell.execute_reply":"2022-05-05T09:08:53.017561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.fc = new_last_yr","metadata":{"id":"Vive2tMh-jmx","execution":{"iopub.status.busy":"2022-05-05T09:08:53.021295Z","iopub.execute_input":"2022-05-05T09:08:53.021648Z","iopub.status.idle":"2022-05-05T09:08:53.026849Z","shell.execute_reply.started":"2022-05-05T09:08:53.021611Z","shell.execute_reply":"2022-05-05T09:08:53.025992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DEVICE","metadata":{"id":"Jxc8ijLn-kP5","outputId":"1da90e95-ab19-4fc5-96b6-a498d34fd535","execution":{"iopub.status.busy":"2022-05-05T09:08:53.028326Z","iopub.execute_input":"2022-05-05T09:08:53.028643Z","iopub.status.idle":"2022-05-05T09:08:53.037949Z","shell.execute_reply.started":"2022-05-05T09:08:53.028603Z","shell.execute_reply":"2022-05-05T09:08:53.0371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_fin = model.to(DEVICE)","metadata":{"id":"IosfdSic-qIs","execution":{"iopub.status.busy":"2022-05-05T09:08:53.039047Z","iopub.execute_input":"2022-05-05T09:08:53.03982Z","iopub.status.idle":"2022-05-05T09:08:53.074403Z","shell.execute_reply.started":"2022-05-05T09:08:53.039784Z","shell.execute_reply":"2022-05-05T09:08:53.073805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"criterion = nn.BCELoss()\noptimizer = Adam(model_fin.fc.parameters() , lr = LR)","metadata":{"id":"l6dNtIKQ-qaF","execution":{"iopub.status.busy":"2022-05-05T09:08:53.075373Z","iopub.execute_input":"2022-05-05T09:08:53.075683Z","iopub.status.idle":"2022-05-05T09:08:53.080481Z","shell.execute_reply.started":"2022-05-05T09:08:53.075648Z","shell.execute_reply":"2022-05-05T09:08:53.079663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(EPOCHS):\n    model_fin.train()\n    su_tr = 0\n    tot_tr = 0\n    loss_list = []\n    \n    train_pbar = tqdm(train, position=0, leave=True)\n    for images , labels in train_pbar:\n        if torch.cuda.is_available():\n            images = Variable(images.cuda())\n            labels = Variable(labels.cuda())\n            \n        optimizer.zero_grad()\n        output = model_fin(images)\n        loss = criterion(torch.squeeze(output) , labels.float())\n        loss_list.append(loss.data)\n        su_tr += torch.sum(output.reshape(labels.shape).round() == labels)\n        tot_tr += labels.shape[0]\n        loss.backward()\n        optimizer.step()\n        \n    model_fin.eval()\n    su_te = 0\n    tot_te = 0\n    with torch.no_grad():\n        for images , labels in test:\n            output = model_fin(images.cuda())\n            su_te += torch.sum(output.reshape(labels.shape).round().cpu() == labels)\n            tot_te += labels.shape[0]\n    \n    torch.save(model_fin, MODEL_PATH)\n    #torch.save(model_fin.state_dict(), MODEL_PATH) 官方推薦\n    print(\"loss is \"+str(torch.mean(torch.tensor(loss_list)))+\" train accu \"+str(su_tr/tot_tr)+\" test accu \"+str(su_te/tot_te))","metadata":{"id":"kuxElCMb-u8d","outputId":"4384aa40-75fc-4135-d0f4-8839efca8274","execution":{"iopub.status.busy":"2022-05-05T09:08:53.081927Z","iopub.execute_input":"2022-05-05T09:08:53.082182Z","iopub.status.idle":"2022-05-05T09:54:04.188048Z","shell.execute_reply.started":"2022-05-05T09:08:53.08215Z","shell.execute_reply":"2022-05-05T09:54:04.187255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def test_submit(model):\n    model.eval()\n    with torch.no_grad():\n        pred_label=[]\n        for images , Id in tqdm(pred):\n            output = model(images.cuda())\n            label = output.round().cpu()\n            pred_label.append(int(label))\n\n    return pred_label\n\ndef predict_CatandDog(path):\n    model = torch.load(\"./model.pth\") #如果GPU訓練CPU跑要加 map_location=torch.device(\"CPU\")\n    if path in \"./test1/\":\n        test_set = CatandDogSet(path)\n        img, t_label , t_path = test_set[np.random.randint(len(test_set))]\n    else:\n        img = Image.open(path)\n    \n    img_ts = test_pred_transforms(img)\n    img_ts = torch.reshape(img_ts, (1, 3, 360, 360))\n    output = model(img_ts.cuda())\n    label = output.round().cpu()\n    ch_label = \"dog\" if int(label)==1 else \"cat\"\n\n\n    print(ch_label)\n    plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:54:04.189415Z","iopub.execute_input":"2022-05-05T09:54:04.190069Z","iopub.status.idle":"2022-05-05T09:54:04.199691Z","shell.execute_reply.started":"2022-05-05T09:54:04.190028Z","shell.execute_reply":"2022-05-05T09:54:04.199044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit = pd.read_csv('../input/dogs-vs-cats/sampleSubmission.csv')\nsubmit['label'] = test_submit(model_fin)\nsubmit","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:54:04.202337Z","iopub.execute_input":"2022-05-05T09:54:04.202599Z","iopub.status.idle":"2022-05-05T09:56:31.005735Z","shell.execute_reply.started":"2022-05-05T09:54:04.202563Z","shell.execute_reply":"2022-05-05T09:56:31.004905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submit.to_csv('./submit_dogcat.csv', index= False)","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:56:31.007082Z","iopub.execute_input":"2022-05-05T09:56:31.007408Z","iopub.status.idle":"2022-05-05T09:56:31.033546Z","shell.execute_reply.started":"2022-05-05T09:56:31.00737Z","shell.execute_reply":"2022-05-05T09:56:31.03288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_CatandDog(\"./test1\")","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:57:07.09996Z","iopub.execute_input":"2022-05-05T09:57:07.100497Z","iopub.status.idle":"2022-05-05T09:57:07.388976Z","shell.execute_reply.started":"2022-05-05T09:57:07.100459Z","shell.execute_reply":"2022-05-05T09:57:07.388354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predict_CatandDog(\"./test1/1234.jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-05-05T09:56:31.470642Z","iopub.execute_input":"2022-05-05T09:56:31.476112Z","iopub.status.idle":"2022-05-05T09:56:32.175158Z","shell.execute_reply.started":"2022-05-05T09:56:31.476073Z","shell.execute_reply":"2022-05-05T09:56:32.174484Z"},"trusted":true},"execution_count":null,"outputs":[]}]}