{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 5GB 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","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"This notebook is prepared for kaggle competition \"https://www.kaggle.com/c/alaska2-image-steganalysis\"\n\n# What is Stegnography?\n\nSteganography is the technique of hiding secret data within an ordinary, non-secret, file or message in order to avoid detection; the secret data is then extracted at its destination. The use of steganography can be combined with encryption as an extra step for hiding or protecting data. The word steganography is derived from the Greek words steganos (meaning hidden or covered) and the Greek root graph (meaning to write).\n\nFor more details please see : https://en.wikipedia.org/wiki/Steganography\n\n\nIn this notebook we are going to explore 3,00,000 images.\n\n* 75,000 original images\n* 75,000 images with JUNIWARD stegnography\n* 75,000 images with JMiPOD stegnography\n* 75,000 images with UERD stegnography\n\n**Using these 3,00,000 images our goal is the train a model which can classify if image has any hidden message or not.**","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"#install jpegio\n# ! git clone https://github.com/hellyjain/jpegio\n# Once downloaded install the package\n# !pip install jpegio/.\n!pip install -q efficientnet","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nfrom kaggle_datasets import KaggleDatasets\nimport tensorflow as tf\nimport tensorflow.keras.layers as L\nimport efficientnet.tfkeras as efn\nfrom sklearn import metrics\nfrom sklearn.model_selection import train_test_split\n# import jpegio as jpio\nimport pandas as pd\nimport numpy as np\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\nimport cv2\nimport gc","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Defining some functions to explore the images and compare the original image (cover) with image having hidden data. ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"#compare cover with corresponding stegnograph picture\n\n\ndef compare_steg(image):    \n    fig, ax = plt.subplots(nrows= 3, ncols = 3, figsize = (22,17))\n    steg = ['JMiPOD', 'JUNIWARD', 'UERD']\n    cover = cv2.imread('/kaggle/input/alaska2-image-steganalysis/Cover/'+image)\n    for r in range(3):\n        coded = cv2.imread('/kaggle/input/alaska2-image-steganalysis/'+str(steg[r])+'/'+image)\n        for c in range(3):\n            ax[r][1].set_title(steg[r])\n            ax[r][0].imshow(cover)\n            ax[r][0].axis('off')\n            ax[r][1].imshow(coded)\n            ax[r][1].axis('off')\n            ax[r][2].imshow(cover - coded)\n            ax[r][2].axis('off')\n\n            \n#Lets do pixel by pixel comparision of raw matrix\n\ndef pixel_summary(image):\n    cover = cv2.imread('/kaggle/input/alaska2-image-steganalysis/Cover/'+image)\n    JMiPOD = cv2.imread('/kaggle/input/alaska2-image-steganalysis/JMiPOD/'+image)\n    JUNIWARD = cv2.imread('/kaggle/input/alaska2-image-steganalysis/JUNIWARD/'+image)\n    UERD = cv2.imread('/kaggle/input/alaska2-image-steganalysis/UERD/'+image)\n    u_cover = np.unique(cover.reshape(512*512,3), axis =0).shape\n    u_JMiPOD = np.unique(JMiPOD.reshape(512*512,3), axis =0).shape\n#     d_JMiPOD = np.unique((cover - JMiPOD).reshape(512*512,3), axis =0).shape\n    u_JUNIWARD = np.unique(JUNIWARD.reshape(512*512,3), axis =0).shape\n#     d_JUNIWARD = np.unique((cover - JUNIWARD).reshape(512*512,3), axis =0).shape\n    u_UERD = np.unique(UERD.reshape(512*512,3), axis =0).shape\n#     d_UERD = np.unique((cover - UERD).reshape(512*512,3), axis =0).shape\n    print('Total unique colors in original image : {}'.format(u_cover[0]))\n    print('Total unique colors in JMiPOD image : {}'.format(u_JMiPOD[0]))\n#     print('Change in colors comparing Original vs JMiPOD image : {}'.format((d_JMiPOD)[0]))\n    print('Total unique colors in JUNIWARD image : {}'.format(u_JUNIWARD[0]))\n#     print('Change in colors comparing Original vs JUNIWARD image : {}'.format((d_JUNIWARD)[0]))\n    print('Total unique colors in UERD image : {}'.format(u_UERD[0]))\n#     print('Change in colors comparing Original vs UERD image : {}'.format((d_UERD)[0]))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Cover image on left,    loaded image in the middle,    pixel differences on the right**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"compare_steg('00001.jpg')\npixel_summary('00001.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"compare_steg('00501.jpg')\npixel_summary('00501.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"compare_steg('01011.jpg')\npixel_summary('01011.jpg')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"compare_steg('62001.jpg')\npixel_summary('62001.jpg')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# **Invoing TPU**","execution_count":null},{"metadata":{"trusted":true},"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)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# For tf.dataset\nAUTO = tf.data.experimental.AUTOTUNE\n\n# Data access\nGCS_DS_PATH = KaggleDatasets().get_gcs_path('alaska2-image-steganalysis')\n\n# Configuration\n# EPOCHS = 10\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync * 2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"GCS_DS_PATH","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Defining functions to read / format the images to feed to Keras","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def decode_image(filename, label=None, image_size=(512, 512)):\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    \n# def decode_image_YCbCr(filename, label=None, image_size=(512, 512)):\n# #     bits = tf.io.read_file(filename)\n#     image = JPEGdecompressYCbCr_v3(filename)\n#     image = tf.cast(image, tf.float32) / 256.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\n# def data_augment(image, label=None):\n#     image = tf.image.random_flip_left_right(image)\n#     image = tf.image.random_flip_up_down(image)\n    \n#     if label is None:\n#         return image\n#     else:\n#         return image, label","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Defining Efficientnet B5 model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model = tf.keras.Sequential([efn.EfficientNetB5(input_shape=(512, 512, 3),weights='imagenet',include_top=False)\n                             ,L.GlobalAveragePooling2D()\n                            ,L.Dense(10, activation='softmax')])\n    model.compile(optimizer='adamax', loss = 'sparse_categorical_crossentropy', metrics=['accuracy'])\n    model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Splitting the 3,00,000 images into 10 batches to avoid memory exception.**","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/training/input_batch.csv')\ntrain['imagepath'] = train.imagepath.str.replace('gs://kds-cd794677eb4416f86e3e23278e2d1f1e37783bc29e7982b08d469689',\n                        GCS_DS_PATH, regex = True)\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Training the model on one batch for now.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"for i in tqdm(range(5,6)):\n    train_paths = train[train['batch'] == i]['imagepath']\n    train_lables = train[train['batch'] == i]['label']\n    train_paths, valid_paths, train_labels, valid_labels = train_test_split(train_paths, train_lables, test_size=0.20, random_state=619)\n    train_dataset = (tf.data.Dataset.from_tensor_slices((train_paths, train_labels)).map(decode_image, num_parallel_calls=AUTO).cache().repeat().shuffle(1024).batch(BATCH_SIZE).prefetch(AUTO))\n    valid_dataset = (tf.data.Dataset.from_tensor_slices((valid_paths, valid_labels)).map(decode_image, num_parallel_calls=AUTO).batch(BATCH_SIZE).cache().prefetch(AUTO))\n    STEPS_PER_EPOCH = train_labels.shape[0] // BATCH_SIZE\n    history = model.fit(train_dataset, epochs=10, batch_size = BATCH_SIZE, steps_per_epoch=STEPS_PER_EPOCH, validation_data=valid_dataset)\n    gc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Read the test images\n\ndef append_path(pre):\n    return np.vectorize(lambda file: os.path.join(GCS_DS_PATH, pre, file))\n\nsubmission = pd.read_csv('/kaggle/input/alaska2-image-steganalysis/sample_submission.csv')\ntest_paths = append_path('Test')(submission.Id.values)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#create submission file\n\ntest_dataset = (tf.data.Dataset.from_tensor_slices(test_paths).map(decode_image, num_parallel_calls=AUTO).batch(BATCH_SIZE))\nlab = model.predict(test_dataset, verbose=1)\nsubmission.Label = 1-lab[:,[0]]\nsubmission.to_csv('submission_ALASKA.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Save model weights and use them while training other batches of images\n\nmodel.save_weights(\"model_b5.h5\")\n# model.load_weights(\"model_b5.h5\")","execution_count":null,"outputs":[]}],"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}