<kaggle_start><data_title>ResNet-50<data_description># ResNet-50

---

## Deep Residual Learning for Image Recognition
Deeper neural networks are more difficult to train. We present a residual learning framework to ease the training of networks that are substantially deeper than those used previously. We explicitly reformulate the layers as learning residual functions with reference to the layer inputs, instead of learning unreferenced functions. We provide comprehensive empirical evidence showing that these residual networks are easier to optimize, and can gain accuracy from considerably increased depth. On the ImageNet dataset we evaluate residual nets with a depth of up to 152 layers---8x deeper than VGG nets but still having lower complexity. 

An ensemble of these residual nets achieves 3.57% error on the ImageNet test set. This result won the 1st place on the ILSVRC 2015 classification task. We also present analysis on CIFAR-10 with 100 and 1000 layers. 

The depth of representations is of central importance for many visual recognition tasks. Solely due to our extremely deep representations, we obtain a 28% relative improvement on the COCO object detection dataset. Deep residual nets are foundations of our submissions to ILSVRC & COCO 2015 competitions, where we also won the 1st places on the tasks of ImageNet detection, ImageNet localization, COCO detection, and COCO segmentation.<br>

**Authors: Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun**<br>
**https://arxiv.org/abs/1512.03385**

---


Architecture visualization: http://ethereon.github.io/netscope/#/gist/db945b393d40bfa26006

![Resnet][1]

---

### What is a Pre-trained Model?
A pre-trained model has been previously trained on a dataset and contains the weights and biases that represent the features of whichever dataset it was trained on. Learned features are often transferable to different data. For example, a model trained on a large dataset of bird images will contain learned features like edges or horizontal lines that you would be transferable your dataset. 

### Why use a Pre-trained Model?
Pre-trained models are beneficial to us for many reasons. By using a pre-trained model you are saving time. Someone else has already spent the time and compute resources to learn a lot of features and your model will likely benefit from it. 


  [1]: https://imgur.com/nyYh5xH.jpg<data_name>resnet50
<code># # Title:Skin-Lesion Segmentation
# ### Importing the Libraries
from keras.models import Model, Sequential
from keras.layers import (
    Activation,
    Dense,
    BatchNormalization,
    Dropout,
    Conv2D,
    Conv2DTranspose,
    MaxPooling2D,
    UpSampling2D,
    Input,
    Reshape,
)
from keras import backend as K
from keras.optimizers import Adam
import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import PIL
import os
from PIL import Image, ImageEnhance, ImageFilter
import matplotlib.pyplot as plt
import cv2
from sklearn.model_selection import train_test_split
from warnings import filterwarnings

filterwarnings("ignore")
plt.rcParams["axes.grid"] = False
np.random.seed(101)
print(os.listdir("../input"))

# The ***PH2 database*** includes
# the manual segmentation, the clinical diagnosis, and the identification of several dermoscopic
# structures, performed by expert dermatologists,
# The ***PH2 database*** was built up through a joint research collaboration between the Universidade do
# Porto, T ́ecnico Lisboa, and the Dermatology service of Hospital Pedro Hispano in Matosinhos,
# Portugal.
# ## Loading the data
# [](http://)Defining a function to load the data in sorted order
import re

numbers = re.compile(r"(\d+)")


def numericalSort(value):
    parts = numbers.split(value)
    parts[1::2] = map(int, parts[1::2])
    return parts


# * * * First we will load the filenames in a list.
filelist_trainx_ph2 = sorted(glob.glob("../input/*/*/trainx/*.bmp"), key=numericalSort)
X_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainx_ph2])
filelist_trainy_ph2 = sorted(glob.glob("../input/*/*/trainy/*.bmp"), key=numericalSort)
Y_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainy_ph2])
plt.figure(figsize=(12, 6))
plt.suptitle("Images from PH2 dataset", fontsize=25, color="blue")
plt.subplot(2, 2, 1)
plt.imshow(X_train_ph2[1])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2[1]).shape))
plt.subplot(2, 2, 2)
plt.imshow(Y_train_ph2[1], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2[1]).shape))
plt.subplot(2, 2, 3)
plt.imshow(X_train_ph2[112])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2[185]).shape))
plt.subplot(2, 2, 4)
plt.imshow(Y_train_ph2[112], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2[185]).shape))
plt.show()


# * The images are of dimensions **(572, 765)** so we will scale down the images. It will also reduce the training time of the network.
# #### Resizing
def resize(filename, size=(256, 192)):
    im = Image.open(filename)
    im_resized = im.resize(size, Image.ANTIALIAS)
    return im_resized


X_train_ph2_resized = []
Y_train_ph2_resized = []
for i in range(len(filelist_trainx_ph2)):
    X_train_ph2_resized.append(resize(filelist_trainx_ph2[i]))
    Y_train_ph2_resized.append(resize(filelist_trainy_ph2[i]))


# The new resized images
plt.figure(figsize=(12, 10))
plt.suptitle("Images from PH2 dataset after Resizing", fontsize=25, color="blue")
plt.subplot(2, 2, 1)
plt.imshow(X_train_ph2_resized[1])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[1]).shape))
plt.subplot(2, 2, 2)
plt.imshow(Y_train_ph2_resized[1], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[1]).shape))
plt.subplot(2, 2, 3)
plt.imshow(X_train_ph2_resized[117])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[185]).shape))
plt.subplot(2, 2, 4)
plt.imshow(Y_train_ph2_resized[117], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[185]).shape))
plt.show()

# Converting the transformed Images into numpy arrays
X_train_ph2 = np.array([np.array(img) for img in X_train_ph2_resized])
Y_train_ph2 = np.array([np.array(img) for img in Y_train_ph2_resized])
plt.figure(figsize=(12, 6))
plt.suptitle(
    "Converting the transformed Image into Numpy Array", fontsize=25, color="blue"
)
plt.subplot(1, 2, 1)
plt.imshow(X_train_ph2[117])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[180]).shape))
plt.subplot(1, 2, 2)
plt.imshow(Y_train_ph2[117], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[180]).shape))
plt.show()

# * Splitting the dataset into training set and test set to verify our model performance without any bias.
x_train, x_test, y_train, y_test = train_test_split(
    X_train_ph2, Y_train_ph2, test_size=0.25, random_state=101
)
plt.figure(figsize=(25, 10))
plt.suptitle("Images from PH2 dataset", fontsize=30, color="blue")
plt.subplot(3, 5, 1)
plt.imshow(X_train_ph2[1])
plt.subplot(3, 5, 2)
plt.imshow(X_train_ph2[12])
plt.subplot(3, 5, 3)
plt.imshow(X_train_ph2[44])
plt.subplot(3, 5, 4)
plt.imshow(X_train_ph2[67])
plt.subplot(3, 5, 5)
plt.imshow(X_train_ph2[100])
plt.subplot(3, 5, 6)
plt.imshow(X_train_ph2[117])
plt.subplot(3, 5, 7)
plt.imshow(X_train_ph2[128])
plt.subplot(3, 5, 8)
plt.imshow(X_train_ph2[147])
plt.subplot(3, 5, 9)
plt.imshow(X_train_ph2[132])
plt.subplot(3, 5, 10)
plt.imshow(X_train_ph2[112])
plt.subplot(3, 5, 11)
plt.imshow(X_train_ph2[31])
plt.subplot(3, 5, 12)
plt.imshow(X_train_ph2[52])
plt.subplot(3, 5, 13)
plt.imshow(X_train_ph2[74])
plt.subplot(3, 5, 14)
plt.imshow(X_train_ph2[86])
plt.subplot(3, 5, 15)
plt.imshow(X_train_ph2[150])
plt.show()
plt.figure(figsize=(25, 10))
plt.suptitle(
    "Mask of the corresponding Images from PH2 dataset", fontsize=30, color="blue"
)
plt.subplot(3, 5, 1)
plt.imshow(Y_train_ph2[1], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 2)
plt.imshow(Y_train_ph2[12], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 3)
plt.imshow(Y_train_ph2[44], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 4)
plt.imshow(Y_train_ph2[67], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 5)
plt.imshow(Y_train_ph2[100], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 6)
plt.imshow(Y_train_ph2[117], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 7)
plt.imshow(Y_train_ph2[128], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 8)
plt.imshow(Y_train_ph2[147], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 9)
plt.imshow(Y_train_ph2[132], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 10)
plt.imshow(Y_train_ph2[112], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 11)
plt.imshow(Y_train_ph2[31], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 12)
plt.imshow(Y_train_ph2[52], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 13)
plt.imshow(Y_train_ph2[74], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 14)
plt.imshow(Y_train_ph2[86], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 15)
plt.imshow(Y_train_ph2[150], cmap=plt.cm.binary_r)
plt.show()


# ## Image Augmentation
# Image augmentation artificially creates training images through different ways of processing or combination of multiple processing, such as random rotation, shifts, shear and flips, etc.
# To build a powerful image classifier using little training data, image augmentation is usually required to boost the performance of deep networks.
# We are going to define to methods for augmentation, **horizontal flipping** , **vertical flipping**, **both flipped** and **random rotation**
def horizontal_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 1)
    y_image = cv2.flip(y_image.astype("float32"), 1)
    return x_image, y_image.astype("int")


def vertical_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 0)
    y_image = cv2.flip(y_image.astype("float32"), 0)
    return x_image, y_image.astype("int")


def both_flip(x_image, y_image):
    x_image = cv2.flip(x_image, -1)
    y_image = cv2.flip(y_image.astype("float32"), -1)
    return x_image, y_image.astype("int")


def random_rotation(x_image, y_image):
    rows_x, cols_x, chl_x = x_image.shape
    rows_y, cols_y = y_image.shape
    rand_num = np.random.randint(-60, 60)
    M1 = cv2.getRotationMatrix2D((cols_x / 2, rows_x / 2), rand_num, 1)
    M2 = cv2.getRotationMatrix2D((cols_y / 2, rows_y / 2), rand_num, 1)
    x_image = cv2.warpAffine(x_image, M1, (cols_x, rows_x))
    y_image = cv2.warpAffine(y_image.astype("float32"), M2, (cols_y, rows_y))
    return np.array(x_image), np.array(y_image.astype("int"))


def img_augmentation(x_train, y_train):
    x_flip = []
    y_flip = []
    x_vert = []
    y_vert = []
    x_both = []
    y_both = []
    x_rotat = []
    y_rotat = []
    for idx in range(len(x_train)):
        x, y = horizontal_flip(x_train[idx], y_train[idx])
        x_flip.append(x)
        y_flip.append(y)
        x, y = vertical_flip(x_train[idx], y_train[idx])
        x_vert.append(x)
        y_vert.append(y)
        x, y = both_flip(x_train[idx], y_train[idx])
        x_both.append(x)
        y_both.append(y)
        x, y = random_rotation(x_train[idx], y_train[idx])
        x_rotat.append(x)
        y_rotat.append(y)
    return (
        np.array(x_flip),
        np.array(y_flip),
        np.array(x_vert),
        np.array(y_vert),
        np.array(x_both),
        np.array(y_both),
        np.array(x_rotat),
        np.array(y_rotat),
    )


# calling the functions for the training data.
(
    x_flipped,
    y_flipped,
    x_vertical,
    y_vertical,
    x_bothed,
    y_bothed,
    x_rotated,
    y_rotated,
) = img_augmentation(x_train, y_train)
(
    x_flipped_t,
    y_flipped_t,
    x_vertical_t,
    y_vertical_t,
    x_bothed_t,
    y_bothed_t,
    x_rotated_t,
    y_rotated_t,
) = img_augmentation(x_test, y_test)
plt.figure(figsize=(25, 16))
plt.suptitle("Image Augmentation", fontsize=25, color="blue")
plt.subplot(6, 4, 1)
plt.imshow(x_train[112])
plt.title("Original Image")
plt.subplot(6, 4, 2)
plt.imshow(y_train[112], plt.cm.binary_r)
plt.title("Original Mask")
plt.subplot(6, 4, 3)
plt.imshow(x_train[12])
plt.title("Original Image")
plt.subplot(6, 4, 4)
plt.imshow(y_train[12], plt.cm.binary_r)
plt.title("Original Mask")
plt.subplot(6, 4, 5)
plt.imshow(x_flipped[112])
plt.title("Horizontal Flipped Image")
plt.subplot(6, 4, 6)
plt.imshow(y_flipped[112], plt.cm.binary_r)
plt.title("Horizontal Flipped Mask")
plt.subplot(6, 4, 7)
plt.imshow(x_flipped[12])
plt.title("Horizontal Flipped Image")
plt.subplot(6, 4, 8)
plt.imshow(y_flipped[12], plt.cm.binary_r)
plt.title("Horizontal Flipped Mask")
plt.subplot(6, 4, 9)
plt.imshow(x_vertical[112])
plt.title("Vertical Flipped Image")
plt.subplot(6, 4, 10)
plt.imshow(y_vertical[112], plt.cm.binary_r)
plt.title("Vertical Flipped Mask")
plt.subplot(6, 4, 11)
plt.imshow(x_vertical[12])
plt.title("Vertical Flipped Image")
plt.subplot(6, 4, 12)
plt.imshow(y_vertical[12], plt.cm.binary_r)
plt.title("Vertical Flipped Mask")
plt.subplot(6, 4, 13)
plt.imshow(x_bothed[112])
plt.title("Flipped both Image")
plt.subplot(6, 4, 14)
plt.imshow(y_bothed[112], plt.cm.binary_r)
plt.title("Flipped both Mask")
plt.subplot(6, 4, 15)
plt.imshow(x_bothed[12])
plt.title("Flipped both Image")
plt.subplot(6, 4, 16)
plt.imshow(y_bothed[12], plt.cm.binary_r)
plt.title("Flipped both Mask")
plt.subplot(6, 4, 17)
plt.imshow(x_rotated[112])
plt.title("Rotated Image")
plt.subplot(6, 4, 18)
plt.imshow(y_rotated[112], plt.cm.binary_r)
plt.title("Rotated Mask")
plt.subplot(6, 4, 19)
plt.imshow(x_rotated[12])
plt.title("Rotated Image")
plt.subplot(6, 4, 20)
plt.imshow(y_rotated[12], plt.cm.binary_r)
plt.title("Rotated Mask")
plt.show()

# Now we join all the augmentations image arrays to the original training arrays.
# For training Set
x_train_full = np.concatenate([x_train, x_rotated, x_flipped, x_bothed, x_vertical])
y_train_full = np.concatenate([y_train, y_rotated, y_flipped, y_bothed, y_vertical])


# ## Defining Evaluation Metrics
# #### Intersection over Union(IOU) or Jaccard Index
# The Jaccard index, also known as Intersection over Union and the Jaccard similarity coefficient is a statistic used for gauging the similarity and diversity of sample sets. The Jaccard coefficient measures similarity between finite sample sets, and is defined as the size of the intersection divided by the size of the union of the sample sets.
# Jaccard index is popular and frequently used as a similarity index.
# The area of overlap J is
# calculated between the segmented binary image A and its ground truth G as shown:
# ***J = |A ∩ G| / |A ∪ G| × 100%.***
def iou(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    union = sum_ - intersection
    jac = (intersection + smooth) / (union + smooth)
    return jac


# #### Dice Coefficient
# The Dice score is not only a measure of how many positives you find, but it also penalizes for the false positives that the method finds, similar to precision. so it is more similar to precision than accuracy.
# The Dice coefficient can be defined as: ***D = 2 |A ∩ G| / |A + G| × 100%*** where A is the algorithm
# output and G is the ground truth.
def dice_coef(y_true, y_pred, smooth=100):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2.0 * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


# #### Precision
# Precision is a good measure to determine, when the costs of False Positive is high.
# ***Precision = true-positive / (true-positive + false-positive)***
# Where,True positive is an outcome where the model correctly predicts the positive class and false positive is an outcome where the model incorrectly predicts the positive class.
#
# '''Precision calculates a metric for multi-label classification of
# how many selected items are relevant.
# '''
def precision(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision


# #### Recall
# Recall actually calculates how many of the Actual Positives our model capture through labeling it as Positive (True Positive). Applying the same understanding, we know that Recall shall be the model metric we use to select our best model when there is a high cost associated with False Negative.
# ***Recall = true-positive /(true-positive + false negative)***
# Where, true positive is an outcome where the model correctly predicts the positive class and false negative is an outcome where the model incorrectly predicts the negative class.
# '''Recall calculates a metric for multi-label classification of
# how many relevant items are selected.
# '''
def recall(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall


# #### Accuracy
# '''Calculates the mean accuracy rate across all predictions for binary
# classification problems.
# '''
def accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)))


# #### Making a Validation Set
x_train, x_val, y_train, y_val = train_test_split(
    x_train_full, y_train_full, test_size=0.20, random_state=101
)
print("Length of the Training Set   : {}".format(len(x_train)))
print("Length of the Test Set       : {}".format(len(x_test)))
print("Length of the Validation Set : {}".format(len(x_val)))


# We will split our full training set into train and validation set.
# Validation dataset is used to validate the performance after each epoch
# ## The Model
# Defining the model in a function which takes two arguments when called
# * **epoch_num**: number of epochs to run
# * **savename**: the name of the model for saving after training
# ## Optimizer and Learning Rate
# * We adopt adam optimization algorithm or adaptive moments, to adjust the learning rate.
# * It is well known that learning rate is one of the critical hyperparameters that have a signiﬁcant impact on classiﬁcation performance.
# ### Advantages of Adam optimizer are:
# * Relatively low memory requirements (though higher than gradient descent and gradient descent with momentum).
# * Usually works well even with a little tuning of hyperparameter.
# * Adam is fairly robust to the choice of hyperparameters, and set the learning rate α as 0.003 to speed up the training procedure.
# #### Model Function
# * SegNet, a deep convolutional network architecture for semantic segmentation. The main motivation behind SegNet was the need to design an efficient architecture for road and indoor scene understanding which is efficient both in terms of memory and computational time.
# * SegNet on the other hand is more efficient since it only stores the max-pooling indices of the feature maps and uses them in its decoder network to achieve good performance.
def segnet(epochs_num, savename):
    # Encoding layer
    img_input = Input(shape=(192, 256, 3))
    x = Conv2D(64, (3, 3), padding="same", name="conv1", strides=(1, 1))(img_input)
    x = BatchNormalization(name="bn1")(x)
    x = Activation("relu")(x)
    x = Conv2D(64, (3, 3), padding="same", name="conv2")(x)
    x = BatchNormalization(name="bn2")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(128, (3, 3), padding="same", name="conv3")(x)
    x = BatchNormalization(name="bn3")(x)
    x = Activation("relu")(x)
    x = Conv2D(128, (3, 3), padding="same", name="conv4")(x)
    x = BatchNormalization(name="bn4")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv5")(x)
    x = BatchNormalization(name="bn5")(x)
    x = Activation("relu")(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv6")(x)
    x = BatchNormalization(name="bn6")(x)
    x = Activation("relu")(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv7")(x)
    x = BatchNormalization(name="bn7")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv8")(x)
    x = BatchNormalization(name="bn8")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv9")(x)
    x = BatchNormalization(name="bn9")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv10")(x)
    x = BatchNormalization(name="bn10")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv11")(x)
    x = BatchNormalization(name="bn11")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv12")(x)
    x = BatchNormalization(name="bn12")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv13")(x)
    x = BatchNormalization(name="bn13")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Dense(1024, activation="relu", name="fc1")(x)
    x = Dense(1024, activation="relu", name="fc2")(x)
    # Decoding Layer
    x = UpSampling2D()(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv1")(x)
    x = BatchNormalization(name="bn14")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv2")(x)
    x = BatchNormalization(name="bn15")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv3")(x)
    x = BatchNormalization(name="bn16")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv4")(x)
    x = BatchNormalization(name="bn17")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv5")(x)
    x = BatchNormalization(name="bn18")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv6")(x)
    x = BatchNormalization(name="bn19")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv7")(x)
    x = BatchNormalization(name="bn20")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv8")(x)
    x = BatchNormalization(name="bn21")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv9")(x)
    x = BatchNormalization(name="bn22")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv10")(x)
    x = BatchNormalization(name="bn23")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv11")(x)
    x = BatchNormalization(name="bn24")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv12")(x)
    x = BatchNormalization(name="bn25")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(1, (3, 3), padding="same", name="deconv13")(x)
    x = BatchNormalization(name="bn26")(x)
    x = Activation("sigmoid")(x)
    pred = Reshape((192, 256))(x)
    model = Model(inputs=img_input, outputs=pred)
    model.compile(
        optimizer=Adam(lr=0.003),
        loss=["binary_crossentropy"],
        metrics=[iou, dice_coef, precision, recall, accuracy],
    )
    model.summary()
    hist = model.fit(
        x_train,
        y_train,
        epochs=epochs_num,
        batch_size=32,
        validation_data=(x_val, y_val),
        verbose=1,
    )
    model.save(savename)
    return model, hist


# ### Loading the Model
# Encoding layer
img_input = Input(shape=(192, 256, 3))
x = Conv2D(64, (3, 3), padding="same", name="conv1", strides=(1, 1))(img_input)
x = BatchNormalization(name="bn1")(x)
x = Activation("relu")(x)
x = Conv2D(64, (3, 3), padding="same", name="conv2")(x)
x = BatchNormalization(name="bn2")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(128, (3, 3), padding="same", name="conv3")(x)
x = BatchNormalization(name="bn3")(x)
x = Activation("relu")(x)
x = Conv2D(128, (3, 3), padding="same", name="conv4")(x)
x = BatchNormalization(name="bn4")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(256, (3, 3), padding="same", name="conv5")(x)
x = BatchNormalization(name="bn5")(x)
x = Activation("relu")(x)
x = Conv2D(256, (3, 3), padding="same", name="conv6")(x)
x = BatchNormalization(name="bn6")(x)
x = Activation("relu")(x)
x = Conv2D(256, (3, 3), padding="same", name="conv7")(x)
x = BatchNormalization(name="bn7")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(512, (3, 3), padding="same", name="conv8")(x)
x = BatchNormalization(name="bn8")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv9")(x)
x = BatchNormalization(name="bn9")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv10")(x)
x = BatchNormalization(name="bn10")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(512, (3, 3), padding="same", name="conv11")(x)
x = BatchNormalization(name="bn11")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv12")(x)
x = BatchNormalization(name="bn12")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv13")(x)
x = BatchNormalization(name="bn13")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Dense(1024, activation="relu", name="fc1")(x)
x = Dense(1024, activation="relu", name="fc2")(x)
# Decoding Layer
x = UpSampling2D()(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv1")(x)
x = BatchNormalization(name="bn14")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv2")(x)
x = BatchNormalization(name="bn15")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv3")(x)
x = BatchNormalization(name="bn16")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv4")(x)
x = BatchNormalization(name="bn17")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv5")(x)
x = BatchNormalization(name="bn18")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv6")(x)
x = BatchNormalization(name="bn19")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv7")(x)
x = BatchNormalization(name="bn20")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv8")(x)
x = BatchNormalization(name="bn21")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv9")(x)
x = BatchNormalization(name="bn22")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv10")(x)
x = BatchNormalization(name="bn23")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv11")(x)
x = BatchNormalization(name="bn24")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv12")(x)
x = BatchNormalization(name="bn25")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(1, (3, 3), padding="same", name="deconv13")(x)
x = BatchNormalization(name="bn26")(x)
x = Activation("sigmoid")(x)
pred = Reshape((192, 256))(x)

# > #### After 120 epochs
model, hist = segnet(epochs_num=120, savename="segnet_120_epoch.h5")
model_1 = Model(inputs=img_input, outputs=pred)
model_1.compile(
    optimizer=Adam(lr=0.003),
    loss=["binary_crossentropy"],
    metrics=[iou, dice_coef, precision, recall, accuracy],
)
model_1.load_weights("segnet_120_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 120 epoch~~~~~~~~~~~~~~~~~~~")
print("\n------------------On Train Set-----------------------------\n")
res = model_1.evaluate(x_train, y_train, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-----------------On Test  Set-----------------------------\n")
res = model_1.evaluate(x_test, y_test, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n----------------On validation Set-----------------------------\n")
res = model_1.evaluate(x_val, y_val, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")

# ### Plotting Training Statistics
plt.figure(figsize=(24, 14))
plt.suptitle("Training Statistics on Train Set", fontsize=30, color="blue")
plt.subplot(2, 3, 1)
plt.plot(hist.history["loss"], "red")
plt.title("Loss", fontsize=18, color="blue")
plt.subplot(2, 3, 2)
plt.plot(hist.history["iou"], "yellow")
plt.title("Jaccard Index", fontsize=18, color="blue")
plt.subplot(2, 3, 3)
plt.plot(hist.history["accuracy"], "green")
plt.title("Accuracy", fontsize=18, color="blue")
plt.subplot(2, 3, 4)
plt.plot(hist.history["val_loss"], "red")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Valdiation Loss", fontsize=18, color="blue")
plt.subplot(2, 3, 5)
plt.plot(hist.history["val_iou"], "yellow")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Valdiation Jaccard Index", fontsize=18, color="blue")
plt.subplot(2, 3, 6)
plt.plot(hist.history["val_accuracy"], "green")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Validation Accuracy", fontsize=18, color="blue")
plt.show()

# ### Visualising Predicted Lesions
# We have trained the model on the **training set**.
# We will make predictions on the unseen **test set**
plt.figure(figsize=(20, 16))
plt.suptitle("Visualising Predicted Lesions", fontsize=30, color="blue")
img_pred = model_1.predict(x_test[49].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 1)
plt.imshow(x_test[49])
plt.title("Original Image")
plt.subplot(4, 3, 2)
plt.imshow(y_test[49], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 3)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[36].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 4)
plt.imshow(x_test[36])
plt.title("Original Image")
plt.subplot(4, 3, 5)
plt.imshow(y_test[36], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 6)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[32].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 7)
plt.imshow(x_test[32])
plt.title("Original Image")
plt.subplot(4, 3, 8)
plt.imshow(y_test[32], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 9)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[21].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 10)
plt.imshow(x_test[21])
plt.title("Original Image")
plt.subplot(4, 3, 11)
plt.imshow(y_test[21], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 12)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
plt.show()


# ### Final Enhance
# * Currently the predicted outputs are blurry because the predicted pixel values are in the range 0 - 1.
# * To make clear edge preditions we can enhance our image by rounding up the pixel values to 1 which are > 0.5 .
# * While rounding down the pixel values to 0 which are < 0.5.
# * We can enhance the image to look for absolute shape predicted by ceiling and flooring the predicted values
def enhance(img):
    sub = (model_1.predict(img.reshape(1, 192, 256, 3))).flatten()
    for i in range(len(sub)):
        if sub[i] > 0.5:
            sub[i] = 1
        else:
            sub[i] = 0
    return sub


plt.figure(figsize=(24, 16))
plt.suptitle("Comparing the Prediction after Enhancement", fontsize=30, color="blue")
plt.subplot(4, 3, 1)
plt.imshow(x_test[21])
plt.title("Original Image")
plt.subplot(4, 3, 2)
plt.imshow(y_test[21], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 3)
plt.imshow(enhance(x_test[21]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 4)
plt.imshow(x_test[19])
plt.title("Original Image")
plt.subplot(4, 3, 5)
plt.imshow(y_test[19], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 6)
plt.imshow(enhance(x_test[19]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 7)
plt.imshow(x_test[36])
plt.title("Original Image")
plt.subplot(4, 3, 8)
plt.imshow(y_test[36], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 9)
plt.imshow(enhance(x_test[36]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 10)
plt.imshow(x_test[49])
plt.title("Original Image")
plt.subplot(4, 3, 11)
plt.imshow(y_test[49], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 12)
plt.imshow(enhance(x_test[49]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.show()


# # **Model: U-Net**
from keras.models import Model, Sequential
from keras.layers import (
    Activation,
    Dense,
    BatchNormalization,
    concatenate,
    Dropout,
    Conv2D,
    Conv2DTranspose,
    MaxPooling2D,
    UpSampling2D,
    Input,
    Reshape,
)
from keras.callbacks import EarlyStopping
from keras.layers.core import SpatialDropout2D
from keras import backend as K
from keras.optimizers import Adam
import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import PIL
from PIL import Image
import matplotlib.pyplot as plt
import cv2
from keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from warnings import filterwarnings

filterwarnings("ignore")
np.random.seed(101)
import re

numbers = re.compile(r"(\d+)")


def numericalSort(value):
    parts = numbers.split(value)
    parts[1::2] = map(int, parts[1::2])
    return parts


filelist_trainx_ph2 = sorted(glob.glob("../input/*/*/trainx/*.bmp"), key=numericalSort)
X_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainx_ph2])
filelist_trainy_ph2 = sorted(glob.glob("../input/*/*/trainy/*.bmp"), key=numericalSort)
Y_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainy_ph2])


def resize(filename, size=(256, 192)):
    im = Image.open(filename)
    im_resized = im.resize(size, Image.ANTIALIAS)
    return im_resized


X_train_ph2_resized = []
Y_train_ph2_resized = []
for i in range(len(filelist_trainx_ph2)):
    X_train_ph2_resized.append(resize(filelist_trainx_ph2[i]))
    Y_train_ph2_resized.append(resize(filelist_trainy_ph2[i]))
X_train = np.array([np.array(img) for img in X_train_ph2_resized])
Y_train = np.array([np.array(img) for img in Y_train_ph2_resized])
x_train, x_test, y_train, y_test = train_test_split(
    X_train, Y_train, test_size=0.25, random_state=101
)


def jaccard_distance(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    jac = (intersection + smooth) / (sum_ - intersection + smooth)
    return 1 - jac


def iou(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    jac = (intersection + smooth) / (sum_ - intersection + smooth)
    return jac


def dice_coe(y_true, y_pred, smooth=100):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2.0 * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


def precision(y_true, y_pred):
    """Calculates the precision, a metric for multi-label classification of
    how many selected items are relevant.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision


def recall(y_true, y_pred):
    """Calculates the recall, a metric for multi-label classification of
    how many relevant items are selected.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall


def accuracy(y_true, y_pred):
    """Calculates the mean accuracy rate across all predictions for binary
    classification problems.
    """
    return K.mean(K.equal(y_true, K.round(y_pred)))


def random_rotation(x_image, y_image):
    rows_x, cols_x, chl_x = x_image.shape
    rows_y, cols_y = y_image.shape
    rand_num = np.random.randint(-40, 40)
    M1 = cv2.getRotationMatrix2D((cols_x / 2, rows_x / 2), rand_num, 1)
    M2 = cv2.getRotationMatrix2D((cols_y / 2, rows_y / 2), rand_num, 1)
    x_image = cv2.warpAffine(x_image, M1, (cols_x, rows_x))
    y_image = cv2.warpAffine(y_image.astype("float32"), M2, (cols_y, rows_y))
    return x_image, y_image.astype("int")


def horizontal_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 1)
    y_image = cv2.flip(y_image.astype("float32"), 1)
    return x_image, y_image.astype("int")


def img_augmentation(x_train, y_train):
    x_rotat = []
    y_rotat = []
    x_flip = []
    y_flip = []
    for idx in range(len(x_train)):
        x, y = random_rotation(x_train[idx], y_train[idx])
        x_rotat.append(x)
        y_rotat.append(y)
        x, y = horizontal_flip(x_train[idx], y_train[idx])
        x_flip.append(x)
        y_flip.append(y)
    return np.array(x_rotat), np.array(y_rotat), np.array(x_flip), np.array(y_flip)


x_rotated, y_rotated, x_flipped, y_flipped = img_augmentation(x_train, y_train)
x_train_full = np.concatenate([x_train, x_rotated, x_flipped])
y_train_full = np.concatenate([y_train, y_rotated, y_flipped])
x_train, x_val, y_train, y_val = train_test_split(
    x_train_full, y_train_full, test_size=0.20, random_state=101
)
print("Length of the Training Set   : {}".format(len(x_train)))
print("Length of the Test Set       : {}".format(len(x_test)))
print("Length of the Validation Set : {}".format(len(x_val)))
# Number of image channels (for example 3 in case of RGB, or 1 for grayscale images)
INPUT_CHANNELS = 3
# Number of output masks (1 in case you predict only one type of objects)
OUTPUT_MASK_CHANNELS = 1


# Pretrained weights
def double_conv_layer(x, size, dropout=0.40, batch_norm=True):
    if K.image_data_format() == "th":
        axis = 1
    else:
        axis = 3
    conv = Conv2D(size, (3, 3), padding="same")(x)
    if batch_norm is True:
        conv = BatchNormalization(axis=axis)(conv)
    conv = Activation("relu")(conv)
    conv = Conv2D(size, (3, 3), padding="same")(conv)
    if batch_norm is True:
        conv = BatchNormalization(axis=axis)(conv)
    conv = Activation("relu")(conv)
    if dropout > 0:
        conv = SpatialDropout2D(dropout)(conv)
    return conv


def UNET_224(epochs_num, savename):
    dropout_val = 0.50
    if K.image_data_format() == "th":
        inputs = Input((INPUT_CHANNELS, 192, 256))
        axis = 1
    else:
        inputs = Input((192, 256, INPUT_CHANNELS))
        axis = 3
    filters = 32
    conv_224 = double_conv_layer(inputs, filters)
    pool_112 = MaxPooling2D(pool_size=(2, 2))(conv_224)
    conv_112 = double_conv_layer(pool_112, 2 * filters)
    pool_56 = MaxPooling2D(pool_size=(2, 2))(conv_112)
    conv_56 = double_conv_layer(pool_56, 4 * filters)
    pool_28 = MaxPooling2D(pool_size=(2, 2))(conv_56)
    conv_28 = double_conv_layer(pool_28, 8 * filters)
    pool_14 = MaxPooling2D(pool_size=(2, 2))(conv_28)
    conv_14 = double_conv_layer(pool_14, 16 * filters)
    pool_7 = MaxPooling2D(pool_size=(2, 2))(conv_14)
    conv_7 = double_conv_layer(pool_7, 32 * filters)
    up_14 = concatenate([UpSampling2D(size=(2, 2))(conv_7), conv_14], axis=axis)
    up_conv_14 = double_conv_layer(up_14, 16 * filters)
    up_28 = concatenate([UpSampling2D(size=(2, 2))(up_conv_14), conv_28], axis=axis)
    up_conv_28 = double_conv_layer(up_28, 8 * filters)
    up_56 = concatenate([UpSampling2D(size=(2, 2))(up_conv_28), conv_56], axis=axis)
    up_conv_56 = double_conv_layer(up_56, 4 * filters)
    up_112 = concatenate([UpSampling2D(size=(2, 2))(up_conv_56), conv_112], axis=axis)
    up_conv_112 = double_conv_layer(up_112, 2 * filters)
    up_224 = concatenate([UpSampling2D(size=(2, 2))(up_conv_112), conv_224], axis=axis)
    up_conv_224 = double_conv_layer(up_224, filters, dropout_val)
    conv_final = Conv2D(OUTPUT_MASK_CHANNELS, (1, 1))(up_conv_224)
    conv_final = Activation("sigmoid")(conv_final)
    pred = Reshape((192, 256))(conv_final)
    model = Model(inputs, pred, name="UNET_224")
    model.compile(
        optimizer=Adam(lr=0.003),
        loss=[jaccard_distance],
        metrics=[iou, dice_coe, precision, recall, accuracy],
    )
    model.summary()
    hist = model.fit(
        x_train,
        y_train,
        epochs=epochs_num,
        batch_size=18,
        validation_data=(x_val, y_val),
        verbose=1,
    )
    model.save(savename)
    return model, hist


model, hist = UNET_224(1, "unet_1_epoch.h5")
dropout_val = 0.50
if K.image_data_format() == "th":
    inputs = Input((INPUT_CHANNELS, 192, 256))
    axis = 1
else:
    inputs = Input((192, 256, INPUT_CHANNELS))
    axis = 3
filters = 32
conv_224 = double_conv_layer(inputs, filters)
pool_112 = MaxPooling2D(pool_size=(2, 2))(conv_224)
conv_112 = double_conv_layer(pool_112, 2 * filters)
pool_56 = MaxPooling2D(pool_size=(2, 2))(conv_112)
conv_56 = double_conv_layer(pool_56, 4 * filters)
pool_28 = MaxPooling2D(pool_size=(2, 2))(conv_56)
conv_28 = double_conv_layer(pool_28, 8 * filters)
pool_14 = MaxPooling2D(pool_size=(2, 2))(conv_28)
conv_14 = double_conv_layer(pool_14, 16 * filters)
pool_7 = MaxPooling2D(pool_size=(2, 2))(conv_14)
conv_7 = double_conv_layer(pool_7, 32 * filters)
up_14 = concatenate([UpSampling2D(size=(2, 2))(conv_7), conv_14], axis=axis)
up_conv_14 = double_conv_layer(up_14, 16 * filters)
up_28 = concatenate([UpSampling2D(size=(2, 2))(up_conv_14), conv_28], axis=axis)
up_conv_28 = double_conv_layer(up_28, 8 * filters)
up_56 = concatenate([UpSampling2D(size=(2, 2))(up_conv_28), conv_56], axis=axis)
up_conv_56 = double_conv_layer(up_56, 4 * filters)
up_112 = concatenate([UpSampling2D(size=(2, 2))(up_conv_56), conv_112], axis=axis)
up_conv_112 = double_conv_layer(up_112, 2 * filters)
up_224 = concatenate([UpSampling2D(size=(2, 2))(up_conv_112), conv_224], axis=axis)
up_conv_224 = double_conv_layer(up_224, filters, dropout_val)
conv_final = Conv2D(OUTPUT_MASK_CHANNELS, (1, 1))(up_conv_224)
conv_final = Activation("sigmoid")(conv_final)
pred = Reshape((192, 256))(conv_final)
model_0 = Model(inputs, pred, name="UNET_224")
model_0.compile(
    optimizer=Adam(lr=0.003),
    loss=[jaccard_distance],
    metrics=[iou, dice_coe, precision, recall, accuracy],
)
model_0.load_weights("unet_1_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 1 epoch~~~~~~~~~~~~~~~~~~~")
print("\n-------------On Train Set--------------------------\n")
res = model_0.evaluate(x_train, y_train, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On Test  Set--------------------------\n")
res = model_0.evaluate(x_test, y_test, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On validation Set---------------------\n")
res = model_0.evaluate(x_val, y_val, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
model, hist = UNET_224(epochs_num=100, savename="unet_100_epoch.h5")
model_1 = Model(inputs, pred, name="UNET_224")
model_1.compile(
    optimizer=Adam(lr=0.003),
    loss=[jaccard_distance],
    metrics=[iou, dice_coe, precision, recall, accuracy],
)
model_1.load_weights("unet_100_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 100 epoch~~~~~~~~~~~~~~~~~~~")
print("\n-------------On Train Set--------------------------\n")
res = model_1.evaluate(x_train, y_train, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On Test  Set--------------------------\n")
res = model_1.evaluate(x_test, y_test, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On validation Set---------------------\n")
res = model_1.evaluate(x_val, y_val, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")


# # **Classification: ResNet50**
import os
import cv2
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
from glob import glob
import seaborn as sns
from PIL import Image
from tqdm import tqdm

np.random.seed(11)  # It's my lucky number
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import (
    train_test_split,
    KFold,
    cross_val_score,
    GridSearchCV,
)
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import itertools
import keras
from keras import regularizers
from keras.utils.np_utils import (
    to_categorical,
)  # used for converting labels to one-hot-encoding
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras import backend as K
from keras.layers.normalization import BatchNormalization
from keras.utils.np_utils import to_categorical  # convert to one-hot-encoding
from keras.optimizers import Adam, RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
from keras.wrappers.scikit_learn import KerasClassifier
from keras.applications.resnet50 import ResNet50
from keras import backend as K
import tensorflow as tf

# Resnet-50 has been pre_trained, weights have been saved in below path
resnet_weights_path = (
    "../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5"
)
# Display the dir list
print(os.listdir("../input"))


# Transfer 'jpg' images to an array IMG
def Dataset_loader(DIR, RESIZE):
    IMG = []
    read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))
    for IMAGE_NAME in tqdm(os.listdir(DIR)):
        PATH = os.path.join(DIR, IMAGE_NAME)
        _, ftype = os.path.splitext(PATH)
        if ftype == ".jpg":
            img = read(PATH)
            img = cv2.resize(img, (RESIZE, RESIZE))
            IMG.append(np.array(img) / 255.0)
    return IMG


X_benign = np.array(Dataset_loader("../input/skindata/train/benign", 224))
X_malignant = np.array(Dataset_loader("../input/skindata/train/malign", 224))
X_benign_test = np.array(Dataset_loader("../input/skindata/test/benign", 224))
X_malignant_test = np.array(Dataset_loader("../input/skindata/test/malign", 224))
# Create labels
y_benign = np.zeros(X_benign.shape[0])
y_malignant = np.ones(X_malignant.shape[0])
y_benign_test = np.zeros(X_benign_test.shape[0])
y_malignant_test = np.ones(X_malignant_test.shape[0])
# Merge data
X_train = np.concatenate((X_benign, X_malignant), axis=0)
y_train = np.concatenate((y_benign, y_malignant), axis=0)
X_test = np.concatenate((X_benign_test, X_malignant_test), axis=0)
y_test = np.concatenate((y_benign_test, y_malignant_test), axis=0)
# Shuffle data
s = np.arange(X_train.shape[0])
np.random.shuffle(s)
X_train = X_train[s]
y_train = y_train[s]
s = np.arange(X_test.shape[0])
np.random.shuffle(s)
X_test = X_test[s]
y_test = y_test[s]
# Display first 15 images of moles, and how they are classified
w = 40
h = 30
fig = plt.figure(figsize=(12, 8))
columns = 5
rows = 3
for i in range(1, columns * rows + 1):
    ax = fig.add_subplot(rows, columns, i)
    if y_train[i] == 0:
        ax.title.set_text("Benign")
    else:
        ax.title.set_text("Malignant")
    plt.imshow(X_train[i], interpolation="nearest")
plt.show()
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
# With data augmentation to prevent overfitting
X_train = X_train / 255.0
X_test = X_test / 255.0


# See learning curve and validation curve
def build(
    input_shape=(224, 224, 3),
    lr=1e-3,
    num_classes=2,
    init="normal",
    activ="relu",
    optim="adam",
):
    model = Sequential()
    model.add(
        Conv2D(
            64,
            kernel_size=(3, 3),
            padding="Same",
            input_shape=input_shape,
            activation=activ,
            kernel_initializer="glorot_uniform",
        )
    )
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(
        Conv2D(
            64,
            kernel_size=(3, 3),
            padding="Same",
            activation=activ,
            kernel_initializer="glorot_uniform",
        )
    )
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128, activation="relu", kernel_initializer=init))
    model.add(Dense(num_classes, activation="softmax"))
    model.summary()
    if optim == "rmsprop":
        optimizer = RMSprop(lr=lr)
    else:
        optimizer = Adam(lr=lr)
    model.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=["accuracy"])
    return model


# Set a learning rate annealer
learning_rate_reduction = ReduceLROnPlateau(
    monitor="val_accuracy", patience=5, verbose=1, factor=0.5, min_lr=1e-7
)
input_shape = (224, 224, 3)
lr = 1e-5
epochs = 50
batch_size = 64
model = ResNet50(
    include_top=True,
    weights=None,
    input_tensor=None,
    input_shape=input_shape,
    pooling="avg",
    classes=2,
)
model.compile(optimizer=Adam(lr), loss="binary_crossentropy", metrics=["accuracy"])
history = model.fit(
    X_train,
    y_train,
    validation_split=0.2,
    epochs=epochs,
    batch_size=batch_size,
    verbose=2,
    callbacks=[learning_rate_reduction],
)
# list all data in history
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# summarize history for loss
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# Train ResNet50 on all the data
model.fit(
    X_train,
    y_train,
    epochs=epochs,
    batch_size=epochs,
    verbose=0,
    callbacks=[learning_rate_reduction],
)
# Testing model on test data to evaluate
y_pred = model.predict(X_test)
print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(y_pred, axis=1)))
# save model
# serialize model to JSON
resnet50_json = model.to_json()
with open("resnet50.json", "w") as json_file:
    json_file.write(resnet50_json)
# serialize weights to HDF5
model.save_weights("resnet50.h5")
print("Saved model to disk")
# Testing model on test data to evaluate
lists = []
y_pred = model.predict(X_test)
for i in range(len(y_pred)):
    if y_pred[i][0] > 0.5:
        lists.append(1)
    else:
        lists.append(0)
# print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(lists, axis=1)))
i = 0
prop_class = []
mis_class = []
for i in range(len(y_test)):
    if y_test[i] == lists[i]:
        prop_class.append(i)
    if len(prop_class) == 8:
        break
i = 0
for i in range(len(y_test)):
    if not y_test[i] == lists[i]:
        mis_class.append(i)
    if len(mis_class) == 8:
        break
# # Display first 8 images of benign
w = 60
h = 40
fig = plt.figure(figsize=(18, 10))
columns = 4
rows = 2


def Transfername(namecode):
    if namecode == 0:
        return "Benign"
    else:
        return "Malignant"


for i in range(len(prop_class)):
    ax = fig.add_subplot(rows, columns, i + 1)
    ax.set_title(
        "Predicted result:"
        + Transfername(lists[prop_class[i]])
        + "\n"
        + "Actual result: "
        + Transfername(Y_test[prop_class[i]])
    )
    plt.imshow(X_test[prop_class[i]], interpolation="nearest")
plt.show()
base_skin_dir = os.path.join("..", "input/ph2cvs")
skin_df = pd.read_csv(os.path.join(base_skin_dir, "ph2data.csv"))
from os.path import isfile


def expand_path(p):
    if isfile("../input/ph2dataset/trainx/" + p + ".bmp"):
        return "../input/ph2dataset/trainx/" + p + ".bmp"
    return p


skin_df["image_path"] = skin_df["Name"]
skin_df["image_path"] = skin_df["image_path"].apply(expand_path)
# 1 = Nevus, 0 = Melenoma
skin_df["cell_type_idx"] = pd.Categorical(skin_df["lesion"]).codes
skin_df["image"] = skin_df["image_path"].map(
    lambda x: np.asarray(Image.open(x).resize((224, 224)))
)
skin_df.head()
n_samples = 5
fig, m_axs = plt.subplots(2, n_samples, figsize=(4 * n_samples, 6))
for n_axs, (type_name, type_rows) in zip(
    m_axs, skin_df.sort_values(["lesion"]).groupby("lesion")
):
    n_axs[0].set_title(type_name)
    for c_ax, (_, c_row) in zip(
        n_axs, type_rows.sample(n_samples, random_state=1234).iterrows()
    ):
        c_ax.imshow(c_row["image"])
        c_ax.axis("off")
skin_df["image"].map(lambda x: x.shape).value_counts()
features = skin_df.drop(columns=["cell_type_idx"], axis=1)
target = skin_df["cell_type_idx"]
x_train_o, x_test_o, y_train_o, y_test_o = train_test_split(
    features, target, test_size=0.2, random_state=42
)
x_train = np.asarray(x_train_o["image"].tolist())
x_test = np.asarray(x_test_o["image"].tolist())
x_train_mean = np.mean(x_train)
x_train_std = np.std(x_train)
x_test_mean = np.mean(x_test)
x_test_std = np.std(x_test)
x_train = (x_train - x_train_mean) / x_train_std
x_test = (x_test - x_test_mean) / x_test_std
# Perform one-hot encoding on the labels
y_train = to_categorical(y_train_o, num_classes=2)
y_test = to_categorical(y_test_o, num_classes=2)
x_train, x_validate, y_train, y_validate = train_test_split(
    x_train, y_train, test_size=0.1, random_state=2
)
# With data augmentation to prevent overfitting
datagen = ImageDataGenerator(
    rotation_range=90,  # randomly rotate images in the range (degrees, 0 to 180)
    zoom_range=0.1,  # Randomly zoom image
    width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
    height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
    horizontal_flip=True,  # randomly flip images
    vertical_flip=True,
)
datagen.fit(x_train)
model = Sequential()
num_labels = 2
base_model = ResNet50(
    include_top=False,
    weights=resnet_weights_path,
    input_shape=(224, 224, 3),
    pooling="avg",
    classes=2,
)
model = Sequential()
model.add(base_model)
model.add(Dropout(0.5))
model.add(Dense(128, activation="relu", kernel_regularizer=regularizers.l2(0.02)))
model.add(Dropout(0.5))
model.add(
    Dense(num_labels, activation="softmax", kernel_regularizer=regularizers.l2(0.02))
)
for layer in base_model.layers:
    layer.trainable = False
for layer in base_model.layers[-22:]:
    layer.trainable = True
# Reviewing our CNN model
model.summary()
tf.keras.utils.plot_model(
    model,
    show_shapes=True,
    show_layer_names=True,
    rankdir="TB",
    expand_nested=True,
    dpi=100,
)  # ,to_file='model.png')
early = EarlyStopping(monitor="val_accuracy", patience=4, mode="max")
# Set a learning rate annealer
learning_rate_reduction = ReduceLROnPlateau(
    monitor="val_accuracy", patience=5, verbose=1, factor=0.5, min_lr=1e-7
)
from keras.callbacks import ModelCheckpoint


class CustomModelCheckPoint(keras.callbacks.Callback):
    def __init__(self, **kargs):
        super(CustomModelCheckPoint, self).__init__(**kargs)
        self.epoch_accuracy = {}  # loss at given epoch
        self.epoch_loss = {}  # accuracy at given epoch

        def on_epoch_begin(self, epoch, logs={}):
            # Things done on beginning of epoch.
            return

        def on_epoch_end(self, epoch, logs={}):
            # things done on end of the epoch
            self.epoch_accuracy[epoch] = logs.get("acc")
            self.epoch_loss[epoch] = logs.get("loss")
            self.model.save_weights("../output/resnet50/name-of-model-%d.h5" % epoch)


checkpointer = ModelCheckpoint(
    filepath="../working/best.hdf5",
    monitor="val_accuracy",
    save_best_only=True,
    mode="max",
)
lr = 0.001
epochs = 50
batch_size = 64
model.compile(optimizer=Adam(lr), loss="binary_crossentropy", metrics=["accuracy"])
history = model.fit_generator(
    datagen.flow(x_train, y_train, batch_size=batch_size),
    validation_data=(x_validate, y_validate),
    epochs=epochs,
    verbose=1,
    steps_per_epoch=x_train.shape[0] // batch_size,
    callbacks=[learning_rate_reduction],
)
# list all data in history
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# summarize history for loss
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# Testing model on test data to evaluate
y_pred = model.predict(x_test)
print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(y_pred, axis=1)))
# model.load_weights("../working/best.hdf5")
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=1)
print("test_accuracy = %f  ;  test_loss = %f" % (test_acc, test_loss))
# save model
# serialize model to JSON
resnet50_json = model.to_json()
with open("resnet50.json", "w") as json_file:
    json_file.write(resnet50_json)
# serialize weights to HDF5
model.save_weights("resnet50.h5")
print("Saved model to disk")


# Function to plot confusion matrix
def plot_confusion_matrix(
    cm, classes, normalize=False, title="Confusion matrix", cmap=plt.cm.Blues
):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    plt.imshow(cm, interpolation="nearest", cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
    if normalize:
        cm = cm.astype("float") / cm.sum(axis=1)[:, np.newaxis]
    thresh = cm.max() / 2.0
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(
            j,
            i,
            cm[i, j],
            horizontalalignment="center",
            color="white" if cm[i, j] > thresh else "black",
        )
    plt.tight_layout()
    plt.ylabel("True label")
    plt.xlabel("Predicted label")


# Predict the values from the validation dataset
Y_pred = model.predict(x_test)
# Convert predictions classes to one hot vectors
Y_pred_classes = np.argmax(Y_pred, axis=1)
# Convert validation observations to one hot vectors
Y_true = np.argmax(y_test, axis=1)
# compute the confusion matrix
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes)
cm_plot_label = ["Nevus", "Melanoma"]
# plot the confusion matrix
plot_confusion_matrix(confusion_mtx, cm_plot_label)
from sklearn.metrics import classification_report

classification_report(np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1))
from sklearn.metrics import roc_auc_score, auc
from sklearn.metrics import roc_curve

roc_log = roc_auc_score(np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1))
false_positive_rate, true_positive_rate, threshold = roc_curve(
    np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1)
)
area_under_curve = auc(false_positive_rate, true_positive_rate)
plt.plot([0, 1], [0, 1], "r--")
plt.plot(
    false_positive_rate,
    true_positive_rate,
    label="AUC = {:.3f}".format(area_under_curve),
)
plt.xlabel("False positive rate")
plt.ylabel("True positive rate")
plt.title("ROC curve")
plt.legend(loc="best")
plt.show()
# plt.savefig(ROC_PLOT_FILE, bbox_inches='tight')
plt.close()
from sklearn import preprocessing

label_encoder = preprocessing.LabelEncoder()
df1 = skin_df.copy()
df1 = df1.drop(
    columns=[
        "Clinical Diagnosis",
        "Histological Diagnosis",
        "image_path",
        "cell_type_idx",
        "image",
    ],
    axis=1,
)
name_cat = label_encoder.fit_transform(df1["Name"])
name_cat = pd.DataFrame({"Name": name_cat})
Asymmetry_cat = label_encoder.fit_transform(df1["Asymmetry"])
Asymmetry_cat = pd.DataFrame({"Asymmetry": Asymmetry_cat})
Pigment_Network_cat = label_encoder.fit_transform(df1["Pigment Network"])
Pigment_Network_cat = pd.DataFrame({"Pigment Network": Pigment_Network_cat})
Dots_Globules_cat = label_encoder.fit_transform(df1["Dots/Globules"])
Dots_Globules_cat = pd.DataFrame({"Dots/Globules": Dots_Globules_cat})
Streaks_cat = label_encoder.fit_transform(df1["Streaks"])
Streaks_cat = pd.DataFrame({"Streaks": Streaks_cat})
Regression_Areas_cat = label_encoder.fit_transform(df1["Regression Areas"])
Regression_Areas_cat = pd.DataFrame({"Regression Areas": Regression_Areas_cat})
Blue_Whitish_Veil_cat = label_encoder.fit_transform(df1["Blue-Whitish Veil"])
Blue_Whitish_Veil_cat = pd.DataFrame({"Blue-Whitish Veil": Blue_Whitish_Veil_cat})
Colors_cat = label_encoder.fit_transform(df1["Colors"])
Colors_cat = pd.DataFrame({"Colors": Colors_cat})
lesion_cat = label_encoder.fit_transform(df1["lesion"])
lesion_cat = pd.DataFrame({"lesion": lesion_cat})
df1.name = name_cat
df1.Asymmetry = Asymmetry_cat
df1.Pigment_Network = Pigment_Network_cat
df1.Dots_Globules = Dots_Globules_cat
df1.Streaks = Streaks_cat
df1.Regression_Areas = Regression_Areas_cat
df1.Blue_Whitish_Veil = Blue_Whitish_Veil_cat
df1.Colors = Colors_cat
df1.lesion = lesion_cat
df1
from sklearn.svm import SVC

model_svc = SVC()
model_svc.fit(x_train_o, y_train)
<|endoftext|>
[{"Id": 69716135, "ScriptId": 18933277, "ParentScriptVersionId": NaN, "ScriptLanguageId": 9, "AuthorUserId": 3956333, "CreationDate": "08/02/2021 22:56:43", "VersionNumber": 1.0, "Title": "Skin-Lesion Segmentation (SegNet Architecture).", "EvaluationDate": "08/02/2021", "IsChange": true, "TotalLines": 1771.0, "LinesInsertedFromPrevious": 877.0, "LinesChangedFromPrevious": 0.0, "LinesUnchangedFromPrevious": 894.0, "LinesInsertedFromFork": 877.0, "LinesDeletedFromFork": 0.0, "LinesChangedFromFork": 0.0, "LinesUnchangedFromFork": 894.0, "TotalVotes": 0}]
[{"Id": 93188012, "KernelVersionId": 69716135, "SourceDatasetVersionId": 9900}, {"Id": 93188013, "KernelVersionId": 69716135, "SourceDatasetVersionId": 1293025}]
[{"Id": 9900, "DatasetId": 6209, "DatasourceVersionId": 9900, "CreatorUserId": 484516, "LicenseName": "CC0: Public Domain", "CreationDate": "12/12/2017 16:54:45", "VersionNumber": 2.0, "Title": "ResNet-50", "Slug": "resnet50", "Subtitle": "ResNet-50 Pre-trained Model for Keras", "Description": "# ResNet-50\n\n---\n\n## Deep Residual Learning for Image Recognition\nDeeper neural networks are more difficult to train. We present a residual learning framework to ease the training of networks that are substantially deeper than those used previously. We explicitly reformulate the layers as learning residual functions with reference to the layer inputs, instead of learning unreferenced functions. We provide comprehensive empirical evidence showing that these residual networks are easier to optimize, and can gain accuracy from considerably increased depth. On the ImageNet dataset we evaluate residual nets with a depth of up to 152 layers---8x deeper than VGG nets but still having lower complexity. \n\nAn ensemble of these residual nets achieves 3.57% error on the ImageNet test set. This result won the 1st place on the ILSVRC 2015 classification task. We also present analysis on CIFAR-10 with 100 and 1000 layers. \n\nThe depth of representations is of central importance for many visual recognition tasks. Solely due to our extremely deep representations, we obtain a 28% relative improvement on the COCO object detection dataset. Deep residual nets are foundations of our submissions to ILSVRC & COCO 2015 competitions, where we also won the 1st places on the tasks of ImageNet detection, ImageNet localization, COCO detection, and COCO segmentation.<br>\n\n**Authors: Kaiming He, Xiangyu Zhang, Shaoqing Ren, Jian Sun**<br>\n**https://arxiv.org/abs/1512.03385**\n\n---\n\n\nArchitecture visualization: http://ethereon.github.io/netscope/#/gist/db945b393d40bfa26006\n\n![Resnet][1]\n\n---\n\n### What is a Pre-trained Model?\nA pre-trained model has been previously trained on a dataset and contains the weights and biases that represent the features of whichever dataset it was trained on. Learned features are often transferable to different data. For example, a model trained on a large dataset of bird images will contain learned features like edges or horizontal lines that you would be transferable your dataset. \n\n### Why use a Pre-trained Model?\nPre-trained models are beneficial to us for many reasons. By using a pre-trained model you are saving time. Someone else has already spent the time and compute resources to learn a lot of features and your model will likely benefit from it. \n\n\n  [1]: https://imgur.com/nyYh5xH.jpg", "VersionNotes": "Added imagenet_class_index.json for use with decode_predictions()", "TotalCompressedBytes": 182733298.0, "TotalUncompressedBytes": 182733298.0}]
[{"Id": 6209, "CreatorUserId": 484516, "OwnerUserId": NaN, "OwnerOrganizationId": 1202.0, "CurrentDatasetVersionId": 9900.0, "CurrentDatasourceVersionId": 9900.0, "ForumId": 12647, "Type": 2, "CreationDate": "12/06/2017 02:12:59", "LastActivityDate": "02/05/2018", "TotalViews": 267558, "TotalDownloads": 22350, "TotalVotes": 359, "TotalKernels": 752}]
# # Title:Skin-Lesion Segmentation
# ### Importing the Libraries
from keras.models import Model, Sequential
from keras.layers import (
    Activation,
    Dense,
    BatchNormalization,
    Dropout,
    Conv2D,
    Conv2DTranspose,
    MaxPooling2D,
    UpSampling2D,
    Input,
    Reshape,
)
from keras import backend as K
from keras.optimizers import Adam
import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import PIL
import os
from PIL import Image, ImageEnhance, ImageFilter
import matplotlib.pyplot as plt
import cv2
from sklearn.model_selection import train_test_split
from warnings import filterwarnings

filterwarnings("ignore")
plt.rcParams["axes.grid"] = False
np.random.seed(101)
print(os.listdir("../input"))

# The ***PH2 database*** includes
# the manual segmentation, the clinical diagnosis, and the identification of several dermoscopic
# structures, performed by expert dermatologists,
# The ***PH2 database*** was built up through a joint research collaboration between the Universidade do
# Porto, T ́ecnico Lisboa, and the Dermatology service of Hospital Pedro Hispano in Matosinhos,
# Portugal.
# ## Loading the data
# [](http://)Defining a function to load the data in sorted order
import re

numbers = re.compile(r"(\d+)")


def numericalSort(value):
    parts = numbers.split(value)
    parts[1::2] = map(int, parts[1::2])
    return parts


# * * * First we will load the filenames in a list.
filelist_trainx_ph2 = sorted(glob.glob("../input/*/*/trainx/*.bmp"), key=numericalSort)
X_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainx_ph2])
filelist_trainy_ph2 = sorted(glob.glob("../input/*/*/trainy/*.bmp"), key=numericalSort)
Y_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainy_ph2])
plt.figure(figsize=(12, 6))
plt.suptitle("Images from PH2 dataset", fontsize=25, color="blue")
plt.subplot(2, 2, 1)
plt.imshow(X_train_ph2[1])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2[1]).shape))
plt.subplot(2, 2, 2)
plt.imshow(Y_train_ph2[1], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2[1]).shape))
plt.subplot(2, 2, 3)
plt.imshow(X_train_ph2[112])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2[185]).shape))
plt.subplot(2, 2, 4)
plt.imshow(Y_train_ph2[112], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2[185]).shape))
plt.show()


# * The images are of dimensions **(572, 765)** so we will scale down the images. It will also reduce the training time of the network.
# #### Resizing
def resize(filename, size=(256, 192)):
    im = Image.open(filename)
    im_resized = im.resize(size, Image.ANTIALIAS)
    return im_resized


X_train_ph2_resized = []
Y_train_ph2_resized = []
for i in range(len(filelist_trainx_ph2)):
    X_train_ph2_resized.append(resize(filelist_trainx_ph2[i]))
    Y_train_ph2_resized.append(resize(filelist_trainy_ph2[i]))


# The new resized images
plt.figure(figsize=(12, 10))
plt.suptitle("Images from PH2 dataset after Resizing", fontsize=25, color="blue")
plt.subplot(2, 2, 1)
plt.imshow(X_train_ph2_resized[1])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[1]).shape))
plt.subplot(2, 2, 2)
plt.imshow(Y_train_ph2_resized[1], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[1]).shape))
plt.subplot(2, 2, 3)
plt.imshow(X_train_ph2_resized[117])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[185]).shape))
plt.subplot(2, 2, 4)
plt.imshow(Y_train_ph2_resized[117], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[185]).shape))
plt.show()

# Converting the transformed Images into numpy arrays
X_train_ph2 = np.array([np.array(img) for img in X_train_ph2_resized])
Y_train_ph2 = np.array([np.array(img) for img in Y_train_ph2_resized])
plt.figure(figsize=(12, 6))
plt.suptitle(
    "Converting the transformed Image into Numpy Array", fontsize=25, color="blue"
)
plt.subplot(1, 2, 1)
plt.imshow(X_train_ph2[117])
plt.xlabel("Dimensions: " + str(np.array(X_train_ph2_resized[180]).shape))
plt.subplot(1, 2, 2)
plt.imshow(Y_train_ph2[117], plt.cm.binary_r)
plt.xlabel("Dimensions: " + str(np.array(Y_train_ph2_resized[180]).shape))
plt.show()

# * Splitting the dataset into training set and test set to verify our model performance without any bias.
x_train, x_test, y_train, y_test = train_test_split(
    X_train_ph2, Y_train_ph2, test_size=0.25, random_state=101
)
plt.figure(figsize=(25, 10))
plt.suptitle("Images from PH2 dataset", fontsize=30, color="blue")
plt.subplot(3, 5, 1)
plt.imshow(X_train_ph2[1])
plt.subplot(3, 5, 2)
plt.imshow(X_train_ph2[12])
plt.subplot(3, 5, 3)
plt.imshow(X_train_ph2[44])
plt.subplot(3, 5, 4)
plt.imshow(X_train_ph2[67])
plt.subplot(3, 5, 5)
plt.imshow(X_train_ph2[100])
plt.subplot(3, 5, 6)
plt.imshow(X_train_ph2[117])
plt.subplot(3, 5, 7)
plt.imshow(X_train_ph2[128])
plt.subplot(3, 5, 8)
plt.imshow(X_train_ph2[147])
plt.subplot(3, 5, 9)
plt.imshow(X_train_ph2[132])
plt.subplot(3, 5, 10)
plt.imshow(X_train_ph2[112])
plt.subplot(3, 5, 11)
plt.imshow(X_train_ph2[31])
plt.subplot(3, 5, 12)
plt.imshow(X_train_ph2[52])
plt.subplot(3, 5, 13)
plt.imshow(X_train_ph2[74])
plt.subplot(3, 5, 14)
plt.imshow(X_train_ph2[86])
plt.subplot(3, 5, 15)
plt.imshow(X_train_ph2[150])
plt.show()
plt.figure(figsize=(25, 10))
plt.suptitle(
    "Mask of the corresponding Images from PH2 dataset", fontsize=30, color="blue"
)
plt.subplot(3, 5, 1)
plt.imshow(Y_train_ph2[1], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 2)
plt.imshow(Y_train_ph2[12], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 3)
plt.imshow(Y_train_ph2[44], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 4)
plt.imshow(Y_train_ph2[67], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 5)
plt.imshow(Y_train_ph2[100], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 6)
plt.imshow(Y_train_ph2[117], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 7)
plt.imshow(Y_train_ph2[128], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 8)
plt.imshow(Y_train_ph2[147], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 9)
plt.imshow(Y_train_ph2[132], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 10)
plt.imshow(Y_train_ph2[112], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 11)
plt.imshow(Y_train_ph2[31], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 12)
plt.imshow(Y_train_ph2[52], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 13)
plt.imshow(Y_train_ph2[74], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 14)
plt.imshow(Y_train_ph2[86], cmap=plt.cm.binary_r)
plt.subplot(3, 5, 15)
plt.imshow(Y_train_ph2[150], cmap=plt.cm.binary_r)
plt.show()


# ## Image Augmentation
# Image augmentation artificially creates training images through different ways of processing or combination of multiple processing, such as random rotation, shifts, shear and flips, etc.
# To build a powerful image classifier using little training data, image augmentation is usually required to boost the performance of deep networks.
# We are going to define to methods for augmentation, **horizontal flipping** , **vertical flipping**, **both flipped** and **random rotation**
def horizontal_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 1)
    y_image = cv2.flip(y_image.astype("float32"), 1)
    return x_image, y_image.astype("int")


def vertical_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 0)
    y_image = cv2.flip(y_image.astype("float32"), 0)
    return x_image, y_image.astype("int")


def both_flip(x_image, y_image):
    x_image = cv2.flip(x_image, -1)
    y_image = cv2.flip(y_image.astype("float32"), -1)
    return x_image, y_image.astype("int")


def random_rotation(x_image, y_image):
    rows_x, cols_x, chl_x = x_image.shape
    rows_y, cols_y = y_image.shape
    rand_num = np.random.randint(-60, 60)
    M1 = cv2.getRotationMatrix2D((cols_x / 2, rows_x / 2), rand_num, 1)
    M2 = cv2.getRotationMatrix2D((cols_y / 2, rows_y / 2), rand_num, 1)
    x_image = cv2.warpAffine(x_image, M1, (cols_x, rows_x))
    y_image = cv2.warpAffine(y_image.astype("float32"), M2, (cols_y, rows_y))
    return np.array(x_image), np.array(y_image.astype("int"))


def img_augmentation(x_train, y_train):
    x_flip = []
    y_flip = []
    x_vert = []
    y_vert = []
    x_both = []
    y_both = []
    x_rotat = []
    y_rotat = []
    for idx in range(len(x_train)):
        x, y = horizontal_flip(x_train[idx], y_train[idx])
        x_flip.append(x)
        y_flip.append(y)
        x, y = vertical_flip(x_train[idx], y_train[idx])
        x_vert.append(x)
        y_vert.append(y)
        x, y = both_flip(x_train[idx], y_train[idx])
        x_both.append(x)
        y_both.append(y)
        x, y = random_rotation(x_train[idx], y_train[idx])
        x_rotat.append(x)
        y_rotat.append(y)
    return (
        np.array(x_flip),
        np.array(y_flip),
        np.array(x_vert),
        np.array(y_vert),
        np.array(x_both),
        np.array(y_both),
        np.array(x_rotat),
        np.array(y_rotat),
    )


# calling the functions for the training data.
(
    x_flipped,
    y_flipped,
    x_vertical,
    y_vertical,
    x_bothed,
    y_bothed,
    x_rotated,
    y_rotated,
) = img_augmentation(x_train, y_train)
(
    x_flipped_t,
    y_flipped_t,
    x_vertical_t,
    y_vertical_t,
    x_bothed_t,
    y_bothed_t,
    x_rotated_t,
    y_rotated_t,
) = img_augmentation(x_test, y_test)
plt.figure(figsize=(25, 16))
plt.suptitle("Image Augmentation", fontsize=25, color="blue")
plt.subplot(6, 4, 1)
plt.imshow(x_train[112])
plt.title("Original Image")
plt.subplot(6, 4, 2)
plt.imshow(y_train[112], plt.cm.binary_r)
plt.title("Original Mask")
plt.subplot(6, 4, 3)
plt.imshow(x_train[12])
plt.title("Original Image")
plt.subplot(6, 4, 4)
plt.imshow(y_train[12], plt.cm.binary_r)
plt.title("Original Mask")
plt.subplot(6, 4, 5)
plt.imshow(x_flipped[112])
plt.title("Horizontal Flipped Image")
plt.subplot(6, 4, 6)
plt.imshow(y_flipped[112], plt.cm.binary_r)
plt.title("Horizontal Flipped Mask")
plt.subplot(6, 4, 7)
plt.imshow(x_flipped[12])
plt.title("Horizontal Flipped Image")
plt.subplot(6, 4, 8)
plt.imshow(y_flipped[12], plt.cm.binary_r)
plt.title("Horizontal Flipped Mask")
plt.subplot(6, 4, 9)
plt.imshow(x_vertical[112])
plt.title("Vertical Flipped Image")
plt.subplot(6, 4, 10)
plt.imshow(y_vertical[112], plt.cm.binary_r)
plt.title("Vertical Flipped Mask")
plt.subplot(6, 4, 11)
plt.imshow(x_vertical[12])
plt.title("Vertical Flipped Image")
plt.subplot(6, 4, 12)
plt.imshow(y_vertical[12], plt.cm.binary_r)
plt.title("Vertical Flipped Mask")
plt.subplot(6, 4, 13)
plt.imshow(x_bothed[112])
plt.title("Flipped both Image")
plt.subplot(6, 4, 14)
plt.imshow(y_bothed[112], plt.cm.binary_r)
plt.title("Flipped both Mask")
plt.subplot(6, 4, 15)
plt.imshow(x_bothed[12])
plt.title("Flipped both Image")
plt.subplot(6, 4, 16)
plt.imshow(y_bothed[12], plt.cm.binary_r)
plt.title("Flipped both Mask")
plt.subplot(6, 4, 17)
plt.imshow(x_rotated[112])
plt.title("Rotated Image")
plt.subplot(6, 4, 18)
plt.imshow(y_rotated[112], plt.cm.binary_r)
plt.title("Rotated Mask")
plt.subplot(6, 4, 19)
plt.imshow(x_rotated[12])
plt.title("Rotated Image")
plt.subplot(6, 4, 20)
plt.imshow(y_rotated[12], plt.cm.binary_r)
plt.title("Rotated Mask")
plt.show()

# Now we join all the augmentations image arrays to the original training arrays.
# For training Set
x_train_full = np.concatenate([x_train, x_rotated, x_flipped, x_bothed, x_vertical])
y_train_full = np.concatenate([y_train, y_rotated, y_flipped, y_bothed, y_vertical])


# ## Defining Evaluation Metrics
# #### Intersection over Union(IOU) or Jaccard Index
# The Jaccard index, also known as Intersection over Union and the Jaccard similarity coefficient is a statistic used for gauging the similarity and diversity of sample sets. The Jaccard coefficient measures similarity between finite sample sets, and is defined as the size of the intersection divided by the size of the union of the sample sets.
# Jaccard index is popular and frequently used as a similarity index.
# The area of overlap J is
# calculated between the segmented binary image A and its ground truth G as shown:
# ***J = |A ∩ G| / |A ∪ G| × 100%.***
def iou(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    union = sum_ - intersection
    jac = (intersection + smooth) / (union + smooth)
    return jac


# #### Dice Coefficient
# The Dice score is not only a measure of how many positives you find, but it also penalizes for the false positives that the method finds, similar to precision. so it is more similar to precision than accuracy.
# The Dice coefficient can be defined as: ***D = 2 |A ∩ G| / |A + G| × 100%*** where A is the algorithm
# output and G is the ground truth.
def dice_coef(y_true, y_pred, smooth=100):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2.0 * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


# #### Precision
# Precision is a good measure to determine, when the costs of False Positive is high.
# ***Precision = true-positive / (true-positive + false-positive)***
# Where,True positive is an outcome where the model correctly predicts the positive class and false positive is an outcome where the model incorrectly predicts the positive class.
#
# '''Precision calculates a metric for multi-label classification of
# how many selected items are relevant.
# '''
def precision(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision


# #### Recall
# Recall actually calculates how many of the Actual Positives our model capture through labeling it as Positive (True Positive). Applying the same understanding, we know that Recall shall be the model metric we use to select our best model when there is a high cost associated with False Negative.
# ***Recall = true-positive /(true-positive + false negative)***
# Where, true positive is an outcome where the model correctly predicts the positive class and false negative is an outcome where the model incorrectly predicts the negative class.
# '''Recall calculates a metric for multi-label classification of
# how many relevant items are selected.
# '''
def recall(y_true, y_pred):
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall


# #### Accuracy
# '''Calculates the mean accuracy rate across all predictions for binary
# classification problems.
# '''
def accuracy(y_true, y_pred):
    return K.mean(K.equal(y_true, K.round(y_pred)))


# #### Making a Validation Set
x_train, x_val, y_train, y_val = train_test_split(
    x_train_full, y_train_full, test_size=0.20, random_state=101
)
print("Length of the Training Set   : {}".format(len(x_train)))
print("Length of the Test Set       : {}".format(len(x_test)))
print("Length of the Validation Set : {}".format(len(x_val)))


# We will split our full training set into train and validation set.
# Validation dataset is used to validate the performance after each epoch
# ## The Model
# Defining the model in a function which takes two arguments when called
# * **epoch_num**: number of epochs to run
# * **savename**: the name of the model for saving after training
# ## Optimizer and Learning Rate
# * We adopt adam optimization algorithm or adaptive moments, to adjust the learning rate.
# * It is well known that learning rate is one of the critical hyperparameters that have a signiﬁcant impact on classiﬁcation performance.
# ### Advantages of Adam optimizer are:
# * Relatively low memory requirements (though higher than gradient descent and gradient descent with momentum).
# * Usually works well even with a little tuning of hyperparameter.
# * Adam is fairly robust to the choice of hyperparameters, and set the learning rate α as 0.003 to speed up the training procedure.
# #### Model Function
# * SegNet, a deep convolutional network architecture for semantic segmentation. The main motivation behind SegNet was the need to design an efficient architecture for road and indoor scene understanding which is efficient both in terms of memory and computational time.
# * SegNet on the other hand is more efficient since it only stores the max-pooling indices of the feature maps and uses them in its decoder network to achieve good performance.
def segnet(epochs_num, savename):
    # Encoding layer
    img_input = Input(shape=(192, 256, 3))
    x = Conv2D(64, (3, 3), padding="same", name="conv1", strides=(1, 1))(img_input)
    x = BatchNormalization(name="bn1")(x)
    x = Activation("relu")(x)
    x = Conv2D(64, (3, 3), padding="same", name="conv2")(x)
    x = BatchNormalization(name="bn2")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(128, (3, 3), padding="same", name="conv3")(x)
    x = BatchNormalization(name="bn3")(x)
    x = Activation("relu")(x)
    x = Conv2D(128, (3, 3), padding="same", name="conv4")(x)
    x = BatchNormalization(name="bn4")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv5")(x)
    x = BatchNormalization(name="bn5")(x)
    x = Activation("relu")(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv6")(x)
    x = BatchNormalization(name="bn6")(x)
    x = Activation("relu")(x)
    x = Conv2D(256, (3, 3), padding="same", name="conv7")(x)
    x = BatchNormalization(name="bn7")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv8")(x)
    x = BatchNormalization(name="bn8")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv9")(x)
    x = BatchNormalization(name="bn9")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv10")(x)
    x = BatchNormalization(name="bn10")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv11")(x)
    x = BatchNormalization(name="bn11")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv12")(x)
    x = BatchNormalization(name="bn12")(x)
    x = Activation("relu")(x)
    x = Conv2D(512, (3, 3), padding="same", name="conv13")(x)
    x = BatchNormalization(name="bn13")(x)
    x = Activation("relu")(x)
    x = MaxPooling2D()(x)
    x = Dense(1024, activation="relu", name="fc1")(x)
    x = Dense(1024, activation="relu", name="fc2")(x)
    # Decoding Layer
    x = UpSampling2D()(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv1")(x)
    x = BatchNormalization(name="bn14")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv2")(x)
    x = BatchNormalization(name="bn15")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv3")(x)
    x = BatchNormalization(name="bn16")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv4")(x)
    x = BatchNormalization(name="bn17")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv5")(x)
    x = BatchNormalization(name="bn18")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv6")(x)
    x = BatchNormalization(name="bn19")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv7")(x)
    x = BatchNormalization(name="bn20")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv8")(x)
    x = BatchNormalization(name="bn21")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv9")(x)
    x = BatchNormalization(name="bn22")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv10")(x)
    x = BatchNormalization(name="bn23")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv11")(x)
    x = BatchNormalization(name="bn24")(x)
    x = Activation("relu")(x)
    x = UpSampling2D()(x)
    x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv12")(x)
    x = BatchNormalization(name="bn25")(x)
    x = Activation("relu")(x)
    x = Conv2DTranspose(1, (3, 3), padding="same", name="deconv13")(x)
    x = BatchNormalization(name="bn26")(x)
    x = Activation("sigmoid")(x)
    pred = Reshape((192, 256))(x)
    model = Model(inputs=img_input, outputs=pred)
    model.compile(
        optimizer=Adam(lr=0.003),
        loss=["binary_crossentropy"],
        metrics=[iou, dice_coef, precision, recall, accuracy],
    )
    model.summary()
    hist = model.fit(
        x_train,
        y_train,
        epochs=epochs_num,
        batch_size=32,
        validation_data=(x_val, y_val),
        verbose=1,
    )
    model.save(savename)
    return model, hist


# ### Loading the Model
# Encoding layer
img_input = Input(shape=(192, 256, 3))
x = Conv2D(64, (3, 3), padding="same", name="conv1", strides=(1, 1))(img_input)
x = BatchNormalization(name="bn1")(x)
x = Activation("relu")(x)
x = Conv2D(64, (3, 3), padding="same", name="conv2")(x)
x = BatchNormalization(name="bn2")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(128, (3, 3), padding="same", name="conv3")(x)
x = BatchNormalization(name="bn3")(x)
x = Activation("relu")(x)
x = Conv2D(128, (3, 3), padding="same", name="conv4")(x)
x = BatchNormalization(name="bn4")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(256, (3, 3), padding="same", name="conv5")(x)
x = BatchNormalization(name="bn5")(x)
x = Activation("relu")(x)
x = Conv2D(256, (3, 3), padding="same", name="conv6")(x)
x = BatchNormalization(name="bn6")(x)
x = Activation("relu")(x)
x = Conv2D(256, (3, 3), padding="same", name="conv7")(x)
x = BatchNormalization(name="bn7")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(512, (3, 3), padding="same", name="conv8")(x)
x = BatchNormalization(name="bn8")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv9")(x)
x = BatchNormalization(name="bn9")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv10")(x)
x = BatchNormalization(name="bn10")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Conv2D(512, (3, 3), padding="same", name="conv11")(x)
x = BatchNormalization(name="bn11")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv12")(x)
x = BatchNormalization(name="bn12")(x)
x = Activation("relu")(x)
x = Conv2D(512, (3, 3), padding="same", name="conv13")(x)
x = BatchNormalization(name="bn13")(x)
x = Activation("relu")(x)
x = MaxPooling2D()(x)
x = Dense(1024, activation="relu", name="fc1")(x)
x = Dense(1024, activation="relu", name="fc2")(x)
# Decoding Layer
x = UpSampling2D()(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv1")(x)
x = BatchNormalization(name="bn14")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv2")(x)
x = BatchNormalization(name="bn15")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv3")(x)
x = BatchNormalization(name="bn16")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv4")(x)
x = BatchNormalization(name="bn17")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(512, (3, 3), padding="same", name="deconv5")(x)
x = BatchNormalization(name="bn18")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv6")(x)
x = BatchNormalization(name="bn19")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv7")(x)
x = BatchNormalization(name="bn20")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(256, (3, 3), padding="same", name="deconv8")(x)
x = BatchNormalization(name="bn21")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv9")(x)
x = BatchNormalization(name="bn22")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(128, (3, 3), padding="same", name="deconv10")(x)
x = BatchNormalization(name="bn23")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv11")(x)
x = BatchNormalization(name="bn24")(x)
x = Activation("relu")(x)
x = UpSampling2D()(x)
x = Conv2DTranspose(64, (3, 3), padding="same", name="deconv12")(x)
x = BatchNormalization(name="bn25")(x)
x = Activation("relu")(x)
x = Conv2DTranspose(1, (3, 3), padding="same", name="deconv13")(x)
x = BatchNormalization(name="bn26")(x)
x = Activation("sigmoid")(x)
pred = Reshape((192, 256))(x)

# > #### After 120 epochs
model, hist = segnet(epochs_num=120, savename="segnet_120_epoch.h5")
model_1 = Model(inputs=img_input, outputs=pred)
model_1.compile(
    optimizer=Adam(lr=0.003),
    loss=["binary_crossentropy"],
    metrics=[iou, dice_coef, precision, recall, accuracy],
)
model_1.load_weights("segnet_120_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 120 epoch~~~~~~~~~~~~~~~~~~~")
print("\n------------------On Train Set-----------------------------\n")
res = model_1.evaluate(x_train, y_train, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-----------------On Test  Set-----------------------------\n")
res = model_1.evaluate(x_test, y_test, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n----------------On validation Set-----------------------------\n")
res = model_1.evaluate(x_val, y_val, batch_size=48)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")

# ### Plotting Training Statistics
plt.figure(figsize=(24, 14))
plt.suptitle("Training Statistics on Train Set", fontsize=30, color="blue")
plt.subplot(2, 3, 1)
plt.plot(hist.history["loss"], "red")
plt.title("Loss", fontsize=18, color="blue")
plt.subplot(2, 3, 2)
plt.plot(hist.history["iou"], "yellow")
plt.title("Jaccard Index", fontsize=18, color="blue")
plt.subplot(2, 3, 3)
plt.plot(hist.history["accuracy"], "green")
plt.title("Accuracy", fontsize=18, color="blue")
plt.subplot(2, 3, 4)
plt.plot(hist.history["val_loss"], "red")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Valdiation Loss", fontsize=18, color="blue")
plt.subplot(2, 3, 5)
plt.plot(hist.history["val_iou"], "yellow")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Valdiation Jaccard Index", fontsize=18, color="blue")
plt.subplot(2, 3, 6)
plt.plot(hist.history["val_accuracy"], "green")
plt.yticks(list(np.arange(0.0, 1.0, 0.10)))
plt.title("Validation Accuracy", fontsize=18, color="blue")
plt.show()

# ### Visualising Predicted Lesions
# We have trained the model on the **training set**.
# We will make predictions on the unseen **test set**
plt.figure(figsize=(20, 16))
plt.suptitle("Visualising Predicted Lesions", fontsize=30, color="blue")
img_pred = model_1.predict(x_test[49].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 1)
plt.imshow(x_test[49])
plt.title("Original Image")
plt.subplot(4, 3, 2)
plt.imshow(y_test[49], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 3)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[36].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 4)
plt.imshow(x_test[36])
plt.title("Original Image")
plt.subplot(4, 3, 5)
plt.imshow(y_test[36], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 6)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[32].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 7)
plt.imshow(x_test[32])
plt.title("Original Image")
plt.subplot(4, 3, 8)
plt.imshow(y_test[32], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 9)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
img_pred = model_1.predict(x_test[21].reshape(1, 192, 256, 3))
plt.subplot(4, 3, 10)
plt.imshow(x_test[21])
plt.title("Original Image")
plt.subplot(4, 3, 11)
plt.imshow(y_test[21], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 12)
plt.imshow(img_pred.reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted Mask")
plt.show()


# ### Final Enhance
# * Currently the predicted outputs are blurry because the predicted pixel values are in the range 0 - 1.
# * To make clear edge preditions we can enhance our image by rounding up the pixel values to 1 which are > 0.5 .
# * While rounding down the pixel values to 0 which are < 0.5.
# * We can enhance the image to look for absolute shape predicted by ceiling and flooring the predicted values
def enhance(img):
    sub = (model_1.predict(img.reshape(1, 192, 256, 3))).flatten()
    for i in range(len(sub)):
        if sub[i] > 0.5:
            sub[i] = 1
        else:
            sub[i] = 0
    return sub


plt.figure(figsize=(24, 16))
plt.suptitle("Comparing the Prediction after Enhancement", fontsize=30, color="blue")
plt.subplot(4, 3, 1)
plt.imshow(x_test[21])
plt.title("Original Image")
plt.subplot(4, 3, 2)
plt.imshow(y_test[21], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 3)
plt.imshow(enhance(x_test[21]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 4)
plt.imshow(x_test[19])
plt.title("Original Image")
plt.subplot(4, 3, 5)
plt.imshow(y_test[19], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 6)
plt.imshow(enhance(x_test[19]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 7)
plt.imshow(x_test[36])
plt.title("Original Image")
plt.subplot(4, 3, 8)
plt.imshow(y_test[36], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 9)
plt.imshow(enhance(x_test[36]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.subplot(4, 3, 10)
plt.imshow(x_test[49])
plt.title("Original Image")
plt.subplot(4, 3, 11)
plt.imshow(y_test[49], plt.cm.binary_r)
plt.title("True Mask")
plt.subplot(4, 3, 12)
plt.imshow(enhance(x_test[49]).reshape(192, 256), plt.cm.binary_r)
plt.title("Predicted after threshold")
plt.show()


# # **Model: U-Net**
from keras.models import Model, Sequential
from keras.layers import (
    Activation,
    Dense,
    BatchNormalization,
    concatenate,
    Dropout,
    Conv2D,
    Conv2DTranspose,
    MaxPooling2D,
    UpSampling2D,
    Input,
    Reshape,
)
from keras.callbacks import EarlyStopping
from keras.layers.core import SpatialDropout2D
from keras import backend as K
from keras.optimizers import Adam
import tensorflow as tf
import numpy as np
import pandas as pd
import glob
import PIL
from PIL import Image
import matplotlib.pyplot as plt
import cv2
from keras.preprocessing.image import ImageDataGenerator
from sklearn.model_selection import train_test_split
from warnings import filterwarnings

filterwarnings("ignore")
np.random.seed(101)
import re

numbers = re.compile(r"(\d+)")


def numericalSort(value):
    parts = numbers.split(value)
    parts[1::2] = map(int, parts[1::2])
    return parts


filelist_trainx_ph2 = sorted(glob.glob("../input/*/*/trainx/*.bmp"), key=numericalSort)
X_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainx_ph2])
filelist_trainy_ph2 = sorted(glob.glob("../input/*/*/trainy/*.bmp"), key=numericalSort)
Y_train_ph2 = np.array([np.array(Image.open(fname)) for fname in filelist_trainy_ph2])


def resize(filename, size=(256, 192)):
    im = Image.open(filename)
    im_resized = im.resize(size, Image.ANTIALIAS)
    return im_resized


X_train_ph2_resized = []
Y_train_ph2_resized = []
for i in range(len(filelist_trainx_ph2)):
    X_train_ph2_resized.append(resize(filelist_trainx_ph2[i]))
    Y_train_ph2_resized.append(resize(filelist_trainy_ph2[i]))
X_train = np.array([np.array(img) for img in X_train_ph2_resized])
Y_train = np.array([np.array(img) for img in Y_train_ph2_resized])
x_train, x_test, y_train, y_test = train_test_split(
    X_train, Y_train, test_size=0.25, random_state=101
)


def jaccard_distance(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    jac = (intersection + smooth) / (sum_ - intersection + smooth)
    return 1 - jac


def iou(y_true, y_pred, smooth=100):
    intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
    sum_ = K.sum(K.square(y_true), axis=-1) + K.sum(K.square(y_pred), axis=-1)
    jac = (intersection + smooth) / (sum_ - intersection + smooth)
    return jac


def dice_coe(y_true, y_pred, smooth=100):
    y_true_f = K.flatten(y_true)
    y_pred_f = K.flatten(y_pred)
    intersection = K.sum(y_true_f * y_pred_f)
    return (2.0 * intersection + smooth) / (K.sum(y_true_f) + K.sum(y_pred_f) + smooth)


def precision(y_true, y_pred):
    """Calculates the precision, a metric for multi-label classification of
    how many selected items are relevant.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))
    precision = true_positives / (predicted_positives + K.epsilon())
    return precision


def recall(y_true, y_pred):
    """Calculates the recall, a metric for multi-label classification of
    how many relevant items are selected.
    """
    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))
    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))
    recall = true_positives / (possible_positives + K.epsilon())
    return recall


def accuracy(y_true, y_pred):
    """Calculates the mean accuracy rate across all predictions for binary
    classification problems.
    """
    return K.mean(K.equal(y_true, K.round(y_pred)))


def random_rotation(x_image, y_image):
    rows_x, cols_x, chl_x = x_image.shape
    rows_y, cols_y = y_image.shape
    rand_num = np.random.randint(-40, 40)
    M1 = cv2.getRotationMatrix2D((cols_x / 2, rows_x / 2), rand_num, 1)
    M2 = cv2.getRotationMatrix2D((cols_y / 2, rows_y / 2), rand_num, 1)
    x_image = cv2.warpAffine(x_image, M1, (cols_x, rows_x))
    y_image = cv2.warpAffine(y_image.astype("float32"), M2, (cols_y, rows_y))
    return x_image, y_image.astype("int")


def horizontal_flip(x_image, y_image):
    x_image = cv2.flip(x_image, 1)
    y_image = cv2.flip(y_image.astype("float32"), 1)
    return x_image, y_image.astype("int")


def img_augmentation(x_train, y_train):
    x_rotat = []
    y_rotat = []
    x_flip = []
    y_flip = []
    for idx in range(len(x_train)):
        x, y = random_rotation(x_train[idx], y_train[idx])
        x_rotat.append(x)
        y_rotat.append(y)
        x, y = horizontal_flip(x_train[idx], y_train[idx])
        x_flip.append(x)
        y_flip.append(y)
    return np.array(x_rotat), np.array(y_rotat), np.array(x_flip), np.array(y_flip)


x_rotated, y_rotated, x_flipped, y_flipped = img_augmentation(x_train, y_train)
x_train_full = np.concatenate([x_train, x_rotated, x_flipped])
y_train_full = np.concatenate([y_train, y_rotated, y_flipped])
x_train, x_val, y_train, y_val = train_test_split(
    x_train_full, y_train_full, test_size=0.20, random_state=101
)
print("Length of the Training Set   : {}".format(len(x_train)))
print("Length of the Test Set       : {}".format(len(x_test)))
print("Length of the Validation Set : {}".format(len(x_val)))
# Number of image channels (for example 3 in case of RGB, or 1 for grayscale images)
INPUT_CHANNELS = 3
# Number of output masks (1 in case you predict only one type of objects)
OUTPUT_MASK_CHANNELS = 1


# Pretrained weights
def double_conv_layer(x, size, dropout=0.40, batch_norm=True):
    if K.image_data_format() == "th":
        axis = 1
    else:
        axis = 3
    conv = Conv2D(size, (3, 3), padding="same")(x)
    if batch_norm is True:
        conv = BatchNormalization(axis=axis)(conv)
    conv = Activation("relu")(conv)
    conv = Conv2D(size, (3, 3), padding="same")(conv)
    if batch_norm is True:
        conv = BatchNormalization(axis=axis)(conv)
    conv = Activation("relu")(conv)
    if dropout > 0:
        conv = SpatialDropout2D(dropout)(conv)
    return conv


def UNET_224(epochs_num, savename):
    dropout_val = 0.50
    if K.image_data_format() == "th":
        inputs = Input((INPUT_CHANNELS, 192, 256))
        axis = 1
    else:
        inputs = Input((192, 256, INPUT_CHANNELS))
        axis = 3
    filters = 32
    conv_224 = double_conv_layer(inputs, filters)
    pool_112 = MaxPooling2D(pool_size=(2, 2))(conv_224)
    conv_112 = double_conv_layer(pool_112, 2 * filters)
    pool_56 = MaxPooling2D(pool_size=(2, 2))(conv_112)
    conv_56 = double_conv_layer(pool_56, 4 * filters)
    pool_28 = MaxPooling2D(pool_size=(2, 2))(conv_56)
    conv_28 = double_conv_layer(pool_28, 8 * filters)
    pool_14 = MaxPooling2D(pool_size=(2, 2))(conv_28)
    conv_14 = double_conv_layer(pool_14, 16 * filters)
    pool_7 = MaxPooling2D(pool_size=(2, 2))(conv_14)
    conv_7 = double_conv_layer(pool_7, 32 * filters)
    up_14 = concatenate([UpSampling2D(size=(2, 2))(conv_7), conv_14], axis=axis)
    up_conv_14 = double_conv_layer(up_14, 16 * filters)
    up_28 = concatenate([UpSampling2D(size=(2, 2))(up_conv_14), conv_28], axis=axis)
    up_conv_28 = double_conv_layer(up_28, 8 * filters)
    up_56 = concatenate([UpSampling2D(size=(2, 2))(up_conv_28), conv_56], axis=axis)
    up_conv_56 = double_conv_layer(up_56, 4 * filters)
    up_112 = concatenate([UpSampling2D(size=(2, 2))(up_conv_56), conv_112], axis=axis)
    up_conv_112 = double_conv_layer(up_112, 2 * filters)
    up_224 = concatenate([UpSampling2D(size=(2, 2))(up_conv_112), conv_224], axis=axis)
    up_conv_224 = double_conv_layer(up_224, filters, dropout_val)
    conv_final = Conv2D(OUTPUT_MASK_CHANNELS, (1, 1))(up_conv_224)
    conv_final = Activation("sigmoid")(conv_final)
    pred = Reshape((192, 256))(conv_final)
    model = Model(inputs, pred, name="UNET_224")
    model.compile(
        optimizer=Adam(lr=0.003),
        loss=[jaccard_distance],
        metrics=[iou, dice_coe, precision, recall, accuracy],
    )
    model.summary()
    hist = model.fit(
        x_train,
        y_train,
        epochs=epochs_num,
        batch_size=18,
        validation_data=(x_val, y_val),
        verbose=1,
    )
    model.save(savename)
    return model, hist


model, hist = UNET_224(1, "unet_1_epoch.h5")
dropout_val = 0.50
if K.image_data_format() == "th":
    inputs = Input((INPUT_CHANNELS, 192, 256))
    axis = 1
else:
    inputs = Input((192, 256, INPUT_CHANNELS))
    axis = 3
filters = 32
conv_224 = double_conv_layer(inputs, filters)
pool_112 = MaxPooling2D(pool_size=(2, 2))(conv_224)
conv_112 = double_conv_layer(pool_112, 2 * filters)
pool_56 = MaxPooling2D(pool_size=(2, 2))(conv_112)
conv_56 = double_conv_layer(pool_56, 4 * filters)
pool_28 = MaxPooling2D(pool_size=(2, 2))(conv_56)
conv_28 = double_conv_layer(pool_28, 8 * filters)
pool_14 = MaxPooling2D(pool_size=(2, 2))(conv_28)
conv_14 = double_conv_layer(pool_14, 16 * filters)
pool_7 = MaxPooling2D(pool_size=(2, 2))(conv_14)
conv_7 = double_conv_layer(pool_7, 32 * filters)
up_14 = concatenate([UpSampling2D(size=(2, 2))(conv_7), conv_14], axis=axis)
up_conv_14 = double_conv_layer(up_14, 16 * filters)
up_28 = concatenate([UpSampling2D(size=(2, 2))(up_conv_14), conv_28], axis=axis)
up_conv_28 = double_conv_layer(up_28, 8 * filters)
up_56 = concatenate([UpSampling2D(size=(2, 2))(up_conv_28), conv_56], axis=axis)
up_conv_56 = double_conv_layer(up_56, 4 * filters)
up_112 = concatenate([UpSampling2D(size=(2, 2))(up_conv_56), conv_112], axis=axis)
up_conv_112 = double_conv_layer(up_112, 2 * filters)
up_224 = concatenate([UpSampling2D(size=(2, 2))(up_conv_112), conv_224], axis=axis)
up_conv_224 = double_conv_layer(up_224, filters, dropout_val)
conv_final = Conv2D(OUTPUT_MASK_CHANNELS, (1, 1))(up_conv_224)
conv_final = Activation("sigmoid")(conv_final)
pred = Reshape((192, 256))(conv_final)
model_0 = Model(inputs, pred, name="UNET_224")
model_0.compile(
    optimizer=Adam(lr=0.003),
    loss=[jaccard_distance],
    metrics=[iou, dice_coe, precision, recall, accuracy],
)
model_0.load_weights("unet_1_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 1 epoch~~~~~~~~~~~~~~~~~~~")
print("\n-------------On Train Set--------------------------\n")
res = model_0.evaluate(x_train, y_train, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On Test  Set--------------------------\n")
res = model_0.evaluate(x_test, y_test, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On validation Set---------------------\n")
res = model_0.evaluate(x_val, y_val, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
model, hist = UNET_224(epochs_num=100, savename="unet_100_epoch.h5")
model_1 = Model(inputs, pred, name="UNET_224")
model_1.compile(
    optimizer=Adam(lr=0.003),
    loss=[jaccard_distance],
    metrics=[iou, dice_coe, precision, recall, accuracy],
)
model_1.load_weights("unet_100_epoch.h5")
print("\n~~~~~~~~~~~~~~~Stats after 100 epoch~~~~~~~~~~~~~~~~~~~")
print("\n-------------On Train Set--------------------------\n")
res = model_1.evaluate(x_train, y_train, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On Test  Set--------------------------\n")
res = model_1.evaluate(x_test, y_test, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")
print("\n-------------On validation Set---------------------\n")
res = model_1.evaluate(x_val, y_val, batch_size=18)
print("________________________")
print("IOU:       |   {:.2f}  |".format(res[1] * 100))
print("Dice Coef: |   {:.2f}  |".format(res[2] * 100))
print("Precision: |   {:.2f}  |".format(res[3] * 100))
print("Recall:    |   {:.2f}  |".format(res[4] * 100))
print("Accuracy:  |   {:.2f}  |".format(res[5] * 100))
print("Loss:      |   {:.2f}  |".format(res[0] * 100))
print("________________________")


# # **Classification: ResNet50**
import os
import cv2
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import os
from glob import glob
import seaborn as sns
from PIL import Image
from tqdm import tqdm

np.random.seed(11)  # It's my lucky number
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import (
    train_test_split,
    KFold,
    cross_val_score,
    GridSearchCV,
)
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import itertools
import keras
from keras import regularizers
from keras.utils.np_utils import (
    to_categorical,
)  # used for converting labels to one-hot-encoding
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D
from keras import backend as K
from keras.layers.normalization import BatchNormalization
from keras.utils.np_utils import to_categorical  # convert to one-hot-encoding
from keras.optimizers import Adam, RMSprop
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping, ReduceLROnPlateau
from keras.wrappers.scikit_learn import KerasClassifier
from keras.applications.resnet50 import ResNet50
from keras import backend as K
import tensorflow as tf

# Resnet-50 has been pre_trained, weights have been saved in below path
resnet_weights_path = (
    "../input/resnet50/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5"
)
# Display the dir list
print(os.listdir("../input"))


# Transfer 'jpg' images to an array IMG
def Dataset_loader(DIR, RESIZE):
    IMG = []
    read = lambda imname: np.asarray(Image.open(imname).convert("RGB"))
    for IMAGE_NAME in tqdm(os.listdir(DIR)):
        PATH = os.path.join(DIR, IMAGE_NAME)
        _, ftype = os.path.splitext(PATH)
        if ftype == ".jpg":
            img = read(PATH)
            img = cv2.resize(img, (RESIZE, RESIZE))
            IMG.append(np.array(img) / 255.0)
    return IMG


X_benign = np.array(Dataset_loader("../input/skindata/train/benign", 224))
X_malignant = np.array(Dataset_loader("../input/skindata/train/malign", 224))
X_benign_test = np.array(Dataset_loader("../input/skindata/test/benign", 224))
X_malignant_test = np.array(Dataset_loader("../input/skindata/test/malign", 224))
# Create labels
y_benign = np.zeros(X_benign.shape[0])
y_malignant = np.ones(X_malignant.shape[0])
y_benign_test = np.zeros(X_benign_test.shape[0])
y_malignant_test = np.ones(X_malignant_test.shape[0])
# Merge data
X_train = np.concatenate((X_benign, X_malignant), axis=0)
y_train = np.concatenate((y_benign, y_malignant), axis=0)
X_test = np.concatenate((X_benign_test, X_malignant_test), axis=0)
y_test = np.concatenate((y_benign_test, y_malignant_test), axis=0)
# Shuffle data
s = np.arange(X_train.shape[0])
np.random.shuffle(s)
X_train = X_train[s]
y_train = y_train[s]
s = np.arange(X_test.shape[0])
np.random.shuffle(s)
X_test = X_test[s]
y_test = y_test[s]
# Display first 15 images of moles, and how they are classified
w = 40
h = 30
fig = plt.figure(figsize=(12, 8))
columns = 5
rows = 3
for i in range(1, columns * rows + 1):
    ax = fig.add_subplot(rows, columns, i)
    if y_train[i] == 0:
        ax.title.set_text("Benign")
    else:
        ax.title.set_text("Malignant")
    plt.imshow(X_train[i], interpolation="nearest")
plt.show()
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
# With data augmentation to prevent overfitting
X_train = X_train / 255.0
X_test = X_test / 255.0


# See learning curve and validation curve
def build(
    input_shape=(224, 224, 3),
    lr=1e-3,
    num_classes=2,
    init="normal",
    activ="relu",
    optim="adam",
):
    model = Sequential()
    model.add(
        Conv2D(
            64,
            kernel_size=(3, 3),
            padding="Same",
            input_shape=input_shape,
            activation=activ,
            kernel_initializer="glorot_uniform",
        )
    )
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(
        Conv2D(
            64,
            kernel_size=(3, 3),
            padding="Same",
            activation=activ,
            kernel_initializer="glorot_uniform",
        )
    )
    model.add(MaxPool2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128, activation="relu", kernel_initializer=init))
    model.add(Dense(num_classes, activation="softmax"))
    model.summary()
    if optim == "rmsprop":
        optimizer = RMSprop(lr=lr)
    else:
        optimizer = Adam(lr=lr)
    model.compile(optimizer=optimizer, loss="binary_crossentropy", metrics=["accuracy"])
    return model


# Set a learning rate annealer
learning_rate_reduction = ReduceLROnPlateau(
    monitor="val_accuracy", patience=5, verbose=1, factor=0.5, min_lr=1e-7
)
input_shape = (224, 224, 3)
lr = 1e-5
epochs = 50
batch_size = 64
model = ResNet50(
    include_top=True,
    weights=None,
    input_tensor=None,
    input_shape=input_shape,
    pooling="avg",
    classes=2,
)
model.compile(optimizer=Adam(lr), loss="binary_crossentropy", metrics=["accuracy"])
history = model.fit(
    X_train,
    y_train,
    validation_split=0.2,
    epochs=epochs,
    batch_size=batch_size,
    verbose=2,
    callbacks=[learning_rate_reduction],
)
# list all data in history
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# summarize history for loss
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# Train ResNet50 on all the data
model.fit(
    X_train,
    y_train,
    epochs=epochs,
    batch_size=epochs,
    verbose=0,
    callbacks=[learning_rate_reduction],
)
# Testing model on test data to evaluate
y_pred = model.predict(X_test)
print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(y_pred, axis=1)))
# save model
# serialize model to JSON
resnet50_json = model.to_json()
with open("resnet50.json", "w") as json_file:
    json_file.write(resnet50_json)
# serialize weights to HDF5
model.save_weights("resnet50.h5")
print("Saved model to disk")
# Testing model on test data to evaluate
lists = []
y_pred = model.predict(X_test)
for i in range(len(y_pred)):
    if y_pred[i][0] > 0.5:
        lists.append(1)
    else:
        lists.append(0)
# print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(lists, axis=1)))
i = 0
prop_class = []
mis_class = []
for i in range(len(y_test)):
    if y_test[i] == lists[i]:
        prop_class.append(i)
    if len(prop_class) == 8:
        break
i = 0
for i in range(len(y_test)):
    if not y_test[i] == lists[i]:
        mis_class.append(i)
    if len(mis_class) == 8:
        break
# # Display first 8 images of benign
w = 60
h = 40
fig = plt.figure(figsize=(18, 10))
columns = 4
rows = 2


def Transfername(namecode):
    if namecode == 0:
        return "Benign"
    else:
        return "Malignant"


for i in range(len(prop_class)):
    ax = fig.add_subplot(rows, columns, i + 1)
    ax.set_title(
        "Predicted result:"
        + Transfername(lists[prop_class[i]])
        + "\n"
        + "Actual result: "
        + Transfername(Y_test[prop_class[i]])
    )
    plt.imshow(X_test[prop_class[i]], interpolation="nearest")
plt.show()
base_skin_dir = os.path.join("..", "input/ph2cvs")
skin_df = pd.read_csv(os.path.join(base_skin_dir, "ph2data.csv"))
from os.path import isfile


def expand_path(p):
    if isfile("../input/ph2dataset/trainx/" + p + ".bmp"):
        return "../input/ph2dataset/trainx/" + p + ".bmp"
    return p


skin_df["image_path"] = skin_df["Name"]
skin_df["image_path"] = skin_df["image_path"].apply(expand_path)
# 1 = Nevus, 0 = Melenoma
skin_df["cell_type_idx"] = pd.Categorical(skin_df["lesion"]).codes
skin_df["image"] = skin_df["image_path"].map(
    lambda x: np.asarray(Image.open(x).resize((224, 224)))
)
skin_df.head()
n_samples = 5
fig, m_axs = plt.subplots(2, n_samples, figsize=(4 * n_samples, 6))
for n_axs, (type_name, type_rows) in zip(
    m_axs, skin_df.sort_values(["lesion"]).groupby("lesion")
):
    n_axs[0].set_title(type_name)
    for c_ax, (_, c_row) in zip(
        n_axs, type_rows.sample(n_samples, random_state=1234).iterrows()
    ):
        c_ax.imshow(c_row["image"])
        c_ax.axis("off")
skin_df["image"].map(lambda x: x.shape).value_counts()
features = skin_df.drop(columns=["cell_type_idx"], axis=1)
target = skin_df["cell_type_idx"]
x_train_o, x_test_o, y_train_o, y_test_o = train_test_split(
    features, target, test_size=0.2, random_state=42
)
x_train = np.asarray(x_train_o["image"].tolist())
x_test = np.asarray(x_test_o["image"].tolist())
x_train_mean = np.mean(x_train)
x_train_std = np.std(x_train)
x_test_mean = np.mean(x_test)
x_test_std = np.std(x_test)
x_train = (x_train - x_train_mean) / x_train_std
x_test = (x_test - x_test_mean) / x_test_std
# Perform one-hot encoding on the labels
y_train = to_categorical(y_train_o, num_classes=2)
y_test = to_categorical(y_test_o, num_classes=2)
x_train, x_validate, y_train, y_validate = train_test_split(
    x_train, y_train, test_size=0.1, random_state=2
)
# With data augmentation to prevent overfitting
datagen = ImageDataGenerator(
    rotation_range=90,  # randomly rotate images in the range (degrees, 0 to 180)
    zoom_range=0.1,  # Randomly zoom image
    width_shift_range=0.1,  # randomly shift images horizontally (fraction of total width)
    height_shift_range=0.1,  # randomly shift images vertically (fraction of total height)
    horizontal_flip=True,  # randomly flip images
    vertical_flip=True,
)
datagen.fit(x_train)
model = Sequential()
num_labels = 2
base_model = ResNet50(
    include_top=False,
    weights=resnet_weights_path,
    input_shape=(224, 224, 3),
    pooling="avg",
    classes=2,
)
model = Sequential()
model.add(base_model)
model.add(Dropout(0.5))
model.add(Dense(128, activation="relu", kernel_regularizer=regularizers.l2(0.02)))
model.add(Dropout(0.5))
model.add(
    Dense(num_labels, activation="softmax", kernel_regularizer=regularizers.l2(0.02))
)
for layer in base_model.layers:
    layer.trainable = False
for layer in base_model.layers[-22:]:
    layer.trainable = True
# Reviewing our CNN model
model.summary()
tf.keras.utils.plot_model(
    model,
    show_shapes=True,
    show_layer_names=True,
    rankdir="TB",
    expand_nested=True,
    dpi=100,
)  # ,to_file='model.png')
early = EarlyStopping(monitor="val_accuracy", patience=4, mode="max")
# Set a learning rate annealer
learning_rate_reduction = ReduceLROnPlateau(
    monitor="val_accuracy", patience=5, verbose=1, factor=0.5, min_lr=1e-7
)
from keras.callbacks import ModelCheckpoint


class CustomModelCheckPoint(keras.callbacks.Callback):
    def __init__(self, **kargs):
        super(CustomModelCheckPoint, self).__init__(**kargs)
        self.epoch_accuracy = {}  # loss at given epoch
        self.epoch_loss = {}  # accuracy at given epoch

        def on_epoch_begin(self, epoch, logs={}):
            # Things done on beginning of epoch.
            return

        def on_epoch_end(self, epoch, logs={}):
            # things done on end of the epoch
            self.epoch_accuracy[epoch] = logs.get("acc")
            self.epoch_loss[epoch] = logs.get("loss")
            self.model.save_weights("../output/resnet50/name-of-model-%d.h5" % epoch)


checkpointer = ModelCheckpoint(
    filepath="../working/best.hdf5",
    monitor="val_accuracy",
    save_best_only=True,
    mode="max",
)
lr = 0.001
epochs = 50
batch_size = 64
model.compile(optimizer=Adam(lr), loss="binary_crossentropy", metrics=["accuracy"])
history = model.fit_generator(
    datagen.flow(x_train, y_train, batch_size=batch_size),
    validation_data=(x_validate, y_validate),
    epochs=epochs,
    verbose=1,
    steps_per_epoch=x_train.shape[0] // batch_size,
    callbacks=[learning_rate_reduction],
)
# list all data in history
print(history.history.keys())
# summarize history for accuracy
plt.plot(history.history["accuracy"])
plt.plot(history.history["val_accuracy"])
plt.title("model accuracy")
plt.ylabel("accuracy")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# summarize history for loss
plt.plot(history.history["loss"])
plt.plot(history.history["val_loss"])
plt.title("model loss")
plt.ylabel("loss")
plt.xlabel("epoch")
plt.legend(["train", "test"], loc="upper left")
plt.show()
# Testing model on test data to evaluate
y_pred = model.predict(x_test)
print(accuracy_score(np.argmax(y_test, axis=1), np.argmax(y_pred, axis=1)))
# model.load_weights("../working/best.hdf5")
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=1)
print("test_accuracy = %f  ;  test_loss = %f" % (test_acc, test_loss))
# save model
# serialize model to JSON
resnet50_json = model.to_json()
with open("resnet50.json", "w") as json_file:
    json_file.write(resnet50_json)
# serialize weights to HDF5
model.save_weights("resnet50.h5")
print("Saved model to disk")


# Function to plot confusion matrix
def plot_confusion_matrix(
    cm, classes, normalize=False, title="Confusion matrix", cmap=plt.cm.Blues
):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    plt.imshow(cm, interpolation="nearest", cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45)
    plt.yticks(tick_marks, classes)
    if normalize:
        cm = cm.astype("float") / cm.sum(axis=1)[:, np.newaxis]
    thresh = cm.max() / 2.0
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(
            j,
            i,
            cm[i, j],
            horizontalalignment="center",
            color="white" if cm[i, j] > thresh else "black",
        )
    plt.tight_layout()
    plt.ylabel("True label")
    plt.xlabel("Predicted label")


# Predict the values from the validation dataset
Y_pred = model.predict(x_test)
# Convert predictions classes to one hot vectors
Y_pred_classes = np.argmax(Y_pred, axis=1)
# Convert validation observations to one hot vectors
Y_true = np.argmax(y_test, axis=1)
# compute the confusion matrix
confusion_mtx = confusion_matrix(Y_true, Y_pred_classes)
cm_plot_label = ["Nevus", "Melanoma"]
# plot the confusion matrix
plot_confusion_matrix(confusion_mtx, cm_plot_label)
from sklearn.metrics import classification_report

classification_report(np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1))
from sklearn.metrics import roc_auc_score, auc
from sklearn.metrics import roc_curve

roc_log = roc_auc_score(np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1))
false_positive_rate, true_positive_rate, threshold = roc_curve(
    np.argmax(y_test, axis=1), np.argmax(Y_pred, axis=1)
)
area_under_curve = auc(false_positive_rate, true_positive_rate)
plt.plot([0, 1], [0, 1], "r--")
plt.plot(
    false_positive_rate,
    true_positive_rate,
    label="AUC = {:.3f}".format(area_under_curve),
)
plt.xlabel("False positive rate")
plt.ylabel("True positive rate")
plt.title("ROC curve")
plt.legend(loc="best")
plt.show()
# plt.savefig(ROC_PLOT_FILE, bbox_inches='tight')
plt.close()
from sklearn import preprocessing

label_encoder = preprocessing.LabelEncoder()
df1 = skin_df.copy()
df1 = df1.drop(
    columns=[
        "Clinical Diagnosis",
        "Histological Diagnosis",
        "image_path",
        "cell_type_idx",
        "image",
    ],
    axis=1,
)
name_cat = label_encoder.fit_transform(df1["Name"])
name_cat = pd.DataFrame({"Name": name_cat})
Asymmetry_cat = label_encoder.fit_transform(df1["Asymmetry"])
Asymmetry_cat = pd.DataFrame({"Asymmetry": Asymmetry_cat})
Pigment_Network_cat = label_encoder.fit_transform(df1["Pigment Network"])
Pigment_Network_cat = pd.DataFrame({"Pigment Network": Pigment_Network_cat})
Dots_Globules_cat = label_encoder.fit_transform(df1["Dots/Globules"])
Dots_Globules_cat = pd.DataFrame({"Dots/Globules": Dots_Globules_cat})
Streaks_cat = label_encoder.fit_transform(df1["Streaks"])
Streaks_cat = pd.DataFrame({"Streaks": Streaks_cat})
Regression_Areas_cat = label_encoder.fit_transform(df1["Regression Areas"])
Regression_Areas_cat = pd.DataFrame({"Regression Areas": Regression_Areas_cat})
Blue_Whitish_Veil_cat = label_encoder.fit_transform(df1["Blue-Whitish Veil"])
Blue_Whitish_Veil_cat = pd.DataFrame({"Blue-Whitish Veil": Blue_Whitish_Veil_cat})
Colors_cat = label_encoder.fit_transform(df1["Colors"])
Colors_cat = pd.DataFrame({"Colors": Colors_cat})
lesion_cat = label_encoder.fit_transform(df1["lesion"])
lesion_cat = pd.DataFrame({"lesion": lesion_cat})
df1.name = name_cat
df1.Asymmetry = Asymmetry_cat
df1.Pigment_Network = Pigment_Network_cat
df1.Dots_Globules = Dots_Globules_cat
df1.Streaks = Streaks_cat
df1.Regression_Areas = Regression_Areas_cat
df1.Blue_Whitish_Veil = Blue_Whitish_Veil_cat
df1.Colors = Colors_cat
df1.lesion = lesion_cat
df1
from sklearn.svm import SVC

model_svc = SVC()
model_svc.fit(x_train_o, y_train)
