{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.10","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":20270,"databundleVersionId":1222630,"sourceType":"competition"},{"sourceId":643971,"sourceType":"datasetVersion","datasetId":319080}],"dockerImageVersionId":30096,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nimport PIL\nimport cv2\nimport itertools\nimport os\nimport shutil\nimport random\nimport glob\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport warnings\n\nfrom tensorflow import keras\nfrom PIL import Image\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Activation, Dense, Flatten, BatchNormalization, Conv2D, MaxPool2D\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.metrics import binary_crossentropy\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.metrics import confusion_matrix\nfrom keras.models import Model, Sequential\nfrom keras.layers import Activation, Dense, BatchNormalization, concatenate, Dropout, Conv2D, Conv2DTranspose, MaxPooling2D, UpSampling2D, Input, Reshape\nfrom keras.callbacks import EarlyStopping\nfrom keras.layers.core import SpatialDropout2D\nfrom sklearn.metrics import precision_recall_curve\nfrom sklearn.metrics import plot_precision_recall_curve\nfrom sklearn.metrics import precision_score\nfrom sklearn.metrics import recall_score\nfrom keras import backend as K\nfrom keras.optimizers import Adam\nfrom sklearn.model_selection import train_test_split\nfrom warnings import filterwarnings\n\nfilterwarnings('ignore')\nnp.random.seed(123)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:57:57.531731Z","iopub.execute_input":"2022-11-20T11:57:57.532017Z","iopub.status.idle":"2022-11-20T11:58:03.236404Z","shell.execute_reply.started":"2022-11-20T11:57:57.531944Z","shell.execute_reply":"2022-11-20T11:58:03.235559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# About the datasets\nhttps://www.kaggle.com/competitions/siim-isic-melanoma-classification/data","metadata":{}},{"cell_type":"code","source":"import re\nnumbers = re.compile(r'(\\d+)')\ndef numericalSort(value):\n    parts = numbers.split(value)\n    parts[1::2] = map(int, parts[1::2])\n    return parts","metadata":{"execution":{"iopub.status.busy":"2022-11-20T13:42:33.109185Z","iopub.execute_input":"2022-11-20T13:42:33.109607Z","iopub.status.idle":"2022-11-20T13:42:33.120522Z","shell.execute_reply.started":"2022-11-20T13:42:33.109519Z","shell.execute_reply":"2022-11-20T13:42:33.117881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BASEPATH = \"../input/siim-isic-melanoma-classification\"\ndf_train = pd.read_csv(os.path.join(BASEPATH, 'train.csv'))\ndf_test  = pd.read_csv(os.path.join(BASEPATH, 'test.csv'))\ndf_sub   = pd.read_csv(os.path.join(BASEPATH, 'sample_submission.csv'))","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:03.24461Z","iopub.execute_input":"2022-11-20T11:58:03.245115Z","iopub.status.idle":"2022-11-20T11:58:03.370502Z","shell.execute_reply.started":"2022-11-20T11:58:03.245077Z","shell.execute_reply":"2022-11-20T11:58:03.369747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:03.371884Z","iopub.execute_input":"2022-11-20T11:58:03.372193Z","iopub.status.idle":"2022-11-20T11:58:03.39918Z","shell.execute_reply.started":"2022-11-20T11:58:03.372165Z","shell.execute_reply":"2022-11-20T11:58:03.398228Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_path = '../input/skin-cancer9-classesisic/Skin cancer ISIC The International Skin Imaging Collaboration/Train'\ntest_path = '../input/skin-cancer9-classesisic/Skin cancer ISIC The International Skin Imaging Collaboration/Test'","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:03.400427Z","iopub.execute_input":"2022-11-20T11:58:03.400798Z","iopub.status.idle":"2022-11-20T11:58:03.404743Z","shell.execute_reply.started":"2022-11-20T11:58:03.400762Z","shell.execute_reply":"2022-11-20T11:58:03.40377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \\\n    .flow_from_directory(directory=train_path, target_size=(224,224),batch_size=10)\nvalid_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \\\n    .flow_from_directory(directory=train_path, target_size=(224,224),batch_size=10)\ntest_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \\\n    .flow_from_directory(directory=test_path, target_size=(224,224),batch_size=10, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:03.40605Z","iopub.execute_input":"2022-11-20T11:58:03.406605Z","iopub.status.idle":"2022-11-20T11:58:04.242198Z","shell.execute_reply.started":"2022-11-20T11:58:03.406569Z","shell.execute_reply":"2022-11-20T11:58:04.241215Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 123\nbatch_size = 10\nimg_height = 224\nimg_width =  224","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:04.243646Z","iopub.execute_input":"2022-11-20T11:58:04.24422Z","iopub.status.idle":"2022-11-20T11:58:04.254156Z","shell.execute_reply.started":"2022-11-20T11:58:04.244179Z","shell.execute_reply":"2022-11-20T11:58:04.249569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes=['pigmented benign keratosis',\n 'melanoma',\n 'vascular lesion',\n 'actinic keratosis',\n 'squamous cell carcinoma',\n 'basal cell carcinoma',\n 'seborrheic keratosis',\n 'dermatofibroma',\n 'nevus']","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:04.26357Z","iopub.execute_input":"2022-11-20T11:58:04.264102Z","iopub.status.idle":"2022-11-20T11:58:04.278717Z","shell.execute_reply.started":"2022-11-20T11:58:04.264058Z","shell.execute_reply":"2022-11-20T11:58:04.27568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport pathlib\ntrain_dir = pathlib.Path(train_path)\ntest_dir = pathlib.Path(test_path)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:04.284182Z","iopub.execute_input":"2022-11-20T11:58:04.2845Z","iopub.status.idle":"2022-11-20T11:58:04.29665Z","shell.execute_reply.started":"2022-11-20T11:58:04.284463Z","shell.execute_reply":"2022-11-20T11:58:04.295566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport os, sys\n\npath = \"../input/siim-isic-melanoma-classification/jpeg/train\"\ndirs = os.listdir( path )\n\ndef resize():\n    for item in dirs:\n        if os.path.isfile(path+item):\n            im = Image.open(path+item)\n            f, e = os.path.splitext(path+item)\n            imResize = im.resize((224,224), Image.ANTIALIAS)\n            imResize.save(f + ' resized.jpg', 'JPEG', quality=90)\n\nresize()","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:04.298014Z","iopub.execute_input":"2022-11-20T11:58:04.29865Z","iopub.status.idle":"2022-11-20T11:58:20.466084Z","shell.execute_reply.started":"2022-11-20T11:58:04.298614Z","shell.execute_reply":"2022-11-20T11:58:20.465208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"imgs, labels = next(train_batches)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:20.467414Z","iopub.execute_input":"2022-11-20T11:58:20.467786Z","iopub.status.idle":"2022-11-20T11:58:20.797419Z","shell.execute_reply.started":"2022-11-20T11:58:20.467748Z","shell.execute_reply":"2022-11-20T11:58:20.79657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plotImages(images_arr):\n    fig, axes = plt.subplots(1, 10, figsize=(20,20))\n    axes = axes.flatten()\n    for img, ax in zip( images_arr, axes):\n        ax.imshow(img)\n        ax.axis('off')\n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:20.799246Z","iopub.execute_input":"2022-11-20T11:58:20.799822Z","iopub.status.idle":"2022-11-20T11:58:20.80561Z","shell.execute_reply.started":"2022-11-20T11:58:20.799781Z","shell.execute_reply":"2022-11-20T11:58:20.804846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotImages(imgs)\nprint(labels)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:20.807111Z","iopub.execute_input":"2022-11-20T11:58:20.807467Z","iopub.status.idle":"2022-11-20T11:58:21.58571Z","shell.execute_reply.started":"2022-11-20T11:58:20.807415Z","shell.execute_reply":"2022-11-20T11:58:21.584151Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential([\n    Conv2D(filters=32, kernel_size=(3, 3), activation='relu', padding = 'same', input_shape=(224,224,3)),\n    MaxPool2D(pool_size=(2, 2), strides=2),\n    Conv2D(filters=64, kernel_size=(3, 3), activation='relu', padding = 'same'),\n    MaxPool2D(pool_size=(2, 2), strides=2),\n    Flatten(),\n    Dense(units= 9, activation='sigmoid')\n])","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:21.586794Z","iopub.execute_input":"2022-11-20T11:58:21.587126Z","iopub.status.idle":"2022-11-20T11:58:24.141079Z","shell.execute_reply.started":"2022-11-20T11:58:21.587086Z","shell.execute_reply":"2022-11-20T11:58:24.140255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:24.14229Z","iopub.execute_input":"2022-11-20T11:58:24.142635Z","iopub.status.idle":"2022-11-20T11:58:24.157533Z","shell.execute_reply.started":"2022-11-20T11:58:24.142601Z","shell.execute_reply":"2022-11-20T11:58:24.156616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:24.159083Z","iopub.execute_input":"2022-11-20T11:58:24.15952Z","iopub.status.idle":"2022-11-20T11:58:24.169179Z","shell.execute_reply.started":"2022-11-20T11:58:24.159485Z","shell.execute_reply":"2022-11-20T11:58:24.168099Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CollectBatchStats(tf.keras.callbacks.Callback):\n  def __init__(self):\n    self.batch_losses = []\n    self.batch_acc = []\n    \n  def on_batch_end(self, batch, logs=None):\n    self.batch_losses.append(logs['loss'])\n    self.batch_acc.append(logs['accuracy'])\n    \n# Early stopping to stop the training if loss start to increase. It also avoids overfitting.\nes = EarlyStopping(patience=3,monitor=\"val_loss\")","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:24.170675Z","iopub.execute_input":"2022-11-20T11:58:24.171004Z","iopub.status.idle":"2022-11-20T11:58:24.178383Z","shell.execute_reply.started":"2022-11-20T11:58:24.170969Z","shell.execute_reply":"2022-11-20T11:58:24.177525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"reducing the steps per epoch increased the accuracy","metadata":{}},{"cell_type":"code","source":"from keras.callbacks import EarlyStopping\n#set early stopping monitor so the model stops training when it won't improve anymore\nearly_stopping_monitor = EarlyStopping(patience=3)\n\n#train model\nhistory = model.fit(x=train_batches,\n    steps_per_epoch=len(train_batches),\n    validation_data=valid_batches,\n    validation_steps=len(valid_batches),\n                    epochs=10,\n                    verbose=2,\n                    callbacks=[early_stopping_monitor]\n                   )\n                               ","metadata":{"execution":{"iopub.status.busy":"2022-11-20T11:58:24.179654Z","iopub.execute_input":"2022-11-20T11:58:24.180018Z","iopub.status.idle":"2022-11-20T12:10:23.423629Z","shell.execute_reply.started":"2022-11-20T11:58:24.179984Z","shell.execute_reply":"2022-11-20T12:10:23.422744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"label_names = sorted(train_batches.class_indices.items(), key=lambda pair:pair[1])\nlabel_names = np.array([key.title() for key, value in label_names])\nlabel_names","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:23.425474Z","iopub.execute_input":"2022-11-20T12:10:23.425842Z","iopub.status.idle":"2022-11-20T12:10:23.434744Z","shell.execute_reply.started":"2022-11-20T12:10:23.4258Z","shell.execute_reply":"2022-11-20T12:10:23.433753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_batch = model.predict(test_batches)\n\nlabels_batch = label_names[np.argmax(result_batch, axis=-1)]\nlabels_batch","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:23.435879Z","iopub.execute_input":"2022-11-20T12:10:23.436252Z","iopub.status.idle":"2022-11-20T12:10:36.471359Z","shell.execute_reply.started":"2022-11-20T12:10:23.436215Z","shell.execute_reply":"2022-11-20T12:10:36.47046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_imgs, test_labels = next(test_batches)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:36.472631Z","iopub.execute_input":"2022-11-20T12:10:36.473009Z","iopub.status.idle":"2022-11-20T12:10:38.828443Z","shell.execute_reply.started":"2022-11-20T12:10:36.472977Z","shell.execute_reply":"2022-11-20T12:10:38.827598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plotImages(test_imgs)\nprint(test_labels)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:38.829777Z","iopub.execute_input":"2022-11-20T12:10:38.830125Z","iopub.status.idle":"2022-11-20T12:10:39.477399Z","shell.execute_reply.started":"2022-11-20T12:10:38.830088Z","shell.execute_reply":"2022-11-20T12:10:39.476435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"saved_model = model.save(\"melanoma_model\")\nfrom keras.preprocessing import image\nimg = image.load_img('../input/skin-cancer9-classesisic/Skin cancer ISIC The International Skin Imaging Collaboration/Test/dermatofibroma/ISIC_0001114.jpg',target_size=(224,224))\nimg = np.asarray(img)\nplt.imshow(img)\nimg = np.expand_dims(img, axis=0)\n\nfrom keras.models import load_model\nsaved_model = load_model(\"melanoma_model\")\noutput = saved_model.predict(img)\nif output[0][0] > output[0][1]:\n    print(\"melanoma\")\nelse:\n    print('not melanoma')\n","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:39.481474Z","iopub.execute_input":"2022-11-20T12:10:39.48209Z","iopub.status.idle":"2022-11-20T12:10:41.187096Z","shell.execute_reply.started":"2022-11-20T12:10:39.482047Z","shell.execute_reply":"2022-11-20T12:10:41.186282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(x=test_batches, steps=len(test_batches), verbose=0)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:41.188604Z","iopub.execute_input":"2022-11-20T12:10:41.189175Z","iopub.status.idle":"2022-11-20T12:10:51.020002Z","shell.execute_reply.started":"2022-11-20T12:10:41.189134Z","shell.execute_reply":"2022-11-20T12:10:51.019115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.round(predictions)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.023269Z","iopub.execute_input":"2022-11-20T12:10:51.023573Z","iopub.status.idle":"2022-11-20T12:10:51.032837Z","shell.execute_reply.started":"2022-11-20T12:10:51.023543Z","shell.execute_reply":"2022-11-20T12:10:51.032091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tf.keras.utils.plot_model(model = model , rankdir=\"TB\", dpi=72, show_shapes=True)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.034078Z","iopub.execute_input":"2022-11-20T12:10:51.034915Z","iopub.status.idle":"2022-11-20T12:10:51.505392Z","shell.execute_reply.started":"2022-11-20T12:10:51.034871Z","shell.execute_reply":"2022-11-20T12:10:51.50441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.evaluate(test_imgs, test_labels)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.507253Z","iopub.execute_input":"2022-11-20T12:10:51.507644Z","iopub.status.idle":"2022-11-20T12:10:51.680195Z","shell.execute_reply.started":"2022-11-20T12:10:51.507599Z","shell.execute_reply":"2022-11-20T12:10:51.679347Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('test data', test_imgs)\npreds = np.round(model.predict(test_imgs),0) \n#to fit them into classification metrics and confusion metrics, some additional modificaitions are required\nprint('rounded test_labels', preds)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.681357Z","iopub.execute_input":"2022-11-20T12:10:51.681694Z","iopub.status.idle":"2022-11-20T12:10:51.791306Z","shell.execute_reply.started":"2022-11-20T12:10:51.681662Z","shell.execute_reply":"2022-11-20T12:10:51.790487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn import metrics\nclasses=['pigmented benign keratosis',\n 'melanoma',\n 'vascular lesion',\n 'actinic keratosis',\n 'squamous cell carcinoma',\n 'basal cell carcinoma',\n 'seborrheic keratosis',\n 'dermatofibroma',\n 'nevus']\nclassification_metrics = metrics.classification_report(test_labels, preds, target_names=classes )\nprint(classification_metrics)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.793264Z","iopub.execute_input":"2022-11-20T12:10:51.793801Z","iopub.status.idle":"2022-11-20T12:10:51.813386Z","shell.execute_reply.started":"2022-11-20T12:10:51.79376Z","shell.execute_reply":"2022-11-20T12:10:51.812559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"epochs = 10\nacc = history.history['accuracy']\nval_acc = history.history['val_accuracy']\n\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs_range = range(epochs)\n\nplt.figure(figsize=(8, 6))\nplt.subplot(1, 2, 1)\nplt.plot(epochs_range, acc, label='Training Accuracy')\nplt.plot(epochs_range, val_acc, label='Validation Accuracy')\nplt.legend(loc='lower right')\nplt.title('Training and Validation Accuracy')\n\nplt.subplot(1, 2, 2)\nplt.plot(epochs_range, loss, label='Training Loss')\nplt.plot(epochs_range, val_loss, label='Validation Loss')\nplt.legend(loc='upper right')\nplt.title('Training and Validation Loss')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:51.814629Z","iopub.execute_input":"2022-11-20T12:10:51.814961Z","iopub.status.idle":"2022-11-20T12:10:52.070645Z","shell.execute_reply.started":"2022-11-20T12:10:51.814926Z","shell.execute_reply":"2022-11-20T12:10:52.069776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_history(history):\n    plt.plot(history.history[\"accuracy\"])\n    plt.plot(history.history[\"val_accuracy\"])\n    plt.title(\"model accuracy\")\n    plt.ylabel(\"accuracy\")\n    plt.xlabel(\"epoch\")\n    plt.legend([\"train\", \"validation\"], loc=\"upper left\")\n    plt.show()\n\n\nplot_history(history)","metadata":{"execution":{"iopub.status.busy":"2022-11-20T12:10:52.071894Z","iopub.execute_input":"2022-11-20T12:10:52.072395Z","iopub.status.idle":"2022-11-20T12:10:52.212206Z","shell.execute_reply.started":"2022-11-20T12:10:52.072355Z","shell.execute_reply":"2022-11-20T12:10:52.211102Z"},"trusted":true},"execution_count":null,"outputs":[]}]}