{"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)\nimport matplotlib.pyplot as plt\nimport shutil\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 the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"13462ef00fc484dfee070091eab6c5269106026e"},"cell_type":"markdown","source":"## Preprocessing input"},{"metadata":{"_uuid":"2ea32fe4458eb35d4e607843ce7e650f83003046"},"cell_type":"markdown","source":"### Importing train.csv"},{"metadata":{"trusted":true,"_uuid":"6a20623bd4e23ce27495f555cba20a02db1639eb"},"cell_type":"code","source":"from keras.preprocessing import image\nfrom keras.applications.resnet50 import preprocess_input\nfrom sklearn.preprocessing import LabelEncoder, OneHotEncoder\n\nbatch_size = 256\ninput_shape = (128, 128)\ninput_shape_2 = (128, 128, 3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"96a64e258c24350ebe16cd8bcf8b8671a1851e56","scrolled":true},"cell_type":"code","source":"train_df = pd.read_csv(\"../input/humpback-whale-identification/train.csv\")\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"0c41501eca13f0b00593bedf4302a47f8a620dd2"},"cell_type":"code","source":"bbox = pd.read_csv('../input/generating-whale-bounding-boxes/bounding_boxes.csv')\nbbox.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"724dda9c997163ad43317c5e6b1b8149fa4d91b9"},"cell_type":"code","source":"from PIL import Image as pimg\nfrom scipy.misc import imresize\n\nimage_name = '72c3ce75c.jpg'\nimg = image.load_img(\"../input/humpback-whale-identification/train/\"+image_name)\nx = image.img_to_array(img)\nx = np.uint8(x)\ndetails = bbox[bbox['Image']==image_name]\nnew_x = x[int(details.x0):int(details.x1), int(details.y0):int(details.y1)]\n\nplt.figure(1)\nplt.imshow(x)\nplt.figure(2)\nplt.imshow(new_x)\n\nnewnew = imresize(new_x, size=input_shape_2)\nplt.figure(3)\nplt.imshow(newnew)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"40de42e432ecb1a664384e698898750e571a4718"},"cell_type":"code","source":"def prepareImages_bbox(data, bbox, m, dataset, preprocess=False):\n    print(\"Preparing images\")\n    X_train = np.zeros((m, 128, 128, 3))\n    count = 0\n    \n    for fig in data['Image']:\n        # Load images into images of size 100x100x3\n#         if not preprocess:\n#             img = image.load_img(\"../input/humpback-whale-identification/\"+dataset+\"/\"+fig)\n#             x = image.img_to_array(img)\n#             x0 = int(bbox[bbox['Image']==fig].x0)\n#             x1 = int(bbox[bbox['Image']==fig].x1)\n#             y0 = int(bbox[bbox['Image']==fig].y0)\n#             y1 = int(bbox[bbox['Image']==fig].y1)\n#             if not (x0 >= x1 or y0 >= y1):\n#                 x = x[y0:y1, x0:x1,:]\n#             else :\n#                 x = x[x0:x1, y0:y1, :]\n#             try:\n#                 x = imresize(x, size=(128, 128, 3))\n#             except:\n#                 print(x.shape)\n#                 break\n#         else:\n        img = image.load_img(\"../input/humpback-whale-identification/\"+dataset+\"/\"+fig, target_size=(128,128,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":"38f0ee7678e4072d7b28cc7528c520d7a51655d1"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\n# dtypes = {\n#     'Image' : 'str',\n#    'Id' : 'str',\n# }\n\n# train_dir = \"../input/humpback-whale-identification/train\"\n# test_dir = \"../input/humpback-whale-identification/test\"\n\n# df = pd.read_csv('../input/humpback-whale-identification/train.csv', dtype = dtypes)\n# df = df[df['Id'] != 'new_whale']\n\n# datagen = ImageDataGenerator(\n#     preprocessing_function=preprocess_input,\n#     rotation_range=20,\n#     width_shift_range=0.2,\n#     height_shift_range=0.2,\n#     horizontal_flip=True)\n\n# train_generator = datagen.flow_from_dataframe(\n#     dataframe = df,\n#     directory = train_dir,\n#     x_col = \"Image\",\n#     y_col = \"Id\",\n#     has_ext = True,\n#     classes = np.unique(df.Id.values).tolist(),\n#     class_mode = \"categorical\",\n#     target_size = input_shape,\n#     batch_size = batch_size\n# )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7ab3448fd16a5150be61e8207bd8afee5c5eb323"},"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":"412c8b16127f1caa1a9c1935a555f8e09fd445f8"},"cell_type":"code","source":"'''\nLet's remove the new_whale class and see the results now\n'''\nnew_whale_excluded = train_df[train_df['Id'] != 'new_whale']\n\nnew_whale_excluded = (new_whale_excluded.reset_index()).drop(columns='index')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"afe6bdc08025ea5f57fb6c45a58ae663b3d55add","scrolled":true},"cell_type":"code","source":"X_val = prepareImages_bbox((new_whale_excluded[int(len(new_whale_excluded)*0.9):]).reset_index(), bbox, len((new_whale_excluded[int(len(new_whale_excluded)*0.9):])), \"train\")\nX = prepareImages_bbox((new_whale_excluded[:int(len(new_whale_excluded)*0.9)]).reset_index(), bbox, len((new_whale_excluded[:int(len(new_whale_excluded)*0.9)])), \"train\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8b361ba1662528816c539c39961c91ee1c93782e","scrolled":false},"cell_type":"code","source":"y, label_encoder = prepare_labels(new_whale_excluded['Id'])\ny_val = y[int(len(new_whale_excluded)*0.9):]\ny = y[:int(len(new_whale_excluded)*0.9)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"46b66d10df00ae13cbe08b5fc9c8c824c798f990"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\n'''\nAdditional parameters if you want to use \nrotation_range=20,\nwidth_shift_range=0.2,\nheight_shift_range=0.2,\nzoom_range=0.2,\n'''\n\ndatagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input,\n    rotation_range=60,\n    width_shift_range=0.2,\n    shear_range=0.2,\n    height_shift_range=0.2,\n    horizontal_flip=True)\n\n\ndatagen.fit(X)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"264bec4403292ef2766b0d3d7df4dca6b40ef44f"},"cell_type":"markdown","source":"## Building the network (ResNet50)"},{"metadata":{"trusted":true,"_uuid":"2a99c79510e930fb25e7460598dd290ad244e3f1"},"cell_type":"code","source":"from keras.applications.resnet50 import ResNet50\n\nconv_base = ResNet50(include_top = False,\n                    weights = 'imagenet',\n                    input_shape = input_shape_2)\n\nset_trainable = False\n\nfor layer in conv_base.layers:\n    if layer.name == 'res5b_branch2a':\n        set_trainable = True\n        print('Got here')\n    if set_trainable:\n        layer.trainable = True\n    else :\n        layer.trainable = False\n        \nconv_base.summary()\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"865ed3bda20c05e0e4996648e0d38a2979ab04e7"},"cell_type":"markdown","source":"## Add the Fully connected layers on top of the conv_base"},{"metadata":{"_uuid":"c73c53e569f51d93cc76edce169ccccb583d65fd"},"cell_type":"markdown","source":"\n### Define the model"},{"metadata":{"trusted":true,"_uuid":"d899f0a9b4fa1f4b2fd078ce72fc65eae50685a5"},"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":"ecd36275b21a8ee1ab9d7b05eeb04a9f7e13b991"},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Dense, Flatten, Dropout, BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.metrics import categorical_accuracy, categorical_crossentropy, top_k_categorical_accuracy\nfrom keras.callbacks import ReduceLROnPlateau, EarlyStopping\nfrom keras.layers import Lambda\n\n\n'''\nBuild_model() function to generate a generic model \n'''\n\ndef build_model(conv_base):\n    model = Sequential()\n    model.add(Lambda(preprocess_input, name='preprocessing', input_shape=(128, 128, 3)))\n    model.add(conv_base)\n    model.add(Flatten())\n    model.add(BatchNormalization(momentum=0.1, epsilon=1e-6))\n    model.add(Dropout(0.5))\n    model.add(Dense(4096, activation='relu')) \n    model.add(Dropout(0.5))\n    model.add(Dense(5004, activation='softmax')) # 5005 classes\n    \n    model.compile(optimizer=Adam(lr=0.001, decay=1e-6),\n                 loss='categorical_crossentropy',\n                 metrics=[categorical_crossentropy, categorical_accuracy, top_5_accuracy])\n    \n    model.summary()\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"f2c8601ae4aa4f1a68fae4764a18d1741e4c92c2"},"cell_type":"markdown","source":"\n### Fitting the model"},{"metadata":{"trusted":true,"_uuid":"ff1a7812ad8baae8c1e0b592cf506664e09e4643","scrolled":true},"cell_type":"code","source":"model = build_model(conv_base)\n\nreduce_lr = ReduceLROnPlateau(monitor='val_top_5_accuracy', factor=0.2,\n                              patience=5, min_lr=0.0005)\n\nearly = EarlyStopping(monitor='val_top_5_accuracy', mode='max', patience=5)\n\nhistory = model.fit_generator(datagen.flow(X, y, batch_size=batch_size), validation_data=(X_val, y_val), epochs=50, verbose=1, callbacks=[reduce_lr, early])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"b1686544f6b72682a33ef041fb6c57d05c96d1a6","scrolled":true},"cell_type":"code","source":"# model = build_model(conv_base)\n\n# train_samples = train_generator.filenames\n# reduce_lr = ReduceLROnPlateau(monitor='loss', factor=0.2,\n#                               patience=1, min_lr=0.0005)\n\n# history = model.fit_generator(\n#     train_generator,\n#     steps_per_epoch=len(train_samples)/batch_size,\n#     epochs=50,\n#     callbacks=[reduce_lr]\n# )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"afc2d87bf106e9713a702838a3901e9b172b7adf"},"cell_type":"code","source":"# for batches in train_generator:\n#     print(batches[0].shape)\n#     break","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2143c1d4b7e4a26eff3b02ee6755f0ded21a1809"},"cell_type":"markdown","source":"### Save model"},{"metadata":{"trusted":true,"_uuid":"69f29f690b38447427c04dd20f045473315737be"},"cell_type":"code","source":"# model.save('resnet-v3.h5')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"cffb9dcd014d082588c7ec06f4988d066d7e7ed3"},"cell_type":"markdown","source":"### Create test directory"},{"metadata":{"trusted":true,"_uuid":"fece35b99d696e81bf8597e61beb489900be841a"},"cell_type":"code","source":"sample_sub = pd.read_csv(\"../input/humpback-whale-identification/sample_submission.csv\")\ntest = list(sample_sub.Image)\nprint(len(test))\n\ncol = ['Image']\ntest_df = pd.DataFrame(test, columns=col)\ntest_df['Id'] = ''","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d82663192932eb905f76b46a68c1926e20f21221"},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\ntest_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input,\n)\n\ntest_dir = \"../input/humpback-whale-identification/test\"\n\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe = test_df,\n    directory = test_dir,\n    x_col = \"Image\",\n    y_col = \"Id\",\n    has_ext = True,\n    class_mode = None,\n    target_size = input_shape,\n    batch_size = batch_size\n)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d7ad20033d8562f5418f045ad8de42fda6256f81"},"cell_type":"markdown","source":"### Convert predictions back to their original name"},{"metadata":{"trusted":true,"_uuid":"35b82012a34f643ac09612480a33dedd4761a1ba"},"cell_type":"code","source":"# X = prepareImages_bbox(test_df, bbox, test_df.shape[0], \"test\", preprocess=True)\nunique_labels = np.unique(new_whale_excluded['Id'].values)\n\nlabels_dict = dict()\nlabels_list = []\nfor i in range(len(unique_labels)):\n    labels_dict[unique_labels[i]] = i\n    labels_list.append(unique_labels[i])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3a1f5d307fafecbc0afa05c1cf6be577cd4dd7a7","scrolled":false},"cell_type":"code","source":"test_samples = test_generator.filenames\nprint(len(test_samples))\n\ntest_generator.reset()\npredictions = model.predict_generator(\n    test_generator,\n    steps=len(test_samples)/batch_size,\n    verbose=1\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3b22bf373244f8f5a7debfe4d18a5483022a15d5"},"cell_type":"code","source":"print(len(labels_list))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5279e19caca7252465f900cac77f2c9ad935c6a1"},"cell_type":"code","source":"best_th = 0.38\n\npreds_t = np.concatenate([np.zeros((predictions.shape[0],1))+best_th, predictions],axis=1)\nnp.save(\"preds.npy\",preds_t)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"95e2c99a941f4a3fdc08376b2194f766fa8e58c3"},"cell_type":"code","source":"sample_df = pd.read_csv(\"../input/humpback-whale-identification/sample_submission.csv\")\nsample_list = list(sample_df.Image)\nlabels_list = [\"new_whale\"]+labels_list\npred_list = [[labels_list[i] for i in p.argsort()[-5:][::-1]] for p in preds_t]\npred_dic = dict((key, value) for (key, value) in zip(test_samples,pred_list))\npred_list_cor = [' '.join(pred_dic[id]) for id in sample_list]\ndf = pd.DataFrame({'Image':sample_list,'Id': pred_list_cor})\ndf.to_csv('submission.csv', header=True, index=False)\ndf.head()","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}