{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai import *\nfrom fastai.vision import *\nimport pandas as pd\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n\nSEED = 42\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(torch.cuda.is_available())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\npath = '../input/aptos2019-blindness-detection/'\ntrain_csv_path = path +'train.csv'\ntrain_img_path = path + 'train_images/'\ntrain = pd.read_csv(train_csv_path)\n\n#test path strings\nprint(train_csv_path)\nprint(train_img_path)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"There are total {} images in training dataset\".format(len(train)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f_names = get_image_files(train_img_path)\nf_names[:3]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train['id_code'] = train['id_code'].map(lambda x: (train_img_path + x + '.png'))\n\n#test the paths\nprint(train['id_code'][1])\nprint(train['id_code'][2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tfms = get_transforms(do_flip=True,flip_vert=True,\n                      max_rotate=360,max_warp=0,max_zoom=1.1,\n                      max_lighting=0.1,p_lighting=0.5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data = ImageDataBunch.from_df(path = '', df= train, label_col='diagnosis', ds_tfms=tfms,\n                              valid_pct=0.2, size=224, bs=32).normalize(imagenet_stats)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import PIL\nimport cv2\nIMG_SIZE = 224","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image\n\ndef crop_image1(img,tol=7):\n    # img is image data\n    # tol  is tolerance\n        \n    mask = img>tol\n    return img[np.ix_(mask.any(1),mask.any(0))]\n\ndef crop_image_from_gray(img,tol=7):\n    if img.ndim ==2:\n        mask = img>tol\n        return img[np.ix_(mask.any(1),mask.any(0))]\n    elif img.ndim==3:\n        gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)\n        mask = gray_img>tol\n        \n        check_shape = img[:,:,0][np.ix_(mask.any(1),mask.any(0))].shape[0]\n        if (check_shape == 0): # image is too dark so that we crop out everything,\n            return img # return original image\n        else:\n            img1=img[:,:,0][np.ix_(mask.any(1),mask.any(0))]\n            img2=img[:,:,1][np.ix_(mask.any(1),mask.any(0))]\n            img3=img[:,:,2][np.ix_(mask.any(1),mask.any(0))]\n            #print(img1.shape,img2.shape,img3.shape)\n            img = np.stack([img1,img2,img3],axis=-1)\n        #print(img.shape)\n        return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from fastai.vision import Image\n\ndef _load_format(path,convert_mode, after_open) -> Image :\n    image = cv2.imread(path)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    image = crop_image_from_gray(image)\n    image = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n    image=cv2.addWeighted ( image,4, cv2.GaussianBlur( image , (0,0), 10) ,-4 ,128)\n    img_fastai = Image((pil2tensor(image, np.float32)).div_(255)) #fastai Image format\n    \n    return (img_fastai)\n\nvision.data.open_image = _load_format","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch(rows = 3, figsize= (12,10))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Quadratic kappa:**\n\n- A weighted Kappa is a metric which is used to calculate the amount of similarity between predictions and actuals. A perfect score of 1.0 is granted when both the predictions and actuals are the same.\n- Whereas, the least possible score is -1 which is given when the predictions are furthest away from actuals. In our case, consider all actuals were 0's and all predictions were 4's.This would lead to a QWKP score of -1.\n- The aim is to get as close to 1 as possible. Generally a score of 0.6+ is considered to be a really good score."},{"metadata":{},"cell_type":"markdown","source":"**Calculating Quadratic kappa:**\n\n- Step-1: Under Step-1, we shall be calculating a confusion_matrix between the Predicted and Actual values. Here is a great resource to know more about confusion_matrix.\n- Step-2: Under Step-2, under step-2 each element is weighted. Predictions that are further away from actuals are marked harshly than predictions that are closer to actuals. We will have a less score if our prediction is 5 and actual is 3 as compared to a prediction of 4 in the same case.\n- Step-3: We create two vectors, one for preds and one for actuals, which tells us how many values of each rating exist in both vectors.\n- Step-4:E is the Expected Matrix which is the outer product of the two vectors calculated in step-3.\n- Step-5: Normalise both matrices to have same sum. Since, it is easiest to get sum to be '1', we will simply divide each matrix by it's sum to normalise the data.\n- Step-6: Calculated numerator and denominator of Weighted Kappa and return the Weighted Kappa metric as 1-(num/den)\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\n\ndef quadratic_kappa(actuals, preds):\n    \"\"\"This function calculates the Quadratic Kappa Metric used for Evaluation in the PetFinder competition\n    at Kaggle. It returns the Quadratic Weighted Kappa metric score between the actual and the predicted values \n    of adoption rating.\"\"\"\n    w = np.zeros((5,5))\n    O = confusion_matrix(actuals, preds)\n    for i in range(5): \n        for j in range(5):\n            w[i][j] = float(((i-j)**2)/16)\n    \n    act_hist=np.zeros([5])\n    for item in actuals: \n        act_hist[item]+=1\n    \n    pred_hist=np.zeros([5])\n    for item in preds: \n        pred_hist[item]+=1\n    \n    E = np.outer(act_hist, pred_hist);\n    E = E/E.sum();\n    O = O/O.sum();\n    \n    num=0\n    den=0\n    for i in range(5):\n        for j in range(5):\n            num+=w[i][j]*O[i][j]\n            den+=w[i][j]*E[i][j]\n    return (1 - (num/den))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"- But **Fastai has this metric in built so we use that.**"},{"metadata":{"trusted":true},"cell_type":"code","source":"kappa = KappaScore()\nkappa.weights = \"quadratic\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn = cnn_learner(data, models.resnet34, metrics=[error_rate,kappa])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.save('Stage-1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interpret = ClassificationInterpretation.from_learner(learn)\nlosses,idx = interpret.top_losses()\n\ninterpret.plot_top_losses(9, figsize=(15,11))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interpret.plot_confusion_matrix(figsize=(12,12), dpi=60)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"interpret.most_confused(min_val=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.fit_one_cycle(1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.load('Stage-1')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.lr_find()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.recorder.plot()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.unfreeze()\nlearn.fit_one_cycle(2, max_lr=slice(1e-06,1e-03))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df = pd.read_csv(path+'/sample_submission.csv')\nsample_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.add_test(ImageList.from_df(sample_df,path,folder='test_images',suffix='.png'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"data.show_batch(rows=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# remove zoom from FastAI TTA\ntta_params = {'beta':0.12, 'scale':1.0}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"learn.data.add_test(ImageList.from_df(sample_df,path,folder='test_images',suffix='.png'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds,y = learn.TTA(ds_type=DatasetType.Test, **tta_params)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df.diagnosis = preds.argmax(1)\nsample_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_df.to_csv('submission.csv',index=False)","execution_count":null,"outputs":[]},{"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":1}