{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"scrolled":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)\nimport os\nimport itertools\nfrom random import shuffle\nimport matplotlib.pyplot as plt\nimport cv2\nfrom PIL import Image as pil_image\nfrom math import sqrt\nimport random\nfrom keras.utils import Sequence\nfrom keras.layers import Input\n# from lapjv import lapjv\nfrom tqdm import tqdm_notebook as tqdm\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.applications.resnet50 import ResNet50,preprocess_input\nfrom keras.applications.xception import Xception\nfrom keras.layers.core import Activation, Dense, Dropout, Flatten, Lambda\nfrom keras.layers.convolutional import Conv2D, MaxPooling2D\nfrom keras.layers import *\nfrom keras.models import Sequential, Model\nfrom collections import OrderedDict\nfrom keras.callbacks import ModelCheckpoint,ReduceLROnPlateau\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.model_selection import train_test_split\nfrom keras.models import model_from_json, load_model\nfrom keras import regularizers\n\n\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"de8ddd4970a16030c007c175fcc6e3b4168aac2c"},"cell_type":"code","source":"DATA=\"../input/humpback-whale-identification\"\nTRAIN_IMG=\"../input/humpback-whale-identification/train\"\nTEST_IMG=\"../input/humpback-whale-identification/test\"\nSUBMISSION_DF = '../input/pretrained-model/submission_siamese.csv'\nBB_DATA=\"../input/bounding-boxes-using-image-processing\"\n\nSIAMESE_MOD=\"../input/siamese-trained-new/siamese_trained_bb.h5\"\nSIAMESE_MOD_MID=\"../input/siamese-trained-new/siamese_mid.hdf5\"\n\nSIMPLE_CNN_SUB=\"../input/cnn-outputs/submission_top100.csv\"\nTEST_PARTS_DIR=\"../input/pretrained-model\"\nIM_SIZE=100\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a8f3e1ceeb3dbe2eab7f691a3432ce5dd3579a62"},"cell_type":"markdown","source":"# load data and prepare training set "},{"metadata":{"trusted":true,"_uuid":"41afbccdb396c3812e49e0cf686116ad11e8a424"},"cell_type":"code","source":"TRAIN_FLG=True\n# if os.path.isfile(SIAMESE_MOD):\n#     TRAIN_FLG=False\n#     print(\"model will be loaded from \"+ SIAMESE_MOD)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5900ffe526427444eca33b5a0cfdd35272de0fcb"},"cell_type":"code","source":"test_df= pd.DataFrame({\"Image\":  os.listdir(TEST_IMG)})\nprint(\"test images:\"+ str(len(test_df)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ddfef6f76e7652bde587fc8b926007f716a81a31"},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(DATA, 'train.csv'))\ntrain_df=train_df[train_df['Image']!='859e1399e.jpg']\ntrain_lbl=train_df.copy()\nprint(\"train images:\"+ str(len(train_lbl)))\nprint(\"total unique class:\"+ str(len(np.unique(train_lbl['Id']))))\ntrain_lbl.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7970656f223d50a48ef39f3c8a9742773e75eaa8"},"cell_type":"code","source":"#take out whales with a single train example (2072 examples)\ndf=train_lbl.groupby(['Id']).size().reset_index(\n    name='train_examples')\ndf=df[df['train_examples']>=2]\nsingle_whale_set= set(df.Id.values)\nprint(\"number of classes with more than 1 examples:\"+ str(len(df)))\n\n# print(\"number of classes with more than 1 examples:\"+ str(len(df)))\ntrain_lbl=train_lbl[train_lbl['Id'].isin(df['Id'])]\nprint(\"number of train instances :\"+ str(len(train_lbl)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"416bc68c7d10042abf69b0882f9fc71f3d88a81e"},"cell_type":"code","source":"no_new_whale=train_lbl[train_lbl['Id']!='new_whale']\nprint(\"number of train instances :\"+ str(len(no_new_whale)))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ef68ab4ca0051d43f29c8393f1451e603287a82"},"cell_type":"code","source":"def fetch_whale_img_list(image_dir,labels):\n    img_groups = {}\n    for img_file in tqdm(labels[\"Image\"].values,desc='fetch_whale_img_list'):\n        pid=img_file\n        train_itms=labels[labels['Image']==pid]\n        if train_itms is not None and len(train_itms)>0:\n            gid=labels[labels['Image']==pid].values[0][1] #this is the ralevant whale group\n            if gid in img_groups:\n                img_groups[gid].append(pid)\n            else:\n                img_groups[gid] = [pid]\n    return img_groups\n\nwhales_train_list=fetch_whale_img_list(TRAIN_IMG,no_new_whale)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"a314887df7351b61c5457cd913e95f2529888da0"},"cell_type":"markdown","source":"create triplets of (img1,img2, similarity), where similarity is 1 for same class images and 0 otherwise."},{"metadata":{"trusted":true,"_uuid":"7ac893991c9012889ca709903aec96e23ef0ec05"},"cell_type":"code","source":"def get_random_image(img_groups, gname):\n    photos = img_groups[gname]\n    pname = np.random.choice(photos, size=1)[0]\n    return pname\n    \ndef create_triples(image_dir,labels,data_set='train',img_groups=whales_train_list):\n#     img_groups = fetch_whale_img_list(image_dir,labels)\n    # creat equal number of negative examples\n    group_names = list(img_groups.keys())\n    triples = []\n    # positive pairs are any combination of images in same group\n    for key in img_groups.keys():\n        combs=itertools.combinations(img_groups[key], 2)\n        triple_pos = [(x[0] , x[1] , 1) \n                 for x in combs]\n        idx= np.random.choice(np.arange(len(triple_pos)),size=len(img_groups[key])-1,replace=False)\n        triple_pos=[triple_pos[i] for i in idx]\n        triples.extend(triple_pos)\n        \n        triple_neg = []\n        for x in triple_pos:\n            flg=True\n            while flg:\n                neg_w = np.random.choice(group_names, size=1, replace=False)[0]\n                if neg_w!=key: \n                    flg=False\n            right = get_random_image(img_groups, neg_w)\n            triple_neg.append((x[0], right, 0))\n        triples.extend(triple_neg)\n#         print(\"added neg examples:\"+str(len(triple_neg)))\n#     for i in tqdm(range(len(pos_triples))):\n#         g1, g2 = np.random.choice(np.arange(len(group_names)), size=2, replace=False)\n#         left = get_random_image(img_groups, group_names, g1)\n#         right = get_random_image(img_groups, group_names, g2)\n#         neg_triples.append((left, right, 0))\n#     pos_triples.extend(neg_triples)\n    shuffle(triples)\n    return triples","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fb463eaa02dff8f8dd3cd3f36c54ddbda2595ce4"},"cell_type":"code","source":"if TRAIN_FLG:\n    triples_data = create_triples(TRAIN_IMG,no_new_whale)\n    print(len(triples_data))\n    print(\"triplets examples:\")\n    print(triples_data[0:5])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e18ea5f21c8bcfdabe81a8e6877e2021e5521689","scrolled":false},"cell_type":"code","source":"if TRAIN_FLG:\n    #look at some examples\n    imgs=triples_data[0:10]\n    per_row=2\n    rows=5\n    cols = 2\n    fig, axes = plt.subplots(rows,cols, figsize=(24//per_row*cols,24//per_row*rows))\n    for ax in axes.flatten(): \n        ax.axis('off')\n\n    left=0\n    j=0\n    for i,ax in enumerate(axes.flatten()):\n        img=imgs[j][left]\n        label=imgs[j][2]\n        image_path=os.path.join(TRAIN_IMG, img)\n        left=(left+1)%2\n        if (i+1)%2==0:\n            j=j+1\n        ax.imshow(cv2.imread(image_path))\n        ax.set_title(label)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"ef8ee17727c6dabde76048e0842b8f093d8e677f"},"cell_type":"markdown","source":"generate methods for preprocessing the images: resize, crop using bounding boxes,etc."},{"metadata":{"trusted":true,"_uuid":"7cb5dd87a9ab45982be36a30cf857e1b925bc427"},"cell_type":"code","source":"#read BB data fo train and test\ntrain_bb=pd.read_csv(os.path.join(BB_DATA,\"boxs_train.csv\"))\ntest_bb=pd.read_csv(os.path.join(BB_DATA,\"boxs_test.csv\"))\nbb_all=train_bb.append(test_bb, ignore_index=True)\n\nbb = {}\nfor i in range(len(bb_all)):\n    image=bb_all['Image'].iloc[i].split(\"/\")[-1]\n    x0=float(bb_all['x0'].iloc[i])\n    y0=float(bb_all['y0'].iloc[i])\n    x1=float(bb_all['x1'].iloc[i])\n    y1=float(bb_all['y1'].iloc[i])\n    box=(x0,y0,x1,y1)\n    #save to labels file and dir\n#   croped_image= crop_img(image,box)\n    bb[image] = box","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6b6ad0cc65ba39e32b6cb96408a8c41d7d2aa57f"},"cell_type":"code","source":"# expnd boxes to compensate for bounding box errors\ncrop_margin = 0.1\ndef expand_bb(image,box,margin=crop_margin):\n    size_x,size_y=image.shape[1],image.shape[0]\n    x0, y0, x1, y1 = box[0],box[1],box[2],box[3]\n    dx = x1 - x0\n    dy = y1 - y0\n    x0 = max(0,x0-dx * crop_margin)\n    x1 = min(size_x,x1+ dx * crop_margin + 1)\n    y0 = max(0,y0-dy * crop_margin)\n    y1 = min(size_y, y1+dy * crop_margin + 1)\n    return x0,y0,x1,y1\n\ndef crop_img(image,box):\n    new_box=expand_bb(image,box)\n    if len(image.shape)==3:\n        new_image = image[int(new_box[1]):int(new_box[3]), int(new_box[0]):int(new_box[2]),:]\n    else:\n        new_image = image[int(new_box[1]):int(new_box[3]), int(new_box[0]):int(new_box[2])]\n    return new_image","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"78cb48a1eff27104807f5935abcb948035fbe13d"},"cell_type":"markdown","source":"define image data generator to be used whild training, together with preprocessing"},{"metadata":{"trusted":true,"_uuid":"6b2cea513b99cf4acf5b7538d9877823b7c21537"},"cell_type":"code","source":"RESIZE_IMG = IM_SIZE\nfrom skimage.transform import resize\nfrom keras.utils import np_utils\nimport cv2\n\ndef read_crop_resize(image_path, boxes=bb):\n    image = cv2.imread(image_path)\n    if image is not None:\n        if image_path.split(\"/\")[-1] in boxes:\n            box=boxes[image_path.split(\"/\")[-1]]\n            croped_image= crop_img(image,box)\n            image=croped_image\n        try:\n            image = cv2.resize(image, (RESIZE_IMG, RESIZE_IMG)) \n        except cv2.error as e:\n            print(\"error resizing image:\"+image_path )\n            return None\n    return image\n\ndef preprocess_images(image_names, seed, datagen,directory=TRAIN_IMG):\n    np.random.seed(seed)\n#     X = np.zeros((len(image_names), RESIZE_IMG, RESIZE_IMG, 3))\n    X = np.zeros((len(image_names), RESIZE_IMG, RESIZE_IMG,1))\n    for i, image_name in enumerate(image_names):\n        if os.path.isfile(image_name):\n            image = read_crop_resize(image_name)\n        else:\n            image = read_crop_resize(os.path.join(directory, image_name))\n        if image is not None:\n            if datagen is not None:\n                image = datagen.random_transform(image)\n            else:\n                image = image\n            image=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n            image=np.expand_dims(image, axis=2)\n            X[i]=image\n#             X[i]=cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)\n        else:\n            print(\"error reading image :\"+image_name)\n    return X\n\ndef image_triple_generator(image_triples, directory, batch_size,augment=True,shuffle=True):\n    datagen_args = dict(rescale=1./255,rotation_range=10,\n                        horizontal_flip=True)\n    if not augment:\n        datagen_args = dict(rescale=1./255)\n    datagen_left = ImageDataGenerator(**datagen_args)\n    datagen_right = ImageDataGenerator(**datagen_args)\n#     image_cache = {}\n    \n    while True:\n        # loop once per epoch\n        num_recs = len(image_triples)\n        if shuffle:\n            indices = np.random.permutation(np.arange(num_recs))\n        else:\n            indices = np.arange(num_recs)\n        num_batches = num_recs // batch_size\n#         if num_recs % batch_size > 0: num_batches=+1\n        for bid in range(num_batches):\n            # loop once per batch\n            batch_indices = indices[bid * batch_size : min(num_recs,(bid + 1) * batch_size)]\n            batch = [image_triples[i] for i in batch_indices]\n            # make sure image data generators generate same transformations\n            seed = np.random.randint(low=0, high=1000, size=1)[0]\n            Xleft = preprocess_images([b[0] for b in batch], seed, \n                                      datagen_left,directory)\n            Xright = preprocess_images([b[1] for b in batch],seed,\n                                       datagen_right, directory)\n            Y = np.array([b[2] for b in batch]) # 0 or 1\n            yield ([Xleft.astype(np.uint8), Xright.astype(np.uint8)], Y)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8d9b367b01c49faa1fbfebafa5716a98fdb62202"},"cell_type":"code","source":"if TRAIN_FLG:\n    triples_batch_gen = image_triple_generator(triples_data,TRAIN_IMG, 32)\n    ([Xleft, Xright], Y) = triples_batch_gen.__next__()\n    print(\"generator output shapes:\")\n    print(Xleft.shape, Xright.shape, Y.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d0ceece8d47f49b9eea0b1239e832e81c5f65f1a"},"cell_type":"code","source":"# plt.imshow(Xright[2])","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"617896ffff7a1b97bd16491244b6dc8f6b0c056e"},"cell_type":"markdown","source":"# Load/ Train model"},{"metadata":{"_uuid":"a404a69cd8fbc325f734e88a01595a912aeaa3b9"},"cell_type":"markdown","source":"## branch model "},{"metadata":{"trusted":true,"_uuid":"8bd01192561222ff3eb74b391c9f91989423918c"},"cell_type":"code","source":"def create_base_network(input_shape):\n    '''Base network to be shared (eq. to feature extraction).\n    '''\n    seq = Sequential()\n    # CONV => RELU => POOL\n    seq.add(Conv2D(20, kernel_size=5, padding=\"same\", input_shape=input_shape,data_format=\"channels_last\",activation='relu'))\n    seq.add(BatchNormalization())\n    seq.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))\n    seq.add(BatchNormalization())\n    # CONV => RELU => POOL\n    seq.add(Conv2D(50, kernel_size=5, padding=\"same\",activation='relu'))\n    seq.add(BatchNormalization())\n    seq.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))\n    seq.add(BatchNormalization())\n    seq.add(Flatten())\n    seq.add(Dense(500,kernel_regularizer=regularizers.l2(0.01)))\n    \n    return seq","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c39bd82e2302e51b001ce88209db3469f69d2016"},"cell_type":"code","source":"if TRAIN_FLG:\n    image_size=IM_SIZE\n#     input_shape = (image_size,image_size, 3)\n    input_shape = (image_size,image_size,1)\n    base_network = create_base_network(input_shape)\n\n#     input_shape = (image_size,image_size, 3)\n    input_shape = (image_size,image_size,1)\n    vector_left =Input(shape=base_network.output_shape[1:])\n    vector_right = Input(shape=base_network.output_shape[1:])\n    img_l = Input(shape=input_shape)\n    img_r = Input(shape=input_shape)\n    x_l         = base_network(img_l)\n    x_r         = base_network(img_r)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"70af6ec7761a3befb0596a4ac99d591d3c233c1c"},"cell_type":"markdown","source":"##  head model"},{"metadata":{"trusted":true,"_uuid":"33ba7e308cc0b8b2dba8f3af4a794cb8c64396bc"},"cell_type":"code","source":"if TRAIN_FLG:\n    #layer to merge two encoded inputs with the l1 distance between them\n    mid        = 32\n    L_prod = Lambda(lambda x : x[0]*x[1])([vector_left, vector_right])\n    L_sum = Lambda(lambda x : x[0] + x[1])([vector_left, vector_right])\n    L1_distance= Lambda(lambda x : K.abs(x[0] - x[1]))([vector_left, vector_right])\n    L2_distance= Lambda(lambda x : K.square(x[0] - x[1]))([vector_left, vector_right])\n    distance= Concatenate()([L_prod, L_sum, L1_distance, L2_distance])\n    distance= Reshape((4, base_network.output_shape[1], 1), name='reshape1')(distance)\n    x = Conv2D(mid, (4, 1), activation='relu', padding='valid')(distance)\n    x = BatchNormalization()(x)\n    x = Reshape((base_network.output_shape[1], mid, 1))(x)\n    x = Conv2D(1, (1, mid), activation='linear', padding='valid')(x)\n    x = BatchNormalization()(x)\n    x = Flatten(name='flatten')(x)\n    pred = Dense(1, use_bias=True, activation='sigmoid', name='weighted-average',kernel_initializer=\"random_normal\")(x)\n    head_model = Model([vector_left, vector_right], outputs=pred, name='head')\n\n    x = head_model([x_l, x_r])\n    siamese_model = Model(inputs=[img_l, img_r], outputs= x)\n    siamese_model.compile(loss=\"binary_crossentropy\", optimizer=\"sgd\", metrics=[\"accuracy\"])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"987fa7f820f90ff90eba747ac942c8363ab766ca"},"cell_type":"code","source":"if TRAIN_FLG:\n    from keras.utils.vis_utils import plot_model\n    plot_model(base_network, to_file='branch_plot.png', show_shapes=True, show_layer_names=True,expand_nested=True)\n    pil_image.open('branch_plot.png')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2a11f2721a58ca8882e5c2d920a499afc6079664"},"cell_type":"code","source":"if TRAIN_FLG:\n    plot_model(head_model, to_file='head_plot.png', show_shapes=True, show_layer_names=True,expand_nested=True)\n    pil_image.open('head_plot.png')","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"189fd5c55a7f00ab2a490f4bcc034493c5c49f45"},"cell_type":"markdown","source":"# TRAIN\n"},{"metadata":{"trusted":true,"_uuid":"f05a8808c6da60889c4c92784742e6a5a92ddfa6"},"cell_type":"code","source":"if TRAIN_FLG:\n    triples_train,triples_test =train_test_split(triples_data, test_size=0.2, random_state=42)\n\n    callbacks=[\n        ReduceLROnPlateau(monitor='val_loss',patience=10,min_lr=1e-9,verbose=1,mode='min'),\n        ModelCheckpoint('siamese_mid.hdf5',monitor='val_loss',save_best_only=True,verbose=1)\n    ]\n\n    BATCH_SIZE=32\n    NUM_EPOCHS=30\n\n    train_gen = image_triple_generator(triples_train,TRAIN_IMG, BATCH_SIZE)\n    val_gen = image_triple_generator(triples_test,TRAIN_IMG, BATCH_SIZE)\n\n    num_train_steps = len(triples_train) // BATCH_SIZE\n    num_val_steps = len(triples_test) // BATCH_SIZE\n#     num_train_steps = 100\n#     num_val_steps = 30\n\n    siamese_model.save('siamese_trained_bb.h5')\n    history = siamese_model.fit_generator(train_gen,\n                                  steps_per_epoch=num_train_steps,\n                                  epochs=NUM_EPOCHS,\n                                  validation_data=val_gen,\n                                  validation_steps=num_val_steps,\n                                          callbacks=callbacks)\n    siamese_model.save('siamese_trained_bb.h5')\nelse: #load from file\n    siamese_model=load_model(SIAMESE_MOD)\n    siamese_model.load_weights(SIAMESE_MOD_MID)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e11f0c08c0ac85a6eb4069725436644ffa4d6388"},"cell_type":"markdown","source":"# Evaluation & submission"},{"metadata":{"trusted":true,"_uuid":"15b5febd95cd84f8c3192dbd31632086889af706"},"cell_type":"code","source":"PREDICT=False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee9670c33e5e193accb941266905b1758b21ebff"},"cell_type":"code","source":"# create pairs on test image,train image to gain similarity score between them\ndef create_pairs(test_img,train_imgs):\n    pairs = []\n    for img in train_imgs:\n#         pair = (os.path.join(TEST_IMG,test_img) , os.path.join(TRAIN_IMG,img[0]) , 0)\n        pair = (os.path.join(TEST_IMG,test_img) , os.path.join(TRAIN_IMG,img) , 0)\n        pairs.append(pair)\n    return pairs","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"42717d58249299da148b9755459a7d4c6685ceef"},"cell_type":"code","source":"import sys, os\n\n# Disable\ndef blockPrint():\n    sys.stdout = open(os.devnull, 'w')\n\n# Restore\ndef enablePrint():\n    sys.stdout = sys.__stdout__","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dbe62fcf4423a3bddaa7befe678a3f0bf4c34cb8"},"cell_type":"code","source":"test_paths=pd.read_csv(os.path.join(TEST_PARTS_DIR,\"test_all.txt\"),header=None, names=['Image'])\ntest_paths=test_paths['Image'].values\ntrain_paths=train_df[\"Image\"].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2f7a598bc7d2c9df75738d9ae11e32489a7347a6"},"cell_type":"code","source":"if PREDICT:\n    # scores is an array with number of claases dim\n    #given a scores vector of size (len(train)), group train labels to top 5 scored whales \n    new_whale='new_whale'\n    def get_top5whales(scores,train_paths=train_paths,threshold=0.99):\n        vhigh = 0\n        pos = [0, 0, 0, 0, 0, 0]\n\n        top_w = []\n        top5_submission=[]\n        s = set()\n        a = scores\n        for j in list(reversed(np.argsort(scores))): # j is an encoded label of some whale\n            img = train_paths[j] # get image value of train example j\n\n            if a[j] < threshold and new_whale not in s: # if score is lower than threshold and we didn't put new whale yet, than put new whale in the list\n                pos[len(top5_submission)] += 1\n                s.add(new_whale)\n                top5_submission.append(new_whale)\n            if len(top5_submission) == 5: break;\n            whales=no_new_whale[no_new_whale['Image']==img][\"Id\"]\n            if whales is not None and len(whales)>0:\n                for w in whales.values:\n                    if w not in s: # if we didn't yet added this whale\n                        if a[j] >= threshold:\n                            vhigh += 1\n                        s.add(w)\n                        top5_submission.append(w)\n            if len(top5_submission) == 5: break;\n            if new_whale not in s: pos[5] += 1\n        assert len(top5_submission) == 5 \n        assert len(s) == 5\n        return top5_submission","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"27d71c1c050b50dbcea765fc8ef5e804d4319c9c"},"cell_type":"code","source":"if PREDICT:\n    # for each test image gain similarity core for each one of the train images, and group them to top 5 whales for submission\n    batch_size=64\n\n    submissions={}\n    # test on small set:\n    # test_paths_t=test_paths[:10]\n    for i in tqdm(range(len(test_paths)),desc='scores'):\n    #     print(i)\n        tst_img=test_paths[i]\n        pairs= create_pairs(tst_img,train_paths)\n        pairs1=pairs[:batch_size*(len(pairs)//batch_size)]\n        test_generator = image_triple_generator(image_triples=pairs1,directory=None, batch_size=batch_size,augment=False,shuffle=False)\n        scors1= siamese_model.predict_generator(test_generator,verbose = 1,steps=len(pairs)//batch_size , workers=1) \n        scores=scors1.flatten()\n\n        pairs2=pairs[batch_size*(len(pairs)//batch_size):]\n        test_generator = image_triple_generator(image_triples=pairs2,directory=None, batch_size=len(pairs2),augment=False,shuffle=False)\n        scors2= siamese_model.predict_generator(test_generator,verbose = 1,steps=1 , workers=1) \n\n        scores=np.concatenate((scores,scors2.flatten()))\n        submissions[tst_img]=' '.join(get_top5whales(scores,train_paths=train_paths,threshold=0.99))\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2b89ed37faabf427d65e83ea8c586097d719090a"},"cell_type":"code","source":"if PREDICT:\n    df_whales=pd.DataFrame.from_dict(submissions, orient='index', columns=['Id'])\n    df_whales['Image'] = df_whales.index\n    df_whales.to_csv(\"whales_pred_siamese.csv\", index = False) ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"766b43e6f420a946fc3e7562876dafff90889ef5"},"cell_type":"code","source":"# import the modules we'll need\nfrom IPython.display import HTML\nimport pandas as pd\nimport numpy as np\nimport base64\n\nif PREDICT:\n    # function that takes in a dataframe and creates a text link to  \n    # download it (will only work for files < 2MB or so)\n    # def create_download_link(df, title = \"Download CSV file\", filename = \"data.csv\"):  \n    def create_download_link(df, title = \"Download CSV file\",input_file='whales_pred_siamese.csv', filename = \"data.csv\"):  \n        csv = pd.read_csv(input_file)\n        csv= csv.to_csv(index = False)\n        b64 = base64.b64encode(csv.encode())\n        payload = b64.decode()\n        html = '<a download=\"{filename}\" href=\"data:text/csv;base64,{payload}\" target=\"_blank\">{title}</a>'\n        html = html.format(payload=payload,title=title,filename=filename)\n        return HTML(html)\n\n    # create a random sample dataframe\n\n    # create a link to download the dataframe\n    create_download_link()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"5f88856e928511787353fb9026b92dd58694db33"},"cell_type":"code","source":"#load submission from file (calc offline)\nif not PREDICT:\n    df_whales=pd.read_csv(SUBMISSION_DF)\n    df_whales.to_csv(\"whales_pred_siamese.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}