{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Loading Libraries"},{"metadata":{"trusted":true},"cell_type":"code","source":"!cp ../input/gdcm-conda-install/gdcm.tar .\n!tar -xvzf gdcm.tar\n!conda install --offline ./gdcm/gdcm-2.8.9-py37h71b2a6d_0.tar.bz2","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\n## Loading Libraries\nimport numpy as np\nimport pandas as pd\n\nimport fastai\nfrom fastai.basics import *\nfrom fastai.callback.all import *\nfrom fastai.vision.all import *\nfrom fastai.medical.imaging import *\nimport torchvision.models as models\nimport pydicom\n\n# You can write up to 5GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"source = '../input/rsna-str-pulmonary-embolism-detection'\nfiles = os.listdir(source)\nfiles","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df = pd.read_csv(f'{source}/train.csv')\nprint(df.shape)\ndf.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Data Preparation"},{"metadata":{"trusted":true},"cell_type":"code","source":"get_x = lambda x:f'{source}/train/{x.StudyInstanceUID}/{x.SeriesInstanceUID}/{x.SOPInstanceUID}.dcm'\n\nvocab = ['pe_present_on_image', 'negative_exam_for_pe', 'indeterminate', \n         'rv_lv_ratio_gte_1', 'rv_lv_ratio_lt_1', # Only one label should be true at a time\n         'chronic_pe', 'acute_and_chronic_pe', # Only one label can be true at a time\n         'leftsided_pe', 'central_pe', 'rightsided_pe', # More than one label can be true at a time\n         'qa_motion', 'qa_contrast', 'flow_artifact', 'true_filling_defect_not_pe'] # These are only informational. Maybe use it for study level inferences\n\nget_y = ColReader(vocab) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tfms = [IntToFloatTensor(div=1000.0, div_mask=1), \n        *aug_transforms(size=224)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"block = DataBlock(blocks=(ImageBlock(cls=PILDicom), MultiCategoryBlock(vocab=vocab, encoded=True)), \n                  get_x=get_x,\n                  get_y=get_y,\n                  batch_tfms=tfms)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dls = block.dataloaders(df[:1600], bs=32, num_workers=0)  # Change df[:1600] to df to train on complete data. \ndls.show_batch(max_n=9, nrows=3, ncols=3, figsize=(20,20))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def accuracy_multi(inp, targ, thresh=0.5, sigmoid=True):\n    \"Compute accuracy when `inp` and `targ` are the same size.\"\n    if sigmoid: inp = inp.sigmoid()\n    return ((inp>thresh)==targ.bool()).float().mean()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"head = create_head(nf=1024, n_out=14, lin_ftrs=[512, 128], concat_pool=True)\nconfig = cnn_config(custom_head=head)\n\nlearn = cnn_learner(dls, resnet34, config=config, metrics=accuracy_multi)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr_good = learn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lr_good # pick the learning rate from here to fit method below","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model Development"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(3, lr_max=0.03)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.model_dir = '.'\nlearn.save(file='../working/resnet34')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Model Evaluation"},{"metadata":{"trusted":true},"cell_type":"code","source":"interp = ClassificationInterpretation.from_learner(learn)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"losses,idxs = interp.top_losses()\nlen(dls.valid_ds)==len(losses)==len(idxs)\ninterp.plot_confusion_matrix(figsize=(7,7))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"... Working on inference pipeline currently. Will publish it in the next few days!\nFeedback for improvement is welcome!"}],"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":4,"nbformat_minor":4}