{"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\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport torchvision.transforms as transforms\nfrom torch.utils.data import DataLoader, TensorDataset, Dataset\n\nfrom sklearn.model_selection import train_test_split\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nfrom fastai import *\nfrom fastai.vision import *\n\nimport os, gc, random\nimport time\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4475e580ce3b4e20fbfe6da96bbe2750e25d22ac"},"cell_type":"code","source":"# make training deterministic/reproducible\ndef seed_everything(seed=2018):\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    np.random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    torch.backends.cudnn.deterministic = True\nseed_everything()\n\ndef to_img(*args):\n    return np.array(args, dtype=np.uint8)\n\ndef conv2(ni, no, kernel_size=3, stride=2, padding=0):\n    return nn.Sequential(\n        nn.Conv2d(ni, no, kernel_size=kernel_size, stride=stride, padding=padding, bias=False),\n#         nn.ReLU(inplace=True),\n        nn.LeakyReLU(inplace=True),\n        nn.BatchNorm2d(no)\n    )\n\nclass Flatten(nn.Module):\n    def __init__(self):\n        super(Flatten, self).__init__()\n\n    def forward(self, x):\n        return x.view(x.size(0), -1)\n    \nclass ResBlock(nn.Module):\n    def __init__(self, nf):\n        super(ResBlock, self).__init__()\n        self.conv1 = conv2(nf, nf, kernel_size=3, stride=1, padding=1)\n        self.conv2 = conv2(nf, nf, kernel_size=3, stride=1, padding=1)\n\n    def forward(self, x):\n        x = x + self.conv2(self.conv1(x))\n        return x","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6be6fe2db0e2cde925f56ee4b6ad47e77750c9be"},"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ndevice","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"31be62222f1e591577e6c48a7c82b84b95166980"},"cell_type":"code","source":"class ExImagePoints(ImagePoints):\n    def reconstruct(self, t, x): return ExImagePoints(FlowField(x.size, t), scale=False)\n\nclass PointsProcessor(PreProcessor):\n    \"`PreProcessor` that stores the number of targets for point regression.\"\n    def __init__(self, ds:ItemList):\n        print('PointsProcessor')\n        print(ds)\n        self.c = len(ds.items[0].reshape(-1))\n    def process(self, ds:ItemList):\n        ds.c = self.c\n\nclass ExPointsLabelList(ItemList):\n    \"`ItemList` for points.\"\n    _processor = PointsProcessor\n\n    def __post_init__(self): self.loss_func = MSELossFlat()\n\n    def get(self, i):\n        o = super().get(i)\n        o = torch.tensor(o.astype(np.float32), dtype=torch.float32)\n        return ExImagePoints(FlowField(self.x.get(i).size, o), scale=True, y_first=False)\n\n    def analyze_pred(self, pred, thresh:float=0.5): return pred.view(-1,2)\n\n\nclass ExPointsItemList(ImageItemList):\n    _label_cls,_square_show_res = ExPointsLabelList,False\n\n    def open(self, fn):\n        img = (to_img(*fn.split(' '))/255).reshape(1,96,96)\n        return Image(torch.tensor(img, dtype=torch.float32))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f447b3fea84d2793bded0ccbbc51d0520f1c2c97"},"cell_type":"code","source":"train_df = pd.read_csv('../input/training/training.csv')\ntest_df = pd.read_csv('../input/test/test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7ef097cf980ced1bd42757210e969ffc0a90089b"},"cell_type":"code","source":"# check to missing values\ntrain_df.isna().any().value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"38b57f9f0a38d958ea7bd7d147c664a6ee87e78d"},"cell_type":"code","source":"# drop N/As\ntrain_df.dropna(inplace=True)\ntrain_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"028ac363aa430f2957eadd8382ec63153396b530"},"cell_type":"code","source":"labels = train_df.drop('Image',axis = 1).values.astype(np.float32)\nlabels = labels.reshape(-1, 15, 2)\n# ## convert from (x,y) to (y,x)\n# labels = labels[:, :, [1,0]]\nlabels = torch.tensor(labels, dtype=torch.float32)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"760ebbf3a00d4c93b290997a8fccd616f5b6246b"},"cell_type":"code","source":"valid_pct = 0.2\nrand_idx = np.random.permutation(len(train_df))\ncut = int(valid_pct * len(train_df))\ntrain_idxs, valid_idxs = rand_idx[cut:],rand_idx[:cut]\ntrain_idxs.shape,valid_idxs.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b2eacebcfde8a0edf4ef9d4505d83d8ce7da4f1f"},"cell_type":"code","source":"data = ExPointsItemList(items=train_df.Image, path='.')\ndata = data.split_by_idxs(train_idx=train_idxs,valid_idx=valid_idxs)\ndata = data.label_from_lists(labels[train_idxs],labels[valid_idxs])\n# data = data.databunch(bs=16)\n# data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"dfffd1dab8bc07de10ff37d16d517f0874aceb5c"},"cell_type":"code","source":"empty_labels = np.zeros((len(test_df.Image), 15, 2))\ndata = data.add_test(items=test_df.Image, label=empty_labels)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7e2d51ef99a0897495e89051599ea880e289084d"},"cell_type":"code","source":"tfms = get_transforms(do_flip=True, \n                      flip_vert=False, \n                      max_rotate=0.0, \n                      max_zoom=1.0, \n                      max_lighting=0.2, \n                      max_warp=0.0, \n                      p_affine=0.8, \n                      p_lighting=0.8)\ndata = data.transform(tfms=tfms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"15579a73a584a36f8492e69ed3e4e888cf9fa61f"},"cell_type":"code","source":"data = data.databunch(bs=16)\ndata","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e6fe330409d556b45169098116d2a5df59f91ce8"},"cell_type":"code","source":"data.show_batch(rows=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"87e3311de22dfa8761a3be1db84c289dffbc7874"},"cell_type":"code","source":"model = nn.Sequential(\n    conv2(1, 4, kernel_size=5, stride=1, padding=2),\n    ResBlock(4),\n    nn.MaxPool2d(2,2),\n    conv2(4, 6, kernel_size=5, stride=1, padding=2),\n    nn.MaxPool2d(2,2),\n    conv2(6, 8, kernel_size=4, stride=1, padding=2),\n    nn.MaxPool2d(2,2),\n    Flatten(),\n    nn.Dropout(0.5),\n    nn.Linear(12 * 12 * 8, 250),\n    nn.Dropout(0.5),\n    nn.Linear(250, 30),\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"efca7b019b6c13346c9e62289e7ec18596104dc3"},"cell_type":"code","source":"# (xs,ys) = data.one_batch()\n# model(xs).shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c63a27b89f2f0d10ba5700e18d5fa10bc05c3868"},"cell_type":"code","source":"def rmse(preds, targets):\n    return torch.sqrt(nn.functional.mse_loss(preds, targets.view(targets.size(0), -1)))\n\ndef mse(preds, targets):\n    return nn.functional.mse_loss(preds, targets.view(targets.size(0), -1)) \n\nlearn = Learner(data, model, loss_func=mse, metrics=rmse)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a1aec87c4e1a73d1c7247ca1a3c98c2e4ed8d30c"},"cell_type":"code","source":"learn.lr_find(end_lr=100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a43328d5cab998aa6dd76938b5f16db0c2785787"},"cell_type":"code","source":"learn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8edb4a1fc8a46a75cf2ca0c0fbbee95d23bd2593"},"cell_type":"code","source":"learn.fit_one_cycle(20, max_lr=1e-2/2)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"49aaf1091e1ca47ff38254eb5203573ae3e0c661"},"cell_type":"markdown","source":"## Test set"},{"metadata":{"trusted":true,"_uuid":"42611cee76fdfc9e4be27e85f2a1010086d3606b"},"cell_type":"code","source":"preds,y = learn.get_preds(ds_type=DatasetType.Test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b7c7d836fe0f2e61e2872e8566805ab42b071f96"},"cell_type":"code","source":"preds.min(),preds.max()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e011eae942b35800e36543180606cfcb0ae5ee7a"},"cell_type":"code","source":"preds = preds * 48 + 48","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c3ee4efd44aef77c469c64aa1445b374b9ed35c0"},"cell_type":"code","source":"def show_im(img, pnts):\n    img = (to_img(*img.split(' '))/255).reshape(1,96,96)\n    img = Image(torch.tensor(img, dtype=torch.float32))\n    pnts = pnts.reshape(15, 2)\n    pnts = ImagePoints(FlowField(img.size, pnts), y_first=True)\n    img.show(y=pnts)\n\nshow_im(test_df.Image[1], preds[1])\n# show_im(train_df.Image[0], labels[0][:,[1,0]].reshape(-1))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ba6c22e2204017fee0aade672719404354a020c3"},"cell_type":"code","source":"# (y,x) -> (x,y)\npreds = preds.reshape(-1, 15, 2)[:, :, [1,0]]\npreds = preds.reshape(-1, 30)\npreds = preds.detach().numpy()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8c6597d4408764ba4868b8c4fdc69c17d4aee367"},"cell_type":"markdown","source":"### Submit Result"},{"metadata":{"trusted":true,"_uuid":"7380e0b896bac0cc6b2872b1205ada8045ff06f4"},"cell_type":"code","source":"look_id = pd.read_csv('../input/IdLookupTable.csv')\nlook_id.drop('Location',axis=1,inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"81f8bb66792b4117d9d7c07a21c4cc1a941b6e9b"},"cell_type":"code","source":"columns = train_df.drop('Image', axis=1).columns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"effee91d8ab376a2576694b067e5b43d5efe3069"},"cell_type":"code","source":"ind = np.array(columns)\nvalue = np.array(range(0,30))\nmaps = pd.Series(value,ind)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8f98139dfd9cc91b0bbba4b7c172a49ca57308e3"},"cell_type":"code","source":"look_id['location_id'] = look_id.FeatureName.map(maps)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bca2a016bdd62f98e41432ec82add75d27fcc6f0"},"cell_type":"code","source":"df = look_id.copy()\nlocation = pd.DataFrame({'Location':[]})\nfor i in range(1,1784):\n    ind = df[df.ImageId==i].location_id\n    location = location.append(pd.DataFrame(preds[i-1][list(ind)],columns=['Location']), ignore_index=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"50002321a6e58a0453b337fc324167a656d744ed"},"cell_type":"code","source":"look_id['Location']=location","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f6e5cb0e747027be1bfb4af4f78f539f53e72267"},"cell_type":"code","source":"look_id[['RowId','Location']].to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"99804dfa393a54611a319daac3a98384765583c6"},"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}