Spaces:
Sleeping
Sleeping
Implement Evaluation Metrics
#13
by thesparshsaxena - opened
- repository/DBClient.py +7 -0
- repository/Search_Image.py +39 -7
repository/DBClient.py
CHANGED
|
@@ -14,3 +14,10 @@ def get_db_client():
|
|
| 14 |
}
|
| 15 |
)
|
| 16 |
return db
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
}
|
| 15 |
)
|
| 16 |
return db
|
| 17 |
+
|
| 18 |
+
def get_db_client_for_relevance():
|
| 19 |
+
client = chromadb.PersistentClient(path=f"/data/dbs/{get_user_storage_id()}")
|
| 20 |
+
db = client.get_or_create_collection(
|
| 21 |
+
name = "relevance",
|
| 22 |
+
)
|
| 23 |
+
return db
|
repository/Search_Image.py
CHANGED
|
@@ -6,7 +6,7 @@ import numpy as np
|
|
| 6 |
from io import BytesIO
|
| 7 |
import time
|
| 8 |
import bm25s
|
| 9 |
-
from repository.DBClient import get_db_client
|
| 10 |
from repository.Embedding_model import load_embedding_model
|
| 11 |
import torch
|
| 12 |
import torch.nn.functional as F
|
|
@@ -22,6 +22,7 @@ with st.sidebar:
|
|
| 22 |
# show all images from chromadb in batch of 50
|
| 23 |
try:
|
| 24 |
db = get_db_client()
|
|
|
|
| 25 |
except Exception as e:
|
| 26 |
st.warning("No images found. Please upload some images first.")
|
| 27 |
st.stop()
|
|
@@ -62,8 +63,10 @@ if not search_query:
|
|
| 62 |
st.image(image, width="stretch")
|
| 63 |
if st.button("Delete", key=metadata["id"]):
|
| 64 |
db.delete(ids=[metadata["id"]])
|
|
|
|
| 65 |
if os.path.exists(metadata["filepath"]):
|
| 66 |
os.remove(metadata["filepath"])
|
|
|
|
| 67 |
|
| 68 |
else:
|
| 69 |
start_time = time.time()
|
|
@@ -146,7 +149,8 @@ else:
|
|
| 146 |
}
|
| 147 |
|
| 148 |
best_metadata = dict(sorted(best_metadata.items(), key=lambda item: item[1]["combined_score"], reverse=True)[:k])
|
| 149 |
-
|
|
|
|
| 150 |
for filename, data in best_metadata.items():
|
| 151 |
metadata = data["metadata"]
|
| 152 |
|
|
@@ -167,9 +171,37 @@ else:
|
|
| 167 |
f"Combined: {data['combined_score']:.2f}"
|
| 168 |
)
|
| 169 |
)
|
| 170 |
-
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
|
| 174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
st.write(f"Search took {time.time() - start_time:.2f} seconds")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
from io import BytesIO
|
| 7 |
import time
|
| 8 |
import bm25s
|
| 9 |
+
from repository.DBClient import get_db_client, get_db_client_for_relevance
|
| 10 |
from repository.Embedding_model import load_embedding_model
|
| 11 |
import torch
|
| 12 |
import torch.nn.functional as F
|
|
|
|
| 22 |
# show all images from chromadb in batch of 50
|
| 23 |
try:
|
| 24 |
db = get_db_client()
|
| 25 |
+
relevance_db = get_db_client_for_relevance()
|
| 26 |
except Exception as e:
|
| 27 |
st.warning("No images found. Please upload some images first.")
|
| 28 |
st.stop()
|
|
|
|
| 63 |
st.image(image, width="stretch")
|
| 64 |
if st.button("Delete", key=metadata["id"]):
|
| 65 |
db.delete(ids=[metadata["id"]])
|
| 66 |
+
relevance_db.delete(ids=[metadata["id"]])
|
| 67 |
if os.path.exists(metadata["filepath"]):
|
| 68 |
os.remove(metadata["filepath"])
|
| 69 |
+
|
| 70 |
|
| 71 |
else:
|
| 72 |
start_time = time.time()
|
|
|
|
| 149 |
}
|
| 150 |
|
| 151 |
best_metadata = dict(sorted(best_metadata.items(), key=lambda item: item[1]["combined_score"], reverse=True)[:k])
|
| 152 |
+
if "relevance_score" not in st.session_state:
|
| 153 |
+
st.session_state["relevance_score"] = [0] * k
|
| 154 |
for filename, data in best_metadata.items():
|
| 155 |
metadata = data["metadata"]
|
| 156 |
|
|
|
|
| 171 |
f"Combined: {data['combined_score']:.2f}"
|
| 172 |
)
|
| 173 |
)
|
| 174 |
+
columns = st.columns(3)
|
| 175 |
+
i = 1
|
| 176 |
+
with columns[0]:
|
| 177 |
+
if st.button("Delete", key=f"delete_{metadata['id']}"):
|
| 178 |
+
db.delete(ids=[metadata["id"]])
|
| 179 |
+
if os.path.exists(metadata["filepath"]):
|
| 180 |
+
os.remove(metadata["filepath"])
|
| 181 |
+
with columns[1]:
|
| 182 |
+
if st.checkbox("Relevant ๐", key=f"relevant_{metadata['id']}"):
|
| 183 |
+
relevance_db.add(
|
| 184 |
+
ids=[metadata["id"]],
|
| 185 |
+
metadatas=[{**metadata, "relevance": 1, "query": search_query}]
|
| 186 |
+
)
|
| 187 |
+
st.session_state["relevance_score"][i - 1] = 1
|
| 188 |
+
with columns[2]:
|
| 189 |
+
if st.checkbox("Irrelevant ๐", key=f"irrelevant_{metadata['id']}"):
|
| 190 |
+
relevance_db.add(
|
| 191 |
+
ids=[metadata["id"]],
|
| 192 |
+
metadatas=[{**metadata, "relevance": 0, "query": search_query}]
|
| 193 |
+
)
|
| 194 |
+
st.session_state["relevance_score"][i - 1] = 0
|
| 195 |
+
i += 1
|
| 196 |
st.write(f"Search took {time.time() - start_time:.2f} seconds")
|
| 197 |
+
st.info(f"You can provide relevance feedback by marking images as relevant or irrelevant. Ensure you have atleast {k} relevant images to evaluate the NDCG@{k} score.")
|
| 198 |
+
with st.button(f"Evaluate NDCG@{k}"):
|
| 199 |
+
ndcg_score = 0.0
|
| 200 |
+
if "relevance_score" in st.session_state:
|
| 201 |
+
relevance_scores = st.session_state["relevance_score"]
|
| 202 |
+
ideal_relevance_scores = sorted(relevance_scores, reverse=True)
|
| 203 |
+
dcg = sum((2 ** rel - 1) / math.log2(idx + 2) for idx, rel in enumerate(relevance_scores))
|
| 204 |
+
idcg = sum((2 ** rel - 1) / math.log2(idx + 2) for idx, rel in enumerate(ideal_relevance_scores))
|
| 205 |
+
ndcg_score = dcg / idcg if idcg > 0 else 0.0
|
| 206 |
+
st.title(f"NDCG@{k}: {ndcg_score:.4f}")
|
| 207 |
+
st.warning("Please note that the NDCG score is based on the relevance feedback you have provided. If you haven't marked any images as relevant or irrelevant, the score will be inaccurate.")
|