{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport seaborn as sns\nimport os\nprint(os.listdir(\"../input\"))\nfrom matplotlib import pyplot as plt\nimport cv2\nfrom PIL import Image\nimport random\nfrom imgaug import augmenters as iaa\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential, load_model,Model\nfrom keras.layers import Activation,Dropout,Flatten,Dense,Input,BatchNormalization,Conv2D\nfrom keras.applications.inception_resnet_v2 import preprocess_input\nfrom keras.applications import InceptionResNetV2\nfrom keras.callbacks import ModelCheckpoint\nfrom keras.callbacks import LambdaCallback\nfrom keras.callbacks import Callback\nfrom keras import metrics\nfrom keras.optimizers import Adam \nfrom keras import backend as K\nimport tensorflow as tf\nimport keras\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ac5cedba5491fbe1b43241d61ec1bdd7a61c62fb","_kg_hide-input":true},"cell_type":"code","source":"df = pd.read_csv(\"../input/train.csv\")\nprint(\"Total number of unique ids:\",df.Id.count())\nprint(\"Total number of images:\", df.Id.count()*4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40e9cf83ac3d6d3dfd48ee036fa5dfba97cae8af","_kg_hide-input":true,"_kg_hide-output":false},"cell_type":"code","source":"df.head(2)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"c100980a6cf331feb702d6c9b217cd7c254671aa"},"cell_type":"markdown","source":"Let's train a classifier for baseline. I'm choosing InceptionResnet50 but another interesting candidate is NasNet."},{"metadata":{"trusted":true,"_uuid":"f8a46f740b05574d55f5d48fd636d500ae14b7e6"},"cell_type":"code","source":"path_to_train = '/kaggle/input/train/'\ndata = pd.read_csv('/kaggle/input/train.csv')\n\ntrain_dataset_info = []\nfor name, labels in zip(data['Id'], data['Target'].str.split(' ')):\n    train_dataset_info.append({\n        'path':os.path.join(path_to_train, name),\n        'labels':np.array([int(label) for label in labels])})\ntrain_dataset_info = np.array(train_dataset_info)\n\nfrom sklearn.model_selection import train_test_split\ntrain_ids, test_ids, train_targets, test_target = train_test_split(\n    data['Id'], data['Target'], test_size=0.2, random_state=42)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"997e0cfd24fde6ab5ba9ebb7ef881fbc9a0a07d6"},"cell_type":"code","source":"class data_generator:\n    \n    def create_train(dataset_info, batch_size, shape, augument=True):\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, 28))\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                batch_labels[i][dataset_info[idx]['labels']] = 1\n            yield batch_images, batch_labels\n    \n    def load_image(path, shape):\n        R = np.array(Image.open(path+'_red.png'))\n        G = np.array(Image.open(path+'_green.png'))\n        B = np.array(Image.open(path+'_blue.png'))\n        Y = np.array(Image.open(path+'_yellow.png'))\n\n        image = np.stack((\n            R,\n            (G+Y)/2, \n            (B+Y)/2),-1)\n\n        image = cv2.resize(image, (shape[0], shape[1]))\n        image = np.divide(image, 255)\n        return image        \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":"9a4add9fa7daf95f5880d82fafdb43c053d96977"},"cell_type":"code","source":"input_shape=(299,299,3)\ntrain_datagen = data_generator.create_train(\n    train_dataset_info, 5, input_shape, augument=True)\n\nimages, labels = next(train_datagen)\n\nfig, ax = plt.subplots(1,5,figsize=(25,5))\nfor i in range(5):\n    ax[i].imshow(images[i])\nprint('min: {0}, max: {1}'.format(images.min(), images.max()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1598f679d67f3668f44b5493a0e0ac45b0ffbe80"},"cell_type":"code","source":"def create_model(input_shape, n_out):\n    model = Sequential()\n    model.add(InceptionResNetV2(include_top=False,input_shape= input_shape, pooling='avg', weights=\"imagenet\"))\n    model.add(Dense(1024))\n    model.add(Activation('relu'))\n    model.add(Dropout(0.8))\n    model.add(Dense(n_out, activation='sigmoid'))\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"4bfda06a1c00c0387e5fa16b628239e81571683e"},"cell_type":"code","source":"def f1(y_true, y_pred):\n    tp = K.sum(K.cast(y_true*y_pred, 'float'), axis=0)\n    fp = K.sum(K.cast((1-y_true)*y_pred, 'float'), axis=0)\n    fn = K.sum(K.cast(y_true*(1-y_pred), 'float'), axis=0)\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n    f1 = 2*p*r / (p+r+K.epsilon())\n    f1 = tf.where(tf.is_nan(f1), tf.zeros_like(f1), f1)\n    return K.mean(f1)\ndef show_history(history):\n    fig, ax = plt.subplots(1, 3, figsize=(15,5))\n    ax[0].set_title('loss')\n    ax[0].plot(history.epoch, history.history[\"loss\"], label=\"Train loss\")\n    ax[0].plot(history.epoch, history.history[\"val_loss\"], label=\"Validation loss\")\n    ax[1].set_title('f1')\n    ax[1].plot(history.epoch, history.history[\"f1\"], label=\"Train f1\")\n    ax[1].plot(history.epoch, history.history[\"val_f1\"], label=\"Validation f1\")\n    ax[2].set_title('acc')\n    ax[2].plot(history.epoch, history.history[\"acc\"], label=\"Train acc\")\n    ax[2].plot(history.epoch, history.history[\"val_acc\"], label=\"Validation acc\")\n    ax[0].legend()\n    ax[1].legend()\n    ax[2].legend()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d71acd73dc9f5c4605f943485b7a3d8887832736","scrolled":true},"cell_type":"code","source":"model = create_model(\n    input_shape, \n    n_out=28)\n\ncheckpointer = ModelCheckpoint(\n    '/kaggle/working/InceptionResNetV2.model',\n    verbose=2, save_best_only=True)\n\nBATCH_SIZE = 10\nINPUT_SHAPE = (299,299,3)\n\ntrain_generator = data_generator.create_train(\n    train_dataset_info[train_ids.index], BATCH_SIZE, INPUT_SHAPE, augument=False)\nvalidation_generator = data_generator.create_train(\n    train_dataset_info[test_ids.index], 256, INPUT_SHAPE, augument=False)\n\nmodel.layers[0].trainable = True\n\nmodel.compile(\n    loss='binary_crossentropy',  \n    optimizer=Adam(1e-4),\n    metrics=['acc', f1])\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch=500,\n    validation_data=next(validation_generator),\n    epochs=10, \n    verbose=1,\n    callbacks=[checkpointer])\nshow_history(history)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0cb9ffd60a64a96596ca132728653f00efd0c64c"},"cell_type":"code","source":"from tqdm import tqdm\nsubmit = pd.read_csv('../input/sample_submission.csv')\npredicted = []\nfor name in tqdm(submit['Id']):\n    path = os.path.join('../input/test/', name)\n    image = data_generator.load_image(path, INPUT_SHAPE)\n    score_predict = model.predict(image[np.newaxis])[0]\n    label_predict = np.arange(28)[score_predict>=0.1]\n    str_predict_label = ' '.join(str(l) for l in label_predict)\n    predicted.append(str_predict_label)\n    \nsubmit['Predicted'] = predicted\nsubmit.to_csv('submission.csv', index=False)","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}