{"cells":[{"metadata":{"_uuid":"8f5b7fb3a79e40fa8212f0b76995194c45251b2b"},"cell_type":"markdown","source":"# Reference\n- https://www.kaggle.com/anezka/cnn-with-keras-for-humpback-whale-id\n- https://www.kaggle.com/pestipeti/keras-cnn-starter\n- https://www.kaggle.com/satian/keras-mobilenet-starter\n- https://www.kaggle.com/gimunu/data-augmentation-with-keras-into-cnn\n- https://keras.io/preprocessing/image/"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \nimport os\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mplimg\nfrom matplotlib.pyplot import imshow\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.preprocessing import OneHotEncoder\n\nimport tensorflow as tf\n\nfrom keras import layers\nfrom keras.preprocessing import image\nfrom keras.applications.imagenet_utils import preprocess_input\nfrom keras.layers import Input, Dense, Activation, BatchNormalization, Flatten, Conv2D\nfrom keras.layers import AveragePooling2D, MaxPooling2D, Dropout\nfrom keras.models import Model\n\nimport keras.backend as K\nfrom keras.models import Sequential\n\nimport warnings\nwarnings.simplefilter(\"ignore\", category=DeprecationWarning)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e4e5099e1d3bfd7da7d7cde685330d19db4be081"},"cell_type":"code","source":"SEED = 42\nnp.random.seed(SEED)\ntf.set_random_seed(SEED)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fbe1531eb23fceb7da14549590c9b22114ed234e"},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/train.csv\")\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8457c3ce739028b8ce7d1dd0c762ab95dcdcfa59"},"cell_type":"code","source":"def prepareImages(data, m, dataset):\n    print(\"Preparing images\")\n    X_train = np.zeros((m, 100, 100, 3))\n    count = 0\n    \n    for fig in data['Image']:\n        #load images into images of size 100x100x3\n        img = image.load_img(\"../input/\"+dataset+\"/\"+fig, target_size=(100, 100, 3))\n        x = image.img_to_array(img)\n        x = preprocess_input(x)\n\n        X_train[count] = x\n        if (count%500 == 0):\n            print(\"Processing image: \", count+1, \", \", fig)\n        count += 1\n    \n    return X_train","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ef6acf709a73af4697a9ddd7b3dfc00a8144c195"},"cell_type":"code","source":"def prepare_labels(y):\n    values = np.array(y)\n    label_encoder = LabelEncoder()\n    integer_encoded = label_encoder.fit_transform(values)\n    # print(integer_encoded)\n\n    onehot_encoder = OneHotEncoder(sparse=False)\n    integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)\n    onehot_encoded = onehot_encoder.fit_transform(integer_encoded)\n    # print(onehot_encoded)\n\n    y = onehot_encoded\n    # print(y.shape)\n    return y, label_encoder","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e6682392d6436b9e7afaa42ec1130451d78bb009"},"cell_type":"code","source":"X = prepareImages(train_df, train_df.shape[0], \"train\")\nX /= 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9d0aac6cc7b9fbb1dd33157027cd6e273a250ced"},"cell_type":"code","source":"y, label_encoder = prepare_labels(train_df['Id'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"87d2d22f4ee41e8f9d63eb2a3dadb90abd9b499f"},"cell_type":"code","source":"train_df[\"Id\"].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9f6159a964fe37174053287342e2e80f847189fc"},"cell_type":"markdown","source":"## As you can see, classes are 5005 but data contain 25361 images.\n- Data augmentation is needed!\n- We can do data augmentation with keras easily"},{"metadata":{"trusted":true,"_uuid":"33060ad00d219509e5c8d656ce936a1dc9667668"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(\n    rescale=1./255,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    rotation_range=90,\n    featurewise_center=True,\n    width_shift_range=0.2,\n    height_shift_range=0.2)\n\ntrain_datagen.fit(X)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"acdebc17d6da8cb91e32c8827ccdc38ab48f43cb"},"cell_type":"markdown","source":"# Model development"},{"metadata":{"trusted":true,"_uuid":"1145abf5ec69cf14795bb44fc8b4717559b54d3b"},"cell_type":"code","source":"BATCH_SIZE = 32\nEPOCHS = 40","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ed2020ed87693bf82f0dc232de3d855c89ee3d56"},"cell_type":"code","source":"from keras.applications import MobileNet\nfrom keras.applications.mobilenet import preprocess_input\nfrom keras.optimizers import Adam\nfrom keras.metrics import categorical_accuracy, top_k_categorical_accuracy, categorical_crossentropy\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"08289388bf70d80eb671c5a9b51fe94c49f104bd"},"cell_type":"code","source":"train_datagen = ImageDataGenerator(\n        rescale=1./255,\n        shear_range=0.2,\n        zoom_range=0.2,\n        horizontal_flip=True)\n\ntrain_datagen.fit(X)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"35a448e5225b2c1e1ebfc3130c6b0b411a121eec"},"cell_type":"code","source":"def valid_generator(batch_size, data, target):\n    while True:\n        for kk in range(0, data.shape[0], batch_size):\n            start = kk\n            end = min(start + batch_size, data.shape[0])\n            x = data[start:end]\n            y = target[start:end]\n            yield x, y","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dcc1c014a5d429be40e6c73b9fc5a86604f8cfe8"},"cell_type":"code","source":"val_set_number = np.random.choice(X.shape[0], 2000)\nvalid_datagen = valid_generator(BATCH_SIZE, X[val_set_number], y[val_set_number])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"386d57d48d68a2f6b74ddfbd5b4ad07ec280ec92"},"cell_type":"code","source":"def top_5_accuracy(y_true, y_pred):\n    return top_k_categorical_accuracy(y_true, y_pred, k=5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2eedbee96d37051c50e328bdcaaa9631f5dbe0cf"},"cell_type":"code","source":"best_save_model_file = '../working/mymodel.h5'","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5d175ba12c82b0eda61c75925ed5854219dbcd5b"},"cell_type":"code","source":"callbacks = [EarlyStopping(monitor='val_loss',\n                           patience=20,\n                           verbose=1,\n                           min_delta=0.00001,\n                           mode='min'),\n             ReduceLROnPlateau(monitor='val_loss',\n                               factor=0.1,\n                               patience=2,\n                               verbose=1,\n                               min_delta=0.0001,\n                               mode='min'),\n             ModelCheckpoint(monitor='val_loss',save_weights_only=True,\n                             filepath=best_save_model_file,\n                             save_best_only=True,\n                             mode='min') ,\n             ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f18fc5194695c41dd923249cf4055a95695d6b23"},"cell_type":"code","source":"model = MobileNet(input_shape=(100, 100, 3), alpha=1., weights=None, classes=5005)\nmodel.compile(optimizer=Adam(lr=0.002), loss='categorical_crossentropy',\n              metrics=[categorical_crossentropy, categorical_accuracy, top_5_accuracy])\nprint(model.summary())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"1c7ae8ca65314abfde06a2f2841ee86102b9b8e0"},"cell_type":"code","source":"history = model.fit_generator(train_datagen.flow(X, y, batch_size=BATCH_SIZE), validation_data=valid_datagen, validation_steps=X.shape[0] // BATCH_SIZE,\n                   steps_per_epoch = X.shape[0] // BATCH_SIZE,\n                   epochs=EPOCHS, verbose=1, callbacks=callbacks)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c600dbe8123134e79ef3da240985fc6fd5a3161d"},"cell_type":"code","source":"plt.plot(history.history['categorical_accuracy'])\nplt.title('Model categorical accuracy')\nplt.ylabel('categorical accuracy')\nplt.xlabel('Epoch')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fa7271a1e6ea757a0666da8330d24c98d1a0fa12"},"cell_type":"markdown","source":"# Submission"},{"metadata":{"trusted":true,"_uuid":"aa4a170b86cc3b4930edfd78f8a248dad3c57fd7"},"cell_type":"code","source":"test = os.listdir(\"../input/test/\")\nprint(len(test))\ncol = ['Image']\ntest_df = pd.DataFrame(test, columns=col)\ntest_df['Id'] = ''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7d1a2f15e3313146d6fec91f310ed660786c061e"},"cell_type":"code","source":"X = prepareImages(test_df, test_df.shape[0], \"test\")\nX /= 255","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"00c0a335e127cc37e056f2c7e9ac057c9dd838a7"},"cell_type":"code","source":"predictions = model.predict(np.array(X), verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9a4ed4e8719eb156ed916c53263007e86bc71ae6"},"cell_type":"code","source":"for i, pred in enumerate(predictions):\n    test_df.loc[i, 'Id'] = ' '.join(label_encoder.inverse_transform(pred.argsort()[-5:][::-1]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"326455436ae35ca7f4074ed2ca1c27f823919462"},"cell_type":"code","source":"test_df.head(10)\ntest_df.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c6caac4c2c9a0fdb1df6141bd746f1ec8703a1df"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b91a781159e3237ab459a161f06e877f980fe2a9"},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"","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}