import numpy as np
import matplotlib.pyplot as plt
import cv2
import os
import random
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
datadir = 'UKbench'
complete_images = []
img_size = 100
load_data(datadir)
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.
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])
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
inputs1 = []
for image,class_num in train_dataset:
inputs1.append(image)
inputs1 = np.array(inputs1)
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)
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 _________________________________________________________________
preprocessed_images = preprocess_input(inputs1)
conv4_features = model1.predict(preprocessed_images)
print(conv4_features.shape)
inputs2 = conv4_features
(1500, 6, 6, 512)
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
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
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 _________________________________________________________________
features = model2(inputs2)
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)
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
num_nearest = 1
mean_features = mean_tensor(features)
manual_grad = grad_analytic(features[0],mean_features[0])
auto_grad = grad_tape(features,mean_features)
print(manual_grad.shape)
print(auto_grad.shape)
(1, 512) (1500, 512)
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)
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)
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)
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
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)
scores = []
scores.append(score_before_training)
print(scores)
[2.358]
num_epochs = 4
loss_hist = []
opt = tf.optimizers.Adam()
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
print(scores)
[2.358, 2.406, 2.416, 2.384, 2.382]
plt.plot(scores)
[<matplotlib.lines.Line2D at 0x1e733c4ba88>]