{"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Resources:\n\nhttps://www.kaggle.com/xhlulu/aptos-2019-densenet-keras-starter\n\nhttps://www.kaggle.com/wouterbulten/getting-started-with-the-panda-dataset\n\nhttps://www.kaggle.com/yeayates21/densenet-keras-starter-fork-v2\n\nhttps://www.kaggle.com/xhlulu/jigsaw-tpu-xlm-roberta\n\nhttps://medium.com/@vijayabhaskar96/tutorial-image-classification-with-keras-flow-from-directory-and-generators-95f75ebe5720\n\nhttps://stackoverflow.com/questions/55328355/keras-flow-from-directory-read-only-from-selected-sub-directories\n\nhttps://kylewbanks.com/blog/train-validation-split-with-imagedatagenerator-keras\n\nhttps://medium.com/@vijayabhaskar96/tutorial-image-classification-with-keras-flow-from-directory-and-generators-95f75ebe5720"},{"metadata":{},"cell_type":"markdown","source":"# Imports"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import os\nimport gc\nimport json\nimport math\nimport cv2\nimport PIL\nfrom PIL import Image\nimport numpy as np\nfrom keras import layers\nfrom keras.applications import DenseNet121\nfrom keras.callbacks import Callback, ModelCheckpoint\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.optimizers import Adam\nimport matplotlib.pyplot as plt\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import cohen_kappa_score, accuracy_score\nimport scipy\nimport tensorflow as tf\nfrom tqdm import tqdm\n%matplotlib inline\nfrom keras.preprocessing import image","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Config Settings"},{"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":{},"cell_type":"markdown","source":"# Fixed Constants"},{"metadata":{"trusted":true},"cell_type":"code","source":"# class directories\ncover_dir = \"../input/alaska2-image-steganalysis/Cover/\"\nJMiPOD_dir = \"../input/alaska2-image-steganalysis/JMiPOD/\"\nJUNIWARD_dir = \"../input/alaska2-image-steganalysis/JUNIWARD/\"\nUERD_dir = \"../input/alaska2-image-steganalysis/UERD/\"\n# add to list\nclass_locs = [cover_dir, JMiPOD_dir, JUNIWARD_dir, UERD_dir]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Variable Constants"},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 8\nTRAIN_VAL_SPLIT_RATIO = 0.50\nEPOCHS = 4\n# sample size for each class\ncN = 2000","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training Data"},{"metadata":{"trusted":true},"cell_type":"code","source":"def preprocess_image(image_path, desired_size=224):\n    im = Image.open(image_path)\n    im = im.resize((desired_size, desired_size))\n    im = np.array(im) / 255\n    return im","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\n\n# total samles \nN = cN * len(class_locs)\n# initialize y_train\ny_train = []\n# initalize x_train\nx_train = np.empty((N, 224, 224, 3), dtype=np.float16)\n# initialize class counter\nimClassNum = 0\n\n# run loop to grab training data\nfor imClass_dir in class_locs:\n    imClassNum += 1\n    print(\"running class\", str(imClassNum), \"...\")\n    for i, filename in enumerate(os.listdir(imClass_dir)):\n        x_train[i, :, :, :] = preprocess_image(imClass_dir+filename)\n        print(str(round(i/75000,2))+\"% of total images processed, \"+str(i)+\" images in total\", end=\"\\r\")\n        if i == cN:\n            print(\"\")\n            print(\"finished with class \" + str(imClassNum) + \"..\")\n            break\n    y_train.extend([imClassNum] * cN)\n\n# convert y_train to numpy    \ny_train = np.array(y_train)    \n\nprint(\"final training dataset shape..\")\nprint(\"x_train shape: \", x_train.shape)\nprint(\"y_train len: \", len(y_train))\nprint(str(round(N/(75000*4),2))+\"% of total images being used for training\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# pre-processing the target (i.e. one-hot encoding the target)\ny_train = pd.get_dummies(y_train).values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train.shape","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Validation Split"},{"metadata":{"trusted":true},"cell_type":"code","source":"x_train, x_val, y_train, y_val = train_test_split(\n    x_train, y_train, \n    test_size=TRAIN_VAL_SPLIT_RATIO, \n    random_state=2020\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Image Gen"},{"metadata":{"trusted":true},"cell_type":"code","source":"# define gen\nimg_gen = ImageDataGenerator(\n        zoom_range=0.15,  # set range for random zoom\n        # set mode for filling points outside the input boundaries\n        fill_mode='constant',\n        cval=0.,  # value used for fill_mode = \"constant\"\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=True,  # randomly flip images\n    )\n\n# create generator\ndata_generator = img_gen.flow(x_train, y_train, batch_size=BATCH_SIZE, seed=2019)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Create Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"densenet = DenseNet121(\n    weights='../input/densenet-keras/DenseNet-BC-121-32-no-top.h5',\n    include_top=False,\n    input_shape=(224,224,3)\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_model():\n    model = Sequential()\n    model.add(densenet)\n    model.add(layers.GlobalAveragePooling2D())\n    model.add(layers.Dropout(0.80))\n    model.add(layers.Dense(4, activation='sigmoid'))\n    \n    model.compile(\n        loss='binary_crossentropy',\n        optimizer=Adam(lr=0.00010509613402110064),\n        metrics=['accuracy']\n    )\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = build_model()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit_generator(\n    data_generator,\n    steps_per_epoch=x_train.shape[0] / BATCH_SIZE,\n    epochs=EPOCHS,\n    validation_data=(x_val, y_val)\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training Plots"},{"metadata":{"trusted":true},"cell_type":"code","source":"history_df = pd.DataFrame(history.history)\nhistory_df[['loss', 'val_loss']].plot()\nhistory_df[['accuracy', 'val_accuracy']].plot()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submission"},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv(\"../input/alaska2-image-steganalysis/sample_submission.csv\")\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# test data directory\ntest_dir = \"../input/alaska2-image-steganalysis/Test/\"\n\n# do similar data loading we did on train but on the test\\holdout set\nN = len([name for name in os.listdir(test_dir)])\nx_test = np.empty((N, 224, 224, 3), dtype=np.uint8)\nfor i, filename in enumerate(tqdm(os.listdir(test_dir))):\n    x_test[i, :, :, :] = preprocess_image(test_dir+filename)\n\nx_test.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_test = model.predict(x_test)\ny_test = y_test[:,0]\nsub['Label'] = y_test","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.to_csv(\"submission.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}