{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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)\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":"# print(os.listdir(\"../input/train\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import shutil \nfrom tqdm import tqdm\n\ntrain_dir = 'train'\nval_dir = 'val'\ntest_dir = 'test'\n\nshutil.copytree('../input/test', os.path.join(test_dir, 'unknown'))\n\nfor dir_name in [train_dir, val_dir]:\n    for class_name in ['dog', 'cat']:\n        os.makedirs(os.path.join(dir_name, class_name), exist_ok=True)\n\nfor i, file_name in enumerate(tqdm(os.listdir('../input/train'))):\n    dest_dir = train_dir if i % 5 != 0 else val_dir\n    \n    for class_name in ['dog', 'cat']:\n        if file_name.startswith(class_name):\n            shutil.copy(os.path.join('../input/train', file_name),\n                        os.path.join(dest_dir, class_name, file_name))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nimport numpy as np\nimport torchvision\nimport matplotlib.pyplot as plt\nimport time\nimport copy\n\nfrom torchvision import transforms, models\ntrain_transforms = transforms.Compose([\n    transforms.RandomResizedCrop(224),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])\n\nval_transforms = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])\n\ntrain_dataset = torchvision.datasets.ImageFolder(train_dir, train_transforms)\nval_dataset = torchvision.datasets.ImageFolder(val_dir, val_transforms)\ntest_dataset = torchvision.datasets.ImageFolder(test_dir, val_transforms)\n\nbatch_size = 32\ntrain_dataloader = torch.utils.data.DataLoader(\n    train_dataset, batch_size=batch_size, shuffle=True, num_workers=batch_size)\nval_dataloader = torch.utils.data.DataLoader(\n    val_dataset, batch_size=batch_size, shuffle=False, num_workers=batch_size)\ntest_dataloader = torch.utils.data.DataLoader(\n    test_dataset, batch_size=batch_size, shuffle=False, num_workers=batch_size)\n\nclass_names = train_dataset.classes\n\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"len(train_dataloader), len(train_dataset)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_batch, y_batch = next(iter(val_dataloader))\nmean = np.array([0.485, 0.456, 0.406])\nstd = np.array([0.229, 0.224, 0.225])\nplt.imshow(X_batch[0].permute(1, 2, 0).numpy() * std + mean);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_input(input_tensor, title=''):\n    image = input_tensor.permute(1, 2, 0).numpy()\n    image = std * image + mean\n    plt.imshow(image.clip(0, 1))\n    plt.title(title)\n    plt.show()\n\nX_batch, y_batch = next(iter(train_dataloader))\n\nfor x_item, y_item in zip(X_batch, y_batch):\n    show_input(x_item, title=class_names[y_item])\n    plt.pause(0.001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_model(model, loss, optimizer, scheduler, num_epochs=25):\n    for epoch in range(num_epochs):\n        print('Epoch {}/{}:'.format(epoch, num_epochs - 1), flush=True)\n\n        # Each epoch has a training and validation phase\n        for phase in ['train', 'val']:\n            if phase == 'train':\n                dataloader = train_dataloader\n                scheduler.step()\n                model.train()  # Set model to training mode\n            else:\n                dataloader = val_dataloader\n                model.eval()   # Set model to evaluate mode\n\n            running_loss = 0.\n            running_acc = 0.\n\n            # Iterate over data.\n            for inputs, labels in tqdm(dataloader):\n                inputs = inputs.to(device)\n                labels = labels.to(device)\n\n                optimizer.zero_grad()\n\n                # forward and backward\n                with torch.set_grad_enabled(phase == 'train'):\n                    preds = model(inputs)\n                    loss_value = loss(preds, labels)\n                    preds_class = preds.argmax(dim=1)\n\n                    # backward + optimize only if in training phase\n                    if phase == 'train':\n                        loss_value.backward()\n                        optimizer.step()\n\n                # statistics\n                running_loss += loss_value.item()\n                running_acc += (preds_class == labels.data).float().mean()\n\n            epoch_loss = running_loss / len(dataloader)\n            epoch_acc = running_acc / len(dataloader)\n\n            print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))\n\n        print()\n\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = models.resnet18(pretrained=True)\n\n# Disable grad for all conv layers\nfor param in model.parameters():\n    param.requires_grad = False\n\nmodel.fc = torch.nn.Linear(model.fc.in_features, 2)\n\nmodel = model.to(device)\nloss = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=1.0e-3)\n\n# Decay LR by a factor of 0.1 every 7 epochs\nscheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_model(model, loss, optimizer, scheduler, num_epochs=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.eval()\n\ntest_predictions = []\nfor inputs, labels in tqdm(test_dataloader):\n    inputs = inputs.to(device)\n    labels = labels.to(device)\n    with torch.set_grad_enabled(False):\n        preds = model(inputs)\n    test_predictions.append(\n        torch.nn.functional.softmax(preds, dim=1)[:,1].data.cpu().numpy())\n    \ntest_predictions = np.concatenate(test_predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_batch, y_batch = next(iter(test_dataloader))\n\nfor x_item, pred in zip(X_batch, test_predictions):\n    show_input(x_item, title=pred)\n    plt.pause(0.001)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_file_names = os.listdir(os.path.join(test_dir, 'unknown'))\n\nsubmission_df = pd.DataFrame.from_dict({'id': np.arange(1, len(test_predictions) + 1),\n                                        'label': np.zeros(len(test_predictions))})\nfor i, file_name in enumerate(test_file_names):\n    index = int(file_name[:file_name.rfind('.')])\n    submission_df.at[index-1, 'label'] = test_predictions[i]\nsubmission_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf train val test","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}