{"cells":[{"metadata":{},"cell_type":"markdown","source":"# load modules and dataframe","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nfrom keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\nimport time\n\nimport os","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels_dataframe = pd.read_csv('/kaggle/input/dog-breed-identification/labels.csv')\nsample = pd.read_csv('/kaggle/input/dog-breed-identification/sample_submission.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"* create random permutation for shuffling data ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"ix = np.random.permutation(len(labels_dataframe))\nlabels_dataframe = labels_dataframe.iloc[ix]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### create dictionary class\n* class-->labels\n* labels-->class","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class_to_index = dict({breed:ix for ix, breed in enumerate(labels_dataframe['breed'].unique())})\nindex_to_class = dict({ix:breed for ix, breed in enumerate(labels_dataframe['breed'].unique())})\nlabels_dataframe['breed'] = labels_dataframe['breed'].map(class_to_index)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"image_shape = (331, 331, 3)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### API for loading images and timer for runtime duration","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"st_time = 0\ndef start_timer():\n    global st_time\n    st_time = time.time()\ndef stop_timer():\n    global st_time\n    total = time.time() - st_time\n    st_time = 0\n    print('total runtime: {}'.format(total))\n\ndef run_with_timer(function, param, return_value = True):\n    if return_value == True:\n        start_timer()\n        result = function(**param)\n        stop_timer()\n        return result\n    else:\n        start_timer()\n        function(**param)\n        stop_timer()\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def load_from_dataframe(dataframe, image_shape, img_dir, x_col = None, y_col = None,):\n    no_of_images = len(dataframe)\n    images = np.zeros((no_of_images, image_shape[0], image_shape[1], image_shape[2]), dtype = np.uint8)\n    if y_col:\n        labels = np.zeros((no_of_images, 1), dtype = np.uint8)\n        for ix in range(no_of_images):\n            filename = dataframe.loc[ix, x_col]\n            path = os.path.join(img_dir, filename + '.jpg')\n            image = load_img(path, target_size = (image_shape[0], image_shape[1]))\n            image = img_to_array(image)\n            images[ix] = image\n            labels[ix] = dataframe.loc[ix, y_col]\n        print('Found {} validated image filenames belonging to {} classes.'.format(no_of_images, np.unique(labels).size))\n        return images, labels\n    else:\n        for ix in range(no_of_images):\n            filename = dataframe.loc[ix, x_col]\n            path = os.path.join(img_dir, filename + '.jpg')\n            image = load_img(path, target_size = (image_shape[0], image_shape[1]))\n            image = img_to_array(image)\n            images[ix] = image\n        print('Found {} validated image filenames'.format(no_of_images))\n        return images","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## load train images","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"params = dict(dataframe = labels_dataframe, image_shape = image_shape, img_dir = '/kaggle/input/dog-breed-identification/train', x_col = 'id', y_col = 'breed')\nimages, labels = run_with_timer(load_from_dataframe, params)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## base models for getting feature","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import Sequential\nfrom keras.layers import Lambda, InputLayer\n\ndef get_feature(model_name, preprocess_input, images, pooling = 'avg', target_size = (331,331,3)):\n    base_model = model_name(input_shape = target_size, include_top=False, pooling = pooling)\n\n    model = Sequential()\n    model.add(InputLayer(input_shape = target_size))\n    model.add(Lambda(preprocess_input))\n    model.add(base_model)\n\n    feature = model.predict(images)\n    \n    print('feature-map shape: {}'.format(feature.shape))\n    return feature","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### inception model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.inception_v3 import InceptionV3, preprocess_input\n\ninception_preprocess = preprocess_input\nparams = dict(model_name = InceptionV3, preprocess_input = inception_preprocess, images = images, pooling = 'avg')\ninception_feature = run_with_timer(get_feature, params)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### NASNetLarge model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.nasnet import NASNetLarge, preprocess_input\n\nnasnet_preprocessor = preprocess_input\nparams = dict(model_name = NASNetLarge, preprocess_input = nasnet_preprocessor, images = images, pooling = 'avg')\nnasnet_features = run_with_timer(get_feature, params)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Xception model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.xception import Xception, preprocess_input\n\nxception_preprocess = preprocess_input\nparams = dict(model_name = Xception, preprocess_input = xception_preprocess, images = images, pooling = 'avg')\nxception_feature = run_with_timer(get_feature, params)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### ResNet50V2 model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.inception_resnet_v2 import InceptionResNetV2, preprocess_input\n\nresnet_preprocess = preprocess_input\nparams = dict(model_name = InceptionResNetV2, preprocess_input = resnet_preprocess, images = images, pooling = 'avg')\nresnet_feature = run_with_timer(get_feature, params)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### concatenate all feature\n* concatenate all feature from different base models","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"final_features = np.concatenate([inception_feature, nasnet_features, xception_feature, resnet_feature], axis = 1)\nprint('final features shape: {}'.format(final_features.shape))\ndel images, inception_feature, nasnet_features, xception_feature, resnet_feature","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Predction Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.layers import Dropout, Dense\n\ndef create_model(features_shape = 1024):\n    model = Sequential()\n    model.add(InputLayer(input_shape = (features_shape, )))\n    model.add(Dropout(0.6))\n    model.add(Dense(4096, activation = 'relu'))\n    model.add(Dropout(0.6))\n    model.add(Dense(len(class_to_index), activation = 'softmax'))\n    \n    model.compile(loss = 'sparse_categorical_crossentropy', optimizer ='Adam', metrics = ['accuracy'])\n    return model","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = create_model(final_features.shape[1])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### train model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit(final_features, labels, batch_size = 128, epochs = 6, validation_split = 0.2)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### prediction from current model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"params = dict(dataframe = sample, image_shape = image_shape, img_dir = '/kaggle/input/dog-breed-identification/test', x_col = 'id')\nimages = run_with_timer(load_from_dataframe, params)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"inception_feature = run_with_timer(get_feature, dict(model_name = InceptionV3, preprocess_input = inception_preprocess, images = images, pooling = 'avg'))\nnasnet_features = run_with_timer(get_feature, dict(model_name = NASNetLarge, preprocess_input = nasnet_preprocessor, images = images, pooling = 'avg'))\nxception_feature = run_with_timer(get_feature, dict(model_name = Xception, preprocess_input = xception_preprocess, images = images, pooling = 'avg'))\nresnet_feature = run_with_timer(get_feature, dict(model_name = InceptionResNetV2, preprocess_input = resnet_preprocess, images = images, pooling = 'avg'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"final_features = np.concatenate([inception_feature, nasnet_features, xception_feature, resnet_feature], axis = 1)\nprint('final features shape: {}'.format(final_features.shape))\ndel images, inception_feature, nasnet_features, xception_feature, resnet_feature","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction = model.predict(final_features)\nsubmission = pd.DataFrame({'id':sample.id.values})\nsubmission['id'] = submission['id'].apply(lambda x : x.split('.')[0])\nprediction = pd.DataFrame(prediction)\nprediction.columns = class_to_index.keys()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.concat([submission, prediction], axis = 1)\nsubmission.to_csv('submission.csv', index = False)","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}