{"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":"markdown","source":"# GAN to assist in Melanoma Detection\n\n[melanoma competition](https://www.kaggle.com/c/siim-isic-melanoma-classification/data)\n","metadata":{}},{"cell_type":"code","source":"import glob\nimport os\nimport time\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nprint(tf.__version__)\n\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.applications.mobilenet_v2 import preprocess_input\nfrom IPython import display","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:02.185135Z","iopub.execute_input":"2021-11-11T11:31:02.18574Z","iopub.status.idle":"2021-11-11T11:31:02.19794Z","shell.execute_reply.started":"2021-11-11T11:31:02.185688Z","shell.execute_reply":"2021-11-11T11:31:02.19645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Why use GAN?\n\n* Dataset target classes are highly imbalance, only 1.76% of malignant\n\n## Interesting topics to try\n\n1. GAN to generate additional malignant class images\n2. Using VAEs to train anomaly detection from benign (non lethal) lesion\n3. GAN to generate SR and additional attention based cropping for train a better lesion classifier and detector","metadata":{}},{"cell_type":"code","source":"# asign some paths\ntrain_csv_path = '../input/siim-isic-melanoma-classification/train.csv'\ntest_csv_path = '../input/siim-isic-melanoma-classification/test.csv'\nimage_path = '../input/siim-isic-melanoma-classification/jpeg/train/'\n\n# read the csv data using pandas\ntrain_df = pd.read_csv(train_csv_path)\ntest_df = pd.read_csv(test_csv_path)\n\nprint(\"unique values in column 'target': {}\".format(list(train_df['target'].unique())))\ntarget_dis = list(train_df['target'].value_counts())\nbenign_per = target_dis[0]/sum(target_dis)\nprint(\"target count distribution: {}\".format(target_dis))\nprint(\"benign percentage: {:.2f}% vs malignant: {:.2f}%\".format(benign_per*100, (1-benign_per)*100))","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:02.20048Z","iopub.execute_input":"2021-11-11T11:31:02.201225Z","iopub.status.idle":"2021-11-11T11:31:02.303532Z","shell.execute_reply.started":"2021-11-11T11:31:02.201131Z","shell.execute_reply":"2021-11-11T11:31:02.302149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1. DCGAN to generate Malignant images\n\nSource\n* [code](https://www.tensorflow.org/tutorials/generative/dcgan) \n* [GAN-based Synthetic Medical Image Augmentation](https://arxiv.org/pdf/1803.01229.pdf)\n\nDataset\n* [JPEG 128x128](https://www.kaggle.com/cdeotte/jpeg-melanoma-128x128) melanoma from Chris Deotte\n\nProblems:\n* Generated images are nowhere near the input images\n* Maybe needs some augmentation. [Augmentation in GAN](https://arxiv.org/pdf/2006.05338v1.pdf) ","metadata":{}},{"cell_type":"code","source":"# detect and initialize TPU (ignore if using GPU)\n# try:\n#     tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n#     print('Device:', tpu.master())\n#     tf.config.experimental_connect_to_cluster(tpu)\n#     tf.tpu.experimental.initialize_tpu_system(tpu)\n#     # set distribution strategy\n#     strategy = tf.distribute.experimental.TPUStrategy(tpu)\n# except:\n#     strategy = tf.distribute.get_strategy()\n# print('Number of replicas:', strategy.num_replicas_in_sync)\n\n# # Use these params if using TPU\n# IMAGE_SIZE = [128, 128]  # used for reshaping\n# AUTOTUNE = tf.data.experimental.AUTOTUNE\n# GCS_PATH = KaggleDatasets().get_gcs_path('melanoma-128x128')  # store dataset to gcs buckets for the TPU to access in cloud\n# BATCH_SIZE = 16 * strategy.num_replicas_in_sync","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:02.305288Z","iopub.execute_input":"2021-11-11T11:31:02.305809Z","iopub.status.idle":"2021-11-11T11:31:02.311678Z","shell.execute_reply.started":"2021-11-11T11:31:02.305731Z","shell.execute_reply":"2021-11-11T11:31:02.310258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Preprocess Image","metadata":{}},{"cell_type":"code","source":"path_tfrec = '../input/melanoma-128x128/'\npath_jpg = '../input/jpeg-melanoma-128x128/train/'\nIMAGE_SIZE = [128, 128]\n\nmalignant = train_df[train_df[\"target\"] == 1]  # list of malignant images\n\ndef preprocess_X():  # load the images into memory\n    X = []\n    for img in malignant.image_name.values:\n        img_name = path_jpg + img + '.jpg'\n        i = tf.keras.preprocessing.image.load_img(img_name) #color_mode='grayscale')\n        i = tf.keras.preprocessing.image.img_to_array(i)\n        i = preprocess_input(i)  # preprocessing fits the pixel value from -127.5 to 127.5\n        X.append(i)\n    return np.array(X)  # convert to numpy array","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:02.315261Z","iopub.execute_input":"2021-11-11T11:31:02.316054Z","iopub.status.idle":"2021-11-11T11:31:02.330858Z","shell.execute_reply.started":"2021-11-11T11:31:02.316004Z","shell.execute_reply":"2021-11-11T11:31:02.329467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = preprocess_X()\nX.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:02.335288Z","iopub.execute_input":"2021-11-11T11:31:02.336316Z","iopub.status.idle":"2021-11-11T11:31:03.107678Z","shell.execute_reply.started":"2021-11-11T11:31:02.336253Z","shell.execute_reply":"2021-11-11T11:31:03.106506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Display preprocessed image","metadata":{}},{"cell_type":"code","source":"def display_img(arr):\n    i = tf.keras.preprocessing.image.array_to_img(arr)\n    plt.imshow(i, cmap='gray')\n\nplt.figure(figsize=(7,7))\nfor i in range(9):\n    plt.subplot(3,3, i+1)\n    display_img(X[i])  ","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:03.109645Z","iopub.execute_input":"2021-11-11T11:31:03.110442Z","iopub.status.idle":"2021-11-11T11:31:04.270979Z","shell.execute_reply.started":"2021-11-11T11:31:03.110365Z","shell.execute_reply":"2021-11-11T11:31:04.268078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Hyperparameters","metadata":{}},{"cell_type":"code","source":"BUFFER_SIZE = 584\nBATCH_SIZE = 32  # from 128\nEPOCHS = 50  # from 50\nnoise_dim = 200  # from 100\nnum_examples_to_generate = 9\n\n# We will reuse this seed overtime (so it's easier to visualize progress in the animated GIF)\nseed = tf.random.normal([num_examples_to_generate, noise_dim])","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:04.272923Z","iopub.execute_input":"2021-11-11T11:31:04.273758Z","iopub.status.idle":"2021-11-11T11:31:04.282458Z","shell.execute_reply.started":"2021-11-11T11:31:04.273708Z","shell.execute_reply":"2021-11-11T11:31:04.281341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Increase training data with Augmentations","metadata":{}},{"cell_type":"code","source":"def augmentation_pipeline(image):\n    image = tf.image.random_flip_left_right(image)\n#     image = tf.image.resize(image, IMAGE_RESIZE)\n    return image","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:04.284177Z","iopub.execute_input":"2021-11-11T11:31:04.284991Z","iopub.status.idle":"2021-11-11T11:31:04.294766Z","shell.execute_reply.started":"2021-11-11T11:31:04.284944Z","shell.execute_reply":"2021-11-11T11:31:04.29317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Simple dataset processing with batch and shuffle\ndef get_dataset():\n    ds = tf.data.Dataset.from_tensor_slices(X)\n#     ds = ds.map(augmentation_pipeline)\n    ds = ds.shuffle(BUFFER_SIZE)\n    ds = ds.batch(BATCH_SIZE)\n    return ds\n    \ntrain_dataset = get_dataset()\n# inspect a batch\nn_batch = 0\nfor i in train_dataset:\n    n_batch += 1\nprint(f\"num of batch: {n_batch}, shape of each batch: {i.shape}\")","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:04.296735Z","iopub.execute_input":"2021-11-11T11:31:04.297717Z","iopub.status.idle":"2021-11-11T11:31:04.602127Z","shell.execute_reply.started":"2021-11-11T11:31:04.297665Z","shell.execute_reply":"2021-11-11T11:31:04.600469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create Generator and Discriminator","metadata":{}},{"cell_type":"code","source":"def make_generator_model():\n    model = tf.keras.Sequential()   # dense unit is configured to match soon tobe reshaped layer\n    model.add(layers.Dense(32*32*256, use_bias=False, input_shape=(noise_dim,)))  # starts with 1D array, input is noise array of 100\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    # 32x32 bcz there's 2 conv2D. 128/2/2=32\n    model.add(layers.Reshape((32, 32, 256)))\n\n    model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))\n    model.add(layers.BatchNormalization())\n    model.add(layers.LeakyReLU())\n\n    model.add(layers.Conv2DTranspose(3, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))\n\n    return model\n\n# create the generator\ngenerator = make_generator_model()\ngenerator.summary()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:04.604569Z","iopub.execute_input":"2021-11-11T11:31:04.605363Z","iopub.status.idle":"2021-11-11T11:31:04.784978Z","shell.execute_reply.started":"2021-11-11T11:31:04.60531Z","shell.execute_reply":"2021-11-11T11:31:04.781501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Display an image generated from noise (G still not trained yet)","metadata":{}},{"cell_type":"code","source":"noise = tf.random.normal([1, noise_dim])  # outputs random values from normal dist. to a certain array shape\ngenerated_image = generator(noise, training=False)  # interesting, doesn't need .fit .predict or anything\n\nplt.imshow(generated_image[0, :, :, :]*255)#, cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:04.78771Z","iopub.execute_input":"2021-11-11T11:31:04.788215Z","iopub.status.idle":"2021-11-11T11:31:05.003315Z","shell.execute_reply.started":"2021-11-11T11:31:04.788168Z","shell.execute_reply":"2021-11-11T11:31:05.002104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_discriminator_model():\n    model = tf.keras.Sequential()   # basic binary classification model\n    model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',\n                                     input_shape=[128, 128, 3]))\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.3))\n\n    model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))\n    model.add(layers.LeakyReLU())\n    model.add(layers.Dropout(0.3))\n\n    model.add(layers.Flatten())\n    model.add(layers.Dense(1))\n\n    return model\n\n# create D\ndiscriminator = make_discriminator_model()\nprint(discriminator.summary())","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.005189Z","iopub.execute_input":"2021-11-11T11:31:05.005659Z","iopub.status.idle":"2021-11-11T11:31:05.090799Z","shell.execute_reply.started":"2021-11-11T11:31:05.005608Z","shell.execute_reply":"2021-11-11T11:31:05.087493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let the untrained D predict that generated image","metadata":{}},{"cell_type":"code","source":"decision = discriminator(generated_image)\nprint(decision)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.096259Z","iopub.execute_input":"2021-11-11T11:31:05.096711Z","iopub.status.idle":"2021-11-11T11:31:05.109611Z","shell.execute_reply.started":"2021-11-11T11:31:05.096671Z","shell.execute_reply":"2021-11-11T11:31:05.107741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Define Loss and Optimizer","metadata":{}},{"cell_type":"code","source":"# This method returns a helper function to compute cross entropy loss (prob between 0 and 1)\ncross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.111029Z","iopub.execute_input":"2021-11-11T11:31:05.111491Z","iopub.status.idle":"2021-11-11T11:31:05.117193Z","shell.execute_reply.started":"2021-11-11T11:31:05.111443Z","shell.execute_reply":"2021-11-11T11:31:05.115605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Discriminator Loss\nmeasures how well D distinguish real and fake images. It compares the discriminator's predictions on real images to an array of 1s, and the discriminator's predictions on fake (generated) images to an array of 0s.","metadata":{}},{"cell_type":"code","source":"def discriminator_loss(real_output, fake_output):\n    # ones_like creates array of ones with similar shape as the input array\n    real_loss = cross_entropy(tf.ones_like(real_output), real_output)\n    fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)\n    total_loss = real_loss + fake_loss\n    return total_loss","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.119701Z","iopub.execute_input":"2021-11-11T11:31:05.120321Z","iopub.status.idle":"2021-11-11T11:31:05.132856Z","shell.execute_reply.started":"2021-11-11T11:31:05.120264Z","shell.execute_reply":"2021-11-11T11:31:05.131512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Generator Loss\nMeasures how well G can trick D. If G is performing well, D will classify fake images as 1 (real)\nthe discriminator will classify the fake images as real (or 1). Here, we will compare the discriminators decisions on the generated images to an array of 1s. Here, we will compare the discriminators decisions on the generated images to an array of 1s.","metadata":{}},{"cell_type":"code","source":"def generator_loss(fake_output):\n    return cross_entropy(tf.ones_like(fake_output), fake_output)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.134733Z","iopub.execute_input":"2021-11-11T11:31:05.1355Z","iopub.status.idle":"2021-11-11T11:31:05.143614Z","shell.execute_reply.started":"2021-11-11T11:31:05.135445Z","shell.execute_reply":"2021-11-11T11:31:05.142037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Optimizers","metadata":{}},{"cell_type":"code","source":"generator_optimizer = tf.keras.optimizers.Adam(1e-4)  # but here they use the same Adam anyway\ndiscriminator_optimizer = tf.keras.optimizers.Adam(1e-4)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.146594Z","iopub.execute_input":"2021-11-11T11:31:05.147619Z","iopub.status.idle":"2021-11-11T11:31:05.155676Z","shell.execute_reply.started":"2021-11-11T11:31:05.147569Z","shell.execute_reply":"2021-11-11T11:31:05.154224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create callbacks","metadata":{}},{"cell_type":"code","source":"checkpoint_dir = './training_checkpoints'\ncheckpoint_prefix = os.path.join(checkpoint_dir, \"ckpt\")\ncheckpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer,\n                                 discriminator_optimizer=discriminator_optimizer,\n                                 generator=generator,\n                                 discriminator=discriminator)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.15797Z","iopub.execute_input":"2021-11-11T11:31:05.159139Z","iopub.status.idle":"2021-11-11T11:31:05.176485Z","shell.execute_reply.started":"2021-11-11T11:31:05.159088Z","shell.execute_reply":"2021-11-11T11:31:05.175235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Defining training loop\n\nThe training loop begins with generator receiving a random seed as input. That seed is used to produce an image. The discriminator is then used to classify real images (drawn from the training set) and fake images (produced by the generator). The loss is calculated for each of these models, and the gradients are used to update the generator and discriminator.","metadata":{}},{"cell_type":"code","source":"# Notice the use of `tf.function`\n# This annotation causes the function to be \"compiled\".\n@tf.function\ndef train_step(images):\n    noise = tf.random.normal([BATCH_SIZE, noise_dim])\n\n    with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:\n        generated_images = generator(noise, training=True)\n        real_output = discriminator(images, training=True)\n        fake_output = discriminator(generated_images, training=True)\n\n        gen_loss = generator_loss(fake_output)\n        disc_loss = discriminator_loss(real_output, fake_output)\n\n    gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)\n    gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)\n\n    generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))\n    discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.18237Z","iopub.execute_input":"2021-11-11T11:31:05.182758Z","iopub.status.idle":"2021-11-11T11:31:05.240856Z","shell.execute_reply.started":"2021-11-11T11:31:05.182728Z","shell.execute_reply":"2021-11-11T11:31:05.239898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_and_save_images(model, epoch, test_input):\n    # Notice `training` is set to False.\n    # This is so all layers run in inference mode (batchnorm).\n    predictions = model(test_input, training=False)  # same as num_examples_to_generate\n    fig = plt.figure(figsize=(12,12))\n\n    for i in range(predictions.shape[0]):\n        plt.subplot(3, 3, i+1)\n        plt.imshow(predictions[i, :, :, :] * 127.5 + 127.5, cmap='gray')\n        plt.axis('off')\n\n    #plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.24555Z","iopub.execute_input":"2021-11-11T11:31:05.246281Z","iopub.status.idle":"2021-11-11T11:31:05.256928Z","shell.execute_reply.started":"2021-11-11T11:31:05.246229Z","shell.execute_reply":"2021-11-11T11:31:05.255579Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(dataset, epochs):\n    for epoch in range(epochs):\n        start = time.time()\n\n        for image_batch in dataset:\n            train_step(image_batch)\n\n        # Produce images for the GIF as we go\n        display.clear_output(wait=True)\n        generate_and_save_images(generator,\n                                 epoch + 1,\n                                 seed)\n\n        # Save the model every 15 epochs\n        if (epoch + 1) % 15 == 0:\n            checkpoint.save(file_prefix = checkpoint_prefix)\n\n        print ('Time for epoch {} is {} sec'.format(epoch + 1, time.time()-start))\n\n        # Generate after the final epoch\n        display.clear_output(wait=True)\n        generate_and_save_images(generator, epochs, seed)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.259342Z","iopub.execute_input":"2021-11-11T11:31:05.259889Z","iopub.status.idle":"2021-11-11T11:31:05.272806Z","shell.execute_reply.started":"2021-11-11T11:31:05.259842Z","shell.execute_reply":"2021-11-11T11:31:05.271371Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train(train_dataset, EPOCHS)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:31:05.274703Z","iopub.execute_input":"2021-11-11T11:31:05.275468Z","iopub.status.idle":"2021-11-11T11:33:03.132759Z","shell.execute_reply.started":"2021-11-11T11:31:05.275419Z","shell.execute_reply":"2021-11-11T11:33:03.131546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. GAN for anomali detection\n\n* Anomali detection in Alzheimer Disease with GAN\n* SHOW RESULTS\n\n* Also other research that has anomali results: HERE HERE and HERE\n* Very effective when positive samples are rare, it's also a how doctors learn to classify\n* But in melanoma, is it really effective? since the difference between benign and malignant images can sometimes be **very subtle**","metadata":{}},{"cell_type":"markdown","source":"### 2.1 Papers on anomali detection\n\n* [Lesion detection in Brain MRI with constrained adversarial auto-encoder](https://arxiv.org/pdf/1806.04972.pdf)\n* ","metadata":{}},{"cell_type":"code","source":"benign = train_df[train_df[\"target\"] == 0]\nmalignant = train_df[train_df[\"target\"] == 1]\n","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2021-11-11T11:33:03.134648Z","iopub.execute_input":"2021-11-11T11:33:03.135571Z","iopub.status.idle":"2021-11-11T11:33:03.150476Z","shell.execute_reply.started":"2021-11-11T11:33:03.135519Z","shell.execute_reply":"2021-11-11T11:33:03.14901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_img(target, n=49):\n    img_name = target.image_name.values\n    ex_img = np.random.choice(img_name, n)  # grab n number of images\n    plt.figure(figsize=(15,15))\n    for i in range(n):\n        plt.plot(4,4  , i + 1)\n        img = plt.imread(image_path + ex_img[i]+'.jpg')\n        plt.savefig('/kaggle/working/malignant_gans_generated/GAN_img_{:04d}.jpg'.format(i))\n        plt.imshow(img, cmap='gray')\n        plt.axis('off')\n    plt.tight_layout()\n               \n        # plt.savefig(\"result/outputt.jpg\")\n","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.152202Z","iopub.execute_input":"2021-11-11T11:33:03.152932Z","iopub.status.idle":"2021-11-11T11:33:03.164998Z","shell.execute_reply.started":"2021-11-11T11:33:03.152885Z","shell.execute_reply":"2021-11-11T11:33:03.163693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#clear *image_at_epoch","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.167372Z","iopub.execute_input":"2021-11-11T11:33:03.16805Z","iopub.status.idle":"2021-11-11T11:33:03.173884Z","shell.execute_reply.started":"2021-11-11T11:33:03.168006Z","shell.execute_reply":"2021-11-11T11:33:03.172236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#os.mkdir('/kaggle/working/malignant_gans_generated/')","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.176055Z","iopub.execute_input":"2021-11-11T11:33:03.176782Z","iopub.status.idle":"2021-11-11T11:33:03.207273Z","shell.execute_reply.started":"2021-11-11T11:33:03.176734Z","shell.execute_reply":"2021-11-11T11:33:03.205703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#import shutil\n#shutil.rmtree(\"/kaggle/working\")","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.208983Z","iopub.status.idle":"2021-11-11T11:33:03.21Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(benign)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.212005Z","iopub.status.idle":"2021-11-11T11:33:03.21405Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show_img(benign)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.215795Z","iopub.status.idle":"2021-11-11T11:33:03.216991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_img(malignant)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:29.071495Z","iopub.execute_input":"2021-11-11T11:33:29.071895Z","iopub.status.idle":"2021-11-11T11:45:48.99424Z","shell.execute_reply.started":"2021-11-11T11:33:29.071861Z","shell.execute_reply":"2021-11-11T11:45:48.993096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#malignant.savefig(\"../input/siim-isic-melanoma-classification/jpeg/train/picture.jpg\")","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:33:03.221596Z","iopub.status.idle":"2021-11-11T11:33:03.222727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import re\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly\nimport plotly.graph_objects as go\nimport cv2\nimport tensorflow as tf\nfrom kaggle_datasets import KaggleDatasets\nfrom functools import partial\nimport sklearn\nfrom tqdm import tqdm_notebook as tqdm\nimport gc\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:33:55.829791Z","iopub.execute_input":"2021-11-11T12:33:55.830074Z","iopub.status.idle":"2021-11-11T12:34:01.191511Z","shell.execute_reply.started":"2021-11-11T12:33:55.830041Z","shell.execute_reply":"2021-11-11T12:34:01.190731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nexcept:\n    strategy = tf.distribute.get_strategy()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:44.697082Z","iopub.execute_input":"2021-11-11T12:34:44.697418Z","iopub.status.idle":"2021-11-11T12:34:44.709659Z","shell.execute_reply.started":"2021-11-11T12:34:44.697389Z","shell.execute_reply":"2021-11-11T12:34:44.708888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Device:', tpu.master())\nprint('Number of replicas:', strategy.num_replicas_in_sync)\nprint(\"Version of Tensorflow used : \", tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:35:01.865047Z","iopub.execute_input":"2021-11-11T12:35:01.865383Z","iopub.status.idle":"2021-11-11T12:35:01.890187Z","shell.execute_reply.started":"2021-11-11T12:35:01.865351Z","shell.execute_reply":"2021-11-11T12:35:01.889005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"code","source":"BATCH_SIZE = 16 * strategy.num_replicas_in_sync\nIMAGE_SIZE = [1024, 1024]\nSHAPE = [256, 256]","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:03.858773Z","iopub.execute_input":"2021-11-11T12:34:03.859095Z","iopub.status.idle":"2021-11-11T12:34:04.157626Z","shell.execute_reply.started":"2021-11-11T12:34:03.859066Z","shell.execute_reply":"2021-11-11T12:34:04.156329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = pd.DataFrame(pd.read_csv(\"../input/siim-isic-melanoma-classification/train.csv\"))\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.158895Z","iopub.status.idle":"2021-11-11T12:34:04.159635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.DataFrame(pd.read_csv(\"../input/siim-isic-melanoma-classification/test.csv\"))\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.261442Z","iopub.execute_input":"2021-11-11T12:34:04.261692Z","iopub.status.idle":"2021-11-11T12:34:04.317832Z","shell.execute_reply.started":"2021-11-11T12:34:04.261666Z","shell.execute_reply":"2021-11-11T12:34:04.317186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = \"/kaggle/input/siim-isic-melanoma-classification/jpeg/train/\"","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.398951Z","iopub.execute_input":"2021-11-11T12:34:04.399195Z","iopub.status.idle":"2021-11-11T12:34:04.405193Z","shell.execute_reply.started":"2021-11-11T12:34:04.399171Z","shell.execute_reply":"2021-11-11T12:34:04.404511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_names = train[\"image_name\"].values + \".jpg\"\nrandom_images = [np.random.choice(image_names) for i in range(4)] # Generates a random sample from a given 1-D array\nrandom_images ","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.577437Z","iopub.execute_input":"2021-11-11T12:34:04.577714Z","iopub.status.idle":"2021-11-11T12:34:04.602726Z","shell.execute_reply.started":"2021-11-11T12:34:04.57769Z","shell.execute_reply":"2021-11-11T12:34:04.601613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_images = []","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.770296Z","iopub.execute_input":"2021-11-11T12:34:04.770564Z","iopub.status.idle":"2021-11-11T12:34:04.774576Z","shell.execute_reply.started":"2021-11-11T12:34:04.770539Z","shell.execute_reply":"2021-11-11T12:34:04.773295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (12, 8))\nfor i in range(4) : \n    plt.subplot(2, 2, i + 1) \n    image = cv2.imread(os.path.join(train_dir, random_images[i]))\n    # cv2 reads images in BGR format. Hence we convert it to RGB\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n    sample_images.append(image)\n    plt.imshow(image, cmap = \"gray\")\n    plt.grid(True)\n# Automatically adjust subplot parameters to give specified padding.\nplt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:04.934463Z","iopub.execute_input":"2021-11-11T12:34:04.934706Z","iopub.status.idle":"2021-11-11T12:34:05.101568Z","shell.execute_reply.started":"2021-11-11T12:34:04.934683Z","shell.execute_reply":"2021-11-11T12:34:05.100407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def non_local_means_denoising(image) : \n    denoised_image = cv2.fastNlMeansDenoisingColored(image, None, 10, 10, 7, 21)\n    return denoised_image","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:05.203516Z","iopub.execute_input":"2021-11-11T12:34:05.20381Z","iopub.status.idle":"2021-11-11T12:34:05.211695Z","shell.execute_reply.started":"2021-11-11T12:34:05.203782Z","shell.execute_reply":"2021-11-11T12:34:05.210933Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_image = cv2.imread(os.path.join(train_dir, random_images[0]))\n# cv2 reads images in BGR format. Hence we convert it to RGB\nsample_image = cv2.cvtColor(sample_image, cv2.COLOR_BGR2RGB)\ndenoised_image = non_local_means_denoising(sample_image)\n\n\nplt.figure(figsize = (12, 8))\nplt.subplot(1,2,1)\nplt.imshow(sample_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Normal Image\")\n\nplt.subplot(1,2,2)  \nplt.imshow(denoised_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Denoised image\")    \n# Automatically adjust subplot parameters to give specified padding.\nplt.tight_layout() ","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:05.264977Z","iopub.execute_input":"2021-11-11T12:34:05.265224Z","iopub.status.idle":"2021-11-11T12:34:05.290598Z","shell.execute_reply.started":"2021-11-11T12:34:05.2652Z","shell.execute_reply":"2021-11-11T12:34:05.28941Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def histogram_equalization(image) : \n    image_ycrcb = cv2.cvtColor(image, cv2.COLOR_RGB2YCR_CB)\n    y_channel = image_ycrcb[:,:,0] # apply local histogram processing on this channel\n    cr_channel = image_ycrcb[:,:,1]\n    cb_channel = image_ycrcb[:,:,2]\n    \n    # Local histogram equalization\n    clahe = cv2.createCLAHE(clipLimit = 2.0, tileGridSize=(8,8))\n    equalized = clahe.apply(y_channel)\n    equalized_image = cv2.merge([equalized, cr_channel, cb_channel])\n    equalized_image = cv2.cvtColor(equalized_image, cv2.COLOR_YCR_CB2RGB)\n    return equalized_image","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:05.501605Z","iopub.execute_input":"2021-11-11T12:34:05.501872Z","iopub.status.idle":"2021-11-11T12:34:05.508536Z","shell.execute_reply.started":"2021-11-11T12:34:05.501834Z","shell.execute_reply":"2021-11-11T12:34:05.507626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"equalized_image = histogram_equalization(denoised_image)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:34:05.725004Z","iopub.execute_input":"2021-11-11T12:34:05.725257Z","iopub.status.idle":"2021-11-11T12:34:05.747001Z","shell.execute_reply.started":"2021-11-11T12:34:05.725233Z","shell.execute_reply":"2021-11-11T12:34:05.745469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (12, 8))\nplt.subplot(1,3,1)\nplt.imshow(sample_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Normal Image\", fontsize = 14)\n\nplt.subplot(1,3,2)  \nplt.imshow(denoised_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"denoised image after histogram processing\", fontsize = 14)\n\nplt.subplot(1,3,3)  \nplt.imshow(equalized_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Histogram equalized image\", fontsize = 14)\n# Automatically adjust subplot parameters to give specified padding.\nplt.tight_layout()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:57:08.043251Z","iopub.execute_input":"2021-11-11T11:57:08.043687Z","iopub.status.idle":"2021-11-11T11:57:08.73061Z","shell.execute_reply.started":"2021-11-11T11:57:08.043643Z","shell.execute_reply":"2021-11-11T11:57:08.729447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def segmentation(image, k, attempts) : \n    vectorized = np.float32(image.reshape((-1, 3)))\n    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 20, 1.0)\n    res , label , center = cv2.kmeans(vectorized, k, None, criteria, attempts, cv2.KMEANS_PP_CENTERS)\n    center = np.uint8(center)\n    res = center[label.flatten()]\n    segmented_image = res.reshape((image.shape))\n    return segmented_image","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:57:23.630582Z","iopub.execute_input":"2021-11-11T11:57:23.631118Z","iopub.status.idle":"2021-11-11T11:57:23.640066Z","shell.execute_reply.started":"2021-11-11T11:57:23.631085Z","shell.execute_reply":"2021-11-11T11:57:23.638746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (12, 8))\nplt.subplot(1,1,1)\nplt.imshow(denoised_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"de Noised Image\")","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:57:30.254156Z","iopub.execute_input":"2021-11-11T11:57:30.254553Z","iopub.status.idle":"2021-11-11T11:57:30.63406Z","shell.execute_reply.started":"2021-11-11T11:57:30.254519Z","shell.execute_reply":"2021-11-11T11:57:30.632976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (12, 8))\nsegmented_image = segmentation(denoised_image, 3, 10) # k = 3, attempt = 10\nplt.subplot(1,3,1)\nplt.imshow(segmented_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Segmented Image with k = 3\")\n\nsegmented_image = segmentation(denoised_image, 4, 10) # k = 4, attempt = 10\nplt.subplot(1,3,2)\nplt.imshow(segmented_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Segmented Image with k = 4\")\n\nsegmented_image = segmentation(denoised_image, 5, 10) # k = 5, attempt = 10\nplt.subplot(1,3,3)\nplt.imshow(segmented_image, cmap = \"gray\")\nplt.grid(False)\nplt.title(\"Segmented Image with k = 5\")","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:57:49.375626Z","iopub.execute_input":"2021-11-11T11:57:49.376006Z","iopub.status.idle":"2021-11-11T11:57:53.920971Z","shell.execute_reply.started":"2021-11-11T11:57:49.375973Z","shell.execute_reply":"2021-11-11T11:57:53.919684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nexcept:\n    strategy = tf.distribute.get_strategy()","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:01:40.590347Z","iopub.execute_input":"2021-11-11T12:01:40.5908Z","iopub.status.idle":"2021-11-11T12:01:40.598169Z","shell.execute_reply.started":"2021-11-11T12:01:40.590764Z","shell.execute_reply":"2021-11-11T12:01:40.596566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Device:', tpu.master())\nprint('Number of replicas:', strategy.num_replicas_in_sync)\nprint(\"Version of Tensorflow used : \", tf.__version__)","metadata":{"execution":{"iopub.status.busy":"2021-11-11T12:01:56.199543Z","iopub.execute_input":"2021-11-11T12:01:56.199949Z","iopub.status.idle":"2021-11-11T12:01:56.238959Z","shell.execute_reply.started":"2021-11-11T12:01:56.199898Z","shell.execute_reply":"2021-11-11T12:01:56.235829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"AUTOTUNE = tf.data.experimental.AUTOTUNE\nGCS_PATH = KaggleDatasets().get_gcs_path()\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync\nIMAGE_SIZE = [1024, 1024]\nSHAPE = [256, 256]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split \ntraining_files, validation_files = train_test_split(tf.io.gfile.glob(GCS_PATH + \"/tfrecords/train*.tfrec\"),\n                                                   test_size = 0.1, random_state = 42)\n\ntesting_files = tf.io.gfile.glob(GCS_PATH + \"/tfrecords/test*.tfrec\")\n\nprint(\"Number of training files = \", len(training_files))\nprint(\"Number of validation files = \", len(validation_files))\nprint(\"Number of test files = \", len(testing_files))","metadata":{"execution":{"iopub.status.busy":"2021-11-11T11:58:31.190907Z","iopub.execute_input":"2021-11-11T11:58:31.191283Z","iopub.status.idle":"2021-11-11T11:58:31.30165Z","shell.execute_reply.started":"2021-11-11T11:58:31.191249Z","shell.execute_reply":"2021-11-11T11:58:31.299751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}