{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"from __future__ import print_function\nfrom __future__ import division\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport pickle\nimport numpy as np\nimport torchvision\nfrom torchvision import datasets, models, transforms\nfrom torch.utils.data import TensorDataset, DataLoader,Dataset\nimport matplotlib.pyplot as plt\nimport time\nimport os\nimport copy\nimport pandas as pd\nimport PIL.Image as Image\nfrom torch.utils.data.sampler import SubsetRandomSampler\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.preprocessing import OneHotEncoder\ntrain_on_gpu = True\n\nprint(\"PyTorch Version: \",torch.__version__)\nprint(\"Torchvision Version: \",torchvision.__version__)\n\ndf_train = pd.read_csv(\"../input/train.csv\")\n\ndata_dir = \"../input/train\"\nmodel_name = \"densenet\"\nnum_classes = 5005\nbatch_size = 32\nnum_epochs = 15\nfeature_extract = False\nnum_workers = 0\n\ndef prepare_labels(y):\n    # From here: https://www.kaggle.com/pestipeti/keras-cnn-starter\n    values = np.array(y)\n    label_encoder = LabelEncoder()\n    integer_encoded = label_encoder.fit_transform(values)\n\n    onehot_encoder = OneHotEncoder(sparse=False)\n    integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)\n    onehot_encoded = onehot_encoder.fit_transform(integer_encoded)\n\n    y = onehot_encoded\n    return y, label_encoder\n\ny, le = prepare_labels(df_train['Id'])\nprint(y)\n\nclass WhaleDataset(Dataset):\n    def __init__(self, datafolder, datatype='train', df=None,\n                 transform = transforms.Compose([transforms.ToTensor()]), y=None):\n        self.datafolder = datafolder\n        self.datatype = datatype\n        self.y = y\n        if self.datatype == 'train':\n            self.df = df.values\n        self.image_files_list = [s for s in os.listdir(datafolder)]\n        self.transform = transform\n\n\n    def __len__(self):\n        return len(self.image_files_list)\n    \n    def __getitem__(self, idx):\n        if self.datatype == 'train':\n            img_name = os.path.join(self.datafolder, self.df[idx][0])\n            label = self.y[idx]\n            \n        elif self.datatype == 'test':\n            img_name = os.path.join(self.datafolder, self.image_files_list[idx])\n            label = np.zeros((5005,))\n\n        image = Image.open(img_name).convert('RGB')\n        image = self.transform(image)\n        if self.datatype == 'train':\n            return image, label\n        elif self.datatype == 'test':\n            # so that the images will be in a correct order\n            return image, label, self.image_files_list[idx]\n\n\n\ndef set_parameter_requires_grad(model, feature_extracting):\n    if feature_extracting:\n        for param in model.parameters():\n            param.requires_grad = False\n\n\ndef initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):\n    # Initialize these variables which will be set in this if statement. Each of these\n    #   variables is model specific.\n    model_ft = None\n    input_size = 0\n\n    if model_name == \"resnet\":\n        \"\"\" Resnet34\n        \"\"\"\n        model_ft = models.resnet34(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n\n    elif model_name == \"alexnet\":\n        \"\"\" Alexnet\n        \"\"\"\n        model_ft = models.alexnet(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier[6].in_features\n        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)\n        input_size = 224\n\n    elif model_name == \"vgg\":\n        \"\"\" VGG11_bn\n        \"\"\"\n        model_ft = models.vgg11_bn(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier[6].in_features\n        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)\n        input_size = 224\n\n    elif model_name == \"squeezenet\":\n        \"\"\" Squeezenet\n        \"\"\"\n        model_ft = models.squeezenet1_0(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        model_ft.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))\n        model_ft.num_classes = num_classes\n        input_size = 224\n\n    elif model_name == \"densenet\":\n        \"\"\" Densenet\n        \"\"\"\n        model_ft = models.densenet121(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        num_ftrs = model_ft.classifier.in_features\n        model_ft.classifier = nn.Linear(num_ftrs, num_classes)\n        input_size = 224\n\n    elif model_name == \"inception\":\n        \"\"\" Inception v3\n        Be careful, expects (299,299) sized images and has auxiliary output\n        \"\"\"\n        model_ft = models.inception_v3(pretrained=use_pretrained)\n        set_parameter_requires_grad(model_ft, feature_extract)\n        # Handle the auxilary net\n        num_ftrs = model_ft.AuxLogits.fc.in_features\n        model_ft.AuxLogits.fc = nn.Linear(num_ftrs, num_classes)\n        # Handle the primary net\n        num_ftrs = model_ft.fc.in_features\n        model_ft.fc = nn.Linear(num_ftrs,num_classes)\n        input_size = 299\n\n    else:\n        print(\"Invalid model name, exiting...\")\n        exit()\n\n    return model_ft, input_size\n\n# Initialize the model for this run\nmodel_ft, input_size = initialize_model(model_name, num_classes, feature_extract, use_pretrained=True)\n\n# Print the model we just instantiated\nprint(model_ft)\n\n\n\ndata_transforms = transforms.Compose([\n                                      transforms.Resize((224,224)),\n                                      transforms.RandomHorizontalFlip(0.5),\n                                      transforms.RandomAffine(30),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                                             std=[0.229, 0.224, 0.225])\n    ])\n\ntest_transforms = transforms.Compose([\n                                      transforms.Resize((224,224)),\n                                      transforms.ToTensor(),\n                                      transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                                             std=[0.229, 0.224, 0.225])\n    ])\n\n\ndef accuracy(outputs,labels):\n    preds = outputs.max(dim=1)[1]\n    return (preds==labels).float().sum()\n\ndef train(batch_size = 32, epochs = 10, transform = None):\n    tfmd_dataset = WhaleDataset(datafolder = \"../input/train\", datatype='train', df = df_train, \n                                transform = transform, y=y)\n#     train_sampler = SubsetRandomSampler(list(range(len(os.listdir('../input/train')))))\n    dataloader = torch.utils.data.DataLoader(tfmd_dataset, batch_size=batch_size, shuffle=True, \n                                             num_workers=num_workers)\n    criterion = nn.BCEWithLogitsLoss()\n    optimizer = optim.Adam(model_ft.parameters(), lr=0.0001)\n    \n    if torch.cuda.is_available():\n        model_ft.cuda()\n        nn.DataParallel(model_ft)\n        print(\"GPU\")\n    epoch_loss_data = []\n    epoch_accuracy_data = []\n\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\n    print(device)\n    \n    for epoch in range(1,epochs+1):  # loop over the dataset multiple times\n\n        running_loss, running_loss_total,epoch_accuracy = 0.0, 0.0,0.0\n        for i, data in enumerate(dataloader, 0):\n            # get the inputs\n            inputs, labels = data\n            labels = labels.double()\n            inputs, labels = inputs.to(device), labels.to(device)\n        \n            # zero the parameter gradients\n            optimizer.zero_grad()\n            # forward + backward + optimize\n            outputs = model_ft(inputs).double()\n            \n            loss = criterion(outputs, labels)\n            \n            loss.backward()\n            optimizer.step()\n\n            # print statistics\n#             epoch_accuracy += accuracy(outputs,labels)\n#             running_epoch_acc = epoch_accuracy/(labels.size()[0] * (i+1))\n            running_loss += loss.item()\n            running_loss_total += loss.item()\n            if i%30 == 29:\n                print('[%d, %5d] loss: %.3f, epoch_accuracy:' % (epoch, i + 1,\n                                                                    running_loss))\n                running_loss = 0.0\n            if i%100 == 99:\n                torch.save(model_ft.state_dict(), 'checkpoint')\n                torch.save(optimizer.state_dict(), 'optimizer_checkpoint')\n                with open('Running_loss.p','wb') as f:\n                    pickle.dump(running_loss_total,f)\n#                 with open('Running_accuracy.p','wb') as f:\n#                     pickle.dump(running_epoch_acc,f)\n#         epoch_accuracy_data.append(running_epoch_acc)\n        epoch_loss_data.append(running_loss_total)\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9d1b676136f6d4968c9ef58269afdfb623dc21ca","scrolled":false},"cell_type":"code","source":"train(transform=data_transforms,epochs=28,batch_size=32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0cb00ed5ca93754e9847d7f0d75351208ad02ee2","scrolled":true},"cell_type":"code","source":"#train(transform=data_transforms,epochs=2,batch_size=32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9dcffe05f53f1766f3352d86e402bbba79344dac"},"cell_type":"code","source":"sub = pd.read_csv(\"../input/sample_submission.csv\")\ndef test(batch_size, transform, model):\n    test_set = WhaleDataset(datafolder = \"../input/test\", datatype = \"test\", transform = transform)\n    test_loader = torch.utils.data.DataLoader(test_set, batch_size=32, num_workers=num_workers)\n    model.eval()\n    for (data, target, name) in test_loader:\n        data = data.cuda()\n        output = model(data)\n        print(output)\n        output = output.cpu().detach().numpy()\n        for i, (e, n) in enumerate(list(zip(output, name))):\n            sub.loc[sub['Image'] == n, 'Id'] = ' '.join(le.inverse_transform(e.argsort()[-5:][::-1]))\n    sub.to_csv('basic_model.csv', index=False)    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a546c82691c3757bfb3228c53d186a70c243210"},"cell_type":"code","source":"test(32, test_transforms, model_ft)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8762213033d7b4d635501987d53faa210c5e7e58"},"cell_type":"code","source":"print(sub.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"70febd8912262ff61cf86cc309d0e3a802ece46a"},"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}