diff --git a/examples/ai/face_similarity.ipynb b/examples/ai/face_similarity.ipynb
index 5938bea4a4d..d849a67fbcc 100644
--- a/examples/ai/face_similarity.ipynb
+++ b/examples/ai/face_similarity.ipynb
@@ -42,7 +42,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 2,
"id": "dc6b0bc2-b95f-4190-bf77-fa2dc57fc247",
"metadata": {},
"outputs": [
@@ -50,6 +50,8 @@
"name": "stderr",
"output_type": "stream",
"text": [
+ "/Users/oliverrice/Documents/supabase/supabase/examples/ai/venv/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
+ " from .autonotebook import tqdm as notebook_tqdm\n",
"Found cached dataset parquet (/Users/oliverrice/.cache/huggingface/datasets/ashraq___parquet/default-f6987358ed4d9f01/0.0.0/2a3b91fbd88a2c90d1dbbb32b460cf621d31bd5b05b934492fdef7d8d6f236ec)\n"
]
},
@@ -62,7 +64,7 @@
"})"
]
},
- "execution_count": 18,
+ "execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
@@ -217,6 +219,7 @@
"# create vector store client\n",
"vx = vecs.create_client(DB_CONNECTION)\n",
"\n",
+ "vx.delete_collection('faces')\n",
"# create a PostgreSQL/pgvector table named \"faces\" to contain the face embeddings\n",
"faces = vx.create_collection(name=\"faces\", dimension=128)"
]
@@ -273,7 +276,11 @@
" # is produced. We'll skip those cases\n",
" if len(embeddings) == 1:\n",
" embedding = embeddings[0]\n",
- " records.append((f\"{ix}\", embedding, {}))"
+ " records.append((\n",
+ " f\"{ix}\",\n",
+ " embedding,\n",
+ " {k: v for k, v in person.items() if k != 'image'}\n",
+ " ))"
]
},
{
@@ -327,330 +334,38 @@
},
{
"cell_type": "code",
- "execution_count": 13,
- "id": "b6596cd4-836a-4f1d-b21a-49a6e11b4fed",
+ "execution_count": 10,
+ "id": "8673ff6e-31e5-4344-990d-bf3c84be5824",
"metadata": {},
- "outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Look Alikes\n"
- ]
- },
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- "
\n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- },
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "
David Hasselhoff
\n",
- "

\n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
Guillermo GarcÃa Cantú
\n",
- "

\n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- " \n",
- "
\n",
- "
\n",
- "
Michael Madsen
\n",
- "

\n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "
"
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
+ "outputs": [],
"source": [
- "import ipyplot\n",
+ "from IPython.core.display import HTML\n",
+ "from typing import Dict, Any\n",
"\n",
- "# Grab a random face from the dataset\n",
- "query_face = people[1522]['image']\n",
+ "def render_similar_faces(person_image: Image, faces_collection: vecs.Collection) -> HTML:\n",
+ " # create query face embedding\n",
+ " face_embedding = face_recognition.face_encodings(np.array(person_image))[0]\n",
+ " \n",
+ " # query database for similar results\n",
+ " result = faces_collection.query(face_embedding, limit=5, include_metadata=True)\n",
+ " # read metadata from the results\n",
+ " result_metadata = [x[1] for x in result]\n",
"\n",
- "# Create the face's embedding\n",
- "query_embedding = face_recognition.face_encodings(np.array(query_face))[0]\n",
- "\n",
- "# Query the collection for the 3 most similar faces (which will include their own)\n",
- "top_n = faces.query(\n",
- " query_vector=query_embedding,\n",
- " limit = 3\n",
- ")\n",
- "\n",
- "# Display the result\n",
- "look_alikes = [people[int(image_id)] for image_id in top_n]\n",
- "images = [person['image'] for person in look_alikes]\n",
- "labels = [person['name'] for person in look_alikes]\n",
- "print(\"Look Alikes\")\n",
- "ipyplot.plot_images(images, labels, img_width=150)"
+ " captioned_images = []\n",
+ " for metadata in result_metadata:\n",
+ " html = f\"\"\"\n",
+ " \n",
+ "
\n",
+ " {metadata[\"name\"]}\n",
+ " \n",
+ " \"\"\"\n",
+ " captioned_images.append(html)\n",
+ " \n",
+ " return HTML(data=f\"\"\"\n",
+ " \n",
+ " {\"\".join(captioned_images)}\n",
+ "
\n",
+ " \"\"\")"
]
},
{
@@ -661,1930 +376,175 @@
"## Example Results\n",
"\n",
"For convenience we'll create a function to search the database and try test it out on several celebrities. Since our query faces\n",
- "are also in the dataset, the query face should always be first in the results."
+ "are also in the dataset, the query face is the first in the result output."
]
},
{
"cell_type": "code",
- "execution_count": 14,
- "id": "f53b4b4f-3a55-4a15-9fc8-02fbe10d6b54",
- "metadata": {},
- "outputs": [],
- "source": [
- "def display_search_results(query_face: Image, faces_collection: vecs.Collection):\n",
- " print(\"Query Face\")\n",
- " ipyplot.plot_images([query_face], [\"Query Face\"], img_width=150)\n",
- "\n",
- " query_embedding = face_recognition.face_encodings(np.array(query_face))[0]\n",
- " \n",
- " top_n = faces_collection.query(\n",
- " query_vector=query_embedding,\n",
- " limit = 6\n",
- " )\n",
- " look_alikes = [people[int(image_id)] for image_id in top_n]\n",
- " images = [person['image'] for person in look_alikes]\n",
- " labels = [person['name'] for person in look_alikes]\n",
- " print(\"Look Alikes\")\n",
- " ipyplot.plot_images(images, labels, img_width=150)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
+ "execution_count": 11,
"id": "2e5f05e8-5fc3-42e8-9a3b-4b3c7ce0dc4a",
"metadata": {},
"outputs": [
- {
- "name": "stdout",
- "output_type": "stream",
- "text": [
- "Query Face\n"
- ]
- },
{
"data": {
"text/html": [
"\n",
- " \n",
- " \n",
- "
\n",
- "
\n",
- "