{"cells":[{"metadata":{"_uuid":"bafd23cda0792a64c969a945c3563c3dacc08a32"},"cell_type":"markdown","source":"https://github.com/radekosmulski/whale"},{"metadata":{"trusted":true,"_uuid":"fe24a8ec4d6f5c51255c53d5c6a331b20e6ca7b7"},"cell_type":"code","source":"from fastai.vision import *\nfrom fastai.metrics import accuracy\nfrom fastai.basic_data import *\nimport pandas as pd\n\nfrom fastai import *\nfrom fastai.vision import *","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9303f069dd19330ca8871f1c9f350b9b1dceb5f4"},"cell_type":"markdown","source":"## A look at the data"},{"metadata":{"trusted":true,"_uuid":"f77e902dd2e66c09ec154e24b35e20062b435b9c"},"cell_type":"code","source":"!ls ../input","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e53c7295d89f53ed6e127f1e98b8d23ba2ce93f3"},"cell_type":"code","source":"path = Path('../input/')\npath_test = Path('../input/test')\npath_train = Path('../input/train')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e8ee3e0a92c00ea0365aaea8ecde627a2c27b61"},"cell_type":"code","source":"df = pd.read_csv(path/'train.csv')#.sample(frac=0.05)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4fd09f763f4bdbc8d6fb84f2c01b72fe88b8b97"},"cell_type":"code","source":"df.Id.value_counts().head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"06d450f303ff804dd0a9b3eed590e1dfee99d958"},"cell_type":"code","source":"(df.Id == 'new_whale').mean()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dbf0daf1b827d749669a5924477ce7c992742acc"},"cell_type":"code","source":"(df.Id.value_counts() == 1).mean()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"397a1c912740556eca19a4d7d4d0e446218aea59"},"cell_type":"markdown","source":"41% of all whales have only a single image associated with them.\n\n38% of all images contain a new whale - a whale that has not been identified as one of the known whales.\n\nThere is a superb writeup on what a solution to this problem might look like [here](https://www.kaggle.com/martinpiotte/whale-recognition-model-with-score-0-78563/notebook). In general, the conversation in the Kaggle [forum](https://www.kaggle.com/c/humpback-whale-identification/discussion) also seems to have some very informative threads.\n\nEither way, starting with a simple model that can be hacked together in a couple of lines of code is a recommended approach. It is good to have a baseline to build on - going for a complex model from start is a way for dying a thousand deaths by subtle bugs."},{"metadata":{"trusted":true,"_uuid":"4bd2320eaac188439d3f1d494844c311755eccca"},"cell_type":"code","source":"df.Id.nunique()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1fd4f603dd0fffab31d149e09918de7d7bc9f511"},"cell_type":"code","source":"df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d33e129f64c696d5e42ece6b4f8ec4abbc3c9d9b"},"cell_type":"code","source":"fn2label = {row[1].Image: row[1].Id for row in df.iterrows()}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"177f19cb3780d6e1018a0edcf68034e2e70321eb"},"cell_type":"code","source":"SZ = 224\nBS = 64\nNUM_WORKERS = 0\nSEED=0","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3722f32cf0cffcf09a27f22fdf21beff00879a54"},"cell_type":"code","source":"#tfms = get_transforms(do_flip=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eb2dbd82c8c49b4a5e1dd40ef78ff817cb6db347"},"cell_type":"code","source":"#data = ImageDataBunch.from_df(path_train, df, ds_tfms=tfms, size=150,num_workers=0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fe488fb15d4649abb7e2a2d7241a5f0085603edd"},"cell_type":"code","source":"data = (\n    ImageItemList\n        .from_folder('../input/train')\n        .random_split_by_pct(seed=SEED)\n        .label_from_func(lambda path: fn2label[path.name])\n        .add_test(ImageItemList.from_folder('../input/test'))\n        .transform(get_transforms(do_flip=False, max_zoom=1, max_warp=0, max_rotate=2), size=SZ, resize_method=ResizeMethod.SQUISH)\n        .databunch(bs=BS, num_workers=NUM_WORKERS, path='../input/train')\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2182fdd968d41d181f43329743457329ff158d6f"},"cell_type":"code","source":"data.show_batch(rows=3)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3358c5276c0a8228ebafdf9bfb09733c2c0c8655"},"cell_type":"markdown","source":"## Train"},{"metadata":{"trusted":true,"_uuid":"615544a28ffd697f40b920b3617031ce32f423a1"},"cell_type":"code","source":"name = f'res50-{SZ}'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4a3b04567c6b3291eea0192a13437f3bded0dcfe"},"cell_type":"code","source":"!git clone https://github.com/radekosmulski/whale","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b9244c08828ed1318468ea4f38c8d602bc408b7a"},"cell_type":"code","source":"import sys\n # Add directory holding utility functions to path to allow importing utility funcitons\n#sys.path.insert(0, '/kaggle/working/protein-atlas-fastai')\nsys.path.append('/kaggle/working/whale')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b5c88c81cea11516377a30351d23ce816d638430"},"cell_type":"code","source":"from whale.utils import map5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"624021a5ed5a48ba17f8c4544ec2fcf80c31b3d7"},"cell_type":"code","source":"MODEL_PATH = \"/tmp/model/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0197170934df7eb2359ef33855c46f92b562b0b0"},"cell_type":"code","source":"learn = create_cnn(data, models.resnet50, metrics=[accuracy, map5], model_dir=MODEL_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6e038a7c55fed226f8df0efd91d4197963cd38d2"},"cell_type":"code","source":"learn.fit_one_cycle(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"198a68f6fec38b62724c0a659bafa11ffe6971df"},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"740ca5ded159bc493e4c7c3cc005d8ee28698cb8"},"cell_type":"code","source":"learn.save(f'{name}-stage-1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f8904c79c0938e7a19a005e920b3a11743627bb7"},"cell_type":"code","source":"learn.unfreeze()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6b9347d0131664c10c3090e5c799402b1edbb16a"},"cell_type":"code","source":"learn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d992a2df387b03b83b235b309125272b59112546"},"cell_type":"code","source":"learn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"59108c8b47907da99109602b224eb1a7633563dc"},"cell_type":"code","source":"max_lr = 1e-4\nlrs = [max_lr/100, max_lr/10, max_lr]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8e3cc121ec58324705457bde72af4d3d0fe8133f"},"cell_type":"code","source":"learn.fit_one_cycle(5, lrs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2ef94caf8d5781cf65fab399d3eada71b146f825"},"cell_type":"code","source":"learn.save(f'{name}-stage-2')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8312f2e2a0d6e53c7a95054c8e400c8026bc3938"},"cell_type":"code","source":"learn.recorder.plot_losses()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"071a7fa7c4ad532a5045234cda5b70ff82b4ef82"},"cell_type":"markdown","source":"This is not a loss plot you would normally expect to see. Why does it look like this? Let's consider what images appear in the validation set:\n * images of whales that do not appear in the train set (whales where all their images were randomly assigned to the validation set) - there is nothing our model can learn about these!\n * images of whales with multiple images in the dataset where some subset of those got assigned to the validation set\n * `new_whale` images\n \nIntuitively, a model such as the above does not seem to frame the problem in a way that would be easy for a neural network to solve. Nonetheless, it is interesting to think how we could improve on the construction of the validation set? What tweaks could be made to the model to improve its performance?"},{"metadata":{"_uuid":"d2fbae01c895324b229b5be2717b6ffedfddd97f"},"cell_type":"markdown","source":"## Predict"},{"metadata":{"trusted":true,"_uuid":"fd42db59c37286745fe3fe4239591b447254b878"},"cell_type":"code","source":"preds, _ = learn.get_preds(DatasetType.Test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2a107adb37fc26e4fb5dfe9905909c9ab3bb1d2b"},"cell_type":"code","source":"from whale.utils import *","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8d29c36b9dbe92e62eaab36ccdeb9fa2da69da45"},"cell_type":"code","source":"def create_submission(preds, data, name, classes=None):\n    if not classes: classes = data.classes\n    sub = pd.DataFrame({'Image': [path.name for path in data.test_ds.x.items]})\n    sub['Id'] = top_5_pred_labels(preds, classes)\n    sub.to_csv(f'{name}.csv', index=False) # compression='gzip'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2e15b94991e5a2dda4c7b40de94cc2584769d0dc"},"cell_type":"code","source":"create_submission(preds, learn.data, name)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"eacd6592024dd6597c21a3f34da36f347159d751"},"cell_type":"code","source":"pd.read_csv(f'{name}.csv').head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c09b7e31de7b55cbddb117fa7c6d1c5798cf84c3"},"cell_type":"code","source":"!rm -rf /kaggle/working/whale","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"44fc6a33e9fd0fd3b3127b6601fdf7e8fc9f8d18"},"cell_type":"code","source":"#!kaggle competitions submit -c humpback-whale-identification -f {name}.csv.gz -m \"{name}\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c5478e17764a10174a68189c9e0fde1a67b0be2"},"cell_type":"code","source":"#!kaggle competitions submit -c humpback-whale-identification -f {name}.csv -m \"{name}\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b251d5d6662c77a132739a28bfe8f4128675c34c"},"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}