{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nimport glob\nimport cv2\nfrom tqdm import tqdm\nfrom PIL import Image, ImageFile\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.preprocessing.image import *\n\nfrom sklearn import model_selection\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom plotly.offline import iplot\nimport cufflinks as cf\ncf.go_offline()\ncf.set_config_file(offline=False, world_readable=True)\nimport warnings\nwarnings.filterwarnings('ignore')\n\n\nfrom kaggle_datasets import KaggleDatasets\n\nfrom IPython.core.interactiveshell import InteractiveShell\nInteractiveShell.ast_node_interactivity = \"all\"\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-27T16:56:41.605971Z","iopub.execute_input":"2021-07-27T16:56:41.606279Z","iopub.status.idle":"2021-07-27T16:56:41.629535Z","shell.execute_reply.started":"2021-07-27T16:56:41.606250Z","shell.execute_reply":"2021-07-27T16:56:41.628566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading and Exploring Dataset","metadata":{}},{"cell_type":"code","source":"train_df = pd.read_csv('../input/siim-isic-melanoma-classification/train.csv')\ntrain_df.shape","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.630604Z","iopub.execute_input":"2021-07-27T16:56:41.630903Z","iopub.status.idle":"2021-07-27T16:56:41.716920Z","shell.execute_reply.started":"2021-07-27T16:56:41.630876Z","shell.execute_reply":"2021-07-27T16:56:41.715848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.720894Z","iopub.execute_input":"2021-07-27T16:56:41.721227Z","iopub.status.idle":"2021-07-27T16:56:41.738787Z","shell.execute_reply.started":"2021-07-27T16:56:41.721198Z","shell.execute_reply":"2021-07-27T16:56:41.737449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['target'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.740577Z","iopub.execute_input":"2021-07-27T16:56:41.740967Z","iopub.status.idle":"2021-07-27T16:56:41.755039Z","shell.execute_reply.started":"2021-07-27T16:56:41.740928Z","shell.execute_reply":"2021-07-27T16:56:41.753704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##checking for missing vals\ntrain_df.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.756204Z","iopub.execute_input":"2021-07-27T16:56:41.756590Z","iopub.status.idle":"2021-07-27T16:56:41.789052Z","shell.execute_reply.started":"2021-07-27T16:56:41.756535Z","shell.execute_reply":"2021-07-27T16:56:41.787859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.dropna(axis=0, subset=['sex'], inplace=True)\ntrain_df.dropna(axis = 0,subset=['age_approx'], inplace=True)\ntrain_df.dropna(axis=0, subset=['anatom_site_general_challenge'], inplace=True)\n\ntrain_df.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.790665Z","iopub.execute_input":"2021-07-27T16:56:41.791005Z","iopub.status.idle":"2021-07-27T16:56:41.847460Z","shell.execute_reply.started":"2021-07-27T16:56:41.790974Z","shell.execute_reply":"2021-07-27T16:56:41.846395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.849120Z","iopub.execute_input":"2021-07-27T16:56:41.849462Z","iopub.status.idle":"2021-07-27T16:56:41.868302Z","shell.execute_reply.started":"2021-07-27T16:56:41.849430Z","shell.execute_reply":"2021-07-27T16:56:41.867291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (10,10))\ndata = train_df.benign_malignant.value_counts()\ndata.iplot(kind = 'bar', color='blue', title = 'Data Imbalance')","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.869747Z","iopub.execute_input":"2021-07-27T16:56:41.870155Z","iopub.status.idle":"2021-07-27T16:56:41.942601Z","shell.execute_reply.started":"2021-07-27T16:56:41.870122Z","shell.execute_reply":"2021-07-27T16:56:41.941260Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Exploring Image ","metadata":{}},{"cell_type":"code","source":"img = cv2.imread('../input/siim-isic-melanoma-classification/jpeg/train/ISIC_0015719.jpg')\nprint(img.shape)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:41.944364Z","iopub.execute_input":"2021-07-27T16:56:41.944871Z","iopub.status.idle":"2021-07-27T16:56:42.307676Z","shell.execute_reply.started":"2021-07-27T16:56:41.944820Z","shell.execute_reply":"2021-07-27T16:56:42.306636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preparing Dataset","metadata":{}},{"cell_type":"code","source":"##creating labels from target columns with corressponding images \ntrain_dir = '../input/siim-isic-melanoma-classification/jpeg/train/'\ntest_dir = '../input/siim-isic-melanoma-classification/jpeg/test/'\nlabels = []\ndata = []\nfor i in range(train_df.shape[0]):\n    data.append(train_dir + train_df['image_name'].iloc[i] + '.jpg')\n    labels.append(train_df['target'].iloc[i])\n\ndf = pd.DataFrame(data)\ndf.columns = ['images']\ndf['target'] = labels","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:42.311051Z","iopub.execute_input":"2021-07-27T16:56:42.311381Z","iopub.status.idle":"2021-07-27T16:56:43.206703Z","shell.execute_reply.started":"2021-07-27T16:56:42.311351Z","shell.execute_reply":"2021-07-27T16:56:43.205328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv('../input/siim-isic-melanoma-classification/test.csv')\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']","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.208091Z","iopub.execute_input":"2021-07-27T16:56:43.208431Z","iopub.status.idle":"2021-07-27T16:56:43.378007Z","shell.execute_reply.started":"2021-07-27T16:56:43.208399Z","shell.execute_reply":"2021-07-27T16:56:43.377000Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Stratified KFolds","metadata":{}},{"cell_type":"code","source":"groups_by_patient_id_list = train_df['patient_id'].copy().tolist()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.379611Z","iopub.execute_input":"2021-07-27T16:56:43.380025Z","iopub.status.idle":"2021-07-27T16:56:43.385461Z","shell.execute_reply.started":"2021-07-27T16:56:43.379983Z","shell.execute_reply":"2021-07-27T16:56:43.384797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"skf = model_selection.StratifiedKFold(n_splits=10)\nylabels = train_df.target.values\nresult = []   \nfor train_idx, val_idx in skf.split(train_df, ylabels, groups = groups_by_patient_id_list):\n    train_fold = train_df.iloc[train_idx]\n    val_fold = train_df.iloc[val_idx]\n    result.append((train_fold, val_fold))","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.386365Z","iopub.execute_input":"2021-07-27T16:56:43.386660Z","iopub.status.idle":"2021-07-27T16:56:43.435906Z","shell.execute_reply.started":"2021-07-27T16:56:43.386630Z","shell.execute_reply":"2021-07-27T16:56:43.435097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_fold_1, val_fold_1 = result[0][0],result[0][1]\ntrain_fold_2, val_fold_2 = result[1][0],result[1][1]\ntrain_fold_3, val_fold_3 = result[2][0],result[2][1]\ntrain_fold_4, val_fold_4 = result[3][0],result[3][1]\ntrain_fold_5, val_fold_5 = result[4][0],result[4][1]\n\ntrain_fold_6, val_fold_6 = result[6][0],result[6][1]\ntrain_fold_7, val_fold_7 = result[7][0],result[7][1]\ntrain_fold_8, val_fold_8 = result[8][0],result[8][1]\ntrain_fold_9, val_fold_9 = result[9][0],result[9][1]","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.436991Z","iopub.execute_input":"2021-07-27T16:56:43.437418Z","iopub.status.idle":"2021-07-27T16:56:43.451835Z","shell.execute_reply.started":"2021-07-27T16:56:43.437377Z","shell.execute_reply":"2021-07-27T16:56:43.450641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## sanity checks\nsample = train_fold_1.groupby(\"patient_id\")\nsample.get_group(\"IP_0147446\")\nsample.get_group(\"IP_0147446\").count()","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.453764Z","iopub.execute_input":"2021-07-27T16:56:43.454278Z","iopub.status.idle":"2021-07-27T16:56:43.492737Z","shell.execute_reply.started":"2021-07-27T16:56:43.454213Z","shell.execute_reply":"2021-07-27T16:56:43.491685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## TPU/GPU Initialization","metadata":{}},{"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    # TPU detection. No parameters necessary if TPU_NAME environment variable is\n    # set: this is always the case on Kaggle.\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    # Default distribution strategy in Tensorflow. Works on CPU and single GPU.\n    strategy = tf.distribute.get_strategy()\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:43.494011Z","iopub.execute_input":"2021-07-27T16:56:43.494320Z","iopub.status.idle":"2021-07-27T16:56:53.496312Z","shell.execute_reply.started":"2021-07-27T16:56:43.494291Z","shell.execute_reply":"2021-07-27T16:56:53.495536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# For tf.dataset\nAUTO = tf.data.experimental.AUTOTUNE\n\n# Data access\nGCS_PATH = KaggleDatasets().get_gcs_path('siim-isic-melanoma-classification')\n\n# Configuration\nBATCH_SIZE = 8 * strategy.num_replicas_in_sync\nimage_size = 224\nEPOCHS = 3","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:53.497293Z","iopub.execute_input":"2021-07-27T16:56:53.497552Z","iopub.status.idle":"2021-07-27T16:56:54.027008Z","shell.execute_reply.started":"2021-07-27T16:56:53.497526Z","shell.execute_reply":"2021-07-27T16:56:54.026068Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Creating functions that will take in an image name and return image path, this we will apply to the training and validation folds, that we have created**\n**Implementation courtesy of this awesome [kernel](https://www.kaggle.com/reighns/groupkfold-and-stratified-groupkfold-efficientnet/comments)**","metadata":{}},{"cell_type":"code","source":"def train_image_paths(img_name):\n    return GCS_PATH + '/jpeg/train/' + img_name + '.jpg'\n\ndef test_image_paths(image_name):\n    return GCS_PATH + '/jpeg/test/' + img_name + '.jpg'\n\n##applying this to folds data which we created\ntrain_path_fold_1 = train_fold_1.image_name.apply(train_image_paths).values\nval_path_fold_1 = val_fold_1.image_name.apply(train_image_paths).values\n\ntrain_path_fold_2 = train_fold_2.image_name.apply(train_image_paths).values\nval_path_fold_2 = val_fold_2.image_name.apply(train_image_paths).values\n\ntrain_path_fold_3 = train_fold_3.image_name.apply(train_image_paths).values\nval_path_fold_3 = val_fold_3.image_name.apply(train_image_paths).values\n\ntrain_path_fold_4 = train_fold_4.image_name.apply(train_image_paths).values\nval_path_fold_4 = val_fold_4.image_name.apply(train_image_paths).values\n\ntrain_path_fold_5 = train_fold_5.image_name.apply(train_image_paths).values\nval_path_fold_5 = val_fold_5.image_name.apply(train_image_paths).values\n\n\ntrain_labels_fold_1 = train_fold_1.target.values\nval_labels_fold_1 = val_fold_1.target.values","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.028255Z","iopub.execute_input":"2021-07-27T16:56:54.028795Z","iopub.status.idle":"2021-07-27T16:56:54.137589Z","shell.execute_reply.started":"2021-07-27T16:56:54.028744Z","shell.execute_reply":"2021-07-27T16:56:54.136818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preparing Dataset\n- **Using decode_image function from tensorflow, we will generate labels, with the corresponding paths provided, it also will resize the image**","metadata":{}},{"cell_type":"code","source":"def decode_image(filename, label=None, image_size=(image_size,image_size)):\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, size = image_size)\n    \n    if label is None:\n        return image\n    else:\n        return image, label\n\n##augmenting the data\ndef 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_saturation(image, lower = 1, upper = 3)\n#     image = tf.image.adjust_brightness(image, delta = 0.3)\n    image = tf.image.random_contrast(image, lower = 1, upper = 2)\n    if label is None:\n        return image\n    else:\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.138740Z","iopub.execute_input":"2021-07-27T16:56:54.139220Z","iopub.status.idle":"2021-07-27T16:56:54.146108Z","shell.execute_reply.started":"2021-07-27T16:56:54.139173Z","shell.execute_reply":"2021-07-27T16:56:54.145403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Let's check it out**","metadata":{}},{"cell_type":"code","source":"train_fold_1","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.147177Z","iopub.execute_input":"2021-07-27T16:56:54.147636Z","iopub.status.idle":"2021-07-27T16:56:54.181646Z","shell.execute_reply.started":"2021-07-27T16:56:54.147597Z","shell.execute_reply":"2021-07-27T16:56:54.180477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_filename = 'gs://kds-5dd48bdf94d283b2157eff515b17b1a840a9133121124719ad41d5c4/jpeg/train/ISIC_1102075.jpg' \nsample_label = 0\nimage_size = 224\n\n# 1. tf.io_read_file takes in a Tensor of type string and outputs a ensor of type string. \n#    Reads and outputs the entire contents of the input filename. \nbits = tf.io.read_file(sample_filename)\n\n# 2. Decode a JPEG-encoded image to a uint8 tensor. You can also use tf.io.decode_jpeg but according to \n#    tensorflow's website, it might be cleaner to use tf.image.decode_jpeg\nimage = tf.image.decode_jpeg(bits, channels=3)\n\nimage.shape  # outputs TensorShape([4000, 6000, 3])\n\n# 3. image = tf.cast(image, tf.float32) / 255.0 is easy to understand, it takes in \n#    an image, and cast the image into the data type you want. Here we also normalized by dividing by 255.\n\nimage = tf.cast(image, tf.float32) / 255.0\n\n\n# 4. image = tf.image.resize(image, image_size) is also easy to understand. We merely resize this image to the image_size we wish for.\n#    take note in our function defined above, the argument image_size is a tuple already. So we must pass in a tuple of our desired image_size.\nimage = tf.image.resize(image, size = (image_size, image_size))\n\nimage.shape","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.183221Z","iopub.execute_input":"2021-07-27T16:56:54.183917Z","iopub.status.idle":"2021-07-27T16:56:54.380548Z","shell.execute_reply.started":"2021-07-27T16:56:54.183852Z","shell.execute_reply":"2021-07-27T16:56:54.379846Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Next Step, I will be using [tf.data.Dataset](https://www.tensorflow.org/api_docs/python/tf/data/Dataset)\n\nAccording to the tensorflow website: *The tf.data.Dataset* API supports writing descriptive and efficient input pipelines. Dataset usage follows a common pattern:\n\nCreate a source dataset from your input data.\nApply dataset transformations to preprocess the data.\nIterate over the dataset and process the elements.\nIteration happens in a streaming fashion, so the full dataset does not need to fit into memory.","metadata":{}},{"cell_type":"code","source":"# train_labels_fold_1 = train_fold_1.target.values\nsample_data = tf.data.Dataset.from_tensor_slices((train_path_fold_1, train_labels_fold_1))\nfor data in sample_data:\n    print(len(data))\n    print(data[0])\n    print(data[1])   \n    break","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.381549Z","iopub.execute_input":"2021-07-27T16:56:54.382025Z","iopub.status.idle":"2021-07-27T16:56:54.409877Z","shell.execute_reply.started":"2021-07-27T16:56:54.381994Z","shell.execute_reply":"2021-07-27T16:56:54.408854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = tf.data.Dataset.from_tensor_slices((train_path_fold_1, train_labels_fold_1)).map(decode_image, num_parallel_calls=AUTO)\nfor data in dataset:\n    print(len(data))\n    print(data[0])\n    print(data[1])\n    break","metadata":{"execution":{"iopub.status.busy":"2021-07-27T16:56:54.411147Z","iopub.execute_input":"2021-07-27T16:56:54.411855Z","iopub.status.idle":"2021-07-27T16:56:55.940526Z","shell.execute_reply.started":"2021-07-27T16:56:54.411817Z","shell.execute_reply":"2021-07-27T16:56:55.939425Z"},"trusted":true},"execution_count":null,"outputs":[]}]}