{"cells":[{"metadata":{"_uuid":"1a16a82b19992eecfe46424ebf505a53a354e62b"},"cell_type":"markdown","source":"Throught this kernel I'm going to made a model for the  [Human Protein Atlas Image Classification](https://www.kaggle.com/c/human-protein-atlas-image-classification) competition. Our models should be able to classify mixed patterns of proteins in microscope images. That means **this is a multilabel classification problem** so each sample could have more than one label.\n\nAs we have a really huge dataset, I will load \"batches\" of samples each time I train the model. The way I'll train the model will be:\n\n- Randomly load samples from the dataset based on the amount of samples of each type (for me, a type is a possible combination of labels) (proportionally).\n- Train the model with these samples (a few epochs)\n- Reload (randomly) another dataset and repeat  as long as it is required;\n\nMoreover, as I will train the model on a kaggle kernel, I will store my models in a dropbox remote directory and load them from it in order to stop training when needed and be able to continue training that model in other moment.\n\n![process](http://i67.tinypic.com/33dza6u.png)\n\nThere are 28 possible label for a sample. Let's start with defining these possible labels and our data paths:"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%matplotlib inline \nimport matplotlib.pyplot as plt\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport time\nimport copy\n\n\nfrom PIL import Image\n\nDATASET_SIZE = 8000\nBATCH_SIZE = 200\nW = H = 256\n\ntrain_path = '../input/train/'\ntest_path = '../input/test/'\n\nLABEL_MAP = {\n0: \"Nucleoplasm\" ,\n1: \"Nuclear membrane\"   ,\n2: \"Nucleoli\"   ,\n3: \"Nucleoli fibrillar center\",   \n4: \"Nuclear speckles\"   ,\n5: \"Nuclear bodies\"   ,\n6: \"Endoplasmic reticulum\"   ,\n7: \"Golgi apparatus\"  ,\n8: \"Peroxisomes\"   ,\n9:  \"Endosomes\"   ,\n10: \"Lysosomes\"   ,\n11: \"Intermediate filaments\"  , \n12: \"Actin filaments\"   ,\n13: \"Focal adhesion sites\"  ,\n14: \"Microtubules\"   ,\n15: \"Microtubule ends\"   ,\n16: \"Cytokinetic bridge\"   ,\n17: \"Mitotic spindle\"  ,\n18: \"Microtubule organizing center\",  \n19: \"Centrosome\",\n20: \"Lipid droplets\"   ,\n21: \"Plasma membrane\"  ,\n22: \"Cell junctions\"   ,\n23: \"Mitochondria\"   ,\n24: \"Aggresome\"   ,\n25: \"Cytosol\" ,\n26: \"Cytoplasmic bodies\",\n27: \"Rods & rings\"}\n\nLABELS = []\n\nfor label in LABEL_MAP.values():\n    LABELS.append(label)\n    \ntrain_csv_path = '../input/train.csv'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b676bf446d67628e75c7203eb113f96e1cf3528c"},"cell_type":"code","source":"df = pd.read_csv(train_csv_path)\n\nTRAINING_SAMPLES = df.shape[0]\n\nprint(\"we have \" + str(TRAINING_SAMPLES) + \" different samples\")\nprint(\"And there are \"+  str(len(df.Target.unique())) + \" different combinations of labels in our dataset\")\n\nimport seaborn as sns\nsns.set(style=\"dark\")\n\nn = 20\n\nvalues = df['Target'].value_counts()[:n].keys().tolist()\ncounts = df['Target'].value_counts()[:n].tolist()\n\nplt.figure(figsize=(6,6))\npal = sns.cubehelix_palette(n, start=2, rot=0, dark=0, light=.75, reverse=True)\ng = sns.barplot(y=counts, x=values, palette=pal)\ng.set_title(str(n)+\" MOST COMMON LABEL COMBINATIONS\")\ng.set_xticklabels(g.get_xticklabels(),rotation=90);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0fa12d78d51ec7c1b40b6d67abe9c554241b6d4c"},"cell_type":"markdown","source":"\n\n"},{"metadata":{"_uuid":"22ec9acaf21a0ec282eb1f145c344cbc702133a3"},"cell_type":"markdown","source":"Now, how to load our images for a given id:"},{"metadata":{"trusted":true,"_uuid":"c253f4a5120a2f797d974d88917c4a7e03e2fb51"},"cell_type":"code","source":"from PIL import Image\n\ndef load_image(basepath, image_id):\n    images = np.zeros(shape=(256,256,4))\n    r = Image.open(basepath+image_id+\"_red.png\").resize((256,256))\n    g = Image.open(basepath+image_id+\"_green.png\").resize((256,256))\n    b = Image.open(basepath+image_id+\"_blue.png\").resize((256,256))\n    y = Image.open(basepath+image_id+\"_yellow.png\").resize((256,256))\n\n    images[:,:,0] = np.asarray(r)\n    images[:,:,1] = np.asarray(g)\n    images[:,:,2] = np.asarray(b)\n    images[:,:,3] = np.asarray(y)\n    \n    return images","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ecf1edf2c0162067c77ccf2b22895a10813de270"},"cell_type":"markdown","source":"As our dataset is huge, I will calculate the portion of it that correspond to each possible combination of labels and I will use this value to decide how many samples of each type (combination of labels) I will use for training."},{"metadata":{"trusted":true,"_uuid":"191bdf6623f9afb2d0090eeda494e87e421a93af"},"cell_type":"code","source":"targets = df['Target'].value_counts().keys()\ncounts = df['Target'].value_counts().values\n\nhow_many = counts/TRAINING_SAMPLES*DATASET_SIZE\n\n# at least one example of each possible combination of labels..\nhow_many = how_many.astype('int')+1\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f273687682d8b91c8c44e5f6fff243df5d2afe84"},"cell_type":"markdown","source":"We will use a pytorch type dataset defining that loading when create an instance. \n\nAs you can see, I will not load the images in the dataframe because of the obvious memory limitations. I'll load the image for each sample when __get_item__ is called. \n\nTe he function load_data use the array how_many calculated previously for fill an empty dataframe with samples of the complete_dataframe randomly. Also, afer fill that dataframe, we suffle it in order to get a random order of sample types while training."},{"metadata":{"trusted":true,"_uuid":"d9f7c7af4de1eb56ebe11174367be8a10cc7be53"},"cell_type":"code","source":"import torch\nimport numpy as np\nimport pandas as pd\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms, utils\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nfrom skimage import io, transform\nfrom sklearn.preprocessing import MultiLabelBinarizer\nclasses = np.arange(0,28)\nmlb = MultiLabelBinarizer(classes)\nmlb.fit(classes)\n\nclass HumanProteinDataset(Dataset):\n\n    def __init__(self, csv_file,transform=None, test=False):\n        \"\"\"\n        Args:\n            csv_file (string): Path to the csv file with annotations.\n            test (Boolean): the csv no contains labels\n            transform (callable, optional): Optional transform to be applied\n                on a sample.\n        \"\"\"\n        self.test = test\n        self.complete_df = pd.read_csv(csv_file)\n        \n        if not test:\n            self.path = train_path\n            self.loadData()\n        else:\n            self.path = test_path\n            self.df = self.complete_df\n            \n        self.transform = transform\n        \n    def CreateDummyVariables(self):\n        self.complete_df['Targets'] = self.complete_df['Target'].map(lambda x: list(map(int, x.strip().split())))\n            \n    def loadData(self):\n        self.CreateDummyVariables()\n        self.df = pd.DataFrame(columns=['Id','Target'])\n        for i, target in enumerate(targets):\n            fdf = self.complete_df[self.complete_df['Target'] == target]\n            sample = fdf.sample(n=how_many[i], replace=False)\n            self.df = self.df.append(sample)\n        self.df = self.df.sample(frac=1).reset_index(drop=True)\n            \n    def __getitem__(self, idx):\n        \n        image = load_image(self.path, self.df['Id'].iloc[idx])\n        \n        sample = {'image': image}\n\n        if not self.test:\n            target = np.array(self.complete_df['Targets'].iloc[idx])\n            target = mlb.transform([target])\n            sample['target'] = target\n        \n        else:\n            sample['Id'] = self.df['Id'].iloc[idx]\n\n        if self.transform:\n            sample = self.transform(sample)\n        return sample\n    \n    def __len__(self):\n        return self.df.shape[0]\n    \n    def shape(self):\n        return self.df.shape\n    \nclass ToTensor(object):\n    \"\"\"Convert ndarrays in sample to Tensors.\"\"\"\n\n    def __call__(self, sample):\n        \n        image = sample['image']/255.0\n        \n        totensor = transforms.ToTensor()\n        \n        ret = {'image': totensor(image)}\n        \n        if \"target\" in sample.keys():\n            target = sample['target'][0]\n            ret['target'] = target\n        else:\n            ret['Id'] = sample['Id']\n                  \n        return ret","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4613e5dc5d8ec6a596c26dbfcf191021732602f1","scrolled":true},"cell_type":"code","source":"dataset = HumanProteinDataset(train_csv_path, transform=ToTensor())","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2a3c4515f8e72c4219173535e670bb3cf39f4b9f"},"cell_type":"markdown","source":"Check if our images are being loaded right and visualice some of them:"},{"metadata":{"trusted":true,"_uuid":"a34a8e23f8d9ec8c62ec64a397175e996a2592c3"},"cell_type":"code","source":"def Show(sample):\n    f, (ax1,ax2,ax3,ax4) = plt.subplots(1, 4, figsize=(25,25), sharey=True)\n\n    title = ''\n    \n    labels =sample['target']\n                \n    for i, label in enumerate(LABELS):\n        if labels[i] == 1:\n            if title == '':\n                title += label\n            else:\n                title += \" & \" + label\n            \n    ax1.imshow(sample['image'][0,:,:],cmap=\"hot\")\n    ax1.set_title('Red')\n    ax2.imshow(sample['image'][1,:,:],cmap=\"copper\")\n    ax2.set_title('Green')\n    ax3.imshow(sample['image'][2,:,:],cmap=\"bone\")\n    ax3.set_title('Blue')\n    ax4.imshow(sample['image'][3,:,:],cmap=\"afmhot\")\n    ax4.set_title('Yellow')\n    f.suptitle(title, fontsize=20, y=0.62)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"baa790afcb94dabb459f03713ca6527c694e6e13"},"cell_type":"code","source":"import random\n\nidxs = random.sample(range(1, dataset.df.shape[0]), 3)\n\nfor idx in idxs:\n    Show(dataset[idx])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a52b3fb3aed1ab84fab2c4f027384c4790af5109"},"cell_type":"markdown","source":"# TRAINING A MODEL WITH CNN\n# split training dataset into training+validation\n\nthe function prepare_loaders will call dataset.loadData, that means each time we \"prepare our loaders\" the dataset will contain different images for training and validation."},{"metadata":{"trusted":true,"_uuid":"af991b03a82ea7e27bea3604bfcc9fa28ecbd646"},"cell_type":"code","source":"from torch.utils.data.sampler import SubsetRandomSampler\nfrom torch.optim import lr_scheduler\nimport torch.optim as optim\nimport torch.nn as nn\nimport math\n\ndef prepare_loaders():\n    dataset.loadData()\n    num_train = len(dataset)\n    indices = list(range(num_train))\n    val_size = int(0.45 * num_train) \n\n    # Random, non-contiguous split\n    validation_idx = np.random.choice(indices, size=val_size, replace=False)\n    train_idx = list(set(indices) - set(validation_idx))\n\n    train_sampler = SubsetRandomSampler(train_idx)\n    validation_sampler = SubsetRandomSampler(validation_idx)\n\n    dataset_sizes = {}\n\n    dataset_sizes['train'] = len(train_idx)\n    dataset_sizes['val'] = len(validation_idx)\n    \n    train_loader = DataLoader(dataset, batch_size=BATCH_SIZE,num_workers=0, sampler=train_sampler)\n    validation_loader = DataLoader(dataset, batch_size=BATCH_SIZE, num_workers=0,sampler=validation_sampler)\n\n    dataloaders = {}\n\n    dataloaders['train'] = train_loader\n    dataloaders['val'] = validation_loader\n    \n    return (dataloaders, dataset_sizes)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0feeb795afe10b3dfd10d3f82a69955129119726"},"cell_type":"code","source":"dataloaders, dataset_sizes = prepare_loaders()\n\ndataset.df.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a49454c36acc36ad84e16ce4367473e8d0645007"},"cell_type":"markdown","source":"# Model definition"},{"metadata":{"trusted":true,"_uuid":"f819b0e55839822e6bea8d684f7d06750e4bf959"},"cell_type":"code","source":"# Wout = 1 + (Win - Kernel_size + 2Padding)/Stride\n\nclass CNN(nn.Module):\n    def __init__(self):\n        super(CNN, self).__init__()\n        self.conv1 = nn.Sequential(      #input: 4xWxH\n            nn.Conv2d(4,8,5,1,2),        # input_channels, output_channels, kernel_size, stride, padding   \n            nn.ReLU(),                      \n            nn.MaxPool2d(kernel_size=2), #output: 8xW/2xH/2\n        )\n        self.conv2 = nn.Sequential(      #input: 4xWxH\n            nn.Conv2d(8,16,5,1,2),        # input_channels, output_channels, kernel_size, stride, padding   \n            nn.ReLU(),                      \n            nn.MaxPool2d(kernel_size=2), #output: 16xW/4xH/4\n        )\n        self.drop_out = nn.Dropout()\n        self.out1 = nn.Linear( int(16 * W/4 * H/4), 900)   # fully connected layer, output 28 classes\n        self.out2 = nn.Linear( 900, 28)   # fully connected layer, output 28 classes\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.conv2(x)\n        x = x.view(x.size(0), -1)           # flatten the output of conv2 to (batch_size, 32 * 7 * 7)\n        output = self.drop_out(x)\n        output = self.out1(x)\n        output = self.out2(output)\n        return output, x    # return x for visualization\n\ndef init_weights(m):\n        if type(m) == nn.Linear:\n            torch.nn.init.xavier_uniform(m.weight)\n            m.bias.data.fill_(0.01)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"01cf2974995705d1078fb49be52be6fe7f1b87c4"},"cell_type":"markdown","source":"# Training function\n\nsimple training for our model. Not use validation yet."},{"metadata":{"trusted":true,"_uuid":"7af6649a5d3b33d344bbbfdd8b1a591bd6b85e7c"},"cell_type":"code","source":"# create a new subdataset for training\ndataloaders, dataset_sizes = prepare_loaders()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f46761b849ec61a5b54cfb8b8e3963678f01304f"},"cell_type":"code","source":"losses = {}\naccuracys = {}\n\nlosses['train'] = []\nlosses['val'] = []\naccuracys['train'] = []\naccuracys['val'] = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a282cbcd74a28895cf431e8e132f2ff83bf0cb4"},"cell_type":"code","source":"def Train(model, epochs=10, criterion=nn.BCEWithLogitsLoss(reduction='sum'), optimizer= None):\n    since = time.time()\n\n    best_model_wts = copy.deepcopy(model.state_dict())\n    best_acc = 0.0\n\n\n    if optimizer == None:\n        optimizer = optim.Adam(model.parameters(), lr=0.04, betas=(0.9, 0.99))\n    \n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    print(\"training with device: \" + str(device))\n    \n    model.to(device)\n    \n    for epoch in range(epochs):  # loop over the dataset multiple times\n        print('Epoch {}/{}'.format(epoch+1, epochs))\n        print('-' * 10)\n        \n        for phase in ['train', 'val']:\n            if phase == 'train':\n                model.train()  # Set model to training mode\n            else:\n                model.eval()   # Set model to evaluate mode\n                \n            running_loss = 0.0    \n            running_corrects = 0.0\n    \n            for i, data in enumerate(dataloaders[phase], 0):            \n                # get the inputs\n                inputs, labels = data['image'], data['target']\n\n                inputs, labels = inputs.to(device,dtype=torch.float), labels.to(device,dtype=torch.float)\n\n                # zero the parameter gradients\n                optimizer.zero_grad()\n                \n                # forward\n                # track history if only in train\n                with torch.set_grad_enabled(phase == 'train'):\n                    outputs = model(inputs)[0]\n                    preds = outputs > 0\n                    loss = criterion(outputs, labels)\n\n                    # backward + optimize only if in training phase\n                    if phase == 'train':\n                        loss.backward()\n                        optimizer.step()\n                        \n                 # statistics\n                running_loss += loss.item() * inputs.size(0)\n                labels = labels.data.byte()\n                running_corrects += torch.sum((labels == preds).all(1))\n                                \n            epoch_loss = running_loss / dataset_sizes[phase]\n            epoch_acc = running_corrects.float() / dataset_sizes[phase]\n            print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))\n            \n            losses[phase].append(epoch_loss)\n            accuracys[phase].append(epoch_acc)\n            \n            # deep copy the model\n            if phase == 'val' and epoch_acc > best_acc:\n                best_acc = epoch_acc\n                best_model_wts = copy.deepcopy(model.state_dict())\n                \n                \n\n    time_elapsed = time.time() - since\n    print('Training complete in {:.0f}m {:.0f}s'.format(\n        time_elapsed // 60, time_elapsed % 60))\n    print('Best val Acc: {:4f}'.format(best_acc))\n\n    # load best model weights\n    model.load_state_dict(best_model_wts)\n    return model\n\n\ndef run_model(model,batch):\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    model.to(device)\n    inputs = batch\n    inputs = inputs.to(device,dtype=torch.float)\n    out = model(inputs)\n    out = out[0].cpu()\n    return out","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3da05b12da6ea611b5ea192f7fa1b60e2df456e4"},"cell_type":"code","source":"# model creation and initialization\ncnn = CNN()\ncnn.apply(init_weights)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b9db85001682dd2dca870a0618fe25bc2b55d75b","scrolled":false},"cell_type":"code","source":"# training\ntorch.cuda.empty_cache()\ncnn = Train(cnn, epochs=10,  criterion=nn.BCEWithLogitsLoss(reduction='sum'), optimizer = optim.Adam(cnn.parameters(), lr=0.001, betas=(0.9, 0.99)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"45c4cbbc4255697807faccc5ffa615b2339dae98"},"cell_type":"code","source":"# training\ntorch.cuda.empty_cache()\ncnn = Train(cnn, epochs=10,  criterion=nn.BCEWithLogitsLoss(reduction='sum'), optimizer = optim.Adam(cnn.parameters(), lr=0.001, betas=(0.9, 0.99)))\ndataloaders, dataset_sizes = prepare_loaders()\ntorch.cuda.empty_cache()\ncnn = Train(cnn, epochs=10,  criterion=nn.BCEWithLogitsLoss(reduction='sum'), optimizer = optim.Adam(cnn.parameters(), lr=0.001, betas=(0.9, 0.99)))\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9c295859ee17ecedb8aa8f1caa3e0e745589ccb5"},"cell_type":"markdown","source":"# Visualice training curve"},{"metadata":{"trusted":true,"_uuid":"e04e055870f471d5c085bc22637701cf139b0c8d"},"cell_type":"code","source":"plt.plot(np.arange(len(losses['train'])), losses['train'],label=\"train\")\nplt.plot(np.arange(len(losses['val'])), losses['val'], label=\"val\")\nplt.legend()\nplt.title(\"loss by epoch\")\nplt.show()\n\nplt.plot(np.arange(len(accuracys['train'])), accuracys['train'], label=\"train\")\nplt.plot(np.arange(len(accuracys['val'])), accuracys['val'], label=\"val\")\nplt.title(\"accuracy by epoch\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"71d5c972d16add46971cb0eb04ff4a48f5c920b4"},"cell_type":"markdown","source":"# SAVE MODEL TO A FILE AND RESTORE FROM FILE"},{"metadata":{"trusted":true,"_uuid":"23d1a990ee0f43f8f0a0ec27b1cbaea49777b1e6"},"cell_type":"code","source":"def save(model, full = True, name=\"model\"):\n    if not full:\n        torch.save(model.state_dict(), name+'_params.pkl')   # save only the parameters\n    else:\n        torch.save(model, name+'.pkl')  # save entire net\n\n        \ndef restore_net(name=\"model\"):\n    model = torch.load(name+'.pkl')\n    return model\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d7dbc4380f913b8a341c008634c05eb24a5f57fd"},"cell_type":"code","source":"save(cnn, name=\"cnn\")\n!ls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"66b178e603924cc9f06260dc554f5316f3135bf0"},"cell_type":"code","source":"cnn = restore_net(name=\"cnn\")\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"107f12caa085f86aa8a2dfa26874c9bfa59678d2"},"cell_type":"markdown","source":"# SEND AND RECEIVE MODELS FROM/TO DROPBOX TO STORE THEM\n\nWe need to create a [https://www.dropbox.com/developers/apps/create](dropbox-app)  and generate an access token."},{"metadata":{"trusted":true,"_uuid":"8a68e6fdd421e76afeb12c09197aad79b346d2fb"},"cell_type":"code","source":"#!pip install dropbox\nimport dropbox\ndropbox_path='/'\ndbx=dropbox.Dropbox('Your access token')\n\n# upload model to dropbox\n\nfile_name='cnn.pkl'\nwith open(file_name, 'rb') as f:\n    dbx.files_upload(f.read(),dropbox_path+file_name,mute=True, mode=dropbox.files.WriteMode.overwrite)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a335ccb27cf8ba3589789e1b14c7b96ba1e2d3b3"},"cell_type":"code","source":"# load model from dropbox\ndbx.files_download_to_file(file_name,dropbox_path+file_name)\n!ls","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"81b67de832ce716a2f32fa24930e13e731084477"},"cell_type":"markdown","source":"# submit\n"},{"metadata":{"trusted":true,"_uuid":"331e2b592a252dd438c12780686c8e5788173a3d"},"cell_type":"code","source":"submit = pd.read_csv('../input/sample_submission.csv')\n\ndataset_test = HumanProteinDataset(csv_file='../input/sample_submission.csv', transform=transforms.Compose([\n    ToTensor()\n]), test=True)\n\ndataloader_test = DataLoader(dataset_test, batch_size=BATCH_SIZE,\n                        shuffle=False, num_workers=0)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5db4083a2327416466bc72aea327494696ea34fe"},"cell_type":"code","source":"ids = []\npredictions = []\n\ncnn = cnn.cuda()\n\nfor sample_batched in dataloader_test:\n        out = run_model(cnn,sample_batched['image'])\n        \n        preds = []\n        out = out.detach().numpy()\n        for sample in out:\n            p = \"\"\n            for i,label in enumerate(sample):\n                if label > 0:\n                    p += \" \" + str(i)\n                    print(p)\n            if p == \"\":\n                p = \"0\"\n            else:\n                p = p[1:]\n            preds.append(p)\n\n        ids += list(sample_batched['Id'])\n        predictions += preds\n\n    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8d16c25aacf50546b845a5609b808ce6eccb16fa"},"cell_type":"code","source":"print(predictions)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d24d8883add657a08df142bf2164707731fb0389"},"cell_type":"code","source":"df = pd.DataFrame({'Id':ids,'Predicted':predictions})\ndf.to_csv('protein_classification.csv', header=True, index=False)\n\nprint(df)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9898b8d820912140122be2d9c440abe7e1001091"},"cell_type":"code","source":"# import the modules we'll need\nfrom IPython.display import HTML\nimport pandas as pd\nimport numpy as np\nimport base64\n\n# function that takes in a dataframe and creates a text link to  \n# download it (will only work for files < 2MB or so)\ndef create_download_link(df, title = \"Download CSV file\", filename = \"protein_classification.csv\"):  \n    csv = df.to_csv( sep=',', encoding='utf-8', index=False)\n    b64 = base64.b64encode(csv.encode())\n    payload = b64.decode()\n    html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n    html = html.format(payload=payload,title=title,filename=filename)\n    return HTML(html)\n\n\n# create a link to download the dataframe\ncreate_download_link(df)","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}