{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install -q efficientnet","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"%matplotlib inline\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\n\nfrom tqdm import tqdm\nfrom glob import glob\nimport gc\n\nfrom sklearn.model_selection import train_test_split\n\nimport cv2\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nimport seaborn as sns\nfrom IPython.display import display\n\nplt.rcParams[\"figure.figsize\"] = (12,8)\nplt.rcParams['axes.titlesize'] = 16\n\nfrom kaggle_datasets import KaggleDatasets\n\nimport tensorflow as tf\nimport tensorflow.keras.layers as L\n\nimport efficientnet.tfkeras as efn\n\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau, ModelCheckpoint, EarlyStopping\nfrom tensorflow.keras.utils import to_categorical\n\nimport os\nprint(os.listdir('../input/alaska2-image-steganalysis'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"path = '/kaggle/input/alaska2-image-steganalysis/'\nfolders = ['JUNIWARD', 'JMiPOD', 'UERD', 'Cover']","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"sub = pd.read_csv('../input/alaska2-image-steganalysis/sample_submission.csv')\nprint(sub.shape)\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.suptitle('Images from Cover', fontsize = 16)\nfor i, img in enumerate(os.listdir('../input/alaska2-image-steganalysis/Cover')[:12]):\n    plt.subplot(3, 4, i + 1)\n    img = mpimg.imread('../input/alaska2-image-steganalysis/Cover/' + img)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.suptitle('Images from JMiPOD', fontsize = 16)\nfor i, img in enumerate(os.listdir('../input/alaska2-image-steganalysis/JMiPOD')[:12]):\n    plt.subplot(3, 4, i + 1)\n    img = mpimg.imread('../input/alaska2-image-steganalysis/JMiPOD/' + img)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.suptitle('Images from JUNIWARD', fontsize = 16)\nfor i, img in enumerate(os.listdir('../input/alaska2-image-steganalysis/JUNIWARD')[:12]):\n    plt.subplot(3, 4, i + 1)\n    img = mpimg.imread('../input/alaska2-image-steganalysis/JUNIWARD/' + img)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.suptitle('Images from UERD', fontsize = 16)\nfor i, img in enumerate(os.listdir('../input/alaska2-image-steganalysis/UERD')[:12]):\n    plt.subplot(3, 4, i + 1)\n    img = mpimg.imread('../input/alaska2-image-steganalysis/UERD/' + img)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"__Preparing Train and Test paths for training__"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_files = np.array(os.listdir(path + 'Cover/'))\nprint(len(train_files))\ndisplay(train_files[:5])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.DataFrame(columns = ['tag', 'file_path', 'target'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.random.seed(0)\nnp.random.shuffle(train_files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"start = 0\nend = 10000\nsteg_paths = []\nfor tag in folders[:3]:\n    for file in train_files[start: end]:\n        full = tag + '/' + file\n        steg_paths.append(full)\n    start += 10000\n    end += 10000\nsteg_paths[:5], len(steg_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"np.random.shuffle(train_files)\ncover_paths = []\nfor file in train_files[:30000]:\n    full = 'Cover' + '/' + file\n    cover_paths.append(full)\ncover_paths[-5:], len(cover_paths)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img_files = steg_paths + cover_paths\nlen(img_files)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df['file_path'] = img_files\ntrain_df['tag'] = train_df['file_path'].apply(lambda x: x.split('/')[0])\nflag = {'JUNIWARD': 1, 'JMiPOD': 1, 'UERD': 1, 'Cover': 0}\ntrain_df['target'] = train_df['tag'].map(flag)\ntrain_df = train_df.sample(frac = 1).reset_index(drop = True)\ntrain_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.countplot(train_df['tag'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_df = pd.DataFrame(columns = ['file_path', 'label'])\n\ntest_paths = []\n\nfor file in sub['Id']:\n    full = 'Test' + '/' + file\n    test_paths.append(full)\n\ntest_df['file_path'] = test_paths\ntest_df","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Tensorflow version \" + tf.__version__)\nAUTO = tf.data.experimental.AUTOTUNE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Detect hardware, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection. No parameters necessary if TPU_NAME environment variable is set. On Kaggle this is always the case.\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() # default distribution strategy in Tensorflow. Works on CPU and single GPU.\n\nprint(\"REPLICAS: \", strategy.num_replicas_in_sync)\n\nBATCH_SIZE = 16 * strategy.num_replicas_in_sync\nprint(BATCH_SIZE)\n\nGCS_DS_PATH = KaggleDatasets().get_gcs_path()\nprint(GCS_DS_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Format path for TPU\n\ndef format_path(pt):\n    return os.path.join(GCS_DS_PATH, pt)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_paths = train_df['file_path'].apply(format_path).values\ntest_paths = test_df['file_path'].apply(format_path).values\n\ntrain_targets = train_df['target'].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_paths[:5], train_targets[:5]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_path, valid_path, train_label, valid_label = train_test_split(train_paths, train_targets, test_size = 0.2, random_state = 2019)\nprint(train_path.shape, train_label.shape, valid_path.shape, valid_label.shape)","execution_count":null,"outputs":[]},{"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\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    \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\n    .from_tensor_slices((train_path, train_label))\n    .map(decode_image, num_parallel_calls = AUTO)\n    .cache()\n    .repeat()\n    .shuffle(1024)\n    .batch(BATCH_SIZE)\n    .prefetch(AUTO)\n)\n\nvalid_dataset = (\n    tf.data.Dataset\n    .from_tensor_slices((valid_path, valid_label))\n    .map(decode_image, num_parallel_calls = AUTO)\n    .batch(BATCH_SIZE)\n    .cache()\n    .prefetch(AUTO)\n)\n\ntest_dataset = (\n    tf.data.Dataset\n    .from_tensor_slices(test_paths)\n    .map(decode_image, num_parallel_calls = AUTO)\n    .batch(BATCH_SIZE)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"with strategy.scope():\n    model = tf.keras.Sequential([\n        efn.EfficientNetB7(\n            input_shape = (512, 512, 3),\n            weights = 'imagenet',\n            include_top = False\n        ),\n        L.GlobalAveragePooling2D(),\n        L.Dense(1, activation = 'sigmoid')\n    ])\n        \n    model.compile(\n        optimizer = 'adam',\n        loss = 'binary_crossentropy',\n        metrics = ['accuracy']\n    )\n    model.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"STEPS_PER_EPOCH = train_label.shape[0] // BATCH_SIZE\n\ncheckpoint = ModelCheckpoint('model_tpu.h5',monitor = 'val_loss', save_best_only = True, verbose = 1, period = 1)\n\nreduceLR = ReduceLROnPlateau(monitor = 'val_loss', min_lr = 0.00001, patience = 3, mode = 'min', verbose = 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for l in model.layers:\n    print(l)\n    l.trainable = False\n    \nhist = model.fit(train_dataset, epochs = 3, steps_per_epoch = STEPS_PER_EPOCH, validation_data = valid_dataset,\n                 callbacks = [checkpoint, reduceLR])\n\ndel hist\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"EPOCHS = 10\n\nhistory = model.fit(train_dataset, epochs = EPOCHS, steps_per_epoch = STEPS_PER_EPOCH, validation_data = valid_dataset,\n                 callbacks = [checkpoint, reduceLR])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def display_training_curves(training, validation, title, subplot):\n    \"\"\"\n    Source: https://www.kaggle.com/mgornergoogle/getting-started-with-100-flowers-on-tpu\n    \"\"\"\n    if subplot%10 == 1: # set up the subplots on the first call\n        plt.subplots(figsize = (10,10), facecolor = '#F0F0F0')\n        plt.tight_layout()\n    ax = plt.subplot(subplot)\n    ax.set_facecolor('#F8F8F8')\n    ax.plot(training)\n    ax.plot(validation)\n    ax.set_title('model '+ title)\n    ax.set_ylabel(title)\n    #ax.set_ylim(0.28,1.05)\n    ax.set_xlabel('epoch')\n    ax.legend(['train', 'valid.'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"display_training_curves(\n    history.history['loss'], \n    history.history['val_loss'], \n    'Loss', 211)\ndisplay_training_curves(\n    history.history['accuracy'], \n    history.history['val_accuracy'], \n    'Accuracy', 212)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"preds = model.predict(test_dataset, verbose = 1)\nsub.iloc[:, 1:] = preds\nprint(sub.shape)\ndisplay(sub.head())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.to_csv('./submission.csv', index = False)","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}