{"cells":[{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","collapsed":true,"trusted":false},"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)\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.\nTRAIN_IMAGE_PATH = '../input/train/'\nTEST_IMAGE_PATH = '../input/test/'\nCSV_PATH = '../input/'\nOUTPUT_DATA_PATH = './'\nWEIGHT_DATA_FILE_NAME = 'model_weights_20190216_00.h5'\nSUBMISSIONT_DATA_FILE_NAME = 'sample_submission_20190216_00.csv'","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ba9f880a89ee0c1eadb649abeebde8e6503e9b49","trusted":false},"cell_type":"code","source":"from PIL import Image\n\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport tensorflow.keras as K\nfrom tensorflow.keras.layers import Input, Conv2D, Dense, Flatten, Lambda, MaxPooling2D\nfrom tensorflow.keras.regularizers import l2\nfrom tensorflow.keras.initializers import RandomNormal\nfrom tensorflow.keras.models import Model, Sequential\nfrom tensorflow.keras.optimizers import Adam\n\nimport random\nimport time","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_kg_hide-output":true,"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"code","source":"train_df = pd.read_csv(CSV_PATH + 'train.csv')\nprint('Fist Row\\n', train_df.head(1))\nprint('train_df shape : ', train_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0092f0a54a022d1fb98622281521093c505c7a81","trusted":false},"cell_type":"code","source":"unique_id_list = train_df['Id'].unique()\nunique_id_list_size = unique_id_list.size\nprint('Unique ID List Size = ', unique_id_list_size)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3c66c87d0607f318c04971081724c397997c5d8f"},"cell_type":"markdown","source":"**Make dictionarys of images with same ID**"},{"metadata":{"_uuid":"03dedbe2cf3884223989c3fa54fd9b6d4e6a020e","trusted":false},"cell_type":"code","source":"ID_images_dict = {}\nfor index, row in train_df.iterrows():\n    (image_file_name, label) = (row[0], row[1])\n    ID_images_dict.setdefault(label, []).append(image_file_name)\n\nknown_ID_images_dict   = {k: v for (k, v) in ID_images_dict.items() if k != 'new_whale'}","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2fa4ce6405bc49a1e0259c87d7a0f198e93ab5c2"},"cell_type":"markdown","source":"**Histogram of (# of known whale images) vs (# of ID)**"},{"metadata":{"_uuid":"d313ef82d31dbbb40bff6d4ddf68108df1f5f687","trusted":false},"cell_type":"code","source":"ID_count_dict = train_df['Id'].value_counts(ascending = True).to_dict()\n\nknown_ID_count_dict = {k: v for (k, v) in ID_count_dict.items() if k != 'new_whale'}\n# print(known_ID_count_dict)\nknown_ID_count_histogram_df = pd.DataFrame(list(known_ID_count_dict.items()), columns=['ID', 'count'])\n\nvalue_count = known_ID_count_histogram_df['count'].value_counts()\nprint('Known whales')\nprint(\"# of images\\t# of ID's\")\nprint(value_count.head(5))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"fc5d77bb99a350b8e718f7d58e0e1cbdeb61064f"},"cell_type":"markdown","source":"**Show some example of ID vs image list**"},{"metadata":{"_uuid":"ed39d68a15a637ebbf91f362fbb0a6ce8e61fbdb","trusted":false},"cell_type":"code","source":"sorted_known_ID_images_list = sorted(known_ID_images_dict.items(), key = lambda x: len(x[1]))\nprint(sorted_known_ID_images_list[0:3])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7655caabbe9504e99549aee2bd1aeab5e6925aac"},"cell_type":"markdown","source":"**Examine image modes and sizes**\n\n**Add image size and color mode to Dataframe**"},{"metadata":{"_uuid":"57d4acbe91f27b7efa8c54f9d17fe0972f638252"},"cell_type":"markdown","source":"from PIL import Image\n\nimg_mode_list = []\nimg_width_list = []\nimg_height_list = []\nimg_weight_height_ratio_list = []\nfor i in range(len(train_df['Image'])):\n\n    file_name = TRAIN_IMAGE_PATH + train_df['Image'][i]\n    with Image.open(file_name) as tmp_img:\n        img_mode_list.append(tmp_img.mode)\n        img_width_list.append(tmp_img.width)\n        img_height_list.append(tmp_img.height)\n        img_weight_height_ratio_list.append(tmp_img.width/tmp_img.height)\nprint(img_mode_list[0:20]) # RGB or L\n\ntrain_df['Width']  = img_width_list\ntrain_df['Height'] = img_height_list\ntrain_df['WH ratio'] = img_weight_height_ratio_list\ntrain_df['Mode']   = img_mode_list\nprint(train_df.head(2))"},{"metadata":{"_uuid":"10347825c72ff6ae83bcc810204c37bdb2deada6"},"cell_type":"markdown","source":"**Plot image size distribution**"},{"metadata":{"_uuid":"47c3fb221d71bfb5adc727452f6382588f7e33c1"},"cell_type":"markdown","source":"import matplotlib.pyplot as plt\n%matplotlib inline\n\nfig = plt.figure()\nax = fig.add_subplot(1, 1, 1)\n\nx = train_df['Width'].values\ny = train_df['Height'].values\n\nax.scatter(x, y)\nax.set_title('Image Width vs Height')\nax.set_xlabel('Width (pixels)')\nax.set_ylabel('Height (pixels)')"},{"metadata":{"_uuid":"67e3ab3cf402a881f806e2534bf4453049f11577"},"cell_type":"markdown","source":"print('Mode of Width =', train_df['Width'].mode().iloc[0])\nprint('Max Width =', train_df['Width'].max())\nprint('Min Width =', train_df['Width'].min())\nprint('Median of Width =', train_df['Width'].median())\nprint('')\nprint('Mode of Height =', train_df['Height'].mode().iloc[0])\nprint('Max Height =', train_df['Height'].max())\nprint('Min Height =', train_df['Height'].min())\nprint('Median of Height =', train_df['Height'].median())\nprint('')\nprint('# of RGB images =', (train_df['Mode'] == 'RGB').sum())\nprint('# of gray scale images =', (train_df['Mode'] == 'L').sum())"},{"metadata":{"_uuid":"abebc165d9896a4d65e9cba01bd1f9c7b5b11a2a"},"cell_type":"markdown","source":"fig = plt.figure()\nax = fig.add_subplot(1, 1, 1)\n\nx = train_df['WH ratio'].values\n\nax.hist(x, bins = 10)\nax.set_title('Histogram of Width/Height')\nax.set_xlabel('Width/Height ratio')\nax.set_ylabel('freq')"},{"metadata":{"_uuid":"6d160699b7bf38a70596ea3ebc2d8adc6f76b954","collapsed":true},"cell_type":"markdown","source":"**Most of IDs have small number of images meaning not enough images for training**\n\n**Perform image augmentation**"},{"metadata":{"_uuid":"8334eb9a9bea1fa2b3094ae7ab6047797d977dd6","trusted":false},"cell_type":"code","source":"def generate_random_augmented_image(img, nb_images = 100):\n\n    data_generator = ImageDataGenerator(rotation_range     = 10.0, # degree\n                                        width_shift_range  = 0.2,\n                                        height_shift_range = 0.2,\n                                        shear_range        = 5.0, # degree\n                                        zoom_range         = 0.2,\n#                                         horizontal_flip    = True,\n                                        vertical_flip      = True,\n                                       )\n\n    img_list = []\n    for i in range(nb_images):\n        generated_image = data_generator.random_transform(img) \n        img_list.append(generated_image)\n\n    return img_list","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"71125945c75b0c9ce2ea6b769753dc02a772ebb2","trusted":false},"cell_type":"code","source":"img_file_name = TRAIN_IMAGE_PATH + sorted_known_ID_images_list[0][1][0]\n\nIMG_W = int(1050/4) # median of image sizes\nIMG_H = int(525/4)\nIMG_D = 1\n\nfrom PIL import Image\n\ndef get_image_data(img_file_name):\n\n    with Image.open(img_file_name) as jpg_img:\n    \n        tmp = jpg_img.resize((IMG_W, IMG_H))\n        tmp2d = np.asarray(tmp.convert('L'))/255\n        tmp3d = tmp2d.reshape(IMG_H, IMG_W, IMG_D)\n\n    return tmp3d\n    \nplt.imshow(get_image_data(img_file_name).reshape(IMG_H, IMG_W), cmap = 'gray')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b83e359fa97b43bf7ef2f9dcf0adbb1857a3a2da","trusted":false},"cell_type":"code","source":"def show_in_grid(img_list, img_height, img_width, grid_shape = (4, 5)):\n\n    (r, c) = grid_shape\n    fig, axes = plt.subplots(r, c, figsize = (12, 8))\n    \n    k = 0\n    for i in range(c):\n        for j in range(r):\n            axes[j, i].matshow(img_list[k].reshape(img_height, img_width), cmap = 'gray')\n            axes[j, i].get_yaxis().set_visible(False)\n            axes[j, i].get_xaxis().set_visible(False)\n            k = k + 1\n\nimg_list = generate_random_augmented_image(get_image_data(img_file_name), 100)  \nshow_in_grid(img_list, IMG_H, IMG_W, (10, 10))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b867129d748ab580c097c11aee1ff905261caae0"},"cell_type":"markdown","source":"**Create siamese model**"},{"metadata":{"_uuid":"7c3204fbc932daf4f39f20df7834ce283af44e4a","trusted":false},"cell_type":"code","source":"def get_siamese_model(input_shape):\n\n    input_A = Input(input_shape)\n    input_B = Input(input_shape)\n\n    conv_net = Sequential()\n\n    # First layer (525, 262)\n    conv_net.add(Conv2D(filters = 32, kernel_size = (4, 4), padding  = 'same', activation = 'relu',\n                        kernel_initializer = RandomNormal(mean = 0, stddev = 0.01)))\n    conv_net.add(MaxPooling2D(pool_size = (2, 2), padding = 'same'))\n\n    # Second layer (262, 131)\n    conv_net.add(Conv2D(filters = 64, kernel_size = (4, 4), padding  = 'same', activation = 'relu',\n                        kernel_initializer = RandomNormal(mean = 0, stddev = 0.01)))\n    conv_net.add(MaxPooling2D(pool_size = (2, 2), padding = 'same'))\n    \n    # Third layer (131, 66)\n    conv_net.add(Conv2D(filters = 128, kernel_size = (4, 4), padding  = 'same', activation = 'relu',\n                        kernel_initializer = RandomNormal(mean = 0, stddev = 0.01)))\n    conv_net.add(MaxPooling2D(pool_size = (2, 2), padding = 'same'))\n        \n    conv_net.add(Flatten())\n    conv_net.add(Dense(units = 1024, activation = \"sigmoid\",\n                       kernel_initializer = RandomNormal(mean = 0, stddev = 0.01),\n                       bias_initializer = RandomNormal(mean = 0.5, stddev = 0.01)))\n\n    #call the convnet Sequential model on each of the input tensors so params will be shared\n    encoded_A = conv_net(input_A)\n    encoded_B = conv_net(input_B)\n\n    #layer to merge two encoded inputs with the l1 distance between them\n    L1_layer = Lambda(lambda tensors:K.backend.abs(tensors[0] - tensors[1]))\n    L1_distance = L1_layer([encoded_A, encoded_B])\n\n    prediction = Dense(units = 1, activation = 'sigmoid', bias_initializer = RandomNormal(mean = 0.5, stddev = 0.01))(L1_distance)\n    siamese_net = Model(inputs = [input_A, input_B], outputs = prediction)\n    optimizer = Adam(0.001)\n\n    siamese_net.compile(loss = \"binary_crossentropy\", optimizer = optimizer)\n    siamese_net.count_params()\n\n    return siamese_net","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b144b616374121d36334d13ec7dd42e12e4aaf6e","trusted":false},"cell_type":"code","source":"def get_test_data_pair(ID_images_dict):\n\n    nb_label = 10\n    ID_image_list = random.sample(list(ID_images_dict.items()), nb_label)\n  \n    selected_img_A_list = [] # correct one\n    selected_img_B_list = []\n\n    index = random.randint(0, nb_label - 1)\n    img_file_A = random.sample(ID_image_list[index][1], 1) # if the img list contains more than 1, choose one randomly\n    img_A_src = get_image_data(TRAIN_IMAGE_PATH + img_file_A[0])\n#     print('shape = ', img_A.shape)\n    img_A_list = generate_random_augmented_image(img_A_src, nb_images = 1)\n    img_A = img_A_list[0].reshape(IMG_H, IMG_W, IMG_D)\n    for i in range(nb_label):\n        selected_img_A_list.append(img_A)    \n    \n    for i in range(nb_label):\n        img_file_B = random.sample(ID_image_list[i][1], 1)\n        img_B_src = get_image_data(TRAIN_IMAGE_PATH + img_file_B[0])\n        img_B_list = generate_random_augmented_image(img_B_src, nb_images = 1)\n        img_B = img_B_list[0].reshape(IMG_H, IMG_W, IMG_D)\n        selected_img_B_list.append(img_B)\n\n    # diff class : target = 0, same class : target = 1\n    target = np.zeros(nb_label)\n    target[index] = 1\n\n    \n    return (selected_img_A_list, selected_img_B_list), target","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9df82117c2a51f5943327cf23fc6262caebd39e4","trusted":false},"cell_type":"code","source":"def get_train_data_pair(ID_images_dict, sample_size = 100):\n\n    nb_label = 3\n    ID_image_list = random.sample(list(ID_images_dict.items()), nb_label)\n    \n    target_diff = np.zeros(sample_size)\n    target_same = np.ones(sample_size)\n\n    target = np.concatenate([target_diff, target_same])\n\n    label_diff_A = ID_image_list[0][0]\n    label_diff_B = ID_image_list[1][0]\n    label_same_A = ID_image_list[2][0] # make same data set\n    label_same_B = ID_image_list[2][0] # make same data set\n\n    img_src_name_diff_A = random.sample(ID_image_list[0][1], 1) # pick up one image from list of images\n    img_src_name_diff_B = random.sample(ID_image_list[1][1], 1) # for image augmentation\n    img_src_name_same_A = random.sample(ID_image_list[2][1], 1)\n    img_src_name_same_B = random.sample(ID_image_list[2][1], 1)\n\n    img_src_diff_A = get_image_data(TRAIN_IMAGE_PATH + img_src_name_diff_A[0])\n    img_src_diff_B = get_image_data(TRAIN_IMAGE_PATH + img_src_name_diff_B[0])\n    img_src_same_A = get_image_data(TRAIN_IMAGE_PATH + img_src_name_same_A[0])\n    img_src_same_B = get_image_data(TRAIN_IMAGE_PATH + img_src_name_same_B[0])\n\n\n    augmented_img_diff_A_list = generate_random_augmented_image(img_src_diff_A, nb_images = sample_size)\n    augmented_img_diff_B_list = generate_random_augmented_image(img_src_diff_B, nb_images = sample_size)\n    augmented_img_same_A_list = generate_random_augmented_image(img_src_same_A, nb_images = sample_size)\n    augmented_img_same_B_list = generate_random_augmented_image(img_src_same_B, nb_images = sample_size)\n    \n    A = np.concatenate([augmented_img_diff_A_list, augmented_img_same_A_list])\n    B = np.concatenate([augmented_img_diff_B_list, augmented_img_same_B_list])\n\n    return (A, B), target","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b94944635dcd2e0f9eb16c6808933e3464bd01e9","trusted":false},"cell_type":"code","source":"def test_oneshot(model, ID_images_dict, nb_validation):\n\n    nb_correct = 0\n    for i in range(nb_validation):\n\n        (inputs, targets) = get_test_data_pair(ID_images_dict)\n        probabilites = model.predict(inputs)\n    \n        if np.argmax(probabilites) == np.argmax(targets):\n            nb_correct += 1\n\n    accuracy = nb_correct / nb_validation\n\n    return accuracy","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9df17142030c248f097765e3cb8b8ca9990cb230"},"cell_type":"markdown","source":"**Start Model Building**"},{"metadata":{"_uuid":"1ddedf5e6f5222a57755a3cd3900192dfcdc6085","trusted":false},"cell_type":"code","source":"print('Model Building Started')\ninput_shape = (IMG_H, IMG_W, IMG_D)\nsiamese_net = get_siamese_model(input_shape)\nsiamese_net.summary()\noptimizer = Adam(lr = 0.00006)\nsiamese_net.compile(loss = \"binary_crossentropy\", optimizer = optimizer)\nprint('Model Building Finished')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"38d2e17805d0c8ff93f842ebd157506ba43b0d80"},"cell_type":"markdown","source":"**Training Loop**"},{"metadata":{"_uuid":"a074beba9871e90ee05e5c618f6e9e3af280cbd8","scrolled":true,"trusted":false},"cell_type":"code","source":"print('Training Loop Started')\n\nstart = time.time()\n\nnb_iter = 10000\ntmp_accuracy = -1\nevaluation_interval = 10\n\nfor i in range(nb_iter):\n    \n    (train_img_pair, target) = get_train_data_pair(ID_images_dict = known_ID_images_dict, sample_size = 50)\n    loss = siamese_net.train_on_batch(train_img_pair, target)\n \n    if i % (evaluation_interval * 10) == 0:\n        print('Loop = ', i, 'time = ', time.time() - start)\n\n    if i % evaluation_interval == 0:\n#         print('Loop = ', i, 'time = ', time.time() - start)\n        accuracy = test_oneshot(siamese_net, ID_images_dict = known_ID_images_dict, nb_validation = 20)\n\n        if accuracy >= tmp_accuracy:\n            print(\"Current accuracy : {:.2f}, Previous accuracy : {:.2f}\".format(accuracy, tmp_accuracy))\n            tmp_accuracy = accuracy\n    \n    siamese_net.save_weights(OUTPUT_DATA_PATH + WEIGHT_DATA_FILE_NAME)\n\nprint('Training Loop Finished')\nprint(time.time() - start)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"b4fab800c62a640b3c824a5d97512d76e10dd47d"},"cell_type":"markdown","source":"**Load image file names for submission**"},{"metadata":{"trusted":false,"_uuid":"eb1dc1230012af32095ef347a13264e2a3b553ad"},"cell_type":"code","source":"submission_df = pd.read_csv(CSV_PATH + 'sample_submission.csv')\n\nprint(submission_df.head(3))\n\nsubmission_img_file_list = submission_df['Image'].values.tolist()\nprint('\\nLength of submission_img_file_list =', len(submission_img_file_list))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"0d409da401d8d66f71e946595540f0d8e1ba72de","collapsed":true},"cell_type":"markdown","source":"**Display some test images**"},{"metadata":{"_uuid":"b4fbdba365b7ba5fbae310f56243c6d483928655","collapsed":true,"trusted":false},"cell_type":"code","source":"img_list = []\n\nfor fname in submission_img_file_list[0:10]:\n\n    img_file_name = TEST_IMAGE_PATH + fname\n    img_list.append(get_image_data(img_file_name))\n\nshow_in_grid(img_list, IMG_H, IMG_W, grid_shape = (2, 5))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"6ba211d6e33ee941565bc08d57d9c1030b5f0f5c"},"cell_type":"markdown","source":"**Split train images into small lists to save memory**"},{"metadata":{"trusted":false,"_uuid":"6978fc3b4f95b5baa600e663c6c2407d0e382d7c"},"cell_type":"code","source":"sub_ID_images_list = [] #Number of unique ID = 5005\nlen_sub_dict = 50\n\ndef split_test_dict(known_ID_images_dict, unique_id_list, len_sub_dict = 50):\n    \n    tmp_dict = {}\n    for i, (key, value) in enumerate(known_ID_images_dict.items()):\n\n        tmp_dict[key] = value\n        if (( (i + 1) % len_sub_dict) == 0 or i == (unique_id_list.size - 2)): # mod\n            sub_ID_images_list.append(tmp_dict)\n            tmp_dict = {}\n\n    list_length = len(sub_ID_images_list)\n    sub_ID_images_list[list_length - 2].update(sub_ID_images_list[list_length - 1])\n    sub_ID_images_list[list_length - 1].clear()\n\nsplit_test_dict(known_ID_images_dict, unique_id_list, len_sub_dict)\n# print(sub_ID_images_list[list_length - 2])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"08e7c10c8888a51b6faf5d6bd2c6da3de673ea80"},"cell_type":"code","source":"# Length of submission_img_file_list = 7960\ndef get_data_pair(sub_known_ID_images_dict, submission_img_file_name):\n\n    img_A_list = [] # test data\n    img_B_list = [] # train data\n\n    list_length = len(sub_known_ID_images_dict)\n    \n    img_A = get_image_data(TEST_IMAGE_PATH + submission_img_file_name)\n    for i in range(list_length):\n        img_A_list.append(img_A)    \n\n    for i, (key, value) in enumerate(sub_known_ID_images_dict.items()):\n        img_file_name = random.sample(value, 1)[0]\n        img_B = get_image_data(TRAIN_IMAGE_PATH + img_file_name)\n        img_B_list.append(img_B)\n\n    return (img_A_list, img_B_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"928715d0779ff53b1916a9db840a2e527434373c"},"cell_type":"code","source":"nb_sub_dict = len(sub_ID_images_list) - 2 # dict","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"3b12ce94233021a2967b5874787fd51c522dfb54"},"cell_type":"markdown","source":"import matplotlib.pyplot as plt\n%matplotlib inline\n\nplt.imshow(get_image_data(TEST_IMAGE_PATH + submission_img_file_list[1]).reshape(IMG_H, IMG_W), cmap = 'gray')"},{"metadata":{"trusted":false,"_uuid":"a91bcd41b4ca6db555e4407acabd0da3c848c618"},"cell_type":"code","source":"import csv\n\ndef write_to_submission_file(Image = 'Image', Id = 'Id', mode = 'w'):\n\n    with open(OUTPUT_DATA_PATH + SUBMISSIONT_DATA_FILE_NAME, mode) as f:\n        \n        writer = csv.writer(f, lineterminator='\\n')\n        \n        csv_list = []\n        csv_list.append(Image)\n        csv_list.append(Id)\n        \n        writer.writerow(csv_list)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false,"_uuid":"de7a654c612ea161eb0abf68a2486c18b48408f9"},"cell_type":"code","source":"write_to_submission_file()\n\nfor sub_fname in submission_img_file_list:\n\n    max_probability = -1\n    max_pos = 0\n#     for i in range(nb_sub_dict + 1):\n    for i in range(2):\n\n        img_pair_list = get_data_pair(sub_ID_images_list[i], sub_fname)\n        tmp_prob = siamese_net.predict(img_pair_list)\n        sub_max_pos = np.argmax(tmp_prob)\n\n        if max_probability <= tmp_prob[sub_max_pos][0]:\n            max_pos = i * len_sub_dict + sub_max_pos\n            print(i, max_pos, sub_max_pos, tmp_prob[sub_max_pos][0])\n\n    print(\"best match :\", sub_fname, \" = \", unique_id_list[max_pos])\n    write_to_submission_file(sub_fname, unique_id_list[max_pos], 'a')\n\n    print(\"done!\")\n\nprint(\"all done!\")","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}