{ "cells": [ { "cell_type": "markdown", "id": "7b1e97ef", "metadata": {}, "source": [ "\n", "\n", " \n", " \n", " \n", " \n", "
\n", " \n", " \n", " Try in Google Colab\n", " \n", " \n", " \n", " \n", " Share via nbviewer\n", " \n", " \n", " \n", " \n", " View on GitHub\n", " \n", " \n", " \n", " \n", " Download notebook\n", " \n", "
\n" ] }, { "cell_type": "markdown", "id": "c26264f7", "metadata": {}, "source": [ "# Nearest Neighbor Classification of Embeddings with Qdrant\n", "\n", "FiftyOne provides powerful [workflows](https://voxel51.com/docs/fiftyone/user_guide/brain.html) centered around model embeddings. Pre-annotation of raw data, finding annotation mistakes, finding hard samples, and visual similarity searches are just some of the ways that FiftyOne allows you to use embeddings to explore and improve your dataset. However, performing a nearest neighbor search on a large dataset is both technical and tooling challenge.\n", "\n", "To this end, vector search engines have been developed for this exact purpose of efficiently storing, searching, and managing embedding vectors. [Qdrant](https://qdrant.tech/) is a vector database designed to perform an approximate nearest neighbor search (ANN) on dense neural embeddings which is necessary for any production-ready system that is expected to scale to large amounts of data and best of all, it's open-source!\n", "\n", "In this notebook, we're going to load the MNIST dataset into FiftyOne and perform the classification based on ANN, so the data points will be classified by selecting the most common ground truth label among the **K** nearest points from our training dataset. In other words, for each test example, we're going to select its K nearest neighbors, using a chosen distance function, and then just select the best label by voting. All that search in the vector space will be done with Qdrant, to speed things up. We will then evaluate the results of this classification in FiftyOne." ] }, { "cell_type": "markdown", "id": "274f46cd", "metadata": {}, "source": [ "## Setup\n", "\n", "If you haven’t already, install FiftyOne:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "5e542006", "metadata": {}, "outputs": [], "source": [ "!pip install fiftyone" ] }, { "cell_type": "markdown", "id": "5c4f77c0", "metadata": {}, "source": [ "We'll also need the Qdrant Python client:" ] }, { "cell_type": "code", "execution_count": null, "id": "2cea7b23", "metadata": {}, "outputs": [], "source": [ "!pip install qdrant_client" ] }, { "cell_type": "markdown", "id": "2c9abce5", "metadata": {}, "source": [ "In this example, we will also be making use of torchvision models from the [FiftyOne Model Zoo](https://voxel51.com/docs/fiftyone/user_guide/model_zoo/index.html#)." ] }, { "cell_type": "code", "execution_count": null, "id": "c3cc1dd3", "metadata": {}, "outputs": [], "source": [ "!pip install torchvision" ] }, { "cell_type": "markdown", "id": "d8075bb7", "metadata": {}, "source": [ "### Qdrant installation\n", "If you want to start using the semantic search with Qdrant, you need to run an instance of it, as this tool works in a client-server manner. The easiest way to do this is to use an official Docker image and start Qdrant with just a single command:\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "5fc204a5", "metadata": {}, "outputs": [], "source": [ "!docker run -p \"6333:6333\" -p \"6334:6334\" -d qdrant/qdrant" ] }, { "cell_type": "markdown", "id": "2d959395", "metadata": {}, "source": [ "After running the command we’ll have the Qdrant server running, with HTTP API exposed at port 6333 and gRPC interface at 6334." ] }, { "cell_type": "markdown", "id": "89e0b5e0", "metadata": {}, "source": [ "## Loading the dataset\n", "\n", "There are several steps we need to take to get things running smoothly. First of all, we need to load the MNIST dataset and extract the train examples from it, as we're going to use them in our search operations. To make everything even faster, we're not going to use all the examples, but just 2500 samples. We can use the [FiftyOne Dataset Zoo](https://voxel51.com/docs/fiftyone/user_guide/dataset_zoo/index.html) to load the subset of MNIST we want in just one line of code." ] }, { "cell_type": "code", "execution_count": 1, "id": "57c18ce6", "metadata": {}, "outputs": [], "source": [ "import fiftyone as fo\n", "import fiftyone.zoo as foz\n", "import fiftyone.brain as fob" ] }, { "cell_type": "code", "execution_count": 3, "id": "00a6c2ad", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Split 'train' already downloaded\n", "Split 'test' already downloaded\n", "Loading 'mnist' split 'train'\n", " 100% |███████████████| 2500/2500 [4.1s elapsed, 0s remaining, 685.3 samples/s] \n", "Loading 'mnist' split 'test'\n", " 100% |███████████████| 2500/2500 [4.0s elapsed, 0s remaining, 644.8 samples/s] \n", "Dataset 'mnist-2500' created\n" ] } ], "source": [ "# Load the data\n", "dataset = foz.load_zoo_dataset(\"mnist\", max_samples=2500)\n", "train_view = dataset.match_tags(tags=[\"train\"])" ] }, { "cell_type": "markdown", "id": "8a7195b0", "metadata": {}, "source": [ "Let's start by taking a look at the dataset in the [FiftyOne App](https://voxel51.com/docs/fiftyone/user_guide/app.html)." ] }, { "cell_type": "code", "execution_count": 34, "id": "1bc4ed66", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n", " \n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "session = fo.launch_app(train_view)" ] }, { "cell_type": "code", "execution_count": 35, "id": "3998a017", "metadata": {}, "outputs": [], "source": [ "session.freeze() # Screenshot the App for this example" ] }, { "cell_type": "markdown", "id": "24a1d3fc", "metadata": {}, "source": [ "## Generating embeddings and loading into Qdrant\n", "\n", "The next step is to generate embeddings on the samples in the dataset. This can always be done outside of FiftyOne, with your own custom models. However, FiftyOne also provides various different models in the [FiftyOne Model Zoo](https://voxel51.com/docs/fiftyone/user_guide/model_zoo/index.html) that can be used right out of the box to generate embeddings.\n", "\n", "In this example, we use [MobileNetv2](https://voxel51.com/docs/fiftyone/user_guide/model_zoo/models.html#mobilenet-v2-imagenet-torch) trained on ImageNet to compute an embedding for each image." ] }, { "cell_type": "code", "execution_count": 4, "id": "7a3597f6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 100% |███████████████| 2500/2500 [3.7m elapsed, 0s remaining, 7.7 samples/s] \n" ] } ], "source": [ "# Compute embeddings\n", "model = foz.load_zoo_model(\"mobilenet-v2-imagenet-torch\")\n", "\n", "train_embeddings = train_view.compute_embeddings(model)" ] }, { "cell_type": "markdown", "id": "7f3720c4-6e84-4bdc-8798-2302104986a3", "metadata": {}, "source": [ "As of [FiftyOne version 0.20.0](https://docs.voxel51.com/release-notes.html#fiftyone-0-20-0), FiftyOne natively integrates with Qdrant! This means that uploading your embeddings is now as simple as computing similarity on your dataset with the qdrant backend. " ] }, { "cell_type": "code", "execution_count": null, "id": "d56200de-c898-4388-acaf-60d219fdf3db", "metadata": {}, "outputs": [], "source": [ "# Compute similarity with Qdrant backend\n", "fob.compute_similarity(train_view, embeddings=train_embeddings, brain_key=\"qdrant_example\", backend=\"qdrant\")" ] }, { "cell_type": "markdown", "id": "60bd2b0a-6393-46c4-9d45-320fa200eb9b", "metadata": {}, "source": [ "Alternatively, if you don't want to precompute your embeddings, you can pass in a model parameter to [compute_similarity](https://docs.voxel51.com/api/fiftyone.brain.html?highlight=compute_similarity#fiftyone.brain.compute_similarity) and the embeddings will be computed for you and stored in the given field name upon completion." ] }, { "cell_type": "code", "execution_count": null, "id": "5becf099-9639-4549-bccb-aca7a1bd4de5", "metadata": {}, "outputs": [], "source": [ "# Compute similarity with Qdrant backend without precomputed embeddings\n", "#fob.compute_similarity(train_view, model = model, embeddings=train_embeddings_new, brain_key=\"qdrant_example\", backend=\"qdrant\")" ] }, { "cell_type": "markdown", "id": "3b88c449", "metadata": {}, "source": [ "## Nearest neighbor classification\n", "\n", "Now to perform inference on the dataset. We can create the embeddings for our test dataset, but just ignore the ground truth and try to find it out using ANN, then compare if both match. Let's take one step at a time and start with creating the embeddings." ] }, { "cell_type": "code", "execution_count": 9, "id": "0e432ae8", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 100% |███████████████| 2500/2500 [3.9m elapsed, 0s remaining, 12.1 samples/s] \n" ] } ], "source": [ "# Assign the labels to test embeddings by selecting the most common label\n", "# among the neighbours of each sample\n", "test_view = dataset.match_tags(tags=[\"test\"])\n", "test_embeddings = test_view.compute_embeddings(model)" ] }, { "cell_type": "markdown", "id": "ddafd2e9", "metadata": {}, "source": [ "Time for some magic. Let's simply iterate through the test dataset's samples and their corresponding embeddings, and use [sort_by_similarity](https://docs.voxel51.com/api/fiftyone.core.dataset.html?highlight=sort_by_similarity#fiftyone.core.dataset.Dataset.sort_by_similarity) to find the 15 closest embeddings from the training set. We'll also need to calculate the class counts to determine the most common label. This will be stored as an `\"ann_prediction\"` on each test sample in FiftyOne.\n", "\n", "The function below takes an embedding vector as input, uses FiftyOne's [sort_by_similarity](https://docs.voxel51.com/api/fiftyone.core.dataset.html?highlight=sort_by_similarity#fiftyone.core.dataset.Dataset.sort_by_similarity) functionality to find the nearest neighbors to the test embedding, generates a class prediction, and returns a FiftyOne [Classification](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html#classification) object that we can store in our [FiftyOne dataset](https://voxel51.com/docs/fiftyone/user_guide/using_datasets.html)." ] }, { "cell_type": "code", "execution_count": 13, "id": "09260764", "metadata": {}, "outputs": [], "source": [ "def generate_fiftyone_classification(embedding, brain_key, field=\"ground_truth\"):\n", " search_results = dataset.sort_by_similarity(embedding, k=15, brain_key=brain_key)\n", " \n", " # Count the occurrences of each class and select the most common label\n", " # with the confidence estimated as the number of occurrences of the most\n", " # common label divided by a total number of results.\n", " class_counts = search_results.count_values(field + \".label\")\n", " predicted_class = max(class_counts, key=class_counts.get)\n", " occurences_num = class_counts[predicted_class]\n", " confidence = occurences_num / sum(class_counts.values())\n", " prediction = fo.Classification(\n", " label=predicted_class, confidence=confidence\n", " )\n", " return prediction" ] }, { "cell_type": "code", "execution_count": 10, "id": "f93bc429", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 2500/2500 [01:42<00:00, 24.40it/s]\n" ] } ], "source": [ "from tqdm import tqdm\n", "\n", "predictions = []\n", "\n", "# Call Qdrant to find the closest data points\n", "for embedding in tqdm(test_embeddings):\n", " prediction = generate_fiftyone_classification(embedding, brain_key=\"qdrant_example\")\n", " predictions.append(prediction)\n", "\n", "test_view.set_values(\"ann_prediction\", predictions)" ] }, { "cell_type": "markdown", "id": "ccb22a74", "metadata": {}, "source": [ "By the way, we estimated the confidence by calculating the fraction of samples belonging to the most common label. That gives us an intuition of how sure we were while predicting the label for each case and can be used in FiftyOne to easily spot confusing examples." ] }, { "cell_type": "markdown", "id": "451981f6", "metadata": {}, "source": [ "## Evaluation in FiftyOne\n", "\n", "It's high time for some results! Let's start by visualizing how this classifier has performed. We can easily launch the [FiftyOne App](https://voxel51.com/docs/fiftyone/user_guide/app.html) to view the ground truth, predictions, and images themselves." ] }, { "cell_type": "code", "execution_count": 6, "id": "668363a0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n", " \n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "session = fo.launch_app(test_view)" ] }, { "cell_type": "code", "execution_count": 7, "id": "baf5c39e", "metadata": { "scrolled": true }, "outputs": [], "source": [ "session.freeze() # Screenshot the App for this example" ] }, { "cell_type": "markdown", "id": "41f62b38", "metadata": {}, "source": [ "FiftyOne provides a variety of built-in [methods for evaluating your model](https://voxel51.com/docs/fiftyone/user_guide/evaluation.html) predictions, including regressions, classifications, detections, polygons, instance and semantic segmentations, on both image and video datasets. In two lines of code, we can compute and print an evaluation report of our classifier." ] }, { "cell_type": "code", "execution_count": 11, "id": "7de405f6", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " precision recall f1-score support\n", "\n", " 0 - zero 0.87 0.98 0.92 219\n", " 1 - one 0.94 0.98 0.96 287\n", " 2 - two 0.87 0.72 0.79 276\n", " 3 - three 0.81 0.87 0.84 254\n", " 4 - four 0.84 0.92 0.88 275\n", " 5 - five 0.76 0.77 0.77 221\n", " 6 - six 0.94 0.91 0.93 225\n", " 7 - seven 0.83 0.81 0.82 257\n", " 8 - eight 0.95 0.91 0.93 242\n", " 9 - nine 0.94 0.87 0.90 244\n", "\n", " accuracy 0.87 2500\n", " macro avg 0.88 0.87 0.87 2500\n", "weighted avg 0.88 0.87 0.87 2500\n", "\n" ] } ], "source": [ "# Evaluate the ANN predictions, with respect to the values in ground_truth\n", "results = test_view.evaluate_classifications(\n", " \"ann_prediction\", gt_field=\"ground_truth\", eval_key=\"eval_simple\"\n", ")\n", "\n", "# Display the classification metrics\n", "results.print_report()" ] }, { "cell_type": "markdown", "id": "16ec9cd2", "metadata": {}, "source": [ "After performing the evaluation in FiftyOne, we can use the `results` object to generate an [interactive confusion matrix](https://voxel51.com/docs/fiftyone/user_guide/plots.html#confusion-matrices) allowing us to click on cells and automatically update the App to show the corresponding samples." ] }, { "cell_type": "code", "execution_count": 37, "id": "70d2587b", "metadata": {}, "outputs": [ { "data": { "image/png": "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pKdNmyZvvPGG6/4uTIr1mPvvv7/svPPOsttuu8khhxzi1iPvueee7nS6xvj8888XvWf33RBjX4LsPyQJ6JQO/eB98sknsswyywxvMS4WRVpbJS4WJSoURKqrRfTfHtu0zVeVpnlzUx8hiiKpqaqWSESKcSytba3ie9vvLcYdnCSORaJIRNe56L+9N49jtLWJtLV9XjvPJ6nuUuKi3xV15OQ46TjyXA/UnkzkxTpubZVI89Its5z8MElLi4iOKUVeVSWRfu68Nt9PiEhXTjquq6ra//HePMa3nnvBgs/Hd2Y5eVyUjmutXef3QAbfl4ixRz3YFQIQ6EEgBDFWKZ4yZYrr7upa4c4ub6FQcG+ZnjNnjtx9992yww47yFJLLSUPP/yw6yjr26jHjRsnd955p9x1113uJ5s0/sQTT5Q111zTHdN3Q4x9CbL/kCagT6GuvvrqzMRYp3lceuml7kO/xhpruA/zCius4Bhus8027omY/q7b66+/LptssomceeaZUt1xQ3z//ffLLbfcIh9//LGsvfbacvLJJ7vffkvavDrGcSzx/PntN3mdWxRJNGqUl4j4iLFK8cjaetF/d266BqWhudFLjr3EuFhs59R9KxTaOXlvKcVBhbihoefZVbBGjvTLyEeMW1okbmrqef6aGom8f3swvRjHzc1OrnpstbUS1dX5cfLYu7+cXD5eDzb8xNjVTYWv2+bq5v1gI+X41gcGOr47H2h05OXGdybCnq6A7nug44FG11emfg94PExEjNPVgr0gAIG+BH6TY8d4bMdbqefOneveKt170/vh++67zzWldKr0iy++KA0NDbLyyis76dWfZNKtra3NdZm1Q6ySveWWW7p7Yn7HmBEPgRITyFKM33rrLfcD5ueee66stdZa7sN/zz33uH/0LXoqxquttproK+tHjhwpxx57rBxxxBHuTX2ax8UXX+yejunb+S6//HJ577333DSUzu3NN990P3refdMvmeL8D6SQ9t6zP5HR/pznDbGPGNdW14j+03trXNAkbb2ufzDDw0eM+5Ur5ZTJTXrK4jU2SdzaU2SUR6RreHw62R5iHDc0irS19ilLNGbMYErVT6yHGPcjMsrHccppi+f2M5vC+0GLpxj3l1MWD1rcvI8UW38Po3R863fDiPoUB8xgl/4eRulhPR+0IMYZ1IZDQAACjsDD+6wjn7zy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E2JsgIQY2yAhxlZOxEEAAskEZv9ofWn5b/k7xsuc93QPMe6d6cEHHyzbbrutTJo0SZ5//nk5/vjj5fHHH5coilzo3nvv7f7Zcccd5dBDD3Vd4r322sv9bdasWXLBBRc4cfbdEGNfguwPgcAJIMa2AiHGNk6IsYETYmyAhBjbICHGVk7EQQACyQTm/DgfMV763IHFuKmpSb773e+6rvD6668v9913n5smffPNN3dd0E9/+lMZP368HHXUUbL99tvLqaee2jW1+rXXXnPd5aefflpqamqSISwkAjH2wsfOEAifQNv896Wq/YFbYFtoScWB8RH528Hry4J33wwqr7Wue17qxi0fVE7x/PdF4mI4OY1cUqJCVTj5uEzCG9+BAeqWTljfTcW6xaVQFdp4Crd6ZAYBCAxMoJRiXPP1b0n95Fv6nLz1f38ji664xoAd46lTp8r777/vplLrdtttt8kf/vAH0XXIndvpp58uo0ePluOOO0622GILN41ap13rpuuUd9ppJ9dhXmSRRbzKjxh74WNnCIRPADG21ig8cUCMbbVDjC2cwhvflqzziUGM8+HOWSEAgVITePvYDXKZSr309Kekttsa487rVMH985//7CRYxVc37Rg/9NBDct1113Xh0I7xcsstJ5MnT3Yd4zPOOEM23HBD9/fOjvFTTz0ltbW1XggRYy987AyB8AkgxtYahScOiLGtdoixhVN449uSdT4xiHE+3DkrBCBQagJvH5eTGJ/TU4z1bdLTpk2TN954w3V/O6VYr1/XGKsIP/rooz3WGOv645133lkOOeQQtx55zz33dLh0jfH5558vM2fO9MaHGHsj5AAQCJsAYmytT3jigBjbaocYWziFN74tWecTgxjnw52zQgACpSbwzvEb5tIxHnfOH6V2pfapzyrFU6ZMcd1dXSvc2eUtFAruLdMLFixwAqwv19ptt93ctGr96SZddzx27Fi588475a677nI/2aTxJ554oqy55prumL4bYuxLkP0hEDgBxNhaoPDEATG21Q4xtnAKb3xbss4nBjHOhztnhQAESk3g3ZzE+AvdxHju3LnurdK9txVWWMFNo9btxRdflLPPPttNk15mmWXc7xhvttlm7m9tbW2uy6wdYpXsLbfcUk4++WR+x7jUg4fjQ2AoEECMrVUMTxwQY1vtEGMLp/DGtyXrfGIQ43y4c1YI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z4lirM+KPUmABEiABOonwFJqzg4SIAEtAhRjd0wUY3dGFGM9RhRjfU4UY31W7EkCJEACJEAx5hwgARIgARIgARIgARIgARIgARIggZQEmDHmxCABEiABEiABEiABEiABEiABEmjSBCjGTXr4efEkQAIkQAIkQAIkQAIkQAIkQAIUY84BEiABEiABEiABEiABEiABEiCBJk2AYtykh58XTwIkQAIkQAIkQAIkQAIkQAIkQDHmHCABEiABEiABEiABEiABEiABEmjSBCjGTXr4efEkQAJeESgpKZGWLVt6dfiMjrtlyxYpKCjI6LNN6UPr1q2THXbYQSzLakqX3aBr/fbbb+Xnn3+W/fbbr0GfY2cSIAESIAESCCsBinFYR4ZxkUBICcyZM0deffVVadu2rZx77rnSqVOnwCN1JLSqqkrKysqkVatWgcZUXl4up59+ulRWVsqpp54qF110kRQWFgYaE9icffbZAlb9+/eX888/P3TiHiigrScHpyFDhkizZs3k6quvln333TcMYclPP/0k33zzjfredenSJfCYFixYIDfddJPiM2LECGnfvn3gMb322mvy4osvqnl9xhlnSK9evQKNKR6Py3PPPSfz58+XoqIi9f3jg4RAh4QnJwESIIG0BCjGnCAkQALaBB5++GGZPn26XH755VJcXCxTp06V+++/X7p166Z9DC86Pv744/LCCy+oDN8+++wjN9xwgxenadAxcVMMkXnkkUfku+++k0cffVTy8/MbdIxsd66oqFAxPfHEE/K///1PxbTNNttk+zQNPh4eILzzzjvy9ttvy8CBA2X33Xdv8DGy9YEnn3xS8M/QoUPlgQcekAMOOECuuOIKadeuXbZO0aDjgM3dd98tL730knTt2lUJ8nbbbafmeJCccBGlpaVqfj/zzDNK+sAsqAdAmM9/+MMf5LbbbpNtt91WJk6cKEcffbScc845DeKdzc733HOP4EHiqFGjJBaLyfjx4+XPf/6z9O7dO5un4bFIgARIgASyRIBinCWQPAwJNHYCH374oRLiyZMnS48ePdTl4sYPGcjrrrsu8MuHGN9xxx0qQxOUxKSCYNu2DBgwQLE77rjjAufkBDBs2DA58MAD5ZJLLgkkJjw4+Pjjj2X27Nny/vvvS4cOHQRzbMqUKTXzy+/AUBqMsRo9erQcddRRam5jviNGzK8gytD/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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plot = results.plot_confusion_matrix()\n", "plot.show()" ] }, { "cell_type": "code", "execution_count": null, "id": "bff9631b", "metadata": {}, "outputs": [], "source": [ "session.plots.attach(plot)" ] }, { "cell_type": "markdown", "id": "b7c0a4f6", "metadata": {}, "source": [ "Let's dig in a bit further. We can use the [sophisticated query language](https://voxel51.com/docs/fiftyone/user_guide/using_views.html#filtering) of FiftyOne to easily find all predictions that did not match the ground truth, yet were predicted with high confidence. These will generally be the most confusing samples for the dataset and the ones from which we can gather the most insight." ] }, { "cell_type": "code", "execution_count": 3, "id": "25c1373a", "metadata": {}, "outputs": [], "source": [ "from fiftyone import ViewField as F\n", "\n", "# Display FiftyOne app, but include only the wrong predictions that were predicted with high confidence\n", "false_view = (\n", " test_view\n", " .match(F(\"eval_simple\") == False)\n", " .filter_labels(\"ann_prediction\", F(\"confidence\") > 0.7)\n", ")" ] }, { "cell_type": "code", "execution_count": 4, "id": "da76cd58", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n", " \n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "session = fo.launch_app(false_view)" ] }, { "cell_type": "code", "execution_count": 5, "id": "b3f5f5a8", "metadata": {}, "outputs": [], "source": [ "session.freeze() # Screenshot the App for this example" ] }, { "cell_type": "markdown", "id": "c8bdcda6", "metadata": {}, "source": [ "These are the most confusing samples for the model and, as you can see, they are fairly irregular compared to other images in the dataset. A next step we could take to improve the performance of the model could be to use FiftyOne to curate additional samples similar to these. From there, those samples can then be annotated through the integrations between FiftyOne and tools like [CVAT](https://voxel51.com/docs/fiftyone/integrations/cvat.html) and [Labelbox](https://voxel51.com/docs/fiftyone/integrations/labelbox.html). Additionally, we could use some more vectors for training or just perform a fine-tuning of the model with similarity learning, for example using the triplet loss. But right now this example of using FiftyOne and Qdrant for vector similarity classification is working pretty well already.\n", "\n", "And that's it! As simple as that, we created an ANN classification model using FiftyOne with Qdrant as an embeddings backend, so finding the similarity between vectors can stop being a bottleneck as it would in the case of a traditional k-NN." ] }, { "cell_type": "markdown", "id": "9d2cedcf", "metadata": {}, "source": [ "# BDD100k example\n", "\n", "Let's take everything we learned in the previous example and apply it to a more realisitc use-case. In this section, we take a look at how to use nearest neighbor embedding classification for pre-annotation of the BDD100k road-scene dataset to apply a scene-level label determining the time of day.\n", "\n", "This dataset is also available in the FiftyOne Dataset Zoo. If you want to follow along youself, you will need to register at https://bdd-data.berkeley.edu in order to get links to download the data. See the [zoo docs](https://voxel51.com/docs/fiftyone/user_guide/dataset_zoo/datasets.html?highlight=bdd100k#dataset-zoo-bdd100k) for details on loading the dataset.\n", "\n", "We’ll be working with a 1,000 image subset of the validation split:" ] }, { "cell_type": "code", "execution_count": 8, "id": "1d23b0f9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Split 'validation' already prepared\n", "Loading 'bdd100k' split 'validation'\n", " 100% |███████████████| 1000/1000 [21.4s elapsed, 0s remaining, 48.2 samples/s] \n", "Dataset 'bdd100k-validation-1000' created\n" ] } ], "source": [ "import fiftyone as fo\n", "import fiftyone.zoo as foz\n", "import fiftyone.brain as fob\n", "\n", "# The path to the source files that you manually downloaded\n", "source_dir = \"/path/to/dir-with-bdd100k-files\"\n", "\n", "dataset = foz.load_zoo_dataset(\"bdd100k\", split=\"validation\", source_dir=source_dir, max_samples=1000)" ] }, { "cell_type": "markdown", "id": "633de468", "metadata": {}, "source": [ "Let's split this dataset so that 30% of the samples are missing the `timeofday` classification. We will then compute this classification using nearest neighbors." ] }, { "cell_type": "code", "execution_count": 9, "id": "79eca589", "metadata": {}, "outputs": [], "source": [ "import fiftyone.utils.random as four\n", "\n", "four.random_split(dataset, {\"train\": 0.7, \"test\": 0.3})\n", "\n", "train_view = dataset.match_tags(\"train\")\n", "test_view = dataset.match_tags(\"test\")\n", "\n", "# Remove labels from test view for this example\n", "test_view.set_field(\"timeofday\", None).save()" ] }, { "cell_type": "markdown", "id": "8d2f888a", "metadata": {}, "source": [ "Note: This is a larger model than the one used in the previous example. It is recommended this is run on a machine with GPU support or in a Colab notebook." ] }, { "cell_type": "code", "execution_count": 10, "id": "f8b6a2e2", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", " 100% |█████████████████| 700/700 [24.8m elapsed, 0s remaining, 0.5 samples/s] \n" ] } ], "source": [ "# Load a resnet from the model zoo\n", "model = foz.load_zoo_model(\"resnet50-imagenet-torch\")\n", "\n", "# Verify that the model exposes embeddings\n", "print(model.has_embeddings)\n", "# True\n", "\n", "# Compute embeddings for each image\n", "train_embeddings = train_view.compute_embeddings(model)" ] }, { "cell_type": "code", "execution_count": 21, "id": "b07a8bef", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(700, 2048)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "train_embeddings.shape" ] }, { "cell_type": "markdown", "id": "7b901ad2", "metadata": {}, "source": [ "From here we can use the functions defined above to load the embeddings into Qdrant and then generate classifications for the dataset. Specifically, we are looking to generate pre-annotations of the `timeofday` label." ] }, { "cell_type": "code", "execution_count": 11, "id": "ad51c154", "metadata": {}, "outputs": [], "source": [ "# Compute similarity with Qdrant backend\n", "fob.compute_similarity(train_view, embeddings=train_embeddings, brain_key=\"bdd100k_qdrant_example\", backend=\"qdrant\")" ] }, { "cell_type": "code", "execution_count": 16, "id": "cba7d8ed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 100% |█████████████████| 300/300 [10.2m elapsed, 0s remaining, 0.5 samples/s] \n" ] } ], "source": [ "test_embeddings = test_view.compute_embeddings(model)" ] }, { "cell_type": "code", "execution_count": 23, "id": "49ff5bee", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "100%|██████████| 300/300 [00:09<00:00, 30.38it/s]\n" ] } ], "source": [ "from tqdm import tqdm\n", "\n", "predictions = []\n", "# Call Qdrant to find the closest data points\n", "for embedding in tqdm(test_embeddings):\n", " prediction = generate_fiftyone_classification(embedding, brain_key=\"bdd100k_qdrant_example\", field=\"timeofday\")\n", " predictions.append(prediction)\n", "\n", "test_view.set_values(\"timeofday\", predictions)" ] }, { "cell_type": "markdown", "id": "d9985859", "metadata": {}, "source": [ "Now we can pull up the FiftyOne App to inspect the `timeofday` labels on the test set to inspect how the classifier performed." ] }, { "cell_type": "code", "execution_count": 24, "id": "7f1e432d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n", " \n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Inspect how the annotations look\n", "session = fo.launch_app(test_view)" ] }, { "cell_type": "code", "execution_count": 25, "id": "1965a7df", "metadata": {}, "outputs": [], "source": [ "session.freeze()" ] }, { "cell_type": "code", "execution_count": 26, "id": "1bff8bc9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "
\n", "
\n", " \n", "
\n", " \n", "
\n", "\n", "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "session = fo.launch_app(test_view)" ] }, { "cell_type": "code", "execution_count": 27, "id": "4270a1d4", "metadata": {}, "outputs": [], "source": [ "session.freeze()" ] }, { "cell_type": "markdown", "id": "155fff6b", "metadata": {}, "source": [ "From here, there are multiple ways forward to further refine the preannotations. Two of these paths are:\n", "\n", "* Bringing in a QA team to use the [FiftyOne App to tag mistakes](https://voxel51.com/docs/fiftyone/user_guide/app.html#tags-and-tagging)\n", "* Using the [mistakenness feature](https://voxel51.com/docs/fiftyone/user_guide/brain.html#sample-hardness) of the FiftyOne Brain to automatically detect potential annotation mistakes\n", "\n", "Either way, these preannotations can then easily be passed to the annotation tools that FiftyOne integrates with like [CVAT](https://voxel51.com/docs/fiftyone/integrations/cvat.html), [Labelbox](https://voxel51.com/docs/fiftyone/integrations/labelbox.html), etc. for further refinement." ] }, { "cell_type": "markdown", "id": "122cc3a4-e233-42c8-8574-f42aea747d5e", "metadata": {}, "source": [ "# Other ways to interact with Qdrant\n", "\n", "In these examples, we have shown you how to compute embeddings and load them into Qdrant using compute_similarity. However, you can do many other things with the Qdrant integration as well!\n", "\n", "To quickly show you some of this functionality, we'll use th quickstart dataset which contains 200 images." ] }, { "cell_type": "code", "execution_count": 2, "id": "4be58731-8ce7-415b-bc51-bd80d50b3747", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dataset already downloaded\n", "Loading existing dataset 'quickstart'. To reload from disk, either delete the existing dataset or provide a custom `dataset_name` to use\n", "Name: quickstart\n", "Media type: image\n", "Num samples: 200\n", "Persistent: False\n", "Tags: []\n", "Sample fields:\n", " id: fiftyone.core.fields.ObjectIdField\n", " filepath: fiftyone.core.fields.StringField\n", " tags: fiftyone.core.fields.ListField(fiftyone.core.fields.StringField)\n", " metadata: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.metadata.ImageMetadata)\n", " ground_truth: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Detections)\n", " uniqueness: fiftyone.core.fields.FloatField\n", " predictions: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Detections)\n" ] } ], "source": [ "dataset = foz.load_zoo_dataset(\"quickstart\")\n", "print(dataset)" ] }, { "cell_type": "markdown", "id": "1ec84f8c-49f2-4ccb-af77-cdcae10d308e", "metadata": {}, "source": [ "\n", "***Note:*** Each of the following sections can be run independently of each other and in any order." ] }, { "cell_type": "markdown", "id": "fec3b37f-85a7-47c7-a12a-f7922f3f19da", "metadata": {}, "source": [ "### Use an existing index\n", "Suppose you already have a Qdrant collection storing the embedding vectors you need for the samples or patches in your dataset. You can connect to them directly by passing in the `collection_name` parameter to [compute_similarity()](https://docs.voxel51.com/api/fiftyone.brain.html#fiftyone.brain.compute_similarity). " ] }, { "cell_type": "code", "execution_count": 3, "id": "b58d5319-e2c7-4299-b7bc-3ef3a795ccec", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "fob.compute_similarity(\n", " dataset,\n", " model=\"clip-vit-base32-torch\", # zoo model used (if applicable)\n", " embeddings=False, # don't compute embeddings\n", " collection_name=\"your-collection\", # the existing Qdrant collection\n", " brain_key=\"existing_qdrant_index\",\n", " backend=\"qdrant\",\n", ")" ] }, { "cell_type": "markdown", "id": "abaa6a52-0cde-4fba-9f24-00b3fe08d52a", "metadata": {}, "source": [ "### Add or remove embeddings from an index\n", "Now suppose you have made changes to your dataset that involve removing or adding samples. You would need to then modify your embeddings in Qdrant to also reflect these changes. You can use [add_to_index()](https://docs.voxel51.com/api/fiftyone.brain.similarity.html#fiftyone.brain.similarity.SimilarityIndex.add_to_index) and [remove_from_index()](https://docs.voxel51.com/api/fiftyone.brain.similarity.html#fiftyone.brain.similarity.SimilarityIndex.remove_from_index) to add or remove embeddings from an existing Qdrant index." ] }, { "cell_type": "code", "execution_count": 4, "id": "871ee0ed-5013-418a-a0d0-cde537b7a7b7", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Computing embeddings...\n", " 100% |█████████████████| 200/200 [15.5s elapsed, 0s remaining, 13.8 samples/s] \n", "Starting Index Size: 200\n", "Post Delete Index Size: 190\n", " 100% |███████████████████| 20/20 [5.2ms elapsed, 0s remaining, 3.9K samples/s] \n", "Post Addition Index Size: 210\n" ] } ], "source": [ "import numpy as np\n", "\n", "qdrant_index = fob.compute_similarity(\n", " dataset,\n", " model=\"clip-vit-base32-torch\",\n", " brain_key=\"add_or_remove_qdrant_embeddings\",\n", " backend=\"qdrant\",\n", ")\n", "\n", "print(\"Starting Index Size: \" + str(qdrant_index.total_index_size)) # 200\n", "\n", "view = dataset.take(10)\n", "ids = view.values(\"id\")\n", "\n", "# Delete 10 samples from a dataset\n", "dataset.delete_samples(view)\n", "\n", "# Delete the corresponding vectors from the index\n", "qdrant_index.remove_from_index(sample_ids=ids)\n", "\n", "print(\"Post Delete Index Size: \" + str(qdrant_index.total_index_size)) # 190\n", "\n", "# Add 20 samples to a dataset\n", "samples = [fo.Sample(filepath=\"tmp%d.jpg\" % i) for i in range(20)]\n", "sample_ids = dataset.add_samples(samples)\n", "\n", "# Add corresponding embeddings to the index\n", "embeddings = np.random.rand(20, 512)\n", "qdrant_index.add_to_index(embeddings, sample_ids)\n", "\n", "print(\"Post Addition Index Size: \" + str(qdrant_index.total_index_size)) # 210" ] }, { "cell_type": "markdown", "id": "a193af82-6a58-44ac-a77f-8a135906b6a9", "metadata": {}, "source": [ "Since we modified this dataset, we're going to reload it so that it works as expected for the remaining examples." ] }, { "cell_type": "code", "execution_count": 5, "id": "9be45dc2-fca1-4381-bc72-dd9a4f9e1810", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dataset already downloaded\n", "Deleting existing dataset 'quickstart'\n", "Loading 'quickstart'\n", " 100% |█████████████████| 200/200 [1.9s elapsed, 0s remaining, 105.8 samples/s] \n", "Dataset 'quickstart' created\n" ] } ], "source": [ "dataset = foz.load_zoo_dataset(\"quickstart\", drop_existing_dataset=True)" ] }, { "cell_type": "markdown", "id": "546d156a-f442-48ba-a56a-1acf40b9a29e", "metadata": {}, "source": [ "### Retrieve embeddings from an index\n", "Do you have embeddings already calculated on a dataset that you want to retrieve in full? Or perhaps you have a view on your dataset that you want embeddings for? Use the function get_embeddings() to get your embeddings from a Qdrant index by ID." ] }, { "cell_type": "code", "execution_count": 6, "id": "61bda346-1a0e-4535-84d3-c9f28d249c5c", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Computing embeddings...\n", " 100% |█████████████████| 200/200 [15.3s elapsed, 0s remaining, 13.6 samples/s] \n", "(200, 512)\n", "(200,)\n", "(10, 512)\n", "(10,)\n" ] } ], "source": [ "qdrant_index = fob.compute_similarity(\n", " dataset,\n", " model=\"clip-vit-base32-torch\",\n", " brain_key=\"qdrant_index\",\n", " backend=\"qdrant\",\n", ")\n", "\n", "# Retrieve embeddings for the entire dataset\n", "ids = dataset.values(\"id\")\n", "embeddings, sample_ids, _ = qdrant_index.get_embeddings(sample_ids=ids)\n", "print(embeddings.shape) # (200, 512)\n", "print(sample_ids.shape) # (200,)\n", "\n", "# Retrieve embeddings for a view\n", "ids = dataset.take(10).values(\"id\")\n", "embeddings, sample_ids, _ = qdrant_index.get_embeddings(sample_ids=ids)\n", "print(embeddings.shape) # (10, 512)\n", "print(sample_ids.shape) # (10,)" ] }, { "cell_type": "markdown", "id": "46091881-901e-467f-bb52-ca52f203f969", "metadata": {}, "source": [ "### Access the Qdrant client directly\n", "While FiftyOne provides many ways to interact with Qdrant, sometimes you just need to connect directly to get your task done. Thus, you can directly access the Qdrant client instance by using the `client` property of a Qdrant index. From there, you can use the Qdrant methods as desired." ] }, { "cell_type": "code", "execution_count": 7, "id": "6ae342c4-e831-4cba-8b92-40e19cba0b16", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Computing embeddings...\n", " 100% |█████████████████| 200/200 [15.3s elapsed, 0s remaining, 13.4 samples/s] \n", "\n", "collections=[CollectionDescription(name='fiftyone-mnist-2500'), CollectionDescription(name='fiftyone-bdd100k-validation-1000'), CollectionDescription(name='fiftyone-mnist-2500-ais83e'), CollectionDescription(name='fiftyone-quickstart'), CollectionDescription(name='fiftyone-quickstart-jg78it'), CollectionDescription(name='fiftyone-bdd100k-validation-1000-9dll7r'), CollectionDescription(name='fiftyone_docs'), CollectionDescription(name='fiftyone-quickstart-9x04wr'), CollectionDescription(name='fiftyone-quickstart-0czljr'), CollectionDescription(name='fiftyone-mnist-2500-sipg85'), CollectionDescription(name='fiftyone-quickstart-40zten'), CollectionDescription(name='fiftyone-quickstart-9jv2wl'), CollectionDescription(name='fiftyone-quickstart-183n07')]\n" ] } ], "source": [ "qdrant_index = fob.compute_similarity(\n", " dataset,\n", " model=\"clip-vit-base32-torch\",\n", " brain_key=\"access_qdrant_client\",\n", " backend=\"qdrant\",\n", ")\n", "\n", "qdrant_client = qdrant_index.client\n", "print(qdrant_client)\n", "print(qdrant_client.get_collections())" ] }, { "cell_type": "markdown", "id": "78585a2c-de4c-4f56-9cfb-53d7428e8f45", "metadata": {}, "source": [ "### And more!\n", "To read up on everything you can do with the FiftyOne Qdrant integration, check out the [Qdrant integration](https://docs.voxel51.com/integrations/qdrant.html#qdrant-integration) page in our docs!" ] }, { "cell_type": "markdown", "id": "45d1012f", "metadata": {}, "source": [ "# Summary\n", "\n", "FiftyOne and Qdrant can be used together to efficiently perform a nearest neighbor search on embeddings and act on the results on your image and video datasets. The beauty of this process lies in its flexibility and repeatability. You can easily load additional ground truth labels for new fields into both FiftyOne and Qdrant and repeat this pre-annotation process using the existing embeddings. This can quickly cut down on annotation costs and result in higher-quality datasets, faster." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12" } }, "nbformat": 4, "nbformat_minor": 5 }