{"cells":[{"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 in \n\n#import numpy as np # linear algebra\n#import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n#import os\n'''\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n'''\n# Any results you write to the current directory are saved as output.","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\nimport pydicom\nimport os\nimport sys\nimport matplotlib.pyplot as plt\nimport collections\nfrom tqdm import tqdm_notebook as tqdm\nfrom datetime import datetime\n\nfrom math import ceil, floor\nimport cv2\n\nimport tensorflow as tf\nimport keras\n\nimport seaborn as sns\n\nfrom glob import glob\nfrom keras import initializers, regularizers, constraints, optimizers, layers\nfrom keras.optimizers import Optimizer\nfrom keras.callbacks import *","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#sys.path.append(os.path.abspath('../input/efficientnet/efficientnet-master/efficientnet-master'))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"For windowing the input images . Many thanks\n\nhttps://www.kaggle.com/omission/eda-view-dicom-images-with-correct-windowing\nhttps://www.kaggle.com/akensert/resnet50-keras-baseline-model\nhttps://www.kaggle.com/xhlulu/rsna-intracranial-simple-densenet-in-keras/notebook\nhttps://www.kaggle.com/taindow/pytorch-efficientnet-b0\nhttps://www.kaggle.com/rajnishe/efficenet-b5 *\n-- For analysis of data\n\nhttps://www.kaggle.com/allunia/rsna-ih-detection-eda-baseline\nhttps://www.kaggle.com/gzuidhof/full-preprocessing-tutorial"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Path Information\n# Always clean new files after kernel \n# else you will get too many open file issue\n\nBASE_PATH = '/kaggle/input/rsna_noben_png_224_224_v1/'\n\n#CSV_BASE_PATH = '/kaggle/input/rsna-intracranial-hemorrhage-detection/'\n\nTRAIN_PATH = 'stage_1_train_images/'\nTEST_PATH = 'stage_1_test_images/'\n\nTMP_DIR_PATH = '/kaggle/tmp/'\n\nTRAIN_TMP_DIR_PATH = TMP_DIR_PATH + 'train_png_img/'\nTEST_TMP_DIR_PATH  = TMP_DIR_PATH + 'test_png_img/'\n\nIMG_SIZE = 224","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_csv = pd.read_csv(BASE_PATH + 'stage_1_train.csv')\n\nprint(train_df_csv.shape)\n#train_df_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Extract image name\ntrain_df_csv['filename'] = train_df_csv['ID'].apply(lambda st: \"ID_\" + st.split('_')[1] + \".dcm\")\n\n#Extract type of problem\ntrain_df_csv['type'] = train_df_csv['ID'].apply(lambda st: st.split('_')[2])\n\nprint(train_df_csv.shape)\n#train_df_csv.head(8)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df_csv.filename.nunique()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Analysis\nFinding distribution of labels"},{"metadata":{"trusted":true},"cell_type":"code","source":"#train_df_csv.groupby(\"type\").size()\nlabel_dist = train_df_csv.groupby(\"type\").Label.value_counts().unstack().reset_index()\n       \n#.Label.value_counts()#.unstack()\nlabel_dist","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#label_dist.columns = ['type','neg_label','pos_label']\n\n#label_dist","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"'''\ng = sns.catplot(x=\"type\", y=\"neg_label\",\n...                 data=label_dist, saturation=.5,\n...                 kind=\"bar\", ci=None, aspect=1.8)\ng = sns.catplot(x=\"type\", y=\"pos_label\",\n...                 data=label_dist, saturation=.5,\n...                 kind=\"bar\", ci=None, aspect=1.8)\n'''","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Converting train CSV File\n-- Ready for processing , model creation"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Pivot it so that one row contains one image and all labels\npivot_train_df_csv = train_df_csv[['Label', 'filename', 'type']].drop_duplicates().pivot(\n    index='filename', columns='type', values='Label').reset_index()\nprint(pivot_train_df_csv.shape)\npivot_train_df_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv_any = pivot_train_df_csv[pivot_train_df_csv['any'] == 1]\npivot_train_df_csv_nany = pivot_train_df_csv[pivot_train_df_csv['any'] != 1]\n\n#pivot_train_df_csv_any = pivot_train_df_csv_any.iloc[1:50000]\npivot_train_df_csv_any = pivot_train_df_csv_any.sample(n=97103)\n#pivot_train_df_csv_nany = pivot_train_df_csv_nany.iloc[1:50000]\npivot_train_df_csv_nany = pivot_train_df_csv_nany.sample(n=97103)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv=pd.concat([pivot_train_df_csv_any,pivot_train_df_csv_nany])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv=pivot_train_df_csv.reset_index(drop=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image Reading from disk path"},{"metadata":{},"cell_type":"markdown","source":"# Read Test file"},{"metadata":{"trusted":true},"cell_type":"code","source":"# submission file is test file , need to conver into list of images\ntest_df_csv = pd.read_csv(BASE_PATH + 'stage_1_sample_submission.csv')\n\ntest_df_csv['filename'] = test_df_csv['ID'].apply(lambda st: \"ID_\" + st.split('_')[1] + \".dcm\")\ntest_df_csv['type'] = test_df_csv['ID'].apply(lambda st: st.split('_')[2])\n\nprint(test_df_csv.shape)\ntest_df_csv.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_csv = pd.DataFrame(test_df_csv.filename.unique(), columns=['filename'])\nprint(test_df_csv.shape)\n#test_df_csv.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Data Generator Creation"},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv['filename'] = pivot_train_df_csv['filename'].apply(lambda st: st.split('.')[0] + \".png\")\npivot_train_df_csv.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_csv['filename'] = test_df_csv['filename'].apply(lambda st: st.split('.')[0] + \".png\")\ntest_df_csv.head(2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"np.set_printoptions(threshold=sys.maxsize)\nimgpath = BASE_PATH + TEST_PATH+'ID_c16f5348b.png'\n\nimage = cv2.imread(imgpath,0)\nimage = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)\nimage = cv2.addWeighted (image,4, cv2.GaussianBlur(image, (0,0) ,10), -4, 0)\nplt.imshow(image)\nprint(image.shape)\n\nIMG_SIZE = 224"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"image = cv2.imread(imgpath,0)\nimage = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)\nimage = cv2.addWeighted (image,4, cv2.GaussianBlur(image, (0,0) ,10), -4, 0)\nplt.imshow(image)"},{"metadata":{"trusted":true},"cell_type":"code","source":"print(BASE_PATH + TEST_PATH)\n#reading all dcm files into train and text\n# GLOB api work like unix style matching of path\n\ntrain_dcm_img =  sorted(glob(BASE_PATH + TRAIN_PATH + \"*.png\"))\ntest_dcm_img  =  sorted(glob(BASE_PATH + TEST_PATH + \"*.png\"))\n\nprint(\"train files: \", len(train_dcm_img))\nprint(\"test files: \", len(test_dcm_img))\n\npd.reset_option('max_colwidth')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"print(test_dcm_img[:4])\nif '/kaggle/input/rsna_noben_png_224_224_v1/stage_1_test_images/ID_c16f5348b.png' in test_dcm_img:\n    print('y')"},{"metadata":{"trusted":true},"cell_type":"code","source":"pivot_train_df_csv.head(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"num_ill_patients = pivot_train_df_csv[pivot_train_df_csv[\"any\"]==1].shape[0]\nnum_ill_patients","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"undersample_seed = 42\nhealthy_patients = pivot_train_df_csv[pivot_train_df_csv[\"any\"]==0].index.values\nhealthy_patients_selection = np.random.RandomState(undersample_seed).choice(\n    healthy_patients, size=num_ill_patients, replace=False\n)\nlen(healthy_patients_selection)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image, sigmaX=10):\n    \"\"\"\n    The whole preprocessing pipeline:\n    1. Read in image\n    2. Apply masks\n    3. Resize image to desired size\n    4. Add Gaussian noise to increase Robustness\n    cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB)\n    \"\"\"\n    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)\n    #image = cv2.resize(image, (IMG_SIZE, IMG_SIZE))\n    image = cv2.addWeighted (image,4, cv2.GaussianBlur(image, (0,0) ,sigmaX), -4, 128)\n    return image","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\n#   --- TO DO ----\n#   zca_epsilon: epsilon for ZCA whitening. Default is 1e-6.\n#   zca_whitening: Boolean. Apply ZCA whitening.\n#\ndef create_datagen():\n    train_aug = ImageDataGenerator(rescale=1./255, # Important as pixel haev 0 - 255 \n                               horizontal_flip = True,\n                               #zoom_range = 0.15,\n                               #vertical_flip = True,\n                               #shear_range=0.1,\n                               rotation_range = 10,\n                               validation_split=0.20,\n                               preprocessing_function=preprocess_image\n                               )\n    return train_aug","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 32\n\ndef create_test_gen():\n    return ImageDataGenerator(rescale=1./255,\n                              preprocessing_function=preprocess_image).flow_from_dataframe(\n        test_df_csv,\n        directory= BASE_PATH+TEST_PATH,\n        x_col='filename',\n        class_mode=None,\n        target_size=(IMG_SIZE, IMG_SIZE),\n        batch_size=BATCH_SIZE,\n        shuffle=False\n        \n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def create_flow(datagen, subset):\n    return datagen.flow_from_dataframe(\n        pivot_train_df_csv, \n        directory =BASE_PATH+TRAIN_PATH,\n        x_col = 'filename', \n        y_col = ['any', 'epidural', 'intraparenchymal','intraventricular', 'subarachnoid', 'subdural'],\n        class_mode='raw',\n        target_size=(IMG_SIZE, IMG_SIZE),\n        batch_size=BATCH_SIZE,\n        subset=subset\n    )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n# Using original generator\ntrain_data_generator = create_datagen()\n\ntrain_gen = create_flow(train_data_generator, 'training')\nval_gen = create_flow(train_data_generator, 'validation')\n\ntest_gen = create_test_gen()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Model Creation"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.xception import Xception\nfrom keras.models import Model\nfrom keras.layers import Dense, GlobalAveragePooling2D, Dropout, Input\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau\nfrom sklearn.model_selection import train_test_split\nimport keras\nfrom keras.engine import Layer,InputSpec\nfrom keras.applications.resnet50 import ResNet50","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class RAdam(keras.optimizers.Optimizer):\n    \"\"\"RAdam optimizer.\n    # Arguments\n        learning_rate: float >= 0. Learning rate.\n        beta_1: float, 0 < beta < 1. Generally close to 1.\n        beta_2: float, 0 < beta < 1. Generally close to 1.\n        epsilon: float >= 0. Fuzz factor. If `None`, defaults to `K.epsilon()`.\n        decay: float >= 0. Learning rate decay over each update.\n        weight_decay: float >= 0. Weight decay for each param.\n        amsgrad: boolean. Whether to apply the AMSGrad variant of this\n            algorithm from the paper \"On the Convergence of Adam and\n            Beyond\".\n        total_steps: int >= 0. Total number of training steps. Enable warmup by setting a positive value.\n        warmup_proportion: 0 < warmup_proportion < 1. The proportion of increasing steps.\n        min_lr: float >= 0. Minimum learning rate after warmup.\n    # References\n        - [Adam - A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980v8)\n        - [On the Convergence of Adam and Beyond](https://openreview.net/forum?id=ryQu7f-RZ)\n        - [On The Variance Of The Adaptive Learning Rate And Beyond](https://arxiv.org/pdf/1908.03265v1.pdf)\n    \"\"\"\n\n    def __init__(self, learning_rate=0.001, beta_1=0.9, beta_2=0.999,\n                 epsilon=None, decay=0., weight_decay=0., amsgrad=False,\n                 total_steps=0, warmup_proportion=0.1, min_lr=0., **kwargs):\n        learning_rate = kwargs.pop('lr', learning_rate)\n        super(RAdam, self).__init__(**kwargs)\n        with K.name_scope(self.__class__.__name__):\n            self.iterations = K.variable(0, dtype='int64', name='iterations')\n            self.learning_rate = K.variable(learning_rate, name='learning_rate')\n            self.beta_1 = K.variable(beta_1, name='beta_1')\n            self.beta_2 = K.variable(beta_2, name='beta_2')\n            self.decay = K.variable(decay, name='decay')\n            self.weight_decay = K.variable(weight_decay, name='weight_decay')\n            self.total_steps = K.variable(total_steps, name='total_steps')\n            self.warmup_proportion = K.variable(warmup_proportion, name='warmup_proportion')\n            self.min_lr = K.variable(min_lr, name='min_lr')\n        if epsilon is None:\n            epsilon = K.epsilon()\n        self.epsilon = epsilon\n        self.initial_decay = decay\n        self.initial_weight_decay = weight_decay\n        self.initial_total_steps = total_steps\n        self.amsgrad = amsgrad\n\n    def get_updates(self, loss, params):\n        grads = self.get_gradients(loss, params)\n        self.updates = [K.update_add(self.iterations, 1)]\n\n        lr = self.lr\n\n        if self.initial_decay > 0:\n            lr = lr * (1. / (1. + self.decay * K.cast(self.iterations, K.dtype(self.decay))))\n\n        t = K.cast(self.iterations, K.floatx()) + 1\n\n        if self.initial_total_steps > 0:\n            warmup_steps = self.total_steps * self.warmup_proportion\n            decay_steps = K.maximum(self.total_steps - warmup_steps, 1)\n            decay_rate = (self.min_lr - lr) / decay_steps\n            lr = K.switch(\n                t <= warmup_steps,\n                lr * (t / warmup_steps),\n                lr + decay_rate * K.minimum(t - warmup_steps, decay_steps),\n            )\n\n        ms = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='m_' + str(i)) for (i, p) in enumerate(params)]\n        vs = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='v_' + str(i)) for (i, p) in enumerate(params)]\n\n        if self.amsgrad:\n            vhats = [K.zeros(K.int_shape(p), dtype=K.dtype(p), name='vhat_' + str(i)) for (i, p) in enumerate(params)]\n        else:\n            vhats = [K.zeros(1, name='vhat_' + str(i)) for i in range(len(params))]\n\n        self.weights = [self.iterations] + ms + vs + vhats\n\n        beta_1_t = K.pow(self.beta_1, t)\n        beta_2_t = K.pow(self.beta_2, t)\n\n        sma_inf = 2.0 / (1.0 - self.beta_2) - 1.0\n        sma_t = sma_inf - 2.0 * t * beta_2_t / (1.0 - beta_2_t)\n\n        for p, g, m, v, vhat in zip(params, grads, ms, vs, vhats):\n            m_t = (self.beta_1 * m) + (1. - self.beta_1) * g\n            v_t = (self.beta_2 * v) + (1. - self.beta_2) * K.square(g)\n\n            m_corr_t = m_t / (1.0 - beta_1_t)\n            if self.amsgrad:\n                vhat_t = K.maximum(vhat, v_t)\n                v_corr_t = K.sqrt(vhat_t / (1.0 - beta_2_t))\n                self.updates.append(K.update(vhat, vhat_t))\n            else:\n                v_corr_t = K.sqrt(v_t / (1.0 - beta_2_t))\n\n            r_t = K.sqrt((sma_t - 4.0) / (sma_inf - 4.0) *\n                         (sma_t - 2.0) / (sma_inf - 2.0) *\n                         sma_inf / sma_t)\n\n            p_t = K.switch(sma_t >= 5, r_t * m_corr_t / (v_corr_t + self.epsilon), m_corr_t)\n\n            if self.initial_weight_decay > 0:\n                p_t += self.weight_decay * p\n\n            p_t = p - lr * p_t\n\n            self.updates.append(K.update(m, m_t))\n            self.updates.append(K.update(v, v_t))\n            new_p = p_t\n\n            # Apply constraints.\n            if getattr(p, 'constraint', None) is not None:\n                new_p = p.constraint(new_p)\n\n            self.updates.append(K.update(p, new_p))\n        return self.updates\n\n    @property\n    def lr(self):\n        return self.learning_rate\n\n    @lr.setter\n    def lr(self, learning_rate):\n        self.learning_rate = learning_rate\n\n    def get_config(self):\n        config = {\n            'learning_rate': float(K.get_value(self.learning_rate)),\n            'beta_1': float(K.get_value(self.beta_1)),\n            'beta_2': float(K.get_value(self.beta_2)),\n            'decay': float(K.get_value(self.decay)),\n            'weight_decay': float(K.get_value(self.weight_decay)),\n            'epsilon': self.epsilon,\n            'amsgrad': self.amsgrad,\n            'total_steps': float(K.get_value(self.total_steps)),\n            'warmup_proportion': float(K.get_value(self.warmup_proportion)),\n            'min_lr': float(K.get_value(self.min_lr)),\n        }\n        base_config = super(RAdam, self).get_config()\n        return dict(list(base_config.items()) + list(config.items()))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Loss Function"},{"metadata":{"trusted":true},"cell_type":"code","source":"#tf.losses.log_loss\nimport tensorflow as tf\nfrom keras import backend as K\n\n#weight_mask = [2.0,1.0,1.0,1.0,1.0,1.0]\n#weights = tf.expand_dims(weight_mask, axis = 0)\n\ndef custom_log_loss(y_true, y_pred):\n    loss_val = tf.losses.log_loss(y_true, y_pred)\n    #loss_val = tf.nn.sigmoid_cross_entropy_with_logits(labels=y_true, logits=y_pred)\n    #loss_val = tf.losses.sigmoid_cross_entropy(y_true, y_pred)\n    #print(y_true.shape)\n    #print(ck_val)\n    return loss_val","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#K.get_session().run(tf.local_variables_initializer())\n#optimizer = RAdam(lr = 1e-4)\noptimizer = keras.optimizers.adam(lr = .001,beta_1=0.9,beta_2=0.999,epsilon=1e-08,decay=0.0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"\n\nclass CyclicLR(Callback):\n    \"\"\"This callback implements a cyclical learning rate policy (CLR).\n    The method cycles the learning rate between two boundaries with\n    some constant frequency, as detailed in this paper (https://arxiv.org/abs/1506.01186).\n    The amplitude of the cycle can be scaled on a per-iteration or \n    per-cycle basis.\n    This class has three built-in policies, as put forth in the paper.\n    \"triangular\":\n        A basic triangular cycle w/ no amplitude scaling.\n    \"triangular2\":\n        A basic triangular cycle that scales initial amplitude by half each cycle.\n    \"exp_range\":\n        A cycle that scales initial amplitude by gamma**(cycle iterations) at each \n        cycle iteration.\n    For more detail, please see paper.\n    \n    # Example\n        ```python\n            clr = CyclicLR(base_lr=0.001, max_lr=0.006,\n                                step_size=2000., mode='triangular')\n            model.fit(X_train, Y_train, callbacks=[clr])\n        ```\n    \n    Class also supports custom scaling functions:\n        ```python\n            clr_fn = lambda x: 0.5*(1+np.sin(x*np.pi/2.))\n            clr = CyclicLR(base_lr=0.001, max_lr=0.006,\n                                step_size=2000., scale_fn=clr_fn,\n                                scale_mode='cycle')\n            model.fit(X_train, Y_train, callbacks=[clr])\n        ```    \n    # Arguments\n        base_lr: initial learning rate which is the\n            lower boundary in the cycle.\n        max_lr: upper boundary in the cycle. Functionally,\n            it defines the cycle amplitude (max_lr - base_lr).\n            The lr at any cycle is the sum of base_lr\n            and some scaling of the amplitude; therefore \n            max_lr may not actually be reached depending on\n            scaling function.\n        step_size: number of training iterations per\n            half cycle. Authors suggest setting step_size\n            2-8 x training iterations in epoch.\n        mode: one of {triangular, triangular2, exp_range}.\n            Default 'triangular'.\n            Values correspond to policies detailed above.\n            If scale_fn is not None, this argument is ignored.\n        gamma: constant in 'exp_range' scaling function:\n            gamma**(cycle iterations)\n        scale_fn: Custom scaling policy defined by a single\n            argument lambda function, where \n            0 <= scale_fn(x) <= 1 for all x >= 0.\n            mode paramater is ignored \n        scale_mode: {'cycle', 'iterations'}.\n            Defines whether scale_fn is evaluated on \n            cycle number or cycle iterations (training\n            iterations since start of cycle). Default is 'cycle'.\n    \"\"\"\n\n    def __init__(self, base_lr=0.001, max_lr=0.006, step_size=2000., mode='triangular',\n                 gamma=1., scale_fn=None, scale_mode='cycle'):\n        super(CyclicLR, self).__init__()\n\n        self.base_lr = base_lr\n        self.max_lr = max_lr\n        self.step_size = step_size\n        self.mode = mode\n        self.gamma = gamma\n        if scale_fn == None:\n            if self.mode == 'triangular':\n                self.scale_fn = lambda x: 1.\n                self.scale_mode = 'cycle'\n            elif self.mode == 'triangular2':\n                self.scale_fn = lambda x: 1/(2.**(x-1))\n                self.scale_mode = 'cycle'\n            elif self.mode == 'exp_range':\n                self.scale_fn = lambda x: gamma**(x)\n                self.scale_mode = 'iterations'\n        else:\n            self.scale_fn = scale_fn\n            self.scale_mode = scale_mode\n        self.clr_iterations = 0.\n        self.trn_iterations = 0.\n        self.history = {}\n\n        self._reset()\n\n    def _reset(self, new_base_lr=None, new_max_lr=None,\n               new_step_size=None):\n        \"\"\"Resets cycle iterations.\n        Optional boundary/step size adjustment.\n        \"\"\"\n        if new_base_lr != None:\n            self.base_lr = new_base_lr\n        if new_max_lr != None:\n            self.max_lr = new_max_lr\n        if new_step_size != None:\n            self.step_size = new_step_size\n        self.clr_iterations = 0.\n        \n    def clr(self):\n        cycle = np.floor(1+self.clr_iterations/(2*self.step_size))\n        x = np.abs(self.clr_iterations/self.step_size - 2*cycle + 1)\n        if self.scale_mode == 'cycle':\n            return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(cycle)\n        else:\n            return self.base_lr + (self.max_lr-self.base_lr)*np.maximum(0, (1-x))*self.scale_fn(self.clr_iterations)\n        \n    def on_train_begin(self, logs={}):\n        logs = logs or {}\n\n        if self.clr_iterations == 0:\n            K.set_value(self.model.optimizer.lr, self.base_lr)\n        else:\n            K.set_value(self.model.optimizer.lr, self.clr())        \n            \n    def on_batch_end(self, epoch, logs=None):\n        \n        logs = logs or {}\n        self.trn_iterations += 1\n        self.clr_iterations += 1\n\n        self.history.setdefault('lr', []).append(K.get_value(self.model.optimizer.lr))\n        self.history.setdefault('iterations', []).append(self.trn_iterations)\n\n        for k, v in logs.items():\n            self.history.setdefault(k, []).append(v)\n        \n        K.set_value(self.model.optimizer.lr, self.clr())\n    \n\ndef f1(y_true, y_pred):\n    '''\n    metric from here \n    https://stackoverflow.com/questions/43547402/how-to-calculate-f1-macro-in-keras\n    '''\n    def recall(y_true, y_pred):\n        \"\"\"Recall metric.\n\n        Only computes a batch-wise average of recall.\n\n        Computes the recall, a metric for multi-label classification of\n        how many relevant items are selected.\n        \"\"\"\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n        recall = true_positives / (possible_positives + K.epsilon())\n        return recall\n\n    def precision(y_true, y_pred):\n        \"\"\"Precision metric.\n\n        Only computes a batch-wise average of precision.\n\n        Computes the precision, a metric for multi-label classification of\n        how many selected items are relevant.\n        \"\"\"\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n        precision = true_positives / (predicted_positives + K.epsilon())\n        return precision\n    precision = precision(y_true, y_pred)\n    recall = recall(y_true, y_pred)\n    return 2*((precision*recall)/(precision+recall+K.epsilon()))\n    \n\nclr = CyclicLR(base_lr=0.001, max_lr=0.009,\n                        step_size=300., mode='exp_range',\n                        gamma=0.99994)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_layer = Input(shape = (IMG_SIZE,IMG_SIZE,3))\nfrom keras.layers import BatchNormalization\n\nbase_model = ResNet50(weights = None,\n                       include_top = False,\n                       input_tensor = input_layer)\n\nbase_model.load_weights('../input/resnet/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5')\n# all are false\n#for layer in base_model.layers:\n#    layer.trainable = False\n# top 5 are fasle    \n#for layer in base_model.layers[:180]:\n#    layer.trainable = False\n# last 4 are false\n#for layer in vgg_conv.layers[:-4]:\n#    layer.trainable = False\n    \nx = GlobalAveragePooling2D()(base_model.output)\nx = Dropout(0.5)(x)\nx = Dense(512, activation='relu')(x)\nx = BatchNormalization()(x)\nx = Dropout(0.3)(x)\nout = Dense(6, activation = 'sigmoid')(x)\n\nmodel = Model(inputs = input_layer, outputs = out)\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint\n#es = EarlyStopping(monitor='custom_log_Loss', mode='auto', verbose=1, patience=3,restore_best_weights=True)\n#rlrop = ReduceLROnPlateau(monitor='custom_log_loss', \n#                        factor=0.2, \n#                        patience=5, \n#                        verbose=1, \n#                        mode='auto', \n#                        min_lr=1e-6)\nfilepath = \"resNet50_DS_5epoch.h5\"\nmc=ModelCheckpoint(filepath, monitor='custom_log_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='min')\n\n\ncallback_list = [clr,mc]\n\nmodel.compile(optimizer = optimizer, loss = custom_log_loss, metrics = [\"accuracy\",custom_log_loss]) \nmodel.summary()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#print(675123 / BATCH_SIZE\nprint(len(train_gen))\nprint(len(train_gen)/BATCH_SIZE)\nprint(len(val_gen))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class_weights = {0: 2.,\n                1: 1.,\n                2: 1.,\n               3: 1.,\n               4: 1.,\n               5: 1.}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n#train_filenames = os.listdir(BASE_PATH + TRAIN_PATH)\n\n#total_steps = len(train_filenames) / BATCH_SIZE\n\nhistory = model.fit_generator(generator = train_gen, \n                    steps_per_epoch = len(train_gen), \n                    epochs = 5, \n                    validation_data = val_gen, \n                    validation_steps = len(val_gen), #total_steps * 0.15,\n                    callbacks =  callback_list,\n                    class_weight=class_weights)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.save_weights(\"Weight_resNet50_DS_5epoch_2.h5\")\nmodel.save('resNet50_DS_5epoch_2.h5')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Epoch 1/1\n  839/17910 [>.............................] - ETA: 4:20:54 - loss: 0.1778 - accuracy: 0.6707 - custom_log_loss: 0.1778"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test = model.predict_generator(\n    test_gen,\n    steps=len(test_gen),\n    verbose=1\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Append the output predicts in the wide format to the y_test\ntest_df_csv = test_df_csv.join(pd.DataFrame(y_test, columns=[\n    'any', 'epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural'\n]))\n\n# Unpivot table, i.e. wide (N x 6) to long format (6N x 1)\ntest_df_csv = test_df_csv.melt(id_vars=['filename'])\n\n# Combine the filename column with the variable column\ntest_df_csv['ID'] = test_df_csv.filename.apply(lambda x: x.replace('.png', '')) + '_' + test_df_csv.variable\ntest_df_csv['Label'] = test_df_csv['value']\n\ntest_df_csv[['ID', 'Label']].to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df_csv.head(20)","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}