{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":false,"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"from sklearn.utils import shuffle\nimport pandas as pd\nimport os\n\ndf = pd.read_csv(\"../input/train_labels.csv\")\ndf = shuffle(df)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_uuid":"ef9a6aee05dec5ec4ba97fd5e8d2724ff4f743ae","scrolled":true,"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ndf_train, df_val = train_test_split(df, test_size=0.1, stratify= df['label'])\n\nprint(\"Train data: \" + str(len(df_train[df_train[\"label\"] == 1]) + len(df_train[df_train[\"label\"] == 0])))\nprint(\"True positive in train data: \" +  str(len(df_train[df_train[\"label\"] == 1])))\nprint(\"True negative in train data: \" +  str(len(df_train[df_train[\"label\"] == 0])))\nprint(\"Valid data: \" + str(len(df_val[df_val[\"label\"] == 1]) + len(df_val[df_val[\"label\"] == 0])))\nprint(\"True positive in validation data: \" +  str(len(df_val[df_val[\"label\"] == 1])))\nprint(\"True negative in validation data: \" +  str(len(df_val[df_val[\"label\"] == 0])))","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_uuid":"89f0b8d6439c876464b9e44062852a9eb747426f","trusted":true},"cell_type":"code","source":"# Train List\ntrain_list = df_train['id'].tolist()\ntrain_list = ['../input/train/'+ name + \".tif\" for name in train_list]\n\n# Validation List\nval_list = df_val['id'].tolist()\nval_list = ['../input/train/'+ name + \".tif\" for name in val_list]\n\nid_label_map = {k:v for k,v in zip(df.id.values, df.label.values)}","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_uuid":"5d5639a7f9ebeb8fa044f5743bb6237d73f7fe09","trusted":true},"cell_type":"code","source":"def get_id_from_path(file_path):\n    return file_path.split(os.path.sep)[-1].replace('.tif', '')\n\ndef chunker(seq, size):\n    return (seq[pos:pos + size] for pos in range(0, len(seq), size))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install albumentations\nimport albumentations","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_uuid":"94bfd61b2dfcd0f4616e47ede87ab9ddb1a2f83e","trusted":true},"cell_type":"code","source":"import keras\nfrom keras.applications.densenet import DenseNet201, preprocess_input\nfrom keras.layers import Dense, Input, Dropout, MaxPooling2D, Concatenate, GlobalAveragePooling2D, GlobalMaxPooling2D, Flatten, Concatenate\nfrom keras.models import Model\nimport pandas as pd\nfrom random import shuffle\nimport numpy as np\nimport cv2\nimport glob\nimport gc\nimport os\nimport tensorflow as tf\nfrom keras.regularizers import l2\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras.layers import Dense, Dropout, Flatten, Activation, Input, BatchNormalization, Add, GlobalAveragePooling2D,AveragePooling2D,GlobalMaxPooling2D,concatenate\nfrom keras.layers import Lambda, Reshape, DepthwiseConv2D, ZeroPadding2D, Add, MaxPooling2D,Activation, Flatten, Conv2D, Dense, Input, Dropout, Concatenate, GlobalMaxPooling2D, GlobalAveragePooling2D, BatchNormalization\n\nfrom keras.models import Sequential\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint,TensorBoard,TerminateOnNaN\nfrom keras.optimizers import Adam,RMSprop\nfrom keras.models import Model,load_model\nfrom keras.applications import NASNetMobile,MobileNetV2,densenet,resnet50,xception\n\nfrom keras_applications.resnext import ResNeXt50\nfrom albumentations import Resize,Compose, RandomRotate90, Transpose, Flip, OneOf, CLAHE, IAASharpen, IAAEmboss, RandomBrightnessContrast, JpegCompression, Blur, GaussNoise, HueSaturationValue, ShiftScaleRotate, Normalize\n\n\nfrom sklearn.utils import shuffle\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.model_selection import train_test_split,StratifiedKFold\nfrom skimage import data, exposure\nimport itertools\nimport shutil\nimport matplotlib.pyplot as plt\nos.environ['TF_CPP_MIN_LOG_LEVEL']='2'\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import Callback\nfrom keras import backend as K\nclass LRFinder(Callback):\n    def __init__(self,\n                 num_samples,\n                 batch_size,\n                 minimum_lr=1e-5,\n                 maximum_lr=10.,\n                 lr_scale='exp',\n                 validation_data=None,\n                 validation_sample_rate=5,\n                 stopping_criterion_factor=4.,\n                 loss_smoothing_beta=0.98,\n                 save_dir=None,\n                 verbose=True):\n        \n        super(LRFinder, self).__init__()\n\n        if lr_scale not in ['exp', 'linear']:\n            raise ValueError(\"`lr_scale` must be one of ['exp', 'linear']\")\n\n        if validation_data is not None:\n            self.validation_data = validation_data\n            self.use_validation_set = True\n\n            if validation_sample_rate > 0 or validation_sample_rate < 0:\n                self.validation_sample_rate = validation_sample_rate\n            else:\n                raise ValueError(\"`validation_sample_rate` must be a positive or negative integer other than o\")\n        else:\n            self.use_validation_set = False\n            self.validation_sample_rate = 0\n\n        self.num_samples = num_samples\n        self.batch_size = batch_size\n        self.initial_lr = minimum_lr\n        self.final_lr = maximum_lr\n        self.lr_scale = lr_scale\n        self.stopping_criterion_factor = stopping_criterion_factor\n        self.loss_smoothing_beta = loss_smoothing_beta\n        self.save_dir = save_dir\n        self.verbose = verbose\n\n        self.num_batches_ = num_samples // batch_size\n        self.current_lr_ = minimum_lr\n\n        if lr_scale == 'exp':\n            self.lr_multiplier_ = (maximum_lr / float(minimum_lr)) ** (\n                1. / float(self.num_batches_))\n        else:\n            extra_batch = int((num_samples % batch_size) != 0)\n            self.lr_multiplier_ = np.linspace(\n                minimum_lr, maximum_lr, num=self.num_batches_ + extra_batch)\n\n        # If negative, use entire validation set\n        if self.validation_sample_rate < 0:\n            self.validation_sample_rate = self.validation_data[0].shape[0] // batch_size\n\n        self.current_batch_ = 0\n        self.current_epoch_ = 0\n        self.best_loss_ = 1e6\n        self.running_loss_ = 0.\n\n        self.history = {}\n\n    def on_train_begin(self, logs=None):\n\n        self.current_epoch_ = 1\n        K.set_value(self.model.optimizer.lr, self.initial_lr)\n\n        warnings.simplefilter(\"ignore\")\n\n    def on_epoch_begin(self, epoch, logs=None):\n        self.current_batch_ = 0\n\n        if self.current_epoch_ > 1:\n            warnings.warn(\n                \"\\n\\nLearning rate finder should be used only with a single epoch. \"\n                \"Hereafter, the callback will not measure the losses.\\n\\n\")\n\n    def on_batch_begin(self, batch, logs=None):\n        self.current_batch_ += 1\n\n    def on_batch_end(self, batch, logs=None):\n        if self.current_epoch_ > 1:\n            return\n\n        if self.use_validation_set:\n            X, Y = self.validation_data[0], self.validation_data[1]\n\n            # use 5 random batches from test set for fast approximate of loss\n            num_samples = self.batch_size * self.validation_sample_rate\n\n            if num_samples > X.shape[0]:\n                num_samples = X.shape[0]\n\n            idx = np.random.choice(X.shape[0], num_samples, replace=False)\n            x = X[idx]\n            y = Y[idx]\n\n            values = self.model.evaluate(x, y, batch_size=self.batch_size, verbose=False)\n            loss = values[0]\n        else:\n            loss = logs['loss']\n\n        # smooth the loss value and bias correct\n        running_loss = self.loss_smoothing_beta * loss + (\n            1. - self.loss_smoothing_beta) * loss\n        running_loss = running_loss / (\n            1. - self.loss_smoothing_beta**self.current_batch_)\n\n        # stop logging if loss is too large\n        if self.current_batch_ > 1 and self.stopping_criterion_factor is not None and (\n                running_loss >\n                self.stopping_criterion_factor * self.best_loss_):\n\n            if self.verbose:\n                print(\" - LRFinder: Skipping iteration since loss is %d times as large as best loss (%0.4f)\"\n                      % (self.stopping_criterion_factor, self.best_loss_))\n            return\n\n        if running_loss < self.best_loss_ or self.current_batch_ == 1:\n            self.best_loss_ = running_loss\n\n        current_lr = K.get_value(self.model.optimizer.lr)\n\n        self.history.setdefault('running_loss_', []).append(running_loss)\n        if self.lr_scale == 'exp':\n            self.history.setdefault('log_lrs', []).append(np.log10(current_lr))\n        else:\n            self.history.setdefault('log_lrs', []).append(current_lr)\n\n        # compute the lr for the next batch and update the optimizer lr\n        if self.lr_scale == 'exp':\n            current_lr *= self.lr_multiplier_\n        else:\n            current_lr = self.lr_multiplier_[self.current_batch_ - 1]\n\n        K.set_value(self.model.optimizer.lr, current_lr)\n\n        # save the other metrics as well\n        for k, v in logs.items():\n            self.history.setdefault(k, []).append(v)\n\n        if self.verbose:\n            if self.use_validation_set:\n                print(\" - LRFinder: val_loss: %1.4f - lr = %1.8f \" %\n                      (values[0], current_lr))\n            else:\n                print(\" - LRFinder: lr = %1.8f \" % current_lr)\n\n    def on_epoch_end(self, epoch, logs=None):\n        if self.save_dir is not None and self.current_epoch_ <= 1:\n            if not os.path.exists(self.save_dir):\n                os.makedirs(self.save_dir)\n\n            losses_path = os.path.join(self.save_dir, 'losses.npy')\n            lrs_path = os.path.join(self.save_dir, 'lrs.npy')\n\n            np.save(losses_path, self.losses)\n            np.save(lrs_path, self.lrs)\n\n            if self.verbose:\n                print(\"\\tLR Finder : Saved the losses and learning rate values in path : {%s}\"\n                      % (self.save_dir))\n\n        self.current_epoch_ += 1\n\n        warnings.simplefilter(\"default\")\n\n    def plot_schedule(self, clip_beginning=None, clip_endding=None):\n       \n        try:\n            import matplotlib.pyplot as plt\n            plt.style.use('seaborn-white')\n        except ImportError:\n            print(\n                \"Matplotlib not found. Please use `pip install matplotlib` first.\"\n            )\n            return\n\n        if clip_beginning is not None and clip_beginning < 0:\n            clip_beginning = -clip_beginning\n\n        if clip_endding is not None and clip_endding > 0:\n            clip_endding = -clip_endding\n\n        losses = self.losses\n        lrs = self.lrs\n\n        if clip_beginning:\n            losses = losses[clip_beginning:]\n            lrs = lrs[clip_beginning:]\n\n        if clip_endding:\n            losses = losses[:clip_endding]\n            lrs = lrs[:clip_endding]\n\n        plt.plot(lrs, losses)\n        plt.title('Learning rate vs Loss')\n        plt.xlabel('learning rate')\n        plt.ylabel('loss')\n        plt.show()\n\n    @classmethod\n    def restore_schedule_from_dir(cls,\n                                  directory,\n                                  clip_beginning=None,\n                                  clip_endding=None):\n       \n        if clip_beginning is not None and clip_beginning < 0:\n            clip_beginning = -clip_beginning\n\n        if clip_endding is not None and clip_endding > 0:\n            clip_endding = -clip_endding\n\n        losses_path = os.path.join(directory, 'losses.npy')\n        lrs_path = os.path.join(directory, 'lrs.npy')\n\n        if not os.path.exists(losses_path) or not os.path.exists(lrs_path):\n            print(\"%s and %s could not be found at directory : {%s}\" %\n                  (losses_path, lrs_path, directory))\n\n            losses = None\n            lrs = None\n\n        else:\n            losses = np.load(losses_path)\n            lrs = np.load(lrs_path)\n\n            if clip_beginning:\n                losses = losses[clip_beginning:]\n                lrs = lrs[clip_beginning:]\n\n            if clip_endding:\n                losses = losses[:clip_endding]\n                lrs = lrs[:clip_endding]\n\n        return losses, lrs\n\n    @classmethod\n    def plot_schedule_from_file(cls,\n                                directory,\n                                clip_beginning=None,\n                                clip_endding=None):\n       \n        try:\n            import matplotlib.pyplot as plt\n            plt.style.use('seaborn-white')\n        except ImportError:\n            print(\"Matplotlib not found. Please use `pip install matplotlib` first.\")\n            return\n\n        losses, lrs = cls.restore_schedule_from_dir(\n            directory,\n            clip_beginning=clip_beginning,\n            clip_endding=clip_endding)\n\n        if losses is None or lrs is None:\n            return\n        else:\n            plt.plot(lrs, losses)\n            plt.title('Learning rate vs Loss')\n            plt.xlabel('learning rate')\n            plt.ylabel('loss')\n            plt.show()\n\n    @property\n    def lrs(self):\n        return np.array(self.history['log_lrs'])\n\n    @property\n    def losses(self):\n        return np.array(self.history['running_loss_'])","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_uuid":"0a58666bdbd7cb0aa548868a07d34eed44b076d1","trusted":true},"cell_type":"code","source":"def do_train_augmentations():\n    return Compose([\n        #Resize(196,196),\n        RandomRotate90(p=0.5),\n        Transpose(p=0.5),\n        Flip(p=0.5),\n        OneOf([CLAHE(clip_limit=2),\n              IAASharpen(),\n              IAAEmboss(),\n              RandomBrightnessContrast(),\n              JpegCompression(),\n              Blur(),\n              GaussNoise()],\n              p=0.5),\n        HueSaturationValue(p=0.5),\n        ShiftScaleRotate(shift_limit=0.15, scale_limit=0.15, rotate_limit=45, p=0.5),\n       Normalize(p=1)])\n\n\ndef do_inference_aug():\n    return Compose([\n       # Resize(196,196),\n         RandomRotate90(p=0.5),\n         Transpose(p=0.5),\n        Flip(p=0.5),Normalize(p=1)])\n\n\ndef data_gen(list_files,id_label_map,batch_size,aug_func):\n    aug = aug_func()\n    while True:\n        shuffle(list_files)\n        for block in chunker(list_files,batch_size):\n            x = [cv2.imread(addr) for addr in block]\n            y = [id_label_map[get_id_from_path(addr)] for addr in block]\n            yield np.array(x) / 255.,np.array(y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def densenet_model(input_shape,batch_size = 1024):\n    base_model = densenet.DenseNet169(include_top=False, weights='imagenet',  input_shape=input_shape)\n    x = base_model.output\n\n    out1 = GlobalMaxPooling2D()(x)\n    out2 = GlobalAveragePooling2D()(x)\n    #out3 = Flatten()(x)\n    out = concatenate([out1,out2])\n    out = BatchNormalization(epsilon = 1e-5)(out)\n    out = Dropout(0.4)(out)\n    fc = Dense(512,activation = 'relu')(out)\n    fc = BatchNormalization(epsilon = 1e-5)(fc)\n    fc = Dropout(0.3)(fc)\n    fc = Dense(256,activation = 'relu')(fc)\n    fc = BatchNormalization(epsilon = 1e-5)(fc)\n    fc = Dropout(0.3)(fc)\n    X = Dense(1, activation='sigmoid', kernel_initializer='glorot_uniform', bias_initializer='zeros')(fc)\n    model =  Model(inputs=base_model.input, outputs=X)\n    #model.compile(optimizer=tf.keras.optimizers.Adam(lr = 0.0001), loss=tf.keras.losses.binary_crossentropy, metrics=['acc'])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def densenet_model(input_shape,batch_size = 1024):\n    base_model = densenet.DenseNet169(include_top=False, weights='imagenet',  input_shape=input_shape)\n    x = base_model.output\n\n    out2 = GlobalAveragePooling2D()(x)\n    #out3 = Flatten()(x)\n    X = Dense(1, activation='sigmoid', kernel_initializer='glorot_uniform', bias_initializer='zeros')(out2)\n    model =  Model(inputs=base_model.input, outputs=X)\n    #model.compile(optimizer=tf.keras.optimizers.Adam(lr = 0.0001), loss=tf.keras.losses.binary_crossentropy, metrics=['acc'])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"res_model = densenet_model((96,96,3))\n#print(res_model.summary())","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* #### Here is the implementation of One Cycle Policy in the Keras Callback Class"},{"metadata":{"_uuid":"6f0cdeea4e204cbe8c4518de1e9502b317e6f97a","trusted":true},"cell_type":"code","source":"import os\nimport numpy as np\nimport warnings\n\nfrom keras.callbacks import Callback\nfrom keras import backend as K\n\nclass OneCycleLR(Callback):\n    def __init__(self,\n                 max_lr,\n                 end_percentage=0.1,\n                 scale_percentage=None,\n                 maximum_momentum=0.95,\n                 minimum_momentum=0.85,\n                 verbose=True):\n     \n        super(OneCycleLR, self).__init__()\n\n        if end_percentage < 0. or end_percentage > 1.:\n            raise ValueError(\"`end_percentage` must be between 0 and 1\")\n\n        if scale_percentage is not None and (scale_percentage < 0. or scale_percentage > 1.):\n            raise ValueError(\"`scale_percentage` must be between 0 and 1\")\n\n        self.initial_lr = max_lr\n        self.end_percentage = end_percentage\n        self.scale = float(scale_percentage) if scale_percentage is not None else float(end_percentage)\n        self.max_momentum = maximum_momentum\n        self.min_momentum = minimum_momentum\n        self.verbose = verbose\n\n        if self.max_momentum is not None and self.min_momentum is not None:\n            self._update_momentum = True\n        else:\n            self._update_momentum = False\n\n        self.clr_iterations = 0.\n        self.history = {}\n\n        self.epochs = None\n        self.batch_size = None\n        self.samples = None\n        self.steps = None\n        self.num_iterations = None\n        self.mid_cycle_id = None\n\n    def _reset(self):\n       \n        self.clr_iterations = 0.\n        self.history = {}\n\n    def compute_lr(self):\n    \n        if self.clr_iterations > 2 * self.mid_cycle_id:\n            current_percentage = (self.clr_iterations - 2 * self.mid_cycle_id)\n            current_percentage /= float((self.num_iterations - 2 * self.mid_cycle_id))\n            new_lr = self.initial_lr * (1. + (current_percentage *\n                                              (1. - 100.) / 100.)) * self.scale\n\n        elif self.clr_iterations > self.mid_cycle_id:\n            current_percentage = 1. - (\n                self.clr_iterations - self.mid_cycle_id) / self.mid_cycle_id\n            new_lr = self.initial_lr * (1. + current_percentage *\n                                        (self.scale * 100 - 1.)) * self.scale\n\n        else:\n            current_percentage = self.clr_iterations / self.mid_cycle_id\n            new_lr = self.initial_lr * (1. + current_percentage *\n                                        (self.scale * 100 - 1.)) * self.scale\n\n        if self.clr_iterations == self.num_iterations:\n            self.clr_iterations = 0\n\n        return new_lr\n\n    def compute_momentum(self):\n    \n        if self.clr_iterations > 2 * self.mid_cycle_id:\n            new_momentum = self.max_momentum\n\n        elif self.clr_iterations > self.mid_cycle_id:\n            current_percentage = 1. - ((self.clr_iterations - self.mid_cycle_id) / float(\n                                        self.mid_cycle_id))\n            new_momentum = self.max_momentum - current_percentage * (\n                self.max_momentum - self.min_momentum)\n\n        else:\n            current_percentage = self.clr_iterations / float(self.mid_cycle_id)\n            new_momentum = self.max_momentum - current_percentage * (\n                self.max_momentum - self.min_momentum)\n\n        return new_momentum\n\n    def on_train_begin(self, logs={}):\n        logs = logs or {}\n\n        self.epochs = self.params['epochs']\n        self.batch_size = 256\n        self.samples = len(train_list)\n        self.steps = self.params['steps']\n\n        if self.steps is not None:\n            self.num_iterations = self.epochs * self.steps\n        else:\n            if (self.samples % self.batch_size) == 0:\n                remainder = 0\n            else:\n                remainder = 1\n            self.num_iterations = (self.epochs + remainder) * self.samples // self.batch_size\n\n        self.mid_cycle_id = int(self.num_iterations * ((1. - self.end_percentage)) / float(2))\n\n        self._reset()\n        K.set_value(self.model.optimizer.lr, self.compute_lr())\n\n        if self._update_momentum:\n            if not hasattr(self.model.optimizer, 'momentum'):\n                raise ValueError(\"Momentum can be updated only on SGD optimizer !\")\n\n            new_momentum = self.compute_momentum()\n            K.set_value(self.model.optimizer.momentum, new_momentum)\n\n    def on_batch_end(self, epoch, logs=None):\n        logs = logs or {}\n\n        self.clr_iterations += 1\n        new_lr = self.compute_lr()\n\n        self.history.setdefault('lr', []).append(\n            K.get_value(self.model.optimizer.lr))\n        K.set_value(self.model.optimizer.lr, new_lr)\n\n        if self._update_momentum:\n            if not hasattr(self.model.optimizer, 'momentum'):\n                raise ValueError(\"Momentum can be updated only on SGD optimizer !\")\n\n            new_momentum = self.compute_momentum()\n\n            self.history.setdefault('momentum', []).append(\n                K.get_value(self.model.optimizer.momentum))\n            K.set_value(self.model.optimizer.momentum, new_momentum)\n\n        for k, v in logs.items():\n            self.history.setdefault(k, []).append(v)\n\n    def on_epoch_end(self, epoch, logs=None):\n        if self.verbose:\n            if self._update_momentum:\n                print(\" - lr: %0.5f - momentum: %0.2f \" %\n                      (self.history['lr'][-1], self.history['momentum'][-1]))\n\n            else:\n                print(\" - lr: %0.5f \" % (self.history['lr'][-1]))\n\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e0c409e4875937c8e4eacb532e507f70dedede9f","trusted":true,"_kg_hide-output":false},"cell_type":"code","source":"# Define Ony Cycle Policy parameters and train model\n########################################################################################\nfrom keras.optimizers import Adam, SGD\nfrom keras.callbacks import ModelCheckpoint, ReduceLROnPlateau, EarlyStopping\n#from clr import OneCycleLR\n# CLR parameters\n\nbatch_size = 256\nepochs = 50\n# lr_callback = LRFinder(len(train_list), batch_size,\n#                        1e-5, 1.,\n#                        # validation_data=(X_val, Y_val),\n#                        lr_scale='exp', save_dir='weights/')\n# lr_manager = OneCycleLR(max_lr=0.001, end_percentage=0.1, scale_percentage=None,\n#                         maximum_momentum=0.99,minimum_momentum=0.89)\n\nres_model.compile(loss='binary_crossentropy', optimizer=SGD(0.0001, momentum=0.99, nesterov=True), metrics=['accuracy'])\n    \n# callbacks = [lr_manager,\n#            ModelCheckpoint(filepath='densenet169_model.h5', monitor='val_loss',mode='min',verbose=1,save_best_only=True)]\ncallbacks = [ModelCheckpoint(filepath='densenet169_9010model.h5', monitor='val_loss',mode='min',verbose=1,save_best_only=True)]\n\nhistory = res_model.fit_generator(data_gen(train_list, id_label_map, batch_size,do_train_augmentations),\n                              validation_data=data_gen(val_list, id_label_map, batch_size,do_inference_aug),\n                              epochs = epochs,\n                              steps_per_epoch = (len(train_list) // batch_size) + 1,\n                              validation_steps = (len(val_list) // batch_size) + 1,\n                              callbacks=callbacks,\n                              verbose = 1)\nplt.plot(history.history['loss'], label='train')\nplt.plot(history.history['val_loss'], label='valid')\nplt.title(\"model loss\")\nplt.ylabel(\"loss\")\nplt.xlabel(\"epoch\")\nplt.legend([\"train\", \"valid\"], loc=\"upper left\")\nplt.savefig('loss_performance.png')\nplt.clf()\nplt.plot(history.history['acc'], label='train')\nplt.plot(history.history['val_acc'], label='valid')\nplt.title(\"model acc\")\nplt.ylabel(\"acc\")\nplt.xlabel(\"epoch\")\nplt.legend([\"train\", \"valid\"], loc=\"upper left\")\nplt.savefig('acc_performance.png')\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def do_inference_aug():\n    return Compose([\n       # Resize(196,196),\n        RandomRotate90(p=0.5),\n        Transpose(p=0.5),\n        Flip(p=0.5),Normalize(p=1)])\n\n\ndef data_gen(list_files,batch_size,aug_func):\n    aug = aug_func()\n    while True:\n        #shuffle(list_files)\n        for block in chunker(list_files,batch_size):\n            x = [aug(image = cv2.imread(addr))['image'] for addr in block]\n            y = [id_label_map[get_id_from_path(addr)] for addr in block]\n            yield np.array(x) / 255.,np.array(y)\n\n\npreds = res_model.predict_generator(data_gen(val_list,1,do_inference_aug),steps = len(val_list))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_preds = np.array(preds)\ny_preds[preds >= 0.5] = 1\ny_preds[preds < 0.5] = 0\ntrue = df_val['label'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.metrics import roc_auc_score,confusion_matrix,classification_report\nroc_auc_score(true,preds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import sklearn.metrics as metrics\n# calculate the fpr and tpr for all thresholds of the classification\n\nfpr, tpr, threshold = metrics.roc_curve(true, preds)\nroc_auc = metrics.auc(fpr, tpr)\n\n# method I: plt\nimport matplotlib.pyplot as plt\nplt.title('Receiver Operating Characteristic')\nplt.plot(fpr, tpr, 'g', label = 'AUC = %0.2f' % roc_auc)\nplt.legend(loc = 'lower right')\nplt.plot([0, 1], [0, 1],'r--')\nplt.xlim([0, 1])\nplt.ylim([0, 1])\nplt.ylabel('True Positive Rate')\nplt.xlabel('False Positive Rate')\nplt.show()\nplt.savefig('densenet169_auc_roc.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cm = confusion_matrix(true,y_preds)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_confusion_matrix(cm, classes,\n                          normalize=False,\n                          title='Confusion matrix',\n                          cmap=plt.cm.Blues):\n\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n        print(\"Normalized confusion matrix\")\n    else:\n        print('Confusion matrix, without normalization')\n\n    print(cm)\n\n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    fmt = '.2f' if normalize else 'd'\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, format(cm[i, j], fmt),\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n    plt.tight_layout()\n    plt.savefig('densenet169_cm.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_confusion_matrix(cm,['no_tumor_tissue', 'has_tumor_tissue'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"report = classification_report(true,y_preds,target_names=['no_tumor_tissue', 'has_tumor_tissue'])\nprint(report)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"}},"nbformat":4,"nbformat_minor":1}