{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Motivation\nTrying simple and straigntforward fastai v2 process.\nFastai2 (v.2.6.3) full path from training to testing and submission, with the augmentation during training, validation and testing.\nTrying to use only fastai implementations, including FocalLoss(). Exception: using Albumentation library for data augmentation.","metadata":{}},{"cell_type":"code","source":"from fastai.vision.all import *\nimport pandas as pd\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-05-26T15:31:47.55129Z","iopub.execute_input":"2022-05-26T15:31:47.552496Z","iopub.status.idle":"2022-05-26T15:31:50.717263Z","shell.execute_reply.started":"2022-05-26T15:31:47.552318Z","shell.execute_reply":"2022-05-26T15:31:50.715986Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation\nThis section is not the \"pure fastai\". \n\nI got frustrated playing around fastai2 augmentations. There are only few for the item transform. More batch transformations are available, however they will not work for validation and testing. I want the same augmentations to work on validation as well as for training, and it is essential for me to have augmentations during testing because I am using TTA. \n\nAlbumentation library offers great variety of the transformations and efficient implementation - frustration-free. In fact, I got this reference from the official fastai tutorial, so they do recognize their current limitations. https://docs.fast.ai/tutorial.albumentations.html","metadata":{}},{"cell_type":"code","source":"import albumentations as Alb\nclass AlbTransform(Transform):\n    def __init__(self, aug): self.aug = aug\n    def encodes(self, img: PILImage):\n        aug_img = self.aug(image=np.array(img))['image']\n        return PILImage.create(aug_img)\n    \ndef get_augs(): return Alb.Compose([\n    Alb.Transpose(),\n    Alb.Flip(),\n    Alb.RandomRotate90(),\n    Alb.HueSaturationValue(\n      hue_shift_limit=5, \n      sat_shift_limit=5, \n      val_shift_limit=5 ),\n])\n# there are many suggestions to upscale to 196x196\nitem_tfms = [Resize(196), AlbTransform(get_augs())]\nbatch_tfms = Normalize.from_stats(*imagenet_stats) ","metadata":{"execution":{"iopub.status.busy":"2022-05-26T15:31:50.719822Z","iopub.execute_input":"2022-05-26T15:31:50.720122Z","iopub.status.idle":"2022-05-26T15:31:51.87828Z","shell.execute_reply.started":"2022-05-26T15:31:50.720088Z","shell.execute_reply":"2022-05-26T15:31:51.877062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Training-Validation data loader","metadata":{}},{"cell_type":"code","source":"train_path='../input/histopathologic-cancer-detection/train/'\ntrain_df = pd.read_csv('../input/histopathologic-cancer-detection/train_labels.csv')\n# for interactive DEBUG: reduce amount of train images : train_df = train_df[:1024]\ndls = ImageDataLoaders.from_df(train_df, path=train_path, suff='.tif', \n    item_tfms=item_tfms, batch_tfms=batch_tfms, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2022-05-26T15:31:51.880269Z","iopub.execute_input":"2022-05-26T15:31:51.880663Z","iopub.status.idle":"2022-05-26T15:31:52.454445Z","shell.execute_reply.started":"2022-05-26T15:31:51.880616Z","shell.execute_reply":"2022-05-26T15:31:52.453387Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# try this to see dataloader working\n\n# dls.train.show_batch(max_n=12)\n# dls.valid.show_batch(max_n=12)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-05-26T15:43:25.436218Z","iopub.execute_input":"2022-05-26T15:43:25.437773Z","iopub.status.idle":"2022-05-26T15:43:25.443642Z","shell.execute_reply.started":"2022-05-26T15:43:25.437682Z","shell.execute_reply":"2022-05-26T15:43:25.442607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load pre-trained model and fine tune it on our data","metadata":{}},{"cell_type":"code","source":"learn = vision_learner(dls, densenet121, path='.', \n    loss_func=FocalLoss(),  \n    metrics=BalancedAccuracy() ) # because this dataset is unbalanced (40/60)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn.fine_tune(6, freeze_epochs=3) # learn is performed using fit_one_cycle()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# learn.export()\nlearn.save('my_super_model') # I will try to continue training it in a separate notebook","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Testing data loader","metadata":{}},{"cell_type":"code","source":"test_path='../input/histopathologic-cancer-detection/test/'\ntest_df = pd.read_csv('../input/histopathologic-cancer-detection/sample_submission.csv')\n# for interactive DEBUG: test_df = test_df[:12]\n# new loader for the sake of path, which if different from the training path\ntdls = ImageDataLoaders.from_df(test_df, path=test_path, suff='.tif',\n    item_tfms=item_tfms, batch_tfms=batch_tfms, shuffle=False)\ntst_dl = tdls.test_dl(test_df) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# try it working !!! here I need to make sure aug is working, seems like not\n# tst_dl.show_batch(max_n=12)","metadata":{"_kg_hide-output":true,"_kg_hide-input":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Testing round with TTA (Test Time Augmentation)","metadata":{}},{"cell_type":"code","source":"preds, y = learn.tta(dl=tst_dl, n=16, use_max=False)\npreds_f1 = torch.softmax(preds, dim=1)[:, 1]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare submission file","metadata":{}},{"cell_type":"code","source":"lb_df = pd.DataFrame({ 'label' : preds_f1 })\ntest_df.label = lb_df.label\ntest_df.to_csv(f'submission_HST.csv', header=True, index=False)\ntest_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Have a nice day!\nWas it easy? Upvote and comment, please :)","metadata":{}}]}