mirror of
https://github.com/20kaushik02/CSE515_MWDB_Project.git
synced 2025-12-06 09:24:07 +00:00
360 lines
14 KiB
Plaintext
360 lines
14 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from utils import *\n",
|
|
"warnings.filterwarnings('ignore')\n",
|
|
"%matplotlib inline\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"fd_collection = getCollection(\"team_5_mwdb_phase_2\", \"fd_collection\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"class ImageGraph:\n",
|
|
" \"\"\"\n",
|
|
" Construct image-similarity graph and apply personalized pagerank algorithm to get PPR scores and find relevant images\n",
|
|
" \"\"\"\n",
|
|
"\n",
|
|
" def __init__(self, fd_collection, verbose=False):\n",
|
|
" self.fd_collection = fd_collection\n",
|
|
" self.similarity_graph = None\n",
|
|
" self.verbose = verbose\n",
|
|
"\n",
|
|
" def create_similarity_graph(\n",
|
|
" self, n, feature_model, semantic_data=None, dim_reduction_method=None\n",
|
|
" ):\n",
|
|
" if semantic_data is None:\n",
|
|
" # Similarity graph from feature models\n",
|
|
" image_sim_matrix = find_image_image_similarity(fd_collection, feature_model)\n",
|
|
" if self.verbose:\n",
|
|
" print(\"Image-image similarity matrix constructed from\", feature_model)\n",
|
|
" else:\n",
|
|
" # Similarity graph from image-semantic latent space\n",
|
|
" # LS3, LS4\n",
|
|
" if \"sim-matrix\" in semantic_data:\n",
|
|
" # for now, don't work with LS3\n",
|
|
" # TODO: do similar to task 7 and 10\n",
|
|
" image_sim_matrix = np.array(semantic_data[\"sim-matrix\"])\n",
|
|
" if image_sim_matrix.shape[0] != NUM_IMAGES:\n",
|
|
" raise TypeError(\n",
|
|
" \"Functionality to construct similarity graph from LS3 not yet done\"\n",
|
|
" )\n",
|
|
" if self.verbose:\n",
|
|
" print(\"Using image-image similarity matrix from semantic data\")\n",
|
|
" # LS1, LS2\n",
|
|
" else:\n",
|
|
" image_semantic = semantic_data[\"image-semantic\"]\n",
|
|
" # SVD, CP\n",
|
|
" if \"semantics-core\" in semantic_data:\n",
|
|
" semantics_core = np.array(semantic_data[\"semantics-core\"])\n",
|
|
" if len(semantics_core.shape) == 1:\n",
|
|
" semantics_core = np.diag(semantics_core)\n",
|
|
" image_semantic = np.matmul(image_semantic, semantics_core)\n",
|
|
"\n",
|
|
" image_sim_matrix = np.zeros((NUM_IMAGES, NUM_IMAGES))\n",
|
|
" # Calculate half and fill the other\n",
|
|
" for i in range(NUM_IMAGES):\n",
|
|
" for j in range(i + 1, NUM_IMAGES):\n",
|
|
" # Note: lower the value, lower the distance => higher the similarity\n",
|
|
" distance_measure = (\n",
|
|
" kl_divergence_measure\n",
|
|
" if dim_reduction_method == \"lda\"\n",
|
|
" else euclidean_distance_measure\n",
|
|
" )\n",
|
|
" image_sim_matrix[j][i] = distance_measure(\n",
|
|
" np.array(image_semantic[i]),\n",
|
|
" np.array(image_semantic[j]),\n",
|
|
" )\n",
|
|
" image_sim_matrix[i][j] = image_sim_matrix[j][i]\n",
|
|
" if self.verbose:\n",
|
|
" print(\n",
|
|
" \"Image-image similarity matrix constructed from given image-semantic\"\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Create an unweighted directed similarity graph, with no self-loops\n",
|
|
" self.similarity_graph = []\n",
|
|
" for i in range(len(image_sim_matrix)):\n",
|
|
" # distances should be small, so sort in ascending order\n",
|
|
" similar_image_ids = np.argsort(image_sim_matrix[i])[\n",
|
|
" 1 : n + 1\n",
|
|
" ] # exclude self\n",
|
|
" self.similarity_graph.extend(\n",
|
|
" [(i * 2, j * 2) for j in similar_image_ids]\n",
|
|
" ) # i*2 cuz even IDs\n",
|
|
" if self.verbose:\n",
|
|
" print(\"Similarity graph created\")\n",
|
|
"\n",
|
|
" def personalized_pagerank(\n",
|
|
" self, label, m, damping_factor=0.85, max_iter=1000, tol=1e-6\n",
|
|
" ):\n",
|
|
" import time\n",
|
|
"\n",
|
|
" if self.similarity_graph is None:\n",
|
|
" raise ValueError(\n",
|
|
" \"Similarity graph not created. Call create_similarity_graph() first.\"\n",
|
|
" )\n",
|
|
"\n",
|
|
" label_indices = [\n",
|
|
" img[\"image_id\"] for img in self.fd_collection.find({\"true_label\": label})\n",
|
|
" ] # IDs of images with the given label\n",
|
|
" num_label_nodes = len(label_indices)\n",
|
|
"\n",
|
|
" pr_scores = np.ones(NUM_IMAGES) / NUM_IMAGES # Initialize PageRank scores\n",
|
|
" if self.verbose:\n",
|
|
" print(\"Initialized pagerank scores\")\n",
|
|
"\n",
|
|
" for _iter in range(max_iter):\n",
|
|
" prev_scores = np.copy(pr_scores)\n",
|
|
"\n",
|
|
" # for every edge\n",
|
|
" for (i, j) in self.similarity_graph:\n",
|
|
" # add neighbor's score\n",
|
|
" pr_scores[int(i / 2)] += pr_scores[int(j / 2)]\n",
|
|
" # damping\n",
|
|
" pr_scores *= damping_factor\n",
|
|
"\n",
|
|
" # extra teleport prob for label nodes only\n",
|
|
" for label_node in label_indices:\n",
|
|
" pr_scores[label_node] += 1 - damping_factor\n",
|
|
" pr_scores[label_node] /= num_label_nodes\n",
|
|
"\n",
|
|
" # normalize\n",
|
|
" pr_scores /= sum(pr_scores)\n",
|
|
"\n",
|
|
" # check for convergence\n",
|
|
" conv_tol = np.sum(np.abs(prev_scores - pr_scores))\n",
|
|
" if self.verbose:\n",
|
|
" print(f\"Iter {_iter}, conv_tol={conv_tol}\")\n",
|
|
" if conv_tol < tol:\n",
|
|
" if self.verbose:\n",
|
|
" print(f\"Converged\")\n",
|
|
" break\n",
|
|
"\n",
|
|
" # Select top m images based on PageRank scores\n",
|
|
" top_m_indices = np.argsort(pr_scores)[::-1][\n",
|
|
" :m\n",
|
|
" ] # sort indices, reverse and take top m\n",
|
|
" return top_m_indices * 2 # again, even IDs\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"image_sim-cm_fd-svd-10-semantics.json loaded\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"n = int(input(\"Enter value of n (no. of edges for each image in similarity graph): \"))\n",
|
|
"if n < 1:\n",
|
|
" raise ValueError(\"n should be a positive integer\")\n",
|
|
"\n",
|
|
"l = int(input(\"Enter target label l:\"))\n",
|
|
"if l < 0 or l > 100:\n",
|
|
" raise ValueError(\"l should be in range[0,100]\")\n",
|
|
"\n",
|
|
"m = int(input(\"Enter value of m (no. of significant images relative to given label): \"))\n",
|
|
"if m < 1:\n",
|
|
" raise ValueError(\"m should be a positive integer\")\n",
|
|
"\n",
|
|
"given_ls = int(\n",
|
|
" (input(\"Enter 0 to select a feature model, 1 to select a latent space: \"))\n",
|
|
")\n",
|
|
"\n",
|
|
"selected_feature_model = valid_feature_models[\n",
|
|
" str(input(\"Enter feature model - one of \" + str(list(valid_feature_models.keys()))))\n",
|
|
"]\n",
|
|
"\n",
|
|
"if given_ls:\n",
|
|
" selected_latent_space = valid_latent_spaces[\n",
|
|
" str(\n",
|
|
" input(\n",
|
|
" \"Enter latent space - one of \" + str(list(valid_latent_spaces.keys()))\n",
|
|
" )\n",
|
|
" )\n",
|
|
" ]\n",
|
|
"\n",
|
|
" k = int(input(\"Enter value of k (no. of latent semantics): \"))\n",
|
|
" if k < 1:\n",
|
|
" raise ValueError(\"k should be a positive integer\")\n",
|
|
"\n",
|
|
" if selected_latent_space != \"cp\":\n",
|
|
" selected_dim_reduction_method = str(\n",
|
|
" input(\n",
|
|
" \"Enter dimensionality reduction method - one of \"\n",
|
|
" + str(list(valid_dim_reduction_methods.keys()))\n",
|
|
" )\n",
|
|
" )\n",
|
|
"\n",
|
|
" # Loading latent semantics\n",
|
|
" match selected_latent_space:\n",
|
|
" # LS1\n",
|
|
" case \"\":\n",
|
|
" file_prefix = (\n",
|
|
" f\"{selected_feature_model}-{selected_dim_reduction_method}-{k}\"\n",
|
|
" )\n",
|
|
" file_name = file_prefix + \"-semantics.json\"\n",
|
|
" model_name = file_prefix + \"-model.joblib\"\n",
|
|
" if os.path.exists(file_name):\n",
|
|
" data = json.load(open(file_name))\n",
|
|
" print(file_name + \" loaded\")\n",
|
|
" else:\n",
|
|
" raise Exception(file_name + \" does not exist\")\n",
|
|
" # LDA model\n",
|
|
" if selected_dim_reduction_method == \"lda\":\n",
|
|
" if os.path.exists(model_name):\n",
|
|
" data_model = load(model_name)\n",
|
|
" print(model_name + \" loaded\")\n",
|
|
" else:\n",
|
|
" raise Exception(model_name + \" does not exist\")\n",
|
|
" # LS2\n",
|
|
" case \"cp\":\n",
|
|
" file_name = f\"{selected_feature_model}-cp-{k}-semantics.json\"\n",
|
|
" if os.path.exists(file_name):\n",
|
|
" data = json.load(open(file_name))\n",
|
|
" print(file_name + \" loaded\")\n",
|
|
" else:\n",
|
|
" raise Exception(file_name + \" does not exist\")\n",
|
|
" # LS3, LS4\n",
|
|
" case _:\n",
|
|
" file_name = f\"{selected_latent_space}-{selected_feature_model}-{selected_dim_reduction_method}-{k}-semantics.json\"\n",
|
|
" if os.path.exists(file_name):\n",
|
|
" data = json.load(open(file_name))\n",
|
|
" print(file_name + \" loaded\")\n",
|
|
" else:\n",
|
|
" raise Exception(file_name + \" does not exist\")\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"Using image-image similarity matrix from semantic data\n",
|
|
"Similarity graph created\n",
|
|
"Initialized pagerank scores\n",
|
|
"Iter 0, conv_tol=1.719665978050747\n",
|
|
"Iter 1, conv_tol=1.2881607697596094\n",
|
|
"Iter 2, conv_tol=0.2665287566432058\n",
|
|
"Iter 3, conv_tol=0.059527897230663145\n",
|
|
"Iter 4, conv_tol=0.0347000929210205\n",
|
|
"Iter 5, conv_tol=0.02202852715618498\n",
|
|
"Iter 6, conv_tol=0.013882145533702685\n",
|
|
"Iter 7, conv_tol=0.008684261384663692\n",
|
|
"Iter 8, conv_tol=0.005407038899165463\n",
|
|
"Iter 9, conv_tol=0.0033566552382892495\n",
|
|
"Iter 10, conv_tol=0.002079980308951357\n",
|
|
"Iter 11, conv_tol=0.0012874164560444917\n",
|
|
"Iter 12, conv_tol=0.0007962948214944976\n",
|
|
"Iter 13, conv_tol=0.0004923115832688122\n",
|
|
"Iter 14, conv_tol=0.00030429131691503663\n",
|
|
"Iter 15, conv_tol=0.0001880472373585323\n",
|
|
"Iter 16, conv_tol=0.00011619830480688171\n",
|
|
"Iter 17, conv_tol=7.179680034073339e-05\n",
|
|
"Iter 18, conv_tol=4.4360187507886776e-05\n",
|
|
"Iter 19, conv_tol=2.740760859338375e-05\n",
|
|
"Iter 20, conv_tol=1.6933331813984318e-05\n",
|
|
"Iter 21, conv_tol=1.0461878708516084e-05\n",
|
|
"Iter 22, conv_tol=6.463599865544653e-06\n",
|
|
"Iter 23, conv_tol=3.993353111534267e-06\n",
|
|
"Iter 24, conv_tol=2.4671753579536407e-06\n",
|
|
"Iter 25, conv_tol=1.524269424726632e-06\n",
|
|
"Iter 26, conv_tol=9.417228262050036e-07\n",
|
|
"Converged\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"if not given_ls:\n",
|
|
" img_graph = ImageGraph(fd_collection, True)\n",
|
|
" img_graph.create_similarity_graph(n, selected_feature_model)\n",
|
|
" imgs = img_graph.personalized_pagerank(l, m)\n",
|
|
"else:\n",
|
|
" img_graph = ImageGraph(fd_collection, True)\n",
|
|
" img_graph.create_similarity_graph(\n",
|
|
" n,\n",
|
|
" selected_feature_model,\n",
|
|
" data,\n",
|
|
" selected_dim_reduction_method\n",
|
|
" )\n",
|
|
" imgs = img_graph.personalized_pagerank(l, m)\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"array([8464, 8432, 8354, 7988, 8312, 8674, 8628, 8586, 8208, 7990],\n",
|
|
" dtype=int64)"
|
|
]
|
|
},
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"imgs"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.5"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|