{"cells":[{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"collapsed":true},"cell_type":"code","source":"%matplotlib inline\n%reload_ext autoreload\n%autoreload 2\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ad66f06cc4749ad9e4b92e8bb03286742d5343a1","collapsed":true},"cell_type":"code","source":"import json\nimport pydicom\nfrom pathlib import Path\nfrom PIL import ImageDraw, ImageFont\nfrom matplotlib import patches, patheffects\nfrom fastai.conv_learner import *\nfrom fastai.dataset import *\n\ntorch.cuda.set_device(0)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_kg_hide-output":false,"trusted":true,"scrolled":true,"_uuid":"bab9c3291e804a53ec9cbe750fc0535dcfa13be8"},"cell_type":"code","source":"PATH = Path(\"../input\")\nlist(PATH.iterdir())","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0abbe3c5030bac2b38660761122bbdd9ffedd93b"},"cell_type":"markdown","source":"Create dataframe with all csv's. "},{"metadata":{"trusted":true,"_uuid":"1bf34c7c9f0bfbc7ee0a09b265c28547113f544b"},"cell_type":"code","source":"train_bb_df = pd.read_csv(PATH/'stage_1_train_labels.csv')\n# train_bb_df.head()\ntrain_bb_df['duplicate'] = train_bb_df.duplicated(['patientId'], keep=False)\n# train_bb_df[train_bb_df['duplicate']].head()\ndetailed_df = pd.read_csv(PATH/'stage_1_detailed_class_info.csv')\n# merge two df\nclass_df = train_bb_df.merge(detailed_df, on=\"patientId\")\ncsv_df = class_df.filter(['patientId', 'class'], )\n# csv_df = csv_df.set_index('patientId', )\n# detailed_df.head() , \nclass_df.head()\n# csv_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"609464e6e5e46b0aaf561e631ebf9190fe932dbc"},"cell_type":"code","source":"DCMS = 'stage_1_train_images'\nIMG_PATH = PATH/DCMS\nimg_size = 1024\nall_images = list(IMG_PATH.iterdir())\nall_images[:5]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"60166a395d54b73d568aedbdd6707df202957469"},"cell_type":"markdown","source":"We will write our own `open_image` fun, as `open_image` from fastai can't handle `.dcm` files. Next we replace fastai open_image with ours. "},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"9b9465ea57ff0f67f6afc61fc7718222c6ae96d1"},"cell_type":"code","source":"def open_image(loc):\n    if isinstance(loc, str):\n        loc = loc + '.dcm'\n    else: # posix path\n        loc = loc.as_posix()\n    img_arr = pydicom.read_file(loc).pixel_array\n    img_arr = img_arr/img_arr.max()\n    img_arr = (255*img_arr).clip(0, 255)#.astype(np.int32)\n    img_arr = Image.fromarray(img_arr).convert('RGB') # model expects 3 channel image\n    return np.array(img_arr)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"51dd69792edc0835e015475769901cd2fafea732"},"cell_type":"code","source":"from fastai import dataset\ndataset.open_image = open_image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"29b50b8380cbdb0e1d754ff0af25bd05e3c57ef6","collapsed":true},"cell_type":"code","source":"im0 = all_images[0]\nim = open_image(im0)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"51cc5da0413ad2d030e92a60b8ecdecc507677a1"},"cell_type":"markdown","source":"We got image, we have to display it. Lets add those func."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"4a10e2b5be2c2002ff600c7b994bc0e471281d17"},"cell_type":"code","source":"def show_img(im, figsize=None, ax=None):\n    if isinstance(im, Path): # read image from loc\n        im = open_image(im)\n    if not ax: \n        fig,ax = plt.subplots(figsize=figsize)\n    ax.imshow(im)\n    ax.get_xaxis().set_visible(False)\n    ax.get_yaxis().set_visible(False)\n    return ax\n\ndef draw_outline(o, lw):\n  o.set_path_effects([patheffects.Stroke(\n      linewidth=lw, foreground='black'), patheffects.Normal()])\n\ndef draw_rect(ax, b):\n    patch = ax.add_patch(patches.Rectangle(b[:2], *b[-2:], fill=False, edgecolor='white', lw=2))\n    draw_outline(patch, 4)\n\ndef draw_text(ax, xy, txt, sz=14, color='white'):\n    text = ax.text(*xy, txt, verticalalignment='top', color=color, fontsize=sz, weight='bold')\n    draw_outline(text, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7736e4e0fa59c303a6ecac5f12e2d88c09e8a01a"},"cell_type":"code","source":"ax = show_img(im)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"16abef0bc849b1be6e1a1403c9a6de23b55fd70e"},"cell_type":"markdown","source":"Let's have fun to fetch the xy co-ordinate to show the target bounding box. We will first fetch biggest bounding box. We can modify it later to show all bounding box."},{"metadata":{"trusted":true,"scrolled":false,"_uuid":"7f36fe31ae24b436f584bc4bd7e41c8a5d6f2ea1"},"cell_type":"code","source":"def resized (patients, resize):\n    if not resize:\n        return (patients.x, patients.y, patients.width, patients.height), patients.Target\n    else:\n        scale = img_size/resize\n        return (patients.x/scale, patients.y/scale, patients.width/scale, patients.height/scale), patients.Target\n\ndef get_bb_category(im_loc, only_one=True, resize=None):\n    patientId = im_loc.name.split('.dcm')[0]\n    patients = class_df[class_df['patientId'] == patientId]\n\n    patients.iloc[np.argsort(patients.width * patients.height).values]\n    if only_one:\n        patients = patients.iloc[-1:].iloc[0]\n        return resized(patients, resize)\n    else:\n        return [resized(patients.iloc[i], resize )for i in range(len(patients))]\n            \n\nim_loc = IMG_PATH/'00436515-870c-4b36-a041-de91049b9ab4.dcm'   \nget_bb_category(im_loc,only_one=False, resize=224)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"0d6c71c5803d29b45d53af18f292158e949d72cf"},"cell_type":"code","source":"ax = show_img(im_loc, figsize=(16,8))\ndraw_text(ax, (0,0), im_loc.name.split('.dcm')[0], color='green')\nfor b,c in get_bb_category(im_loc,only_one=False):\n    draw_rect(ax, b)\n    draw_text(ax, b[:2], c)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"5a7dbd81d469d0dfdc7405bcb688f361e03960a2"},"cell_type":"markdown","source":"Save our patient with category in csv. We will randomly select 100 pateints."},{"metadata":{"trusted":true,"_uuid":"fb6bfcd641cd47138f95c93827c39d8a0fdc84fe","collapsed":true},"cell_type":"code","source":"CSV = '/tmp/lrg.csv'\ncsv_df.sample(100, random_state=5500).to_csv(CSV, index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"03653d128bc9b4c999c7098e5d86b0c26760df87"},"cell_type":"code","source":"f_model = resnet34\nresize=sz=224\nbs=64","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"24666b14b7bdd8e5eef64dc0f53a073eb890e0f6"},"cell_type":"code","source":"tfms = tfms_from_model(f_model, sz, aug_tfms=transforms_side_on, crop_type=CropType.NO)\nmd = ImageClassifierData.from_csv(PATH, DCMS, CSV, tfms=tfms, bs=bs)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"53dca3aa863d94837e3ed10da35947142a429c09","collapsed":true},"cell_type":"code","source":"x,y=next(iter(md.val_dl))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a9a88e81726feb6d4986574ffe35221f2b77df61"},"cell_type":"code","source":"# does fastai internally uses denorm? \nshow_img(md.val_ds.denorm(to_np(x))[0]);","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cea384ed3710bab20d650989217ff97a417f597c"},"cell_type":"markdown","source":"We will create a learner model for `f_model`. But this was failing because it tries to create `/tmp` inside readonly `../input/tmp` file system. We will override Learner in conv_learner."},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"e95d9eb64eeb873be4c7d12ab9a002ac37f069ea"},"cell_type":"code","source":"# https://github.com/fastai/fastai/blob/921777feb46f215ed2b5f5dcfcf3e6edd299ea92/fastai/conv_learner.py\nfrom fastai.learner import Learner\nclass CustomLearner(Learner):\n    def __init__(self, data, models, opt_fn=None, tmp_name='/tmp', models_name='models', metrics=None, clip=None, crit=None):\n        self.data_,self.models,self.metrics = data,models,metrics\n        self.sched=None\n        self.wd_sched = None\n        self.clip = None\n        self.opt_fn = opt_fn or SGD_Momentum(0.9)\n        self.tmp_path = '/tmp' \n        self.models_path = '/tmp/models' \n        os.makedirs(self.tmp_path, exist_ok=True)\n        os.makedirs(self.models_path, exist_ok=True)\n        self.crit = crit if crit else self._get_crit(data)\n        self.reg_fn = None\n        self.fp16 = False\n        \n    def _get_crit(self, data): return F.mse_loss\n    \nfrom fastai.conv_learner import ConvLearner\nclass CustomConvLearner(CustomLearner, ConvLearner):\n    def __init__(self, data, models, precompute=False, **kwargs):\n        self.precompute = False\n        super().__init__(data, models, **kwargs)\n        if hasattr(data, 'is_multi') and not data.is_reg and self.metrics is None:\n            self.metrics = [accuracy_thresh(0.5)] if self.data.is_multi else [accuracy]\n        if precompute: self.save_fc1()\n        self.freeze()\n        self.precompute = precompute","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fcd6a02effc1807c2b59945ef71015f9ee7a6b2d"},"cell_type":"code","source":"\nlearn = CustomConvLearner.pretrained(f_model, md, metrics=[accuracy])\nlearn.opt_fn = optim.Adam","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"faff68f641272fd1864d8f61c2926487ccde1495"},"cell_type":"code","source":"# def accuracy(preds, targs):\n#     preds,targs=preds.type(torch.LongTensor),targs.type(torch.LongTensor)\n# #     preds = torch.max(preds, dim=1)[1]\n#     return (preds==targs).float().mean()\n\n# from fastai import metrics\n# metrics.accuracy = accuracy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7cd8b122f79910cee06ce487e11aa4c076a8b996","scrolled":true},"cell_type":"code","source":"lrf=learn.lr_find(1e-5,100)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3e1bfd33c50cbc7aa9e1f7cbf6915389c267e869","collapsed":true},"cell_type":"code","source":"learn.sched.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"collapsed":true,"_uuid":"3b873994dd22422fa98c8de9df0e0fe14fa90e45"},"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.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}