{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Add image embeddings to a Table\n", "\n", "In this example we will extend an existing table with embeddings computed from a pre-trained model.\n", "\n", "\n", "\n", "![img](../images/add-embeddings.jpg)\n", "\n", "- Write an initial table containing a single column of image URLs.\n", "- Write a new table containing the input URLs and the embeddings computed from a pre-trained model.\n", "- Apply dimensionality reduction to the extended table to get a final table containing the URLs, the embeddings, and the reduced embeddings." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Install dependencies" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%pip install 3lc[pacmap]\n", "%pip install git+https://github.com/3lc-ai/3lc-examples.git\n", "%pip install transformers" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import io\n", "\n", "import tlc\n", "from PIL import Image\n", "\n", "from tlc_tools.embeddings import add_embeddings_to_table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Project setup\n", "\n", "We load the previously written COCO128 table from [create-table-from-coco.ipynb](../1-create-tables/object%20detection/create-table-from-coco-detection.ipynb)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "table = tlc.Table.from_names(\"initial\", \"COCO128\", \"3LC Tutorials - COCO128\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extend the table with embeddings from a pre-trained model\n", "\n", "We will use the ViT model pre-trained on ImageNet to compute embeddings for the images in the table.\n", "A benefit of using this model is that meaningful embeddings can be extracted easily using the `last_hidden_state` attribute of the model output." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Map the table to return only the image column as a PIL.Image:\n", "def convert_image(sample):\n", " image_bytes = io.BytesIO(tlc.Url(sample[\"image\"]).read())\n", " return Image.open(image_bytes).convert(\"RGB\")\n", "\n", "\n", "table.map(convert_image)\n", "\n", "# Add embeddings to the table:\n", "extended_table = add_embeddings_to_table(table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reduce the embeddings to 2 dimensions\n", "\n", "Finally we reduce the embedding-column to 2 dimensions using UMAP. The result is a table containing the URLs, the embeddings, and the reduced embeddings." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "reduced_table = tlc.reduce_embeddings(\n", " extended_table,\n", " method=\"pacmap\",\n", " n_components=2,\n", " retain_source_embedding_column=False,\n", ")\n", "\n", "print(\n", " reduced_table.table_rows[0].keys()\n", ") # The row-view of the reduced table contains both the embeddings and the reduced embeddings" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# The PaCMAP model is stored in the reduced_table.model_url attribute and can be reused to transform new data\n", "reduced_table.model_url" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "reduced_table.url" ] } ], "metadata": { "kernelspec": { "display_name": ".venv", "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.11.3" } }, "nbformat": 4, "nbformat_minor": 2 }