{"cells":[{"metadata":{"_uuid":"1ee66bbb4a5adbdb8ad70cff3a2aa4a9cd29a801"},"cell_type":"markdown","source":"# **Imports**"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"scrolled":true},"cell_type":"code","source":"import copy, cv2, json, os, time, torch, torchvision\n\nfrom collections import OrderedDict\n\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\nfrom torch import nn\nfrom torch import optim\nfrom torch.autograd import Variable\nimport torch.nn.functional as F\nfrom torch.optim import lr_scheduler\nimport torch.utils.data as data\nfrom torch.utils.data.dataset import Dataset\nfrom torch.utils.data.dataloader import DataLoader\nfrom torchvision import models\nfrom torchvision import transforms\nimport torchvision.datasets as datasets\n\nprint(os.listdir(\"../input\"))\n%load_ext autoreload\n%autoreload 2\n%matplotlib inline\n\nfrom matplotlib.pyplot import figure","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8102b77ecb525349ddcb882d7ab459b3800849d4"},"cell_type":"markdown","source":"# **Exploratory**"},{"metadata":{"trusted":true,"_uuid":"9908f03b3d2ae71390b6d25563c2835ff40b3e13"},"cell_type":"code","source":"print(len(os.listdir('../input/train')))\nprint(len(os.listdir('../input/test')))\ntrain = pd.read_csv('../input/train.csv')\ntrain.head(3)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fe69ba358ac24b5315b6b53a6b321ca2f1e6e09d"},"cell_type":"markdown","source":"### **Most Popular Whales**"},{"metadata":{"trusted":true,"_uuid":"42342b9e6fd2ed8cedc502715866aa5216e2fba0"},"cell_type":"code","source":"train.groupby('Id').count().sort_values('Image',ascending = False).head(10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b6abb0305cedc621330a615817df45dbc97ea80c"},"cell_type":"code","source":"train.groupby('Id').count().plot.hist(range = (0,10))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a34660f8b18c15b6e94e22a6e1e4348625aa034b"},"cell_type":"code","source":"id_map = train[['Id']].drop_duplicates()\nid_map.index = list(range(0,len(id_map)))\nwhale_dict = id_map['Id'].to_dict()\nid_dict = dict((v,k) for k,v in whale_dict.items())\n#id_dict","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6c37d5b48f870297d2da095b57f16deb45611eaa"},"cell_type":"code","source":"with Image.open('../input/test/0027089a4.jpg') as img:\n    fig, ax = plt.subplots()\n    ax.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2c287fa3e7c450aa319c89c2f1d587667d0c3c2e"},"cell_type":"markdown","source":"## **Simple Functions and Setup**"},{"metadata":{"trusted":true,"_uuid":"d36774fddf1b062414adf506fd08ac1822edf12a"},"cell_type":"code","source":"def whale_list(whale_id,df = train):\n    return df[df['Id']==whale_id]['Image'].tolist()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6c37d5b48f870297d2da095b57f16deb45611eaa"},"cell_type":"code","source":"image_list = whale_list('w_23a388d')[:1]\nfor img_path in image_list:\n    with Image.open('../input/train/' + img_path) as img:\n        fig, ax = plt.subplots()\n        ax.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"282ff2c7b78d82c9862230565ec0ad8387b53212"},"cell_type":"markdown","source":"## **Classes and Functions**"},{"metadata":{"trusted":true,"_uuid":"cc6213b279a3aaabf2e4e6a0651b26db209c1473"},"cell_type":"code","source":"class HW_Dataset(Dataset):\n    def __init__(self,filepath, csv_path,transform=None):\n        self.file_path = filepath\n        self.df = pd.read_csv(csv_path)\n        self.transform = transform\n        self.image_list = [x for x in os.listdir(self.file_path)]\n        \n    def __len__(self):\n        return(len(self.image_list))\n    \n    def __getitem__(self,idx):\n        img_path = os.path.join(self.file_path,self.df.Image[idx])\n        label = self.df.Id[idx]\n        img = Image.open(img_path).convert('RGB')\n        img = self.transform(img)\n        \n        return img, label\n\ndef label_to_id(label):\n    x = [id_dict[i] for i in label]\n    return torch.tensor(x)\n\n# Process a PIL image for use in a PyTorch model\ndef process_image(image):\n    #img_transform = transforms.Compose([\n#        transforms.ToTensor()])\n    img_transform = transform\n    pil_image = Image.open(image)\n    pil_image = img_transform(pil_image).float()\n    np_image = np.array(pil_image)    \n    return np_image\n\ndef imshow(image, ax=None, title=None):\n    if ax is None:\n        fig, ax = plt.subplots()\n    # PyTorch tensors assume the color channel is the first dimension\n    # but matplotlib assumes is the third dimension\n    image = image.transpose((1, 2, 0))\n    # Image needs to be clipped between 0 and 1 or it looks like noise when displayed\n    image = np.clip(image, 0, 1)\n    ax.imshow(image)\n    return ax","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f830184811a29a5585ff23dc7453aad63b0120f"},"cell_type":"markdown","source":"# **Data Setup**"},{"metadata":{"_uuid":"520633bd3a32e16decc130fc588c20616528a9e0"},"cell_type":"markdown","source":"#old transform\ndims = 256\ntransform = transforms.Compose([transforms.Resize((256,256)),#transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)),\n                                transforms.ToTensor()])"},{"metadata":{"trusted":true,"_uuid":"d560c944e1c7f816789a0dda1e4e9ee1a7a2323c"},"cell_type":"code","source":"#old 256\ndims = 128\n\ntransform = transforms.Compose([\n                              transforms.Resize((dims, dims)),\n                              transforms.ToTensor(),\n                              transforms.Normalize(mean=[0.485, 0.456, 0.406],\n                                                     std=[0.229, 0.224, 0.225])])\n\ndim1 = max(int(dims**2/2),5005)\ndim2 = max(int((dims**2)/4),5005)\nprint(dim1)\nprint(dim2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6317277b2b4da7e6907fb9ebd52f09190fc0490e"},"cell_type":"code","source":"train_dataset = HW_Dataset('../input/train/','../input/train.csv', transform)\ntest_dataset = HW_Dataset('../input/test/','../input/train.csv', transform)\nlen(test_dataset.image_list)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"273ce280c5963ca12c8941bb1e53ebce14a91adf"},"cell_type":"markdown","source":"### **Custom train_test_split**\nNot sure how to use sklearn.model_selection train_test_split in this instance, since dataset is a list of tuples, so I will create a random indexing on my own"},{"metadata":{"trusted":true,"_uuid":"7f1d8be9b6998be3e15fc58e7d0f9ee612566583"},"cell_type":"code","source":"train_dataset[0][0].size()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e1449281fd21b6b0841977209552a6880f479261"},"cell_type":"code","source":"# example\na = list(range(10))\nb = list(range(5,15))\nnp.setdiff1d(a,b) #in a and not in b","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"93104ee9fcacdb8ae090341f5b87569e24111b0e"},"cell_type":"code","source":"test_size = .2\nn = len(train_dataset)\n\nnp.random.seed(0)\na = list(range(n))\n\ntrain_index = np.random.choice(a,replace=False,size = int(n*(1-test_size)))\ntest_index = np.setdiff1d(a,train_index)\nprint(train_index.size)\nprint(test_index.size)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9b31b563ef571070831e6b147ca72cbf1a63acbf"},"cell_type":"code","source":"data_train = copy.deepcopy(train_dataset)\ndata_train.image_list = [train_dataset.image_list[i] for i in train_index]\n\ndata_test = copy.deepcopy(train_dataset)\ndata_test.image_list = [train_dataset.image_list[i] for i in test_index]\n\ngen_train = DataLoader(data_train,batch_size=16, shuffle=True)\ngen_test = DataLoader(data_test,batch_size=16, shuffle=True)\nfull_train_generator = DataLoader(train_dataset,batch_size=16, shuffle=True)\nfull_test_generator = DataLoader(test_dataset,batch_size=16, shuffle=True)\n\nprint(len(gen_train))\nprint(len(gen_test))\nprint(len(full_train_generator))\nprint(len(full_test_generator))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e8e3ae6e01ed7e72e00ef52b86493b7ad80077e"},"cell_type":"code","source":"print(len(train_dataset))\nprint(len(test_dataset))\nprint(len(data_train))\nprint(len(data_test))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"1d2bcbdbb99d5eb722834896f2edb446c28cea2f"},"cell_type":"markdown","source":"# **Model Setup**"},{"metadata":{"trusted":true,"_uuid":"6317277b2b4da7e6907fb9ebd52f09190fc0490e","scrolled":true},"cell_type":"code","source":"model = models.vgg11(pretrained=True)\n\nclassifier = nn.Sequential(OrderedDict([\n                          ('fc1', nn.Linear(dim1, dim2)),                        \n                          ('relu', nn.ReLU()),\n                          ('fc2', nn.Linear(dim2, 5005)),\n                          ('output', nn.LogSoftmax(dim=1))\n                          ]))\n\nmodel.classifier = classifier\n\ncriterion = nn.NLLLoss()\noptimizer = optim.SGD(model.parameters(), lr=0.003)\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e478f9b993051718cceea27ff3d325082ebc3de7"},"cell_type":"markdown","source":"# **Train Model**"},{"metadata":{"trusted":true,"_uuid":"aad1be8e991242ed8024a919d07924f562c89e75","collapsed":true},"cell_type":"code","source":"epochs = 14\ntraining_data = full_train_generator\n#training_data = gen_train\n\nx = time.time()\nimage_count = len(training_data)\nupdates = 4\nprogress_printer = int(image_count/updates)\n\nfor e in range(epochs):\n    running_loss, i = 0, 0\n\n    for image, label in training_data:            \n        label = label_to_id(label)\n        image, label = image.to(device), label.to(device)\n        i +=1 \n        if i % progress_printer == 0:\n            print('{:.0f}% complete'.format(i/image_count*100))\n            print('Epoch Rate: {}'.format(round((time.time() - x)*updates/60),2))\n            x = time.time()\n        log_ps = model(image)\n        loss = criterion(log_ps, label)\n        \n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        \n        running_loss += loss.item()\n    \n    print('epoch {}: loss: {}'.format(e,running_loss))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3a00d6f67b697f30c74816bbf108afc5a16e0695"},"cell_type":"markdown","source":"## Show"},{"metadata":{"trusted":true,"_uuid":"d768306802edd67c389c9697e08718e349353b56"},"cell_type":"code","source":"image_path = \"../input/train/002b4615d.jpg\"\nshowthis = imshow(process_image(image_path))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5c4de7fef9dd92cbac105aca7496ea045b42fc63"},"cell_type":"code","source":"image_list = whale_list('w_23a388d')[:1]\nfor img_path in image_list:\n    with Image.open('../input/train/' + img_path) as img:\n        fig, ax = plt.subplots()\n        ax.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"06ecd2cd18efd2ec30c3932d51622ffe401735fd"},"cell_type":"markdown","source":"# **Prediction Functions**"},{"metadata":{"trusted":true,"_uuid":"21e1842aaa7960fa5505e06126bfddf55e8bcef2"},"cell_type":"code","source":"def predict(image_path, model, n=5):\n    with torch.no_grad():\n        model.eval()\n        np_array = process_image(image_path)\n        if np_array.shape[0] == 1:\n            #print(np_array.shape)\n            np_array = np.repeat(np_array[:, :], 3, axis=0)\n            #print(np_array.shape)\n        tensor = torch.from_numpy(np_array)\n        model = model.cuda()\n        inputs = Variable(tensor.float().cuda())\n        inputs = inputs.unsqueeze(0)\n        output = model.forward(inputs)  \n        predictions = torch.exp(output).data.topk(n)\n        probabilities = predictions[0].cpu()\n        classes = predictions[1].cpu()\n        classes_np = classes.numpy()[0]\n        classes = [whale_dict[classes_np[i]] for i in list(range(len(classes_np)))]        \n        return probabilities.numpy()[0], classes\n\ndef predict_image(image_path,n = 5):\n    probabilities, classes = predict(image_path, model)\n    fig = plt.figure(figsize=(8,8))\n    ax1 = plt.subplot2grid((20,10), (0,0), colspan=10, rowspan=10)\n    ax2 = plt.subplot2grid((20,10), (10,2), colspan=5, rowspan=8)\n    image = Image.open(image_path)\n    ax1.imshow(image)\n    y_pos = np.arange(n)\n    ax2.set_yticks(y_pos)\n    ax2.set_yticklabels(classes)\n    ax2.invert_yaxis()\n    ax2.set_xlabel('Probability')\n    ax2.barh(y_pos, probabilities)\n    plt.show()\n    return classes","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ad2b904fc3dcee23ae7fcd55d55cb9d776fe5e87"},"cell_type":"markdown","source":"## **Accuracy View**"},{"metadata":{"trusted":true,"_uuid":"42342b9e6fd2ed8cedc502715866aa5216e2fba0"},"cell_type":"code","source":"rank = 500\nranked_whales = train.groupby('Id').count().sort_values('Image',ascending = False).reset_index()\nwhale = ranked_whales['Id'][rank-1]\nprint(whale)\n\nprint(ranked_whales[rank-2:rank+1])\n#whale = 'w_23a388d'\n\nfor image_path in whale_list(whale,train.loc[test_index])[:2]:    \n    print(image_path)\n    image_path = '../input/train/' + image_path\n    x = predict_image(image_path)\n    print(x[0] == whale)\n    print(x)\n    ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3d784b1cddb655a029eb93403087abbc0f14c818"},"cell_type":"markdown","source":"## Create and Submit Predictions"},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"bded32b6f3e41279b5fc794cbde7179509e622fe"},"cell_type":"code","source":"image_list = copy.deepcopy(test_dataset.image_list)\ni = 0\n\njpegs = []\npredictions = []\n\n#for the_jpeg in test_dataset.image_list:\nfor the_jpeg in image_list:  \n    i +=1\n    if i % 1000 == 0:\n        print(i)\n    image_path = '../input/test/' + the_jpeg\n    x, y = predict(image_path,model)\n    preds = ' '.join(y)\n    jpegs.append(the_jpeg)\n    predictions.append(preds)    \n\njpegs\npredictions\n\nwhale_predictions = pd.DataFrame({'Image':jpegs,'Id':predictions})\nprint(whale_predictions.shape)\nwhale_predictions.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"131ba35883a3e67df0add920c19177b74b74f9c1"},"cell_type":"code","source":"whale_predictions.to_csv('second_submission_attempt.csv',index=False)","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}