{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import os\nimport cv2\nimport math\nfrom glob import glob\nfrom tqdm import tqdm\nfrom PIL import Image, ImageDraw\nimport tensorflow as tf\nfrom tensorflow.keras.layers import Activation, Dropout, Flatten, Dense, Input, GlobalAveragePooling2D\nfrom sklearn.model_selection import train_test_split\nfrom imgaug import augmenters as iaa\nfrom tensorflow.keras.metrics import categorical_accuracy, categorical_crossentropy\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.applications import MobileNet\nfrom tensorflow.keras.preprocessing import image\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.models import Sequential, load_model, Model\nfrom tensorflow.keras.callbacks import ModelCheckpoint\nfrom tensorflow.keras import metrics\nfrom tensorflow.keras.optimizers import Adam \nfrom tensorflow.keras import backend as K\nimport tensorflow.keras as keras\n\n\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"print(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8277a98b504aba154088f418e359b4eb261250e9"},"cell_type":"code","source":"PATH = './'\nTRAIN = '../input/train/'\nTEST = '../input/test/'\nLABELS = '../input/train.csv'\nSAMPLE = '../input/sample_submission.csv'","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"label_df = pd.read_csv('../input/train.csv')\nsubmission_df = pd.read_csv('../input/sample_submission.csv')\nlabel_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c9e5b61f7515d0a7366c3e36d66dc25a01c674b"},"cell_type":"code","source":"label_df['Id'].describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10a375a7e3ee8e463fedd668170230c8459cd0a4"},"cell_type":"code","source":"# Display the most frequent ID (without counting new_whale)\nlabel_df['Id'].value_counts()[1:16].plot(kind='bar')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4269c9a22d30f57083b9dd11cd88bb4a5c1326dc"},"cell_type":"code","source":"n_classes = label_df['Id'].nunique()\nimg_shape = (224,224,3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"457582b8522fd04739b57ed3cd81585133a46076"},"cell_type":"code","source":"def get_pad_width(im, new_shape, is_rgb=True):\n    pad_diff = new_shape - im.shape[0], new_shape - im.shape[1]\n    t, b = math.floor(pad_diff[0]/2), math.ceil(pad_diff[0]/2)\n    l, r = math.floor(pad_diff[1]/2), math.ceil(pad_diff[1]/2)\n    if is_rgb:\n        pad_width = ((t,b), (l,r), (0, 0))\n    else:\n        pad_width = ((t,b), (l,r))\n    return pad_width\n\n\ndef pad_and_resize(image_path, dataset):\n    img = cv2.imread(f'../input/{dataset}/{image_path}')\n    pad_width = get_pad_width(img, max(img.shape))\n    padded = np.pad(img, pad_width=pad_width, mode='constant', constant_values=0)\n    resized = cv2.resize(padded, (224,224))\n    \n    return resized","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"737c66af13afed22194850c4dfca182b9899a78f"},"cell_type":"code","source":"data = pd.read_csv('../input/train.csv')\n\ntarget_dummies = pd.get_dummies(label_df['Id'])\ntrain_label = target_dummies.columns.values\ny_train = target_dummies.values\n\ntrain_dataset_info = []\nfor name, labels in zip(data['Image'], y_train):\n    train_dataset_info.append({\n        'path':os.path.join(TRAIN, name),\n        'labels': labels})\ntrain_dataset_info = np.array(train_dataset_info)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"552535ba81693fd9ced303d206405e1424e0ecbb"},"cell_type":"code","source":"train_ids, test_ids, train_targets, test_target = train_test_split(\n    data['Image'], data['Id'], test_size=0.1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"146e195b5fb1b01aede30ccba7cee1a5bb9e9139"},"cell_type":"code","source":"class data_generator:\n    \n    def create_train(dataset_info, batch_size, shape, n_labels, augument=True):\n        assert shape[2] == 3\n        while True:\n            random_indexes = np.random.choice(len(dataset_info), batch_size)\n            batch_images = np.empty((batch_size, shape[0], shape[1], shape[2]))\n            batch_labels = np.zeros((batch_size, n_labels))\n            for i, idx in enumerate(random_indexes):\n                image = data_generator.load_image(\n                    dataset_info[idx]['path'], shape)   \n                if augument:\n                    image = data_generator.augment(image)\n                batch_images[i] = image\n\n                batch_labels[i] = dataset_info[idx]['labels']\n            yield batch_images, batch_labels\n            \n\n    def load_image(path, shape):\n        img = cv2.imread(path)\n        resized = cv2.resize(img,  (shape[0], shape[1]))\n        resized = resized / 255\n        return resized\n\n            \n    def augment(image):\n        augment_img = iaa.Sequential([\n            iaa.OneOf([\n                iaa.Affine(rotate=0),\n                iaa.Affine(rotate=90),\n                iaa.Affine(rotate=180),\n                iaa.Affine(rotate=270),\n                iaa.Fliplr(0.5),\n                iaa.Flipud(0.5),\n            ])], random_order=True)\n        \n        image_aug = augment_img.augment_image(image)\n        return image_aug","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"439f5d8a6171f4fa61f369f60eaf84fa54ae7ca7"},"cell_type":"code","source":"# create visualization datagen\nvis_datagen = data_generator.create_train(\n    train_dataset_info, 5, img_shape, n_classes, augument=False)\n\nimages, labels = next(vis_datagen)\nfig, ax = plt.subplots(1,5,figsize=(25,5))\nfor i in range(5):\n    ax[i].imshow(images[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6f9420096df3a58964e7d4acbb6d39714b1c63a8"},"cell_type":"code","source":"batchsize = 64\n# create train datagen\ntrain_datagen = data_generator.create_train(\n    train_dataset_info[train_ids.index], batchsize, img_shape, n_classes, augument=True)\n\nvalidation_generator = data_generator.create_train(\n    train_dataset_info[test_ids.index], 256, img_shape, n_classes, augument=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10fa3831a8079b0869ec24118ab35d19fa863e04"},"cell_type":"code","source":"def gen_graph(history, title):\n    plt.plot(history.history['categorical_accuracy'])\n    plt.plot(history.history['val_categorical_accuracy'])\n    plt.title('Accuracy ' + title)\n    plt.ylabel('Accuracy')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation',], loc='upper left')\n    plt.show()\n    plt.plot(history.history['categorical_crossentropy'])\n    plt.plot(history.history['val_categorical_crossentropy'])\n    plt.title('Loss ' + title)\n    plt.ylabel('MLogLoss')\n    plt.xlabel('Epoch')\n    plt.legend(['train', 'validation'], loc='upper left')\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"55a88f39b7d16eb6722b9ba7f10da3b1fb1ea32e"},"cell_type":"code","source":"STEPS = 512\nepochs = 15","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"144e98623d0592ebd864bf81de2f734ed6a5d411"},"cell_type":"code","source":"def create_model(input_shape, n_out):\n    base_model = MobileNet(input_shape=input_shape, include_top=False, weights=None, classes=n_out)\n    x = base_model.output\n    x = GlobalAveragePooling2D()(x)\n    x = Activation('relu')(x)\n    x = Dropout(0.2)(x)\n    x = Dense(1024)(x)\n    x = Activation('relu')(x)\n    x = Dense(n_out)(x)\n    logits = Activation('softmax')(x)\n    \n    for layer in base_model.layers:\n        layer.trainable = True\n        \n    return Model(inputs=base_model.input, outputs=logits)\n\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bbf203fc04f323c6a13f6f6f2c413841471be552"},"cell_type":"code","source":"model = create_model(input_shape=img_shape, n_out=n_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee2bb132bab2f8941aac39a9e0c6d468fba166f4"},"cell_type":"code","source":"model.compile(optimizer=Adam(lr=0.002), loss='categorical_crossentropy',\n              metrics=[categorical_crossentropy, categorical_accuracy])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3dd078b5e3b48286c5116e3987424251ef234cbc"},"cell_type":"code","source":"callbacks = [\n    ReduceLROnPlateau(monitor='val_categorical_accuracy', factor=0.5, patience=5,\n                      min_delta=0.005, mode='max', cooldown=3, verbose=1)\n]\n\nhist = model.fit_generator(\n    train_datagen, steps_per_epoch=STEPS, epochs=epochs, verbose=1,\n    validation_data=next(validation_generator),\n    callbacks = callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fd5db445c11e38939ad2c549875624f997e088c4"},"cell_type":"code","source":"#plot\ngen_graph(hist, \n              \"Mobile Net, lr 1e-4\")","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}