{"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)\nimport torch\nimport cv2\nfrom glob import glob\nimport torchvision\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport torchvision.models as models\nimport torchvision.transforms as transforms\nfrom PIL import Image, ImageFile\nfrom torch.utils.data import TensorDataset, DataLoader,Dataset\nfrom sklearn.model_selection import train_test_split\nimport copy \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\nImageFile.LOAD_TRUNCATED_IMAGES = True\n#print(os.listdir(\"../input\"))\n#../input/train/train\n#../input/train/test\n\n# Any results you write to the current directory are saved as output.\nuse_cuda = torch.cuda.is_available()\nif not use_cuda:\n    print('No GPU found. Please use a GPU to train your neural network.')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"df_train = pd.read_csv('../input/train.csv')\ndf_label = pd.read_csv('../input/labels.csv')\ndf_test = pd.read_csv('../input/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train = df_train[:50000]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"label_names = df_label['attribute_name'].values\nlabel_id = df_label['attribute_id'].values\ntrain_labels = np.zeros((df_train.shape[0], len(label_names)))\n\n#for row_index, row in enumerate(df_train['attribute_ids']):\n    #for label in row.split():\n        #train_labels[row_index, int(label)] = 1\n\n#print(train_labels[:20][:50])\n#for col in range(len(label_names)):\n    #df_train[col] = 0\n    \n#df_train[label_id] = train_labels\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#df_test = df_train[:5]\ndf_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# NOTE: class is inherited from Dataset\nclass ImageLabelDataset(Dataset):\n    def __init__(self, df_data, prediction, folder=\"../input\"):\n        super().__init__()\n        self.df = df_data.values\n        self.prediction = prediction.values\n        self.folder = folder\n\n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        tensorimage = self.preprocess_image(self.df[index])\n        label = self.prediction[index]\n        label_tensor = self.get_dummies(label)\n        #x = np.squeeze(label_tensor.detach().cpu().numpy())\n        #print(x.argsort()[-6:][::-1])\n        return [tensorimage, label_tensor]\n    \n    def preprocess_image(self, img_path):\n        data_transform = transforms.Compose([transforms.ToPILImage(),\n                                             transforms.Resize(224), \n                                             transforms.CenterCrop(224), \n                                             transforms.RandomRotation(30), \n                                             transforms.ToTensor()\n                                            ])\n        image = cv2.imread(\"{}/{}.png\".format(self.folder, img_path))\n        image = data_transform(image)\n        return image\n    \n    def get_dummies(self, attribute_id):\n        label_tensor = torch.zeros((1, 1103))\n        for label in attribute_id.split():\n            label_tensor[0, int(label)] = 1\n        return label_tensor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# df_train.head()\nbatch_size = 1\ntrain_image = df_train[\"id\"]\n#target = df_train.drop(['id', 'attribute_ids'],axis=1)\ntarget = df_train[\"attribute_ids\"]\nX_train, X_val, y_train, y_val = train_test_split(train_image, target, random_state=42, test_size=0.1)\n\n\ntest_image = df_test[\"id\"]\ntest_target = df_test[\"attribute_ids\"]\n#test_target = df_test.drop(['id', 'attribute_ids'],axis=1)\n\ntrain_set = ImageLabelDataset(df_data=X_train, prediction=y_train, folder=\"../input/train\")\nval_set = ImageLabelDataset(df_data=X_val, prediction=y_val, folder=\"../input/train\")\npredict_set = ImageLabelDataset(df_data=test_image, prediction=test_target, folder=\"../input/test\")\n\ntrain_loader = torch.utils.data.DataLoader(train_set, batch_size=batch_size, shuffle=True, num_workers=1)\nval_loader = torch.utils.data.DataLoader(val_set, batch_size=batch_size, shuffle=True, num_workers=1)\ntest_loader = torch.utils.data.DataLoader(predict_set, batch_size=1, num_workers=0)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#pd.set_option('display.max_columns', None)\n#pd.set_option('display.max_rows', None)\n#print(y_train.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Hyperparameters\nn_output=1\n# Number of Epochs\nnum_epochs = 2\n# Learning Rate\nlearning_rate = 0.0001\n# Model parameters\n\n# Show stats for every n number of batches\nshow_every_n_batches = 1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def train_rnn(model, batch_size, optimizer, criterion, n_epochs, show_every_n_batches=100):\n    train_loss = 0\n    valid_loss = 0\n    batch_losses = []\n    val_batch_losses = []\n    valid_loss_min = np.Inf\n    \n    model.train()\n    \n    previousLoss = np.Inf\n    minLoss = np.Inf\n\n    print(\"Training for %d epoch(s)...\" % n_epochs)\n    for epoch_i in range(1, n_epochs + 1):\n        model.train()\n        for batch_idx, (data, target) in enumerate(train_loader):\n            \n            if use_cuda:\n                data, target = data.cuda(), target.cuda()\n            # clear the gradients of all optimized variables\n            target = np.squeeze(target)\n            target = target.view(1,-1)\n            #target= target.float()\n            #print(np.squeeze(target))\n            #targs = target.view(-1).long()\n            # print(np.squeeze(target))\n            optimizer.zero_grad()\n            # forward pass: Train compute predicted outputs by passing inputs to the model\n            output = model(data)\n            # calculate the Train batch loss      \n            loss = criterion(output, target)\n            # backward pass: compute gradient of the loss with respect to model parameters\n            loss.backward()\n            # perform a single optimization step (parameter update)\n            optimizer.step()\n            # update training loss\n            ## find the loss and update the model parameters accordingly\n            ## record the average training loss, using something like\n            #train_loss += ((1 / (batch_idx + 1)) * (loss.item() - train_loss))\n            train_loss += loss.item() / len(train_loader)\n            \n        model.eval()\n        for batch_idx, (data, target) in enumerate(val_loader):\n            # move to GPU\n            if use_cuda:\n                data, target = data.cuda(), target.cuda()\n            ## update the average validation loss\n            # forward pass: compute predicted outputs by passing inputs to the model\n            target = np.squeeze(target)\n            target = target.view(1,-1)\n            \n            output = model(data)\n            # calculate the Val batch loss\n            loss = criterion(output, target)\n            # update average validation loss \n            #val_batch_losses.append(loss.item())\n            #valid_loss += ((1 / (batch_idx + 1)) * (loss.item() - valid_loss))\n            valid_loss += loss.item() / len(val_loader)\n        \n        #valid_loss = valid_loss/len(val_loader.dataset)\n        #train_loss = train_loss/len(train_loader.dataset)\n        \n        # print training/validation statistics \n        if epoch_i%show_every_n_batches == 0:\n            print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(epoch_i, train_loss, valid_loss))\n        \n            ## TODO: save the model if validation loss has decreased\n            # save model if validation loss has decreased\n            if valid_loss < valid_loss_min:\n                print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n                valid_loss_min,\n                valid_loss))\n                with open('trained_rnn_new', 'wb') as pickle_file:\n                    torch.save(model.state_dict(), 'trained_rnn_new')\n                valid_loss_min = valid_loss\n                train_loss = 0\n                valid_loss = 0\n                #batch_losses = []\n                #val_batch_losses = []\n  \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_transfer = models.vgg16(pretrained=True)\nprint(model_transfer)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Freeze training for all \"features\" layers\nfor param in model_transfer.features.parameters():\n    param.requires_grad = False\n    \ncustom_model = nn.Sequential(nn.Linear(25088, 1024), \n                  nn.ReLU(),\n                  nn.Dropout(p=0.5), \n                  nn.Linear(1024, 1103),\n                  nn.Sigmoid()\n                 )\n\nmodel_transfer.classifier = custom_model\n\nif use_cuda:\n    model_transfer = model_transfer.cuda()\n\n# print(model_transfer)\n\n# specify loss function\n#criterion_scratch = nn.CrossEntropyLoss()\n#criterion_scratch = nn.BCELoss()\ncriterion_scratch = nn.BCELoss(reduction=\"mean\").to('cuda:0')\n\n# specify optimizer\n#optimizer_scratch = optim.SGD(model_transfer.classifier.parameters(), lr=learning_rate, momentum=0.9)\noptimizer_scratch = optim.Adam(model_transfer.classifier.parameters(), lr=learning_rate)\n\ntrained_rnn = train_rnn(model_transfer, batch_size, optimizer_scratch, criterion_scratch, num_epochs, show_every_n_batches)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model_transfer.load_state_dict(torch.load('trained_rnn_new'))\nmodel_transfer.eval()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = []\nnp.set_printoptions(threshold=100)\nsubmission = pd.read_csv('../input/sample_submission.csv')\nfor batch_idx, (data, target) in enumerate(test_loader):\n    # move to GPU\n    #print(np.squeeze(target.detach().cpu().numpy()))\n    if use_cuda:\n        data, target = data.cuda(), target.cuda()\n    ## update the average validation loss\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = model_transfer(data)\n    #values, indices = output.max(1)    \n    pr = np.squeeze(output.detach().cpu().numpy())\n    #preds.append(indices.item())\n    #x = np.squeeze(target.detach().cpu().numpy())\n    x = list(pr.argsort()[-4:][::-1])\n    #print(x)\n    preds.append( ' '.join(map(str, x)) )\n    #for i in pr:\n        #preds.append(i)\n    #print(batch_idx)\n    #print(pr)\n    #print(x.argsort()[-6:][::-1])\n    #print(pr.argsort()[-6:][::-1])\n    #print(values)\n    # calculate the batch loss\nsubmission[\"attribute_ids\"] = preds\nprint(submission.head())\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# import the modules we'll need\nfrom IPython.display import HTML\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=\"submission_1.csv\"):  \n    csv = df.to_csv(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# create a link to download the dataframe\ncreate_download_link(submission)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predictoutput = pd.read_csv(\"../input/mydatasetforaerialcactus/imetsubmission_1.csv\")\npredictoutput.to_csv('submission.csv', index=False)","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}