{"cells":[{"metadata":{},"cell_type":"markdown","source":"","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"The purpose of this notebook is to develop capability to apply transfer learning to do image classification.After going through fastai's Practical Deep Learning for Coders course, I leveraged fastai library to develop my first image classification model. Remaining of the notebook is structured as below.","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"<a href='#1' > 1. Problem Statement <a><br>\n<a href='#2' > 2. Reading the data <a> <br>\n<a href='#3'> 3. Modelling <a> <br>\n<a href='#4'> 4. Scoring on test and Results<a> \n \n ","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"# <a id='1'> 1. Problem Statement <a>","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Melenoma is one type skin cancers,which is responsible for 75% of skin cancer realted death. Our goal is to build a model which classifies image of mole as either begnign(normal) or malginant( cancer) ","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"<a id='2'> 2. Reading the Data<a>","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"One of the tedious process while using CNN models is data preparation.In this challange,train and test images are located on seperate folders. The label of the train images are provided in seperate csv file.  Fortunately Fastai as developed data API which includes splitting train into development and validation dataset  and preparing the dataset in the format CNN acepts it","execution_count":null},{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\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":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","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)\nimport os\nimport warnings\nimport torch\nwarnings.filterwarnings(\"ignore\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#reading locaiton of train images\ntrain=pd.read_csv(\"../input/siim-isic-melanoma-classification/train.csv\")\n#adding path in the name column\ntrain['name']= train.image_name.apply(lambda x: os.path.join(\"train\",str(x+'.jpg')))\n#selectingo only path and label\nlabel_mapping=train[['name','target']]\n#similar thing for test data\ntest=pd.read_csv(\"../input/siim-isic-melanoma-classification/test.csv\")\ntest['name']=test.image_name.apply(lambda x:(str(x+'.jpg')))\ntest_map=pd.DataFrame(test['name'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#randomly choosing 1200 images with all events in it. The reason to undersample is to quickly get restults rather than waiting 3hrs on modelling process  \nlabel_mapping_event=label_mapping[label_mapping.target==1]\n\nlabel_mapping_nonevent=label_mapping[label_mapping.target==0]\n\n\nlabel_mapping_ne_sub = label_mapping_nonevent.sample(frac=0.02).reset_index(drop=True)\n\ntarget_map=pd.concat((label_mapping_event,label_mapping_ne_sub),axis=0).sample(frac=1).reset_index(drop=True)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#importing necessary variables from fastai\n%reload_ext autoreload\n%autoreload 2\nfrom fastai import *\nfrom fastai.vision import *\nnp.random.seed(123)\ntfms=get_transforms()\ntest_dl=ImageList.from_df(test_map,path='/kaggle/input/siim-isic-melanoma-classification/jpeg/test')\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"src=ImageList.from_df(target_map,path=\"/kaggle/input/siim-isic-melanoma-classification/jpeg\").split_by_rand_pct()\n\ndata=src.label_from_df().add_test(test_dl).transform(tfms,size=64).databunch(bs=32,num_workers=16).normalize(imagenet_stats)\n\narch=models.resnet18\nlearn=cnn_learner(data,arch,metrics=accuracy,model_dir=\"/kaggle/working/\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id='3'>3. Modelling<a>\n ","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"After training on few cycles, we can change the learning rate based on the recorder plot","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"lr=0.1/3\nlearn.fit_one_cycle(1,slice(lr))\nlearn.save('stage2_model')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.load('../input/modelfiles/stage1_model')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.fit_one_cycle(5,slice(1e-2))\nlearn.save('stage_2_model')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()\nlearn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(3,slice(1e-5))\nlearn.save('stage_3_model')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"<a id='4'> 4. Scoring on test and Results <a>","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import roc_auc_score\n\ndef get_auc_subset(preds,targs):\n    pred_np=preds[:,1].detach().numpy()\n    targ_np=targs.detach().numpy()\n    return roc_auc_score(targ_np,pred_np)\n\ndef get_roc(learn):\n    #pred_train,targ_train=learn.get_preds(ds_type=DatasetType.Train)\n    pred_valid,targ_valid=learn.get_preds(ds_type=DatasetType.Valid)\n    #train_auc=get_auc_subset(pred_train,targ_train)\n    valid_auc=get_auc_subset(pred_valid,targ_valid)\n    return valid_auc\n\nvalid_auc=get_roc(learn) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\npred_test,_=learn.get_preds(ds_type=DatasetType.Test)\n\nfinal_pred=pred_test[:,1].detach().numpy()\n\nsubmission=pd.DataFrame({'target':final_pred})\nsubmission['image_name']=test.image_name\nsubmission=submission[['image_name','target']]\nsubmission.to_csv(\"submission2.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Although we used just 2% of availble data and very minimalistic tuning, this model gave 0.85 AUC on public dataset","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}