In [1]:
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os
import random
In [2]:
def load_data(datadir):
    count = 0
    for image in os.listdir(datadir):
        img_path = os.path.join(datadir,image)
        img_arr = cv2.imread(img_path)
        new_arr = cv2.resize(img_arr,(img_size,img_size))
        new_arr = np.array(new_arr)
        class_num = count//4
        complete_images.append([new_arr,class_num])
        count += 1
In [3]:
datadir = 'UKbench'
complete_images = []
img_size = 100
load_data(datadir)
In [4]:
complete_images = np.array(complete_images)
count=0
for image,class_num in complete_images[:6]:
    plt.subplot(3,3,count+1)
    plt.imshow(image)
    plt.title(class_num)
    count += 1
C:\Users\harsh\anaconda3\lib\site-packages\ipykernel_launcher.py:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
  """Entry point for launching an IPython kernel.
In [5]:
train_dataset = []
query_dataset = []
total_images = 2000
for i in range(total_images):
    class_num = i//4
    if(i%4==0):
        query_dataset.append([complete_images[i][0],class_num])
        
    else:
        train_dataset.append([complete_images[i][0],class_num])
In [6]:
print('Number of training Images',len(train_dataset))
print('Number of training Images',len(query_dataset))
num_train_images = len(train_dataset)
num_query_images = len(query_dataset)
Number of training Images 1500
Number of training Images 500
In [7]:
inputs1 = []
for image,class_num in train_dataset:
    inputs1.append(image)

inputs1 = np.array(inputs1)
In [8]:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.applications.vgg16 import VGG16
from tensorflow.keras.applications.vgg16 import preprocess_input
from tensorflow.keras.models import Model
model1_inputs = keras.Input(shape = (100,50,3),
                               name = 'model1_inputs')
model = VGG16(include_top = False, input_shape = (100,100,3))
model1 = Model(inputs = model.inputs, outputs = model.layers[-5].output)
In [9]:
model1.summary()
Model: "functional_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         [(None, 100, 100, 3)]     0         
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 100, 100, 64)      1792      
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 100, 100, 64)      36928     
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 50, 50, 64)        0         
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 50, 50, 128)       73856     
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 50, 50, 128)       147584    
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 25, 25, 128)       0         
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 25, 25, 256)       295168    
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 25, 25, 256)       590080    
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 25, 25, 256)       590080    
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 12, 12, 256)       0         
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 12, 12, 512)       1180160   
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 12, 12, 512)       2359808   
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 12, 12, 512)       2359808   
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 6, 6, 512)         0         
=================================================================
Total params: 7,635,264
Trainable params: 7,635,264
Non-trainable params: 0
_________________________________________________________________
In [10]:
preprocessed_images = preprocess_input(inputs1)
conv4_features = model1.predict(preprocessed_images)
In [11]:
print(conv4_features.shape)
inputs2 = conv4_features
(1500, 6, 6, 512)
In [12]:
def build_model():
    model_inputs = tf.keras.layers.Input(
        shape = (18,18,512),
                                          name = 'model2_inputs', dtype = np.float32)
    x = tf.keras.layers.Conv2D(512,(3,3), activation = 'relu',
                               padding = 'same',
                               name = 'new_conv1')(model_inputs)
    x = tf.keras.layers.Conv2D(512,(3,3),activation = 'relu',
                               padding = 'same',
                               name = 'new_conv2')(x)
    x = tf.keras.layers.Conv2D(512,(3,3),activation = 'relu',
                               padding = 'same',
                               name = 'new_conv3')(x)
    model_outputs = tf.keras.layers.GlobalMaxPool2D()(x)
    model2 = Model(inputs = model_inputs, outputs = model_outputs)
    model2.layers[-4].set_weights(model.layers[-4].get_weights())
    model2.layers[-3].set_weights(model.layers[-3].get_weights())
    model2.layers[-2].set_weights(model.layers[-2].get_weights())
    model2.layers[-2].activation = tf.keras.layers.PReLU(tf.initializers.constant(0.20))
    
    return model2
In [13]:
def mean_tensor(features):
    mean_features = []
    
    for i in range(num_train_images):
        actual_feature = features[i]
        actual_feature = tf.reshape(actual_feature,(1,actual_feature.shape[0]))
        similarities = tf.keras.losses.cosine_similarity(actual_feature,features)
        index = tf.argsort(similarities)
        mask = index[1:num_nearest+1]
        near_tensor = tf.gather(features,mask)
        mean = tf.math.reduce_mean(near_tensor,axis=0)
        mean_features.append(mean)
        
    mean_features = tf.convert_to_tensor(mean_features)
    return mean_features

def custom_loss(features,mean_features):
    cosine_loss = tf.keras.losses.cosine_similarity(
        features,mean_features)
    cosine_loss = tf.math.reduce_sum(cosine_loss)
    
    return cosine_loss
In [14]:
model2 = build_model()
model2.layers[-4].trainable = False
model2.layers[-3].trainable = False
model2.summary()
Model: "functional_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
model2_inputs (InputLayer)   [(None, 18, 18, 512)]     0         
_________________________________________________________________
new_conv1 (Conv2D)           (None, 18, 18, 512)       2359808   
_________________________________________________________________
new_conv2 (Conv2D)           (None, 18, 18, 512)       2359808   
_________________________________________________________________
new_conv3 (Conv2D)           (None, 18, 18, 512)       2359808   
_________________________________________________________________
global_max_pooling2d (Global (None, 512)               0         
=================================================================
Total params: 7,079,424
Trainable params: 2,359,808
Non-trainable params: 4,719,616
_________________________________________________________________
In [15]:
features = model2(inputs2)
In [16]:
print(features.shape)
print(features[0])
(1500, 512)
tf.Tensor(
[-3.86724448e+00 -4.92823839e+00 -4.76020908e+00 -3.30720496e+00
  3.14805679e+01  1.81331043e+01 -4.38848209e+00  3.68302870e+00
 -5.60245514e+00 -4.32678431e-01 -1.18111312e+00 -7.70206928e+00
  2.30247154e+01 -6.45592356e+00 -2.09020066e+00  3.31930237e+01
 -2.96640515e+00  1.59020720e+01 -3.29168630e+00  1.66467247e+01
 -1.59239542e+00 -3.76184726e+00  2.40531015e+00 -2.84475398e+00
 -1.19855583e+00  3.37831955e+01 -4.93994284e+00 -3.12300116e-01
 -1.10271823e+00 -3.79013896e+00  5.98561049e+00 -4.34422636e+00
 -5.27143300e-01 -1.30535078e+00  2.35238590e+01 -3.92592287e+00
  1.41813498e+01  1.75650539e+01 -5.88714409e+00 -2.57613969e+00
  3.32859726e+01 -6.44199312e-01  3.91004868e+01  3.19273434e+01
 -5.01179647e+00 -2.41783786e+00  7.36698246e+00 -3.34693074e+00
 -4.70005751e+00 -2.72365332e+00  2.12616329e+01  2.08557224e+00
  2.61224918e+01  4.87080421e+01  3.21086812e+00  5.44679785e+00
 -5.17127419e+00 -3.81240010e+00  1.87631583e+00 -2.17818809e+00
 -4.17686224e+00 -3.11299515e+00  6.62351322e+00 -3.27044868e+00
  2.04357648e+00 -2.06456828e+00 -4.04586697e+00 -3.23736548e+00
 -3.56649208e+00  1.53556509e+01 -6.89417601e+00  7.88372040e+00
 -6.32929444e-01  1.22311440e+01 -5.68611920e-01 -2.18790412e+00
  5.97390671e+01 -3.04073066e-01 -1.60863674e+00 -1.44786641e-01
 -6.45522642e+00  2.20233917e+01  2.58260651e+01  5.16234741e+01
 -5.52209997e+00  7.76586246e+00  4.15037811e-01 -4.68603945e+00
  9.08567810e+00  5.14080715e+00 -1.55140865e+00 -2.36898518e+00
 -4.46335459e+00 -2.22940254e+00  1.10497570e+01  1.69243183e+01
  5.43260717e+00 -5.35617161e+00 -1.89905679e+00  1.89650822e+01
 -3.90887499e+00  2.38522835e+01 -4.51450586e+00  2.25447578e+01
 -8.12239647e+00 -4.29022789e+00 -1.51432610e+00 -2.10153008e+00
 -4.42796326e+00 -5.39036655e+00 -1.44446957e+00 -4.77039814e+00
 -3.66937137e+00  3.03928871e+01 -2.15266562e+00 -4.69747019e+00
 -2.90777373e+00  6.84955788e+00 -4.25464630e-01 -1.77225006e+00
 -2.39678070e-01 -3.01561403e+00 -7.78813314e+00  7.40070953e+01
  1.49887972e+01  1.58997726e+00 -5.90835190e+00  1.21999903e+01
 -1.89072800e+00  1.64417114e+01  1.73136311e+01 -3.92452121e+00
  5.06957579e+00 -5.27504826e+00 -5.19183779e+00 -7.47854614e+00
 -1.64806688e+00 -2.00487280e+00  2.29710827e+01 -5.45820236e+00
 -7.42003775e+00 -6.06152058e+00  1.49229503e+00 -3.01135945e+00
 -6.31518412e+00 -4.39462805e+00 -1.01910806e+00  2.90809517e+01
 -1.42101502e+00  8.29361057e+00 -2.45182967e+00 -2.57855916e+00
  1.56406527e+01  4.41933870e+00 -1.23436058e+00  1.81815720e+01
  1.65701067e+00  1.08201046e+01 -1.51781738e+00  1.08756855e-01
 -2.74838042e+00  7.44434452e+00 -3.37573600e+00  3.23964500e+01
 -4.57418293e-01 -3.57762003e+00 -1.02579904e+00 -6.61167622e+00
  7.33627701e+00 -4.01897621e+00  1.52127771e+01 -2.99472284e+00
  2.06347980e+01  1.81479721e+01 -3.95993090e+00 -4.41151047e+00
  6.08122253e+00 -3.00223207e+00 -1.94975698e+00  9.90433788e+00
 -1.44890773e+00 -4.19569731e+00 -1.82220805e+00  1.83194530e+00
 -9.30493355e-01 -9.86016750e-01  2.47063656e+01 -1.17864490e+00
 -3.80934209e-01 -1.99836862e+00 -3.61199164e+00 -1.87562847e+00
 -2.06311703e+00 -1.50285888e+00 -4.67515200e-01 -2.93021226e+00
  8.72178745e+00 -3.78894281e+00 -2.90574908e+00 -1.86980021e+00
 -5.42941427e+00 -2.62240261e-01  5.19685221e+00 -4.07007170e+00
 -4.24144030e+00 -5.72246122e+00 -4.06145185e-01 -2.38260055e+00
 -2.70180035e+00  7.81550360e+00 -1.87182114e-01 -3.22586751e+00
  1.25747023e+01 -1.68638670e+00 -4.99252319e+00 -1.06804955e+00
 -7.52389789e-01  4.30940986e-01  4.48195791e+00  2.69072938e+00
  7.66289711e+00 -2.97057962e+00 -3.31657028e+00  1.03348827e+01
 -2.82657981e+00  2.41739140e+01 -3.34372497e+00 -9.57924545e-01
 -2.19885087e+00  1.68772411e+01 -4.11260843e+00 -3.36247063e+00
 -1.38347471e+00 -1.38778043e+00  1.40676327e+01 -3.59049606e+00
  2.57527294e+01 -3.41061330e+00 -4.34188604e+00 -4.92705679e+00
  7.10920095e+00 -1.56627774e+00  9.37640667e+00 -3.59033656e+00
 -4.70008326e+00 -6.10113573e+00 -6.60247946e+00 -6.20063496e+00
 -2.49268556e+00  3.94988632e+00 -7.24356234e-01 -5.91347027e+00
 -3.22955370e+00 -1.83837473e+00 -2.74977684e+00  2.73672237e+01
 -2.97044396e-01 -4.41464424e-01 -2.59766579e+00 -9.22646165e-01
 -2.73666739e+00  2.66383266e+00 -5.68981171e+00 -5.01243258e+00
  9.84170723e+00  2.52822447e+00  1.99928558e+00 -8.09908092e-01
 -6.07101536e+00  2.67132425e+00  1.63855389e-01 -2.50246978e+00
  1.89553089e+01 -7.31856883e-01 -2.26448679e+00 -4.22911692e+00
  3.93505287e+01  2.04604168e+01 -1.92312086e+00 -2.50450516e+00
 -3.95211911e+00  3.39121742e+01 -1.10468388e+00 -3.18945837e+00
 -5.00376225e+00 -6.38336658e-01 -6.08820534e+00  1.04055643e-01
 -3.59316558e-01 -8.38860035e-01 -8.86173368e-01 -2.07169676e+00
  3.48066628e-01  7.23724985e+00  1.74561939e+01 -3.67982650e+00
 -1.09354906e-01 -4.41318464e+00  5.01742649e+00 -1.94869316e+00
  9.68825245e+00 -2.44732070e+00 -4.29277134e+00 -1.79582393e+00
 -2.71341443e+00  7.12525463e+00 -2.21380258e+00 -7.52323508e-01
 -4.88707018e+00 -4.46895790e+00 -7.17387152e+00 -6.72766352e+00
  4.47433591e-01 -3.11017656e+00 -5.84191942e+00  4.60565090e-02
  1.82680380e+00  5.72630119e+01 -2.33376956e+00  2.57676768e+00
 -7.40237713e-01  3.18204761e+00  8.52762794e+00  1.90057456e-01
 -5.30344105e+00 -2.13300872e+00 -2.60826916e-01  1.44639759e+01
  3.86777306e+01 -7.77387190e+00 -5.97837782e+00  6.49542465e+01
 -2.36678433e+00 -2.62161756e+00  3.93886876e+00 -5.08061790e+00
 -4.32349682e+00 -3.84370089e+00 -7.86852181e-01 -8.80454719e-01
  5.29940081e+00  4.31853628e+00 -8.51718724e-01  5.39137154e+01
  4.92753220e+01 -3.55440187e+00  8.06413746e+00  1.48946009e+01
 -5.46746731e+00 -2.24680519e+00  1.34829175e+00 -1.84297717e+00
  6.67966747e+00 -3.59617996e+00  1.21704035e+01 -3.25916839e+00
  3.42575760e+01 -3.13322377e+00 -2.73166156e+00  4.71808815e+01
  2.39393120e+01 -6.52191782e+00 -4.45440006e+00  2.12567921e+01
 -7.01667786e+00 -4.26400900e+00 -1.53531873e+00  7.06622744e+00
 -9.72367108e-01  3.47646904e+01 -1.04477219e-01 -2.68459439e+00
  2.72225022e+00 -5.09038115e+00 -6.48727059e-01 -5.24270296e+00
 -7.18000412e+00  3.46482992e-01 -2.62494445e+00 -1.63046670e+00
 -7.60786057e+00 -1.14197426e-01 -1.93912113e+00 -4.35499287e+00
  6.32774496e+00 -1.43074536e+00  5.57636166e+00 -9.93780613e-01
  1.16584770e+02 -3.43447614e+00  3.68441620e+01 -3.25768518e+00
 -1.52960873e+00 -4.29532576e+00 -3.62129021e+00 -2.57861495e+00
  3.92303395e+00 -5.17331743e+00  5.10773087e+00 -3.12945938e+00
 -4.87181807e+00  3.16022663e+01  9.32156277e+00 -2.41744518e+00
 -3.19321132e+00 -4.27417803e+00 -4.17123938e+00 -2.66694331e+00
  8.43007565e+00 -4.02333403e+00 -4.70839691e+00  4.47693872e+00
  3.90483131e+01 -1.89585876e+00  1.46720724e+01 -5.35832834e+00
  2.33613377e+01  1.90577564e+01  2.10006027e+01 -2.11780524e+00
 -1.77619576e+00 -5.46899271e+00  3.23318052e+00 -4.85282087e+00
 -5.76267958e+00 -1.61905348e+00 -6.17917490e+00 -3.58955050e+00
 -3.96165252e+00 -1.92106217e-01 -9.06788170e-01 -3.03916097e+00
 -2.36973715e+00 -3.55743003e+00 -2.14212203e+00 -3.93417549e+00
 -1.48656166e+00 -4.33551693e+00  2.21941910e+01  4.46391182e+01
  7.38729835e-02  1.89843311e+01 -1.79386067e+00 -3.02644324e+00
  2.50946522e+01  3.88808022e+01 -4.83611774e+00 -6.85326529e+00
 -2.41714525e+00  1.02648087e+01 -1.00129282e+00  8.74644995e-01
 -5.93024790e-01 -4.10337973e+00 -3.96318245e+00  7.98712075e-01
 -7.97026098e-01 -1.43805766e+00 -2.20328808e+00 -4.58875895e+00
 -4.87395477e+00 -2.95924330e+00 -2.71089673e+00 -4.94610739e+00
 -9.64144349e-01  6.68209255e-01 -5.91388655e+00  3.73256278e+00
 -4.11142731e+00  3.37849331e+00 -3.09515047e+00  9.75882339e+00
 -8.47725034e-01 -7.62478292e-01  1.91221008e+01 -8.52798653e+00
 -5.23105955e+00 -2.09107852e+00 -4.85859728e+00 -1.42835867e+00
  1.77173309e+01 -1.70528471e+00 -2.72174239e+00  2.22825482e-01
 -4.77728081e+00 -4.63650751e+00  2.21295452e+01  3.17073307e+01
 -1.25673997e+00  1.72973614e+01 -6.74985600e+00  1.43754196e+01
 -2.77563977e+00  2.89803810e+01  2.54968262e+00 -2.02122545e+00
  3.15477610e+00 -3.61274886e+00 -2.65721297e+00  4.01090908e+00
  3.00924587e+01 -7.35473967e+00  8.97899628e+00 -8.92128766e-01
 -3.80161738e+00  4.29521275e+00  7.37506104e+00 -1.88697493e+00
  2.76325798e+01 -2.96516967e+00 -1.68745768e+00 -4.24984360e+00], shape=(512,), dtype=float32)
In [17]:
def grad_analytic(actual_feature,mean_feature):
    af = tf.reshape(actual_feature,(1,actual_feature.shape[0]))
    am = tf.reshape(mean_feature,(1,mean_feature.shape[0]))
    af_norm = tf.norm(af)
    am_norm = tf.norm(am)
    prod1 = af_norm*am_norm
    prod2 = tf.math.pow(af_norm,3)*am_norm
    grad = (am/prod1) - ((tf.matmul(af,am,transpose_b=True)*af)/prod2)
    return grad

def grad_tape(features,mean_features):
    with tf.GradientTape() as tape:
        features = model2(inputs2)
        loss = custom_loss(features,mean_features)
        grad = tape.gradient(loss,features)
    
    return grad
In [18]:
num_nearest = 1
In [19]:
mean_features = mean_tensor(features)
manual_grad = grad_analytic(features[0],mean_features[0])
auto_grad = grad_tape(features,mean_features)
In [20]:
print(manual_grad.shape)
print(auto_grad.shape)
(1, 512)
(1500, 512)
In [21]:
print(manual_grad[0][:50])
tf.Tensor(
[ 2.40739246e-06 -1.97951522e-05 -1.32955283e-05 -1.46260754e-05
 -1.27278414e-04  8.73497047e-05  2.69623670e-05  2.91758886e-04
 -8.00625639e-06 -4.23896345e-05 -1.91199797e-05 -2.29564102e-06
  2.12045372e-04 -4.01554280e-06 -3.49135553e-06  2.23479903e-04
 -1.12488615e-05 -6.70020381e-05 -2.04920252e-06 -9.50611284e-05
  1.08883796e-05  3.11172334e-06  2.04062264e-04 -3.49388938e-06
 -2.95023710e-07  2.36154883e-05 -6.29770875e-06 -1.26894302e-05
  4.68821199e-05 -3.90107380e-06  3.78434015e-05 -1.10246401e-06
  4.93842963e-05 -1.64933990e-05  4.31018998e-06  2.19553876e-05
 -5.31767691e-05 -1.43636309e-04 -2.99333224e-05  1.30645822e-06
  4.62694152e-05 -1.22777965e-05 -2.06014083e-05  1.72881177e-04
 -6.50160291e-06 -8.06131175e-06 -3.99509518e-05  1.24980288e-05
  5.54506187e-06 -3.45345106e-05], shape=(50,), dtype=float32)
In [22]:
print(auto_grad[0][:50])
tf.Tensor(
[-2.40737972e-06  1.97951704e-05  1.32955465e-05  1.46260900e-05
  1.27278341e-04 -8.73497629e-05 -2.69623579e-05 -2.91758945e-04
  8.00627822e-06  4.23896417e-05  1.91199870e-05  2.29565921e-06
 -2.12045503e-04  4.01556827e-06  3.49136099e-06 -2.23480019e-04
  1.12488688e-05  6.70020236e-05  2.04921344e-06  9.50610993e-05
 -1.08883769e-05 -3.11171243e-06 -2.04062308e-04  3.49389666e-06
  2.95027348e-07 -2.36156047e-05  6.29772330e-06  1.26894329e-05
 -4.68821236e-05  3.90108471e-06 -3.78434270e-05  1.10247856e-06
 -4.93842999e-05  1.64934027e-05 -4.31026274e-06 -2.19553804e-05
  5.31767400e-05  1.43636280e-04  2.99333478e-05 -1.30644912e-06
 -4.62695316e-05  1.22778010e-05  2.06012919e-05 -1.72881293e-04
  6.50161746e-06  8.06131902e-06  3.99509445e-05 -1.24980215e-05
 -5.54505095e-06  3.45345215e-05], shape=(50,), dtype=float32)
In [23]:
query_inputs = []
for image,class_label in query_dataset:
    query_inputs.append(image)
    
query_inputs = np.array(query_inputs)
query_inputs = preprocess_input(query_inputs)
query_features1 = model1.predict(query_inputs)
In [24]:
def top_n_score(n,query_final_features,train_features,train_final_features):
    vector = []
    for i in range(num_query_images):
        temp_score = 0
        actual_feature = query_final_features[i][0]
        actual_feature = tf.reshape(actual_feature,(1,actual_feature.shape[0]))
        similarities = tf.keras.losses.cosine_similarity(actual_feature,train_features)
        index = tf.argsort(similarities)
        for j in range(n):
            if(train_final_features[index[j]][1]==query_final_features[i][1]):
                temp_score += 1

        vector.append(temp_score) 
    
    avg_score = np.sum(vector)/len(vector)
    return avg_score
In [25]:
scores = []
n = 3

def score(query_features1,inputs2):
    query_features2 = model2(query_features1)
    train_features = model2(inputs2)
    query_final_features = []
    for i in range(num_query_images):
        query_final_features.append([query_features2[i],query_dataset[i][1]])

    train_final_features = []
    for i in range(num_train_images):
        train_final_features.append([train_features[i],train_dataset[i][1]])
        
    score = top_n_score(n,query_final_features,train_features,train_final_features)
    return score

score_before_training = score(query_features1,inputs2)
In [26]:
scores = []
scores.append(score_before_training)
print(scores)
[2.358]
In [27]:
num_epochs = 4
loss_hist = []
opt = tf.optimizers.Adam()
In [28]:
for i in range(num_epochs):
    temp_features = model2(inputs2)
    mean_features = mean_tensor(temp_features)
    with tf.GradientTape() as tape:
        tape.watch(model2.trainable_variables)
        features = model2(inputs2)
        loss = custom_loss(features,mean_features)
        loss_hist.append(loss)
        grads = tape.gradient(loss,model2.trainable_variables)
        opt.apply_gradients(zip(grads,model2.trainable_variables))
        display(loss)
        print('Epoch '+str(i+1)+' completed')
     
    temp_score = score(query_features1,inputs2)
    scores.append(temp_score)
<tf.Tensor: shape=(), dtype=float32, numpy=-1166.7727>
Epoch 1 completed
<tf.Tensor: shape=(), dtype=float32, numpy=-1367.8875>
Epoch 2 completed
<tf.Tensor: shape=(), dtype=float32, numpy=-1439.853>
Epoch 3 completed
<tf.Tensor: shape=(), dtype=float32, numpy=-1467.2266>
Epoch 4 completed
In [29]:
print(scores)
[2.358, 2.406, 2.416, 2.384, 2.382]
In [30]:
plt.plot(scores)
Out[30]:
[<matplotlib.lines.Line2D at 0x1e733c4ba88>]