{"cells":[{"metadata":{},"cell_type":"markdown","source":"# SIIM-ISIC Melanoma Classification\n###### Identify melanoma in lesion images\n### What should I expect the data format to be?\nThe images are provided in DICOM format. This can be accessed using commonly-available libraries like pydicom, and contains both image and metadata. It is a commonly used medical imaging data format.\n\nImages are also provided in JPEG and TFRecord format (in the jpeg and tfrecords directories, respectively). Images in TFRecord format have been resized to a uniform 1024x1024.\n\nMetadata is also provided outside of the DICOM format, in CSV files. See the Columns section for a description.\n\n### What am I predicting?\nYou are predicting a binary target for each image. Your model should predict the probability (floating point) between 0.0 and 1.0 that the lesion in the image is malignant (the target). In the training data, train.csv, the value 0 denotes benign, and 1 indicates malignant.\n\n> Files\n* train.csv - the training set\n* test.csv - the test set\n* sample_submission.csv - a sample submission file in the correct format\n\n<img src = \"https://www.mayoclinic.org/-/media/kcms/gbs/patient-consumer/images/2013/11/15/17/43/ds00190_-ds00439_im04411_mcdc7_melanomathu_jpg.jpg\">","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport pydicom as dcm\nimport cv2\n\n'''Customize visualization\nSeaborn and matplotlib visualization.'''\nimport altair as alt\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nsns.set_style(\"whitegrid\")\n%matplotlib inline\nfrom IPython.core.display import HTML\nfrom PIL import Image\n\n\n\n'''Plotly visualization .'''\nimport plotly.express as px\nimport skimage.io\nfrom skimage.transform import resize\nfrom imgaug import augmenters as iaa\n\n\n\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\nimport tensorflow as tf\nimport keras\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, load_model\nfrom keras.layers import (Activation, Dropout, Flatten, Dense, GlobalMaxPooling2D,\n                          BatchNormalization, Input, Conv2D, GlobalAveragePooling2D,concatenate,Concatenate,MaxPool2D)\nfrom keras.callbacks import ModelCheckpoint,EarlyStopping\nfrom keras import metrics,applications,optimizers\nfrom keras import backend as K\nfrom keras.models import Sequential\n!pip install -q efficientnet\nimport efficientnet.tfkeras as efn","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Part I Custom CNN Implementation","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"IMAGE_PATH = \"../input/siim-isic-melanoma-classification/\"\n\ntrain_df = pd.read_csv('../input/siim-isic-melanoma-classification/train.csv')\ntest_df = pd.read_csv('../input/siim-isic-melanoma-classification/test.csv')\n\n\n#Training data\nprint('Training data shape: ', train_df.shape)\nprint(' ')\nprint('Test data shape: ', test_df.shape)\n\ndisplay('**TRAINING DATA**')\ndisplay(train_df.info())\ndisplay('**TEST DATA**')\ndisplay(test_df.info())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.sample(20)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"fig = px.scatter_matrix(train_df,dimensions=[\"age_approx\", \"sex\", \"target\",'anatom_site_general_challenge','diagnosis'], color=\"benign_malignant\")\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"print(train_df.benign_malignant.value_counts())\nsns.countplot(x = 'benign_malignant',data=train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_sub = train_df.anatom_site_general_challenge.value_counts().reset_index()\ndf_sub.columns = ['anatom_site_general_challenge', 'Counts']\nfig = px.bar(df_sub, x=\"anatom_site_general_challenge\", y=\"Counts\", color='anatom_site_general_challenge', barmode='group',\n             height=400)\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_sub = train_df.diagnosis.value_counts().reset_index()\ndf_sub.columns = ['diagnosis', 'Counts']\nfig = px.bar(df_sub, x=\"diagnosis\", y=\"Counts\", color='diagnosis', barmode='group',\n             height=400)\nfig.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"fig = plt.figure(figsize=(15,8),)\nax=sns.kdeplot(train_df.loc[(train_df['sex'] == 'male'),'age_approx'] , color='gray',shade=True,label='Male')\nax=sns.kdeplot(train_df.loc[(train_df['sex'] == 'female'),'age_approx'] , color='g',shade=True, label='Female')\nplt.title('Age Distribution', fontsize = 25, pad = 40)\nplt.ylabel(\"Frequency of Age\", fontsize = 15, labelpad = 20)\nplt.xlabel(\"Age\", fontsize = 15, labelpad = 20);","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"fig = px.histogram(train_df, x=\"age_approx\", y=\"benign_malignant\", color=\"benign_malignant\", marginal=\"rug\")\nfig.show()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"df = train_df.copy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ndef get_df():\n    base_image_dir = '../input/siim-isic-melanoma-classification/jpeg/'\n    train_dir = os.path.join(base_image_dir,'train/')\n    train = pd.read_csv('../input/siim-isic-melanoma-classification/train.csv')\n    df_0=train[train['target']==0].sample(2000)\n    df_1=train[train['target']==1]\n    df=pd.concat([df_0,df_1])\n    df['path'] = df['image_name'].map(lambda x: os.path.join(train_dir,'{}.jpg'.format(x)))\n    df[\"image_name\"]=train_df[\"image_name\"].apply(lambda x:x+\".jpg\")\n    df['image'] = df['path'].map(lambda x: np.asarray(Image.open(x).resize((100,75))))\n    df['target'] = df['target'].astype(str)\n    return df\n\ndf = get_df()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"df['image'].map(lambda x: x.shape).value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def display_samples(df, columns=4, rows=3):\n    fig=plt.figure(figsize=(5*columns, 4*rows))\n\n    for i in range(columns*rows):\n        image_path = df.loc[i,'image_name']\n        image_id = df.loc[i,'image_name']\n        img = cv2.imread(f'../input/siim-isic-melanoma-classification/jpeg/train/{image_path}.jpg')\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        \n        fig.add_subplot(rows, columns, i+1)\n        plt.title(image_id)\n        plt.imshow(img)\n    \n    plt.tight_layout()\n\ndisplay_samples(train_df)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y = df.target\n\nfrom sklearn.model_selection import train_test_split\nfrom keras.utils.np_utils import to_categorical\nx_train_o, x_test_o, y_train, y_test = train_test_split(df, y, test_size=0.25)\n\nx_train = np.asarray(x_train_o['image'].tolist())\nx_test = np.asarray(x_test_o['image'].tolist())\n\nx_train_mean = np.mean(x_train)\nx_train_std = np.std(x_train)\n\nx_test_mean = np.mean(x_test)\nx_test_std = np.std(x_test)\n\nx_train = (x_train - x_train_mean)/x_train_std\nx_test = (x_test - x_test_mean)/x_test_std","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Shape of X_train : ',x_train.shape)\nprint('Shape of y_train : ',y_train.shape)\nprint('===============================================')\nprint('Shape of X_val : ',x_test.shape)\nprint('Shape of y_val : ',y_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"input_shape = (75, 100, 3)\n\nmodel = Sequential()\nmodel.add(Conv2D(32, kernel_size=(3, 3),\n                 activation='relu',\n                 input_shape=input_shape))\nmodel.add(Conv2D(64, (3, 3), activation='relu'))\nmodel.add(MaxPool2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(1, activation='sigmoid'))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(loss=keras.losses.binary_crossentropy,\n              optimizer=optimizers.Adam(lr=0.001),\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"checkpoint = ModelCheckpoint(\"model1.h5\", monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)\nearly = EarlyStopping(monitor='val_loss', min_delta=0, patience=5, verbose=1, mode='auto')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 32 # Todo: experiment with this variable more\nepochs = 50\n\nhistory = model.fit(x_train, y_train,\n          batch_size=batch_size,\n          epochs=epochs,\n          callbacks = [checkpoint, early],\n          verbose=1,\n          validation_data=(x_test, y_test))\n\nscore = model.evaluate(x_test, y_test, verbose=0)\nprint('Test loss:', score[0])\nprint('Test accuracy:', score[1])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(2,1)\nax[0].plot(history.history['loss'], color='b', label=\"Training loss\")\nax[0].plot(history.history['val_loss'], color='r', label=\"Validation loss\",axes =ax[0])\nlegend = ax[0].legend(loc='best', shadow=True)\n\nax[1].plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nax[1].plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\nlegend = ax[1].legend(loc='best', shadow=True)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"submission=pd.read_csv('/kaggle/input/siim-isic-melanoma-classification/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"test_dir = IMAGE_PATH + 'jpeg/test/'\ntest_data=[]\nfor i in range(test_df.shape[0]):\n    test_data.append(test_dir + test_df['image_name'].iloc[i]+'.jpg')\ndf_test=pd.DataFrame(test_data)\ndf_test.columns=['images']","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"target=[]\nfor path in df_test['images']:\n    img=cv2.imread(str(path))\n    img = cv2.resize(img, (75,100))\n    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n    img = img.astype(np.float32)/255.\n    img=np.reshape(img,(1,75,100,3))\n    prediction=model.predict(img)\n    target.append(prediction[0][0])\n\nsubmission['target']=target","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Part-II EfficientNetB7 Implementation","execution_count":null},{"metadata":{"trusted":true,"_kg_hide-input":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom tensorflow.keras.models import Sequential","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X = df.path.values\ny = np.float32(df.target.values)\n\nX_train, X_test, y_train, y_test =train_test_split(X, y, test_size=0.1, random_state=43)\nprint('done!')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"##### TPU Setup","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"AUTO = tf.data.experimental.AUTOTUNE\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy()\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 4 * strategy.num_replicas_in_sync\nSTEPS_PER_EPOCH = y_train.shape[0] // BATCH_SIZE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(filename, label=None, image_size=(100,75)):\n    bits = tf.io.read_file(filename)\n    image = tf.image.decode_jpeg(bits, channels=3)\n    image = tf.cast(image, tf.float32) / 255.0\n    image = tf.image.resize(image, image_size)\n    \n    if label is None:\n        return image\n    else:\n        return image, label\n\ndef data_augment(image, label=None):\n    image = tf.image.random_flip_left_right(image)\n    image = tf.image.random_flip_up_down(image)\n    image = tf.image.random_brightness(image, max_delta=0.3)\n    \n    \n    if label is None:\n        return image\n    else:\n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataset = (\n    tf.data.Dataset.from_tensor_slices((X_train, y_train))\n    .map(decode_image,num_parallel_calls=AUTO)\n    .map(data_augment,num_parallel_calls=AUTO)\n    .repeat()\n    .shuffle(256)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)\n\nvalid_dataset = (\n    tf.data.Dataset\n    .from_tensor_slices((X_test, y_test))\n    .map(decode_image,num_parallel_calls=AUTO)\n    .cache()\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_lrfn(lr_start=0.00001, lr_max=0.00005,lr_min=0.00001, lr_rampup_epochs=5,lr_sustain_epochs=0, lr_exp_decay=.8):\n    \n    lr_max = lr_max * strategy.num_replicas_in_sync\n    def lrfn(epoch):\n        if epoch < lr_rampup_epochs:\n            lr = (lr_max - lr_start) / lr_rampup_epochs * epoch + lr_start\n        elif epoch < lr_rampup_epochs + lr_sustain_epochs:\n            lr = lr_max\n        else:\n            lr = (lr_max - lr_min) *\\\n                 lr_exp_decay**(epoch - lr_rampup_epochs- lr_sustain_epochs) + lr_min\n        return lr\n    return lrfn","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"lrfn = build_lrfn()\nlr_schedule = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose=1)\nEarlyStopping=tf.keras.callbacks.EarlyStopping(monitor=\"val_loss\",patience=10,verbose=True, mode=\"min\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def Eff_B7_NS():\n    model_EfficientNetB7_NS = Sequential([efn.EfficientNetB7(input_shape=(100,75,3),weights='noisy-student',include_top=False),\n                                 tf.keras.layers.GlobalAveragePooling2D(),\n                                 tf.keras.layers.Dense(128,activation='relu'),\n                                 tf.keras.layers.Dense(64,activation='relu'),\n                                 tf.keras.layers.Dense(1,activation='sigmoid')])               \n    model_EfficientNetB7_NS.compile(optimizer='Adam',loss = 'binary_crossentropy',metrics=['binary_accuracy'])\n    \n    \n    return model_EfficientNetB7_NS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model_Eff_B7_NS=Eff_B7_NS()\n    \nmodel_Eff_B7_NS.summary()\n#del model_Eff_B7_NS\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EfficientNetB7_NS = model_Eff_B7_NS.fit(train_dataset,\n                    epochs=10,\n                    callbacks=[lr_schedule,EarlyStopping],\n                    steps_per_epoch=STEPS_PER_EPOCH,\n                    validation_data=valid_dataset)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure()\nfig,(ax1, ax2)=plt.subplots(1,2,figsize=(19,7))\nax1.plot(EfficientNetB7_NS.history['loss'])\nax1.plot(EfficientNetB7_NS.history['val_loss'])\nax1.legend(['training','validation'])\nax1.set_title('loss')\nax1.set_xlabel('epoch')\n\nax2.plot(EfficientNetB7_NS.history['binary_accuracy'])\nax2.plot(EfficientNetB7_NS.history['val_binary_accuracy'])\nax2.legend(['training','validation'])\nax2.set_title('Acurracy')\nax2.set_xlabel('epoch')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## END","execution_count":null}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}