├── README.md ├── Vector Search.png └── AstraDB Image-to-Image vector search.ipynb /README.md: -------------------------------------------------------------------------------- 1 | # ai_ml_workshop_notebooks -------------------------------------------------------------------------------- /Vector Search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datastaxdevs/ai_ml_workshop_notebooks/main/Vector Search.png -------------------------------------------------------------------------------- /AstraDB Image-to-Image vector search.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": { 7 | "id": "ZFIzdcgGejWy" 8 | }, 9 | "source": [ 10 | "# Welcome\n", 11 | "Let's learn some vector search!\n" 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "metadata": { 17 | "id": "dcJA1DsRzeWB" 18 | }, 19 | "source": [ 20 | "# DataSnax image search\n", 21 | "\n", 22 | "Let's do something more interesting with vector search.\n", 23 | "\n", 24 | "In the following section we are going to build and image-to-image search based on:\n", 25 | "\n", 26 | "* a public image model (ViT)\n", 27 | "* a publicly available image dataset\n", 28 | "* AstraDB's vectorDB\n", 29 | "\n", 30 | "We will:\n", 31 | "\n", 32 | "1. setup our environment\n", 33 | "1. download an image dataset\n", 34 | "1. normalize all the photos from our dataset\n", 35 | "1. process them to extract a vector\n", 36 | "1. Add them to a table in our vector db\n", 37 | "1. Use a fresh image to search our db for similar pictures\n", 38 | "\n", 39 | "\n", 40 | "\n", 41 | "" 42 | ] 43 | }, 44 | { 45 | "attachments": {}, 46 | "cell_type": "markdown", 47 | "metadata": { 48 | "id": "ctiEfMgwDJ2S" 49 | }, 50 | "source": [ 51 | "## Setup our environment\n", 52 | "\n", 53 | "**timm** is used to download existing models from Huggingface.co\n", 54 | "\n", 55 | "**datasets** and **datasets[vision]** are used to download example datasets from huggingface. After we are done here, why not pick a different dataset and try it for yourself? [This section of the huggingface shared datasets](https://huggingface.co/datasets?task_categories=task_categories:image-classification&sort=downloads) is a good place to start.\n", 56 | "\n", 57 | "**cassandra-driver** will be used to store and query our embeddings in AstraDB.\n", 58 | "\n", 59 | "**ipyplot** will be used to maker our search display a little nicer here.\n", 60 | "\n", 61 | "**torchvision** will be used to process images and normalizet them.\n", 62 | "\n", 63 | "**PIL** will be used to load images and display them in this workbook.\n", 64 | "\n", 65 | "**imagenet_labels** will be used to demonstrate image classification with the ViT model." 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": null, 71 | "metadata": { 72 | "id": "vqo_dm1_3IaU" 73 | }, 74 | "outputs": [], 75 | "source": [ 76 | "%%capture\n", 77 | "\n", 78 | "!pip install timm\n", 79 | "!pip install datasets\n", 80 | "!pip install datasets[vision]\n", 81 | "!pip install cassandra-driver\n", 82 | "!pip install ipywidgets\n", 83 | "!pip install ipyplot\n", 84 | "\n", 85 | "import torch\n", 86 | "\n", 87 | "import torchvision\n", 88 | "import torchvision.transforms as T\n", 89 | "\n", 90 | "import PIL\n", 91 | "import ipyplot\n", 92 | "\n", 93 | "from timm import create_model\n", 94 | "\n", 95 | "# ImageNet Labels - only needed for showing of image categorization/ViT vector internals\n", 96 | "!wget https://storage.googleapis.com/bit_models/ilsvrc2012_wordnet_lemmas.txt\n", 97 | "imagenet_labels = dict(enumerate(open('ilsvrc2012_wordnet_lemmas.txt')))\n", 98 | "\n" 99 | ] 100 | }, 101 | { 102 | "attachments": {}, 103 | "cell_type": "markdown", 104 | "metadata": { 105 | "id": "x5fqFRZjeshS" 106 | }, 107 | "source": [ 108 | "### Setup our AstraDB Connection\n", 109 | "\n", 110 | "1. If you haven't, please [create an AstraDB instance with vector enabled](https://docs.datastax.com/en/astra-serverless/docs/vector-search/overview.html).\n", 111 | "\n", 112 | "1. [Create a token for a 'Database Administrator' account](https://docs.datastax.com/en/astra-serverless/docs/manage/org/managing-org.html#_manage_application_tokens), you'll need to be able to create tables and read write data as we go along.\n", 113 | "\n", 114 | "1. Fill in the values from the token your created in the next block.\n" 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "#@title Setup our AstraDB Credentials\n", 124 | "\n", 125 | "import ipywidgets as widgets\n", 126 | "import requests\n", 127 | "\n", 128 | "ASTRA_CLIENT_ID = 'client id'#@param {type:\"string\"}\n", 129 | "ASTRA_CLIENT_SECRET = 'client secret' #@param {type:\"string\"}\n", 130 | "ASTRACS_TOKEN = 'astracs token' #@param {type:\"string\"}\n", 131 | "\n", 132 | "\n", 133 | "\n", 134 | "\n", 135 | "def list_databases(token):\n", 136 | " url = \"https://api.astra.datastax.com/v2/databases\"\n", 137 | " headers = {\n", 138 | " \"Authorization\": \"Bearer \" + token,\n", 139 | " \"Content-Type\": \"application/json\"\n", 140 | " }\n", 141 | " response = requests.get(url, headers=headers)\n", 142 | " if response.status_code == 200:\n", 143 | " return response.json()\n", 144 | " else:\n", 145 | " return None\n", 146 | "\n", 147 | "def get_database_names(databases_details):\n", 148 | " return [db['info']['name'] for db in databases_details]\n", 149 | "\n", 150 | "\n", 151 | "databases_details = list_databases(ASTRACS_TOKEN)\n", 152 | "\n", 153 | "\n", 154 | "\n", 155 | "# Create a mapping of database names to their secure bundle URLs\n", 156 | "db_map = {db['info']['name']: db['info']['datacenters'][0]['secureBundleUrl'] for db in databases_details}\n", 157 | "\n", 158 | "# Create a dropdown menu with the database names\n", 159 | "dropdown = widgets.Dropdown(\n", 160 | " options=db_map.keys(),\n", 161 | " description='Database:',\n", 162 | ")\n", 163 | "\n", 164 | "# Create a button that will trigger the download when clicked\n", 165 | "button = widgets.Button(description=\"Download Secure Bundle\")\n", 166 | "\n", 167 | "# Define what the button will do when clicked\n", 168 | "def on_button_clicked(b):\n", 169 | " db_name = dropdown.value\n", 170 | " secure_bundle_url = db_map[db_name]\n", 171 | "\n", 172 | " # Download the file\n", 173 | " response = requests.get(secure_bundle_url)\n", 174 | " file_name = f'{db_name}_secure_bundle.zip'\n", 175 | " file_path = os.path.join(os.getcwd(), file_name) # This will get the full path\n", 176 | " with open(file_path, 'wb') as f:\n", 177 | " f.write(response.content)\n", 178 | " print(f\"Downloaded secure bundle for {db_name} at {file_path}\")\n", 179 | "\n", 180 | " # Save the file path to a variable\n", 181 | " global scb_path\n", 182 | " scb_path = file_path\n", 183 | "\n", 184 | "# Display the dropdown and the button\n", 185 | "button.on_click(on_button_clicked)\n", 186 | "display(dropdown, button)\n" 187 | ] 188 | }, 189 | { 190 | "cell_type": "code", 191 | "execution_count": null, 192 | "metadata": {}, 193 | "outputs": [], 194 | "source": [ 195 | "#@title Connect to our AstraDB VectorDB\n", 196 | "SECURE_CONNECT_BUNDLE_PATH = scb_path\n", 197 | "\n", 198 | "import os\n", 199 | "import pandas as pd #just using this for ipy output formating\n", 200 | "from cassandra.cluster import Cluster\n", 201 | "from cassandra.auth import PlainTextAuthProvider\n", 202 | "from cassandra import ConsistencyLevel\n", 203 | "from cassandra.query import dict_factory\n", 204 | "\n", 205 | "cloud_config = {\n", 206 | " 'secure_connect_bundle': SECURE_CONNECT_BUNDLE_PATH\n", 207 | "}\n", 208 | "auth_provider = PlainTextAuthProvider(ASTRA_CLIENT_ID, ASTRA_CLIENT_SECRET)\n", 209 | "cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider, protocol_version=4)\n", 210 | "session = cluster.connect()" 211 | ] 212 | }, 213 | { 214 | "attachments": {}, 215 | "cell_type": "markdown", 216 | "metadata": { 217 | "id": "P7sK5WqJqrIf" 218 | }, 219 | "source": [ 220 | "## The Data" 221 | ] 222 | }, 223 | { 224 | "attachments": {}, 225 | "cell_type": "markdown", 226 | "metadata": { 227 | "id": "QRoPSwkjGfSf" 228 | }, 229 | "source": [ 230 | "### Setup our data\n", 231 | "\n", 232 | "[Explore the dataset here](https://huggingface.co/datasets/Matthijs/snacks/viewer/default/train)\n", 233 | "\n", 234 | "\n", 235 | "Want to try with another dataset? It should be as easy as making sure that dataset has an \"image\" property that we can load.\n", 236 | "\n", 237 | "If it's hosted on huggingface, you can also just change the string below to load it. (like docker, but data!)" 238 | ] 239 | }, 240 | { 241 | "cell_type": "code", 242 | "execution_count": null, 243 | "metadata": { 244 | "id": "oE73NBsPBJAI" 245 | }, 246 | "outputs": [], 247 | "source": [ 248 | "from datasets import load_dataset, Image\n", 249 | "\n", 250 | "dataset = load_dataset(\"Matthijs/snacks\")" 251 | ] 252 | }, 253 | { 254 | "attachments": {}, 255 | "cell_type": "markdown", 256 | "metadata": { 257 | "id": "G7ZgjaZLG78i" 258 | }, 259 | "source": [ 260 | "### Normalize our data\n", 261 | "\n", 262 | "It's important that our images are formatted similarly for most models if we hope to compare our apples to our oranges.\n", 263 | "\n", 264 | "These steps setup a pipeline to resize images, convert them to a tensor to feed to our model, and normalize that tensor." 265 | ] 266 | }, 267 | { 268 | "cell_type": "code", 269 | "execution_count": null, 270 | "metadata": { 271 | "id": "w1yuBeUkBMP-" 272 | }, 273 | "outputs": [], 274 | "source": [ 275 | "# Define transforms for test\n", 276 | "IMG_SIZE = (224, 224)\n", 277 | "NORMALIZE_MEAN = (0.5, 0.5, 0.5)\n", 278 | "NORMALIZE_STD = (0.5, 0.5, 0.5)\n", 279 | "transforms = [\n", 280 | " T.Resize(IMG_SIZE),\n", 281 | " T.ToTensor(),\n", 282 | " T.Normalize(NORMALIZE_MEAN, NORMALIZE_STD),\n", 283 | " ]\n", 284 | "\n", 285 | "transforms = T.Compose(transforms)\n", 286 | "\n", 287 | "def ds_transforms(examples):\n", 288 | " examples[\"pixel_values\"] = [transforms(image) for image in examples[\"image\"]]\n", 289 | " return examples\n", 290 | "\n", 291 | "dataset = dataset.with_transform(ds_transforms)" 292 | ] 293 | }, 294 | { 295 | "attachments": {}, 296 | "cell_type": "markdown", 297 | "metadata": { 298 | "id": "rSY5ggjxHSVN" 299 | }, 300 | "source": [ 301 | "### Look at our dataset\n", 302 | "\n", 303 | "Let's also look at a row from the dataset that we have downloaded. Notice that our transforms have run and we now have a pixel_values field with a normalized and version of our image ready for processing." 304 | ] 305 | }, 306 | { 307 | "cell_type": "code", 308 | "execution_count": null, 309 | "metadata": { 310 | "id": "nqx_9L0LB9h7" 311 | }, 312 | "outputs": [], 313 | "source": [ 314 | "i = dataset[\"train\"][10]\n", 315 | "print(\"an image from the dataset\")\n", 316 | "display(i)" 317 | ] 318 | }, 319 | { 320 | "attachments": {}, 321 | "cell_type": "markdown", 322 | "metadata": { 323 | "id": "AMw1yQ01E59W" 324 | }, 325 | "source": [ 326 | "## The Model\n", 327 | "\n", 328 | "Let's grab a public model to handle creating vectors from our images. I'm using \"vit_base_patch16_224\" but there are lots of options.\n", 329 | "\n", 330 | "A couple things to keep in mind as you pick pre-existing models\n", 331 | "* Do any models work for your task before any additional training?\n", 332 | "* How do the models perform, is a faster but less effective model good enough?\n", 333 | "\n", 334 | "We are also setting up the GPU for use if it's available. Currently, most models really want a GPU to perform reasonabily. That may change in the near-ish future.\n", 335 | "\n", 336 | "Lastly. we grab a copy of the pretrained model and then load it into our GPU (if available)." 337 | ] 338 | }, 339 | { 340 | "cell_type": "code", 341 | "execution_count": null, 342 | "metadata": { 343 | "id": "4v4kxUAy5EZ9" 344 | }, 345 | "outputs": [], 346 | "source": [ 347 | "model_name = \"vit_base_patch16_224\"\n", 348 | "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", 349 | "print(\"device = \", device)\n", 350 | "# create a ViT model : https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py\n", 351 | "model = create_model(model_name, pretrained=True).to(device)" 352 | ] 353 | }, 354 | { 355 | "attachments": {}, 356 | "cell_type": "markdown", 357 | "metadata": { 358 | "id": "5XzuMg4ArUn_" 359 | }, 360 | "source": [ 361 | "## Data + Model = Embeddings Vector" 362 | ] 363 | }, 364 | { 365 | "attachments": {}, 366 | "cell_type": "markdown", 367 | "metadata": { 368 | "id": "K_VnnsnGrhFq" 369 | }, 370 | "source": [ 371 | "### Inspecting the Model output" 372 | ] 373 | }, 374 | { 375 | "attachments": {}, 376 | "cell_type": "markdown", 377 | "metadata": { 378 | "id": "16PxGBuXYfhD" 379 | }, 380 | "source": [ 381 | "The following code loads an entry from the training data, uploads it's image data to our GPU and then runs our model on it.\n", 382 | "\n", 383 | "VOILA! We have a vector! (though we are still calling it a tensor)\n", 384 | "\n" 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": null, 390 | "metadata": { 391 | "id": "xD9p1suuYXVq" 392 | }, 393 | "outputs": [], 394 | "source": [ 395 | "img_tensor = i[\"pixel_values\"].unsqueeze(0).to(device)\n", 396 | "output = model(img_tensor)\n", 397 | "output" 398 | ] 399 | }, 400 | { 401 | "attachments": {}, 402 | "cell_type": "markdown", 403 | "metadata": { 404 | "id": "-jPvE2B5YllH" 405 | }, 406 | "source": [ 407 | "### What's in an embedding?\n", 408 | "\n", 409 | "Short answer? It depends. But it's not the original content.\n", 410 | "\n", 411 | "The vector our model creates depends entirely on the model. The goal is to create a vector where each dimension is independent of the others, and all the dimensions are normalized.\n", 412 | "\n", 413 | "Our ViT model is actually relatively easy to understand. It was trained on millions of images that had been categorized using labels from Imagenet.\n", 414 | "\n", 415 | "In fact, this model was designed for image classification. To classify the image all we have to do is find the largest value of the vector and look up it's index in the image net label set. (If you have run the steps leading up to this one, you should see the image net data in your content directory)." 416 | ] 417 | }, 418 | { 419 | "cell_type": "code", 420 | "execution_count": null, 421 | "metadata": { 422 | "id": "qZ_JEzjZseq4" 423 | }, 424 | "outputs": [], 425 | "source": [ 426 | "\n", 427 | "def cats_for_vector(vector):\n", 428 | " # copy our vector out of VRAM so we can play with it\n", 429 | " vector = vector.detach().cpu()\n", 430 | " # Find the indexes for the top 5 values in the array\n", 431 | " cats = torch.topk(vector, 5)[1].numpy()[0]\n", 432 | " results = []\n", 433 | " for c in cats:\n", 434 | " results.append([c, imagenet_labels[c], float(vector[0][c])])\n", 435 | " return results\n", 436 | "\n", 437 | "\n", 438 | "image_index = 10\n", 439 | "img = dataset[\"train\"][image_index]\n", 440 | "img_tensor = img[\"pixel_values\"].unsqueeze(0).to(device)\n", 441 | "output = model(img_tensor)\n", 442 | "display(img[\"image\"])\n", 443 | "pd.DataFrame(cats_for_vector(output), columns=[\"cat number\", \"category\", \"strength\"])" 444 | ] 445 | }, 446 | { 447 | "attachments": {}, 448 | "cell_type": "markdown", 449 | "metadata": { 450 | "id": "YajzvevMItYH" 451 | }, 452 | "source": [ 453 | "### Inference - getting the embeddings for our data\n", 454 | "\n", 455 | "Below we are going to embed the vector/tensor result from the model into our dataset.\n", 456 | "\n", 457 | "NOTE: We also create an index for each row in the dataset. That index is used to get back image data after our search. In the real world your data would probably already have some sort of unique id and this approach to id generation would never be a good idea." 458 | ] 459 | }, 460 | { 461 | "cell_type": "code", 462 | "execution_count": null, 463 | "metadata": { 464 | "colab": { 465 | "base_uri": "https://localhost:8080/", 466 | "height": 17, 467 | "referenced_widgets": [ 468 | "913bad51c8fe4edc8208527a7335aeb4", 469 | "93a6333ad8754ed4bcc3a7c5d343483a", 470 | "23db01edb6ea41e093f7d2609b8a4b08", 471 | "44c6a9f4b6dc438e8b28f9d7c07f3ec4", 472 | "269d11c877944733b1849726527efe4f", 473 | "f582d18d1c954eba86b7fb6c061254fa", 474 | "724f0b134b384283978de7fe37b55321", 475 | "5873ea97b0b9481f97cdac790eaad28f", 476 | "061fa93251854196bc1dcec11ca4862d", 477 | "53a2c12ef66640f394a30d8bd5feecbf", 478 | "7f330b7e21b845e5be19f9b04aa5a129", 479 | "e06413c2e35b4042b0bf750de2f1ed1b", 480 | "596dfbcf4c2342599ba2be4e9e7f361b", 481 | "785f072742e94dc3a7f59ce3da1ddcdd", 482 | "ea51ef4ea6af4cd78241d4345e0bded1", 483 | "4160850600f74231b9acd9c424fa1e60", 484 | "3098780cb4c348e0a00bcf739316fe9b", 485 | "c11169fe911a4e9d9e8fa63d942955c5", 486 | "99a75e2e28e341d5860b54f4a7b91771", 487 | "769b18a9d51341dc950f53871d6af085", 488 | "2f2c6d02cf974db6abeab9d8781256a7", 489 | "e67e6576faf3477fba118d9de8932023", 490 | "2b9c996bd47a4cc6aa8ccb3dd72dec52", 491 | "60660805538043c3ad2f8eaaaa17aa0e", 492 | "00b1fc23bedf4e1f983f56ceccc9c148", 493 | "2b7aa88ffc1d47d89237c469833e8ad2", 494 | "40a2328c2176437a80b038a44eeb588e", 495 | "c177f88508ae48bc9d5b11bd35b8e19a", 496 | "b04b00e8ce56498a8989c3702c4f98d4", 497 | "8e99124e4eeb44afb9355c24e0406fba", 498 | "1347d234e4c04ee887a4e446ed4e46a1", 499 | "da5f298b8e72402b9b9e47d69245375f", 500 | "80737d74db254139b6183b3e2dfb99f9" 501 | ] 502 | }, 503 | "id": "OOSuERSpFr1F", 504 | "outputId": "41ee1a58-2158-4df9-eb1d-2112854bfcc5" 505 | }, 506 | "outputs": [], 507 | "source": [ 508 | "def add_embedding(example, idx):\n", 509 | " example[\"id\"] = idx # adding the index to the dataset here\n", 510 | " with torch.no_grad(): # pytorch likes to keep data about the model run, we will run out of memory if we leave this on.\n", 511 | " example[\"embedding\"] = model(example[\"pixel_values\"].unsqueeze(0).to(device)) # analyze the image data, and copy the vector embedding back to system memory\n", 512 | " return example\n", 513 | "\n", 514 | "\n", 515 | "updated_dataset = dataset.map(add_embedding, with_indices=True)" 516 | ] 517 | }, 518 | { 519 | "attachments": {}, 520 | "cell_type": "markdown", 521 | "metadata": { 522 | "id": "bmB6jUqdKp4O" 523 | }, 524 | "source": [ 525 | "## Saving our embeddings to AstraDB\n", 526 | "\n", 527 | "This sets up our AstraDB database to store images in the 'images' table and creates a custom index to enable searching by vectors against the 'images' table." 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": null, 533 | "metadata": { 534 | "id": "dWVHfKriMrMH" 535 | }, 536 | "outputs": [], 537 | "source": [ 538 | "KEYSPACE_NAME = 'vsearch'\n", 539 | "TABLE_NAME = 'images'\n", 540 | "\n", 541 | "#session.execute(f\"DROP TABLE {KEYSPACE_NAME}.{TABLE_NAME}\")\n", 542 | "print(f\"Creating table {TABLE_NAME} in keyspace {KEYSPACE_NAME}\")\n", 543 | "session.execute(f\"CREATE TABLE IF NOT EXISTS {KEYSPACE_NAME}.{TABLE_NAME} (id int PRIMARY KEY, image_vector VECTOR)\")\n", 544 | "\n", 545 | "print(f\"Creating index ann_index on table {TABLE_NAME} and inserting example data\")\n", 546 | "session.execute(f\"CREATE CUSTOM INDEX IF NOT EXISTS ann_index ON {KEYSPACE_NAME}.{TABLE_NAME} (image_vector) USING 'StorageAttachedIndex'\")" 547 | ] 548 | }, 549 | { 550 | "cell_type": "code", 551 | "execution_count": null, 552 | "metadata": { 553 | "id": "7lvV8pTJM2r1" 554 | }, 555 | "outputs": [], 556 | "source": [ 557 | "def insert_embedding(example):\n", 558 | " id = example[\"id\"]\n", 559 | " embedding = example[\"embedding\"][0]\n", 560 | " session.execute(f\"INSERT INTO {KEYSPACE_NAME}.{TABLE_NAME} (id, image_vector) VALUES ({id}, {embedding})\")\n", 561 | " return example\n", 562 | "\n", 563 | "updated_dataset.map(insert_embedding)" 564 | ] 565 | }, 566 | { 567 | "attachments": {}, 568 | "cell_type": "markdown", 569 | "metadata": { 570 | "id": "4MS92hW7Lkor" 571 | }, 572 | "source": [ 573 | "## Querying our data with another image\n", 574 | "\n", 575 | "Let's pretend to upload an image to your cool new image-to-image search app. Fortunately, we have a bunch of images that weren't embedded into our vector DB in our \"test\" and \"validate\" datasets. So we can pretend one of those images has been submitted by a user in order to query our vector db.\n", 576 | "\n", 577 | "We can grab an image from there, calculate it's embeddings and then ask the database for similar images.\n", 578 | "\n", 579 | "Our test set is 952 images, so set the 'search_id' below to some number between 0 and 952.\n", 580 | "\n" 581 | ] 582 | }, 583 | { 584 | "cell_type": "code", 585 | "execution_count": null, 586 | "metadata": { 587 | "id": "20tGwI2vFJ93" 588 | }, 589 | "outputs": [], 590 | "source": [ 591 | "# our test dataset has 952 images, pick a number to try a different search\n", 592 | "search_id = 422 #@param {type:\"integer\"}\n", 593 | "\n", 594 | "# grab an image from out test set (remember, these images are not in our DB)\n", 595 | "img = updated_dataset[\"test\"][search_id]\n", 596 | "print(\"Searching for images like this one:\")\n", 597 | "display(img[\"image\"])\n", 598 | "embedding = img[\"embedding\"][0]\n", 599 | "\n", 600 | "images = []\n", 601 | "labels = []\n", 602 | "KEYSPACE_NAME = 'vsearch'\n", 603 | "TABLE_NAME = 'images'\n", 604 | "# use that embedding as a query\n", 605 | "print(f\"Returning 'nearest neighbor' using ANN search\")\n", 606 | "for row in session.execute(f\"SELECT id, image_vector FROM {KEYSPACE_NAME}.{TABLE_NAME} ORDER BY image_vector ANN OF {embedding} LIMIT 5\"):\n", 607 | " image = updated_dataset[\"train\"][row.id]\n", 608 | " images.append(image[\"image\"])\n", 609 | " labels.append(row.id)\n", 610 | "\n", 611 | "#display our images in a pretty grid\n", 612 | "ipyplot.plot_images(images, labels, img_width=300)\n" 613 | ] 614 | }, 615 | { 616 | "attachments": {}, 617 | "cell_type": "markdown", 618 | "metadata": { 619 | "id": "i09yEhKcVtFw" 620 | }, 621 | "source": [ 622 | "# Next Steps\n", 623 | "\n", 624 | "The road branches here, do you want to:\n", 625 | "\n", 626 | "* Learn more about vectors and what you can do with them?\n", 627 | "https://cloud.google.com/blog/topics/developers-practitioners/meet-ais-multitool-vector-embeddings\n", 628 | "\n", 629 | "* Coffee talk with data scientists (and understand some of the magic)?\n", 630 | "https://developers.google.com/machine-learning/crash-course/\n", 631 | "\n", 632 | "* Embed two sets of vectors into the same space? Ratings + Users anyone?\n", 633 | "https://cloud.google.com/blog/products/ai-machine-learning/scaling-deep-retrieval-tensorflow-two-towers-architecture\n", 634 | "\n", 635 | "* Learn about AstraDB/Apache Cassandra as a tool in awesome new Generative AI agents?\n", 636 | "https://cassio.org\n", 637 | "\n", 638 | "* Dig deeper into the ViT [Unofficial Walkthrough of Vision Transformer](https://colab.research.google.com/github/hirotomusiker/schwert_colab_data_storage/blob/master/notebook/Vision_Transformer_Tutorial.ipynb#scrollTo=y_uWXBvo1X1C)" 639 | ] 640 | } 641 | ], 642 | "metadata": { 643 | "colab": { 644 | "machine_shape": "hm", 645 | "provenance": [], 646 | "toc_visible": true 647 | }, 648 | "kernelspec": { 649 | "display_name": "Python 3", 650 | "name": "python3" 651 | }, 652 | "language_info": { 653 | "codemirror_mode": { 654 | "name": "ipython", 655 | "version": 3 656 | }, 657 | "file_extension": ".py", 658 | "mimetype": "text/x-python", 659 | "name": "python", 660 | "nbconvert_exporter": "python", 661 | "pygments_lexer": "ipython3", 662 | "version": "3.10.11" 663 | }, 664 | "widgets": { 665 | "application/vnd.jupyter.widget-state+json": { 666 | "00b1fc23bedf4e1f983f56ceccc9c148": { 667 | "model_module": "@jupyter-widgets/controls", 668 | "model_module_version": "1.5.0", 669 | "model_name": "FloatProgressModel", 670 | "state": { 671 | "_dom_classes": [], 672 | "_model_module": "@jupyter-widgets/controls", 673 | "_model_module_version": "1.5.0", 674 | "_model_name": "FloatProgressModel", 675 | "_view_count": null, 676 | "_view_module": "@jupyter-widgets/controls", 677 | "_view_module_version": "1.5.0", 678 | "_view_name": "ProgressView", 679 | "bar_style": "", 680 | "description": "", 681 | "description_tooltip": null, 682 | "layout": "IPY_MODEL_8e99124e4eeb44afb9355c24e0406fba", 683 | "max": 955, 684 | "min": 0, 685 | "orientation": "horizontal", 686 | "style": "IPY_MODEL_1347d234e4c04ee887a4e446ed4e46a1", 687 | "value": 955 688 | } 689 | }, 690 | "061fa93251854196bc1dcec11ca4862d": { 691 | "model_module": "@jupyter-widgets/controls", 692 | "model_module_version": "1.5.0", 693 | "model_name": "ProgressStyleModel", 694 | "state": { 695 | "_model_module": "@jupyter-widgets/controls", 696 | "_model_module_version": "1.5.0", 697 | "_model_name": "ProgressStyleModel", 698 | "_view_count": null, 699 | "_view_module": "@jupyter-widgets/base", 700 | "_view_module_version": "1.2.0", 701 | "_view_name": "StyleView", 702 | "bar_color": null, 703 | "description_width": "" 704 | } 705 | }, 706 | "1347d234e4c04ee887a4e446ed4e46a1": { 707 | "model_module": "@jupyter-widgets/controls", 708 | "model_module_version": "1.5.0", 709 | "model_name": "ProgressStyleModel", 710 | "state": { 711 | "_model_module": "@jupyter-widgets/controls", 712 | "_model_module_version": "1.5.0", 713 | "_model_name": "ProgressStyleModel", 714 | "_view_count": null, 715 | "_view_module": "@jupyter-widgets/base", 716 | "_view_module_version": "1.2.0", 717 | "_view_name": "StyleView", 718 | "bar_color": null, 719 | "description_width": "" 720 | } 721 | }, 722 | "23db01edb6ea41e093f7d2609b8a4b08": { 723 | "model_module": "@jupyter-widgets/controls", 724 | "model_module_version": "1.5.0", 725 | "model_name": "FloatProgressModel", 726 | "state": { 727 | "_dom_classes": [], 728 | "_model_module": "@jupyter-widgets/controls", 729 | "_model_module_version": "1.5.0", 730 | "_model_name": "FloatProgressModel", 731 | "_view_count": null, 732 | "_view_module": "@jupyter-widgets/controls", 733 | "_view_module_version": "1.5.0", 734 | "_view_name": "ProgressView", 735 | "bar_style": "", 736 | "description": "", 737 | "description_tooltip": null, 738 | "layout": "IPY_MODEL_5873ea97b0b9481f97cdac790eaad28f", 739 | "max": 4838, 740 | "min": 0, 741 | "orientation": "horizontal", 742 | "style": "IPY_MODEL_061fa93251854196bc1dcec11ca4862d", 743 | "value": 4838 744 | } 745 | }, 746 | "269d11c877944733b1849726527efe4f": { 747 | "model_module": "@jupyter-widgets/base", 748 | "model_module_version": "1.2.0", 749 | "model_name": "LayoutModel", 750 | "state": { 751 | "_model_module": "@jupyter-widgets/base", 752 | "_model_module_version": "1.2.0", 753 | "_model_name": "LayoutModel", 754 | "_view_count": null, 755 | "_view_module": "@jupyter-widgets/base", 756 | "_view_module_version": "1.2.0", 757 | "_view_name": "LayoutView", 758 | "align_content": null, 759 | "align_items": null, 760 | "align_self": null, 761 | "border": null, 762 | "bottom": null, 763 | "display": null, 764 | "flex": null, 765 | "flex_flow": null, 766 | "grid_area": null, 767 | "grid_auto_columns": null, 768 | "grid_auto_flow": null, 769 | "grid_auto_rows": null, 770 | "grid_column": null, 771 | "grid_gap": null, 772 | "grid_row": null, 773 | "grid_template_areas": null, 774 | "grid_template_columns": null, 775 | "grid_template_rows": null, 776 | "height": null, 777 | "justify_content": null, 778 | "justify_items": null, 779 | "left": null, 780 | "margin": null, 781 | "max_height": null, 782 | "max_width": null, 783 | "min_height": null, 784 | "min_width": null, 785 | "object_fit": null, 786 | "object_position": null, 787 | "order": null, 788 | "overflow": null, 789 | "overflow_x": null, 790 | "overflow_y": null, 791 | "padding": null, 792 | "right": null, 793 | "top": null, 794 | "visibility": "hidden", 795 | "width": null 796 | } 797 | }, 798 | "2b7aa88ffc1d47d89237c469833e8ad2": { 799 | "model_module": "@jupyter-widgets/controls", 800 | "model_module_version": "1.5.0", 801 | "model_name": "HTMLModel", 802 | "state": { 803 | "_dom_classes": [], 804 | "_model_module": "@jupyter-widgets/controls", 805 | "_model_module_version": "1.5.0", 806 | "_model_name": "HTMLModel", 807 | "_view_count": null, 808 | "_view_module": "@jupyter-widgets/controls", 809 | "_view_module_version": "1.5.0", 810 | "_view_name": "HTMLView", 811 | "description": "", 812 | "description_tooltip": null, 813 | "layout": "IPY_MODEL_da5f298b8e72402b9b9e47d69245375f", 814 | "placeholder": "​", 815 | "style": "IPY_MODEL_80737d74db254139b6183b3e2dfb99f9", 816 | "value": " 955/955 [00:14<00:00, 67.36 examples/s]" 817 | } 818 | }, 819 | "2b9c996bd47a4cc6aa8ccb3dd72dec52": { 820 | "model_module": "@jupyter-widgets/controls", 821 | "model_module_version": "1.5.0", 822 | "model_name": "HBoxModel", 823 | "state": { 824 | "_dom_classes": [], 825 | "_model_module": "@jupyter-widgets/controls", 826 | "_model_module_version": "1.5.0", 827 | "_model_name": "HBoxModel", 828 | "_view_count": null, 829 | "_view_module": "@jupyter-widgets/controls", 830 | "_view_module_version": "1.5.0", 831 | "_view_name": "HBoxView", 832 | "box_style": "", 833 | "children": [ 834 | "IPY_MODEL_60660805538043c3ad2f8eaaaa17aa0e", 835 | "IPY_MODEL_00b1fc23bedf4e1f983f56ceccc9c148", 836 | "IPY_MODEL_2b7aa88ffc1d47d89237c469833e8ad2" 837 | ], 838 | "layout": "IPY_MODEL_40a2328c2176437a80b038a44eeb588e" 839 | } 840 | }, 841 | "2f2c6d02cf974db6abeab9d8781256a7": { 842 | "model_module": "@jupyter-widgets/base", 843 | "model_module_version": "1.2.0", 844 | "model_name": "LayoutModel", 845 | "state": { 846 | "_model_module": "@jupyter-widgets/base", 847 | "_model_module_version": "1.2.0", 848 | "_model_name": "LayoutModel", 849 | "_view_count": null, 850 | "_view_module": "@jupyter-widgets/base", 851 | "_view_module_version": "1.2.0", 852 | "_view_name": "LayoutView", 853 | "align_content": null, 854 | "align_items": null, 855 | "align_self": null, 856 | "border": null, 857 | "bottom": null, 858 | "display": null, 859 | "flex": null, 860 | "flex_flow": null, 861 | "grid_area": null, 862 | "grid_auto_columns": null, 863 | "grid_auto_flow": null, 864 | "grid_auto_rows": null, 865 | "grid_column": null, 866 | "grid_gap": null, 867 | "grid_row": null, 868 | "grid_template_areas": null, 869 | "grid_template_columns": null, 870 | "grid_template_rows": null, 871 | "height": null, 872 | "justify_content": null, 873 | "justify_items": null, 874 | "left": null, 875 | "margin": null, 876 | "max_height": null, 877 | "max_width": null, 878 | "min_height": null, 879 | "min_width": null, 880 | "object_fit": null, 881 | "object_position": null, 882 | "order": null, 883 | "overflow": null, 884 | "overflow_x": null, 885 | "overflow_y": null, 886 | "padding": null, 887 | "right": null, 888 | "top": null, 889 | "visibility": null, 890 | "width": null 891 | } 892 | }, 893 | "3098780cb4c348e0a00bcf739316fe9b": { 894 | "model_module": "@jupyter-widgets/base", 895 | "model_module_version": "1.2.0", 896 | "model_name": "LayoutModel", 897 | "state": { 898 | "_model_module": "@jupyter-widgets/base", 899 | "_model_module_version": "1.2.0", 900 | "_model_name": "LayoutModel", 901 | "_view_count": null, 902 | "_view_module": "@jupyter-widgets/base", 903 | "_view_module_version": "1.2.0", 904 | "_view_name": "LayoutView", 905 | "align_content": null, 906 | "align_items": null, 907 | "align_self": null, 908 | "border": null, 909 | "bottom": null, 910 | "display": null, 911 | "flex": null, 912 | "flex_flow": null, 913 | "grid_area": null, 914 | "grid_auto_columns": null, 915 | "grid_auto_flow": null, 916 | "grid_auto_rows": null, 917 | "grid_column": null, 918 | "grid_gap": null, 919 | "grid_row": null, 920 | "grid_template_areas": null, 921 | "grid_template_columns": null, 922 | "grid_template_rows": null, 923 | "height": null, 924 | "justify_content": null, 925 | "justify_items": null, 926 | "left": null, 927 | "margin": null, 928 | "max_height": null, 929 | "max_width": null, 930 | "min_height": null, 931 | "min_width": null, 932 | "object_fit": null, 933 | "object_position": null, 934 | "order": null, 935 | "overflow": null, 936 | "overflow_x": null, 937 | "overflow_y": null, 938 | "padding": null, 939 | "right": null, 940 | "top": null, 941 | "visibility": null, 942 | "width": null 943 | } 944 | }, 945 | "40a2328c2176437a80b038a44eeb588e": { 946 | "model_module": "@jupyter-widgets/base", 947 | "model_module_version": "1.2.0", 948 | "model_name": "LayoutModel", 949 | "state": { 950 | "_model_module": "@jupyter-widgets/base", 951 | "_model_module_version": "1.2.0", 952 | "_model_name": "LayoutModel", 953 | "_view_count": null, 954 | "_view_module": "@jupyter-widgets/base", 955 | "_view_module_version": "1.2.0", 956 | "_view_name": "LayoutView", 957 | "align_content": null, 958 | "align_items": null, 959 | "align_self": null, 960 | "border": null, 961 | "bottom": null, 962 | "display": null, 963 | "flex": null, 964 | "flex_flow": null, 965 | "grid_area": null, 966 | "grid_auto_columns": null, 967 | "grid_auto_flow": null, 968 | "grid_auto_rows": null, 969 | "grid_column": null, 970 | "grid_gap": null, 971 | "grid_row": null, 972 | "grid_template_areas": null, 973 | "grid_template_columns": null, 974 | "grid_template_rows": null, 975 | "height": null, 976 | "justify_content": null, 977 | "justify_items": null, 978 | "left": null, 979 | "margin": null, 980 | "max_height": null, 981 | "max_width": null, 982 | "min_height": null, 983 | "min_width": null, 984 | "object_fit": null, 985 | "object_position": null, 986 | "order": null, 987 | "overflow": null, 988 | "overflow_x": null, 989 | "overflow_y": null, 990 | "padding": null, 991 | "right": null, 992 | "top": null, 993 | "visibility": "hidden", 994 | "width": null 995 | } 996 | }, 997 | "4160850600f74231b9acd9c424fa1e60": { 998 | "model_module": "@jupyter-widgets/base", 999 | "model_module_version": "1.2.0", 1000 | "model_name": "LayoutModel", 1001 | "state": { 1002 | "_model_module": "@jupyter-widgets/base", 1003 | "_model_module_version": "1.2.0", 1004 | "_model_name": "LayoutModel", 1005 | "_view_count": null, 1006 | "_view_module": "@jupyter-widgets/base", 1007 | "_view_module_version": "1.2.0", 1008 | "_view_name": "LayoutView", 1009 | "align_content": null, 1010 | "align_items": null, 1011 | "align_self": null, 1012 | "border": null, 1013 | "bottom": null, 1014 | "display": null, 1015 | "flex": null, 1016 | "flex_flow": null, 1017 | "grid_area": null, 1018 | "grid_auto_columns": null, 1019 | "grid_auto_flow": null, 1020 | "grid_auto_rows": null, 1021 | "grid_column": null, 1022 | "grid_gap": null, 1023 | "grid_row": null, 1024 | "grid_template_areas": null, 1025 | "grid_template_columns": null, 1026 | "grid_template_rows": null, 1027 | "height": null, 1028 | "justify_content": null, 1029 | "justify_items": null, 1030 | "left": null, 1031 | "margin": null, 1032 | "max_height": null, 1033 | "max_width": null, 1034 | "min_height": null, 1035 | "min_width": null, 1036 | "object_fit": null, 1037 | "object_position": null, 1038 | "order": null, 1039 | "overflow": null, 1040 | "overflow_x": null, 1041 | "overflow_y": null, 1042 | "padding": null, 1043 | "right": null, 1044 | "top": null, 1045 | "visibility": "hidden", 1046 | "width": null 1047 | } 1048 | }, 1049 | "44c6a9f4b6dc438e8b28f9d7c07f3ec4": { 1050 | "model_module": "@jupyter-widgets/controls", 1051 | "model_module_version": "1.5.0", 1052 | "model_name": "HTMLModel", 1053 | "state": { 1054 | "_dom_classes": [], 1055 | "_model_module": "@jupyter-widgets/controls", 1056 | "_model_module_version": "1.5.0", 1057 | "_model_name": "HTMLModel", 1058 | "_view_count": null, 1059 | "_view_module": "@jupyter-widgets/controls", 1060 | "_view_module_version": "1.5.0", 1061 | "_view_name": "HTMLView", 1062 | "description": "", 1063 | "description_tooltip": null, 1064 | "layout": "IPY_MODEL_53a2c12ef66640f394a30d8bd5feecbf", 1065 | "placeholder": "​", 1066 | "style": "IPY_MODEL_7f330b7e21b845e5be19f9b04aa5a129", 1067 | "value": " 4834/4838 [01:32<00:00, 68.69 examples/s]" 1068 | } 1069 | }, 1070 | "53a2c12ef66640f394a30d8bd5feecbf": { 1071 | "model_module": "@jupyter-widgets/base", 1072 | "model_module_version": "1.2.0", 1073 | "model_name": "LayoutModel", 1074 | "state": { 1075 | "_model_module": "@jupyter-widgets/base", 1076 | "_model_module_version": "1.2.0", 1077 | "_model_name": "LayoutModel", 1078 | "_view_count": null, 1079 | "_view_module": "@jupyter-widgets/base", 1080 | "_view_module_version": "1.2.0", 1081 | "_view_name": "LayoutView", 1082 | "align_content": null, 1083 | "align_items": null, 1084 | "align_self": null, 1085 | "border": null, 1086 | "bottom": null, 1087 | "display": null, 1088 | "flex": null, 1089 | "flex_flow": null, 1090 | "grid_area": null, 1091 | "grid_auto_columns": null, 1092 | "grid_auto_flow": null, 1093 | "grid_auto_rows": null, 1094 | "grid_column": null, 1095 | "grid_gap": null, 1096 | "grid_row": null, 1097 | "grid_template_areas": null, 1098 | "grid_template_columns": null, 1099 | "grid_template_rows": null, 1100 | "height": null, 1101 | "justify_content": null, 1102 | "justify_items": null, 1103 | "left": null, 1104 | "margin": null, 1105 | "max_height": null, 1106 | "max_width": null, 1107 | "min_height": null, 1108 | "min_width": null, 1109 | "object_fit": null, 1110 | "object_position": null, 1111 | "order": null, 1112 | "overflow": null, 1113 | "overflow_x": null, 1114 | "overflow_y": null, 1115 | "padding": null, 1116 | "right": null, 1117 | "top": null, 1118 | "visibility": null, 1119 | "width": null 1120 | } 1121 | }, 1122 | "5873ea97b0b9481f97cdac790eaad28f": { 1123 | "model_module": "@jupyter-widgets/base", 1124 | "model_module_version": "1.2.0", 1125 | "model_name": "LayoutModel", 1126 | "state": { 1127 | "_model_module": "@jupyter-widgets/base", 1128 | "_model_module_version": "1.2.0", 1129 | "_model_name": "LayoutModel", 1130 | "_view_count": null, 1131 | "_view_module": "@jupyter-widgets/base", 1132 | "_view_module_version": "1.2.0", 1133 | "_view_name": "LayoutView", 1134 | "align_content": null, 1135 | "align_items": null, 1136 | "align_self": null, 1137 | "border": null, 1138 | "bottom": null, 1139 | "display": null, 1140 | "flex": null, 1141 | "flex_flow": null, 1142 | "grid_area": null, 1143 | "grid_auto_columns": null, 1144 | "grid_auto_flow": null, 1145 | "grid_auto_rows": null, 1146 | "grid_column": null, 1147 | "grid_gap": null, 1148 | "grid_row": null, 1149 | "grid_template_areas": null, 1150 | "grid_template_columns": null, 1151 | "grid_template_rows": null, 1152 | "height": null, 1153 | "justify_content": null, 1154 | "justify_items": null, 1155 | "left": null, 1156 | "margin": null, 1157 | "max_height": null, 1158 | "max_width": null, 1159 | "min_height": null, 1160 | "min_width": null, 1161 | "object_fit": null, 1162 | "object_position": null, 1163 | "order": null, 1164 | "overflow": null, 1165 | "overflow_x": null, 1166 | "overflow_y": null, 1167 | "padding": null, 1168 | "right": null, 1169 | "top": null, 1170 | "visibility": null, 1171 | "width": null 1172 | } 1173 | }, 1174 | "596dfbcf4c2342599ba2be4e9e7f361b": { 1175 | "model_module": "@jupyter-widgets/controls", 1176 | "model_module_version": "1.5.0", 1177 | "model_name": "HTMLModel", 1178 | "state": { 1179 | "_dom_classes": [], 1180 | "_model_module": "@jupyter-widgets/controls", 1181 | "_model_module_version": "1.5.0", 1182 | "_model_name": "HTMLModel", 1183 | "_view_count": null, 1184 | "_view_module": "@jupyter-widgets/controls", 1185 | "_view_module_version": "1.5.0", 1186 | "_view_name": "HTMLView", 1187 | "description": "", 1188 | "description_tooltip": null, 1189 | "layout": "IPY_MODEL_3098780cb4c348e0a00bcf739316fe9b", 1190 | "placeholder": "​", 1191 | "style": "IPY_MODEL_c11169fe911a4e9d9e8fa63d942955c5", 1192 | "value": "Map: 100%" 1193 | } 1194 | }, 1195 | "60660805538043c3ad2f8eaaaa17aa0e": { 1196 | "model_module": "@jupyter-widgets/controls", 1197 | "model_module_version": "1.5.0", 1198 | "model_name": "HTMLModel", 1199 | "state": { 1200 | "_dom_classes": [], 1201 | "_model_module": "@jupyter-widgets/controls", 1202 | "_model_module_version": "1.5.0", 1203 | "_model_name": "HTMLModel", 1204 | "_view_count": null, 1205 | "_view_module": "@jupyter-widgets/controls", 1206 | "_view_module_version": "1.5.0", 1207 | "_view_name": "HTMLView", 1208 | "description": "", 1209 | "description_tooltip": null, 1210 | "layout": "IPY_MODEL_c177f88508ae48bc9d5b11bd35b8e19a", 1211 | "placeholder": "​", 1212 | "style": "IPY_MODEL_b04b00e8ce56498a8989c3702c4f98d4", 1213 | "value": "Map: 100%" 1214 | } 1215 | }, 1216 | "724f0b134b384283978de7fe37b55321": { 1217 | "model_module": "@jupyter-widgets/controls", 1218 | "model_module_version": "1.5.0", 1219 | "model_name": "DescriptionStyleModel", 1220 | "state": { 1221 | "_model_module": "@jupyter-widgets/controls", 1222 | "_model_module_version": "1.5.0", 1223 | "_model_name": "DescriptionStyleModel", 1224 | "_view_count": null, 1225 | "_view_module": "@jupyter-widgets/base", 1226 | "_view_module_version": "1.2.0", 1227 | "_view_name": "StyleView", 1228 | "description_width": "" 1229 | } 1230 | }, 1231 | "769b18a9d51341dc950f53871d6af085": { 1232 | "model_module": "@jupyter-widgets/controls", 1233 | "model_module_version": "1.5.0", 1234 | "model_name": "ProgressStyleModel", 1235 | "state": { 1236 | "_model_module": "@jupyter-widgets/controls", 1237 | "_model_module_version": "1.5.0", 1238 | "_model_name": "ProgressStyleModel", 1239 | "_view_count": null, 1240 | "_view_module": "@jupyter-widgets/base", 1241 | "_view_module_version": "1.2.0", 1242 | "_view_name": "StyleView", 1243 | "bar_color": null, 1244 | "description_width": "" 1245 | } 1246 | }, 1247 | "785f072742e94dc3a7f59ce3da1ddcdd": { 1248 | "model_module": "@jupyter-widgets/controls", 1249 | "model_module_version": "1.5.0", 1250 | "model_name": "FloatProgressModel", 1251 | "state": { 1252 | "_dom_classes": [], 1253 | "_model_module": "@jupyter-widgets/controls", 1254 | "_model_module_version": "1.5.0", 1255 | "_model_name": "FloatProgressModel", 1256 | "_view_count": null, 1257 | "_view_module": "@jupyter-widgets/controls", 1258 | "_view_module_version": "1.5.0", 1259 | "_view_name": "ProgressView", 1260 | "bar_style": "", 1261 | "description": "", 1262 | "description_tooltip": null, 1263 | "layout": "IPY_MODEL_99a75e2e28e341d5860b54f4a7b91771", 1264 | "max": 952, 1265 | "min": 0, 1266 | "orientation": "horizontal", 1267 | "style": "IPY_MODEL_769b18a9d51341dc950f53871d6af085", 1268 | "value": 952 1269 | } 1270 | }, 1271 | "7f330b7e21b845e5be19f9b04aa5a129": { 1272 | "model_module": "@jupyter-widgets/controls", 1273 | "model_module_version": "1.5.0", 1274 | "model_name": "DescriptionStyleModel", 1275 | "state": { 1276 | "_model_module": "@jupyter-widgets/controls", 1277 | "_model_module_version": "1.5.0", 1278 | "_model_name": "DescriptionStyleModel", 1279 | "_view_count": null, 1280 | "_view_module": "@jupyter-widgets/base", 1281 | "_view_module_version": "1.2.0", 1282 | "_view_name": "StyleView", 1283 | "description_width": "" 1284 | } 1285 | }, 1286 | "80737d74db254139b6183b3e2dfb99f9": { 1287 | "model_module": "@jupyter-widgets/controls", 1288 | "model_module_version": "1.5.0", 1289 | "model_name": "DescriptionStyleModel", 1290 | "state": { 1291 | "_model_module": "@jupyter-widgets/controls", 1292 | "_model_module_version": "1.5.0", 1293 | "_model_name": "DescriptionStyleModel", 1294 | "_view_count": null, 1295 | "_view_module": "@jupyter-widgets/base", 1296 | "_view_module_version": "1.2.0", 1297 | "_view_name": "StyleView", 1298 | "description_width": "" 1299 | } 1300 | }, 1301 | "8e99124e4eeb44afb9355c24e0406fba": { 1302 | "model_module": "@jupyter-widgets/base", 1303 | "model_module_version": "1.2.0", 1304 | "model_name": "LayoutModel", 1305 | "state": { 1306 | "_model_module": "@jupyter-widgets/base", 1307 | "_model_module_version": "1.2.0", 1308 | "_model_name": "LayoutModel", 1309 | "_view_count": null, 1310 | "_view_module": "@jupyter-widgets/base", 1311 | "_view_module_version": "1.2.0", 1312 | "_view_name": "LayoutView", 1313 | "align_content": null, 1314 | "align_items": null, 1315 | "align_self": null, 1316 | "border": null, 1317 | "bottom": null, 1318 | "display": null, 1319 | "flex": null, 1320 | "flex_flow": null, 1321 | "grid_area": null, 1322 | "grid_auto_columns": null, 1323 | "grid_auto_flow": null, 1324 | "grid_auto_rows": null, 1325 | "grid_column": null, 1326 | "grid_gap": null, 1327 | "grid_row": null, 1328 | "grid_template_areas": null, 1329 | "grid_template_columns": null, 1330 | "grid_template_rows": null, 1331 | "height": null, 1332 | "justify_content": null, 1333 | "justify_items": null, 1334 | "left": null, 1335 | "margin": null, 1336 | "max_height": null, 1337 | "max_width": null, 1338 | "min_height": null, 1339 | "min_width": null, 1340 | "object_fit": null, 1341 | "object_position": null, 1342 | "order": null, 1343 | "overflow": null, 1344 | "overflow_x": null, 1345 | "overflow_y": null, 1346 | "padding": null, 1347 | "right": null, 1348 | "top": null, 1349 | "visibility": null, 1350 | "width": null 1351 | } 1352 | }, 1353 | "913bad51c8fe4edc8208527a7335aeb4": { 1354 | "model_module": "@jupyter-widgets/controls", 1355 | "model_module_version": "1.5.0", 1356 | "model_name": "HBoxModel", 1357 | "state": { 1358 | "_dom_classes": [], 1359 | "_model_module": "@jupyter-widgets/controls", 1360 | "_model_module_version": "1.5.0", 1361 | "_model_name": "HBoxModel", 1362 | "_view_count": null, 1363 | "_view_module": "@jupyter-widgets/controls", 1364 | "_view_module_version": "1.5.0", 1365 | "_view_name": "HBoxView", 1366 | "box_style": "", 1367 | "children": [ 1368 | "IPY_MODEL_93a6333ad8754ed4bcc3a7c5d343483a", 1369 | "IPY_MODEL_23db01edb6ea41e093f7d2609b8a4b08", 1370 | "IPY_MODEL_44c6a9f4b6dc438e8b28f9d7c07f3ec4" 1371 | ], 1372 | "layout": "IPY_MODEL_269d11c877944733b1849726527efe4f" 1373 | } 1374 | }, 1375 | "93a6333ad8754ed4bcc3a7c5d343483a": { 1376 | "model_module": "@jupyter-widgets/controls", 1377 | "model_module_version": "1.5.0", 1378 | "model_name": "HTMLModel", 1379 | "state": { 1380 | "_dom_classes": [], 1381 | "_model_module": "@jupyter-widgets/controls", 1382 | "_model_module_version": "1.5.0", 1383 | "_model_name": "HTMLModel", 1384 | "_view_count": null, 1385 | "_view_module": "@jupyter-widgets/controls", 1386 | "_view_module_version": "1.5.0", 1387 | "_view_name": "HTMLView", 1388 | "description": "", 1389 | "description_tooltip": null, 1390 | "layout": "IPY_MODEL_f582d18d1c954eba86b7fb6c061254fa", 1391 | "placeholder": "​", 1392 | "style": "IPY_MODEL_724f0b134b384283978de7fe37b55321", 1393 | "value": "Map: 100%" 1394 | } 1395 | }, 1396 | "99a75e2e28e341d5860b54f4a7b91771": { 1397 | "model_module": "@jupyter-widgets/base", 1398 | "model_module_version": "1.2.0", 1399 | "model_name": "LayoutModel", 1400 | "state": { 1401 | "_model_module": "@jupyter-widgets/base", 1402 | "_model_module_version": "1.2.0", 1403 | "_model_name": "LayoutModel", 1404 | "_view_count": null, 1405 | "_view_module": "@jupyter-widgets/base", 1406 | "_view_module_version": "1.2.0", 1407 | "_view_name": "LayoutView", 1408 | "align_content": null, 1409 | "align_items": null, 1410 | "align_self": null, 1411 | "border": null, 1412 | "bottom": null, 1413 | "display": null, 1414 | "flex": null, 1415 | "flex_flow": null, 1416 | "grid_area": null, 1417 | "grid_auto_columns": null, 1418 | "grid_auto_flow": null, 1419 | "grid_auto_rows": null, 1420 | "grid_column": null, 1421 | "grid_gap": null, 1422 | "grid_row": null, 1423 | "grid_template_areas": null, 1424 | "grid_template_columns": null, 1425 | "grid_template_rows": null, 1426 | "height": null, 1427 | "justify_content": null, 1428 | "justify_items": null, 1429 | "left": null, 1430 | "margin": null, 1431 | "max_height": null, 1432 | "max_width": null, 1433 | "min_height": null, 1434 | "min_width": null, 1435 | "object_fit": null, 1436 | "object_position": null, 1437 | "order": null, 1438 | "overflow": null, 1439 | "overflow_x": null, 1440 | "overflow_y": null, 1441 | "padding": null, 1442 | "right": null, 1443 | "top": null, 1444 | "visibility": null, 1445 | "width": null 1446 | } 1447 | }, 1448 | "b04b00e8ce56498a8989c3702c4f98d4": { 1449 | "model_module": "@jupyter-widgets/controls", 1450 | "model_module_version": "1.5.0", 1451 | "model_name": "DescriptionStyleModel", 1452 | "state": { 1453 | "_model_module": "@jupyter-widgets/controls", 1454 | "_model_module_version": "1.5.0", 1455 | "_model_name": "DescriptionStyleModel", 1456 | "_view_count": null, 1457 | "_view_module": "@jupyter-widgets/base", 1458 | "_view_module_version": "1.2.0", 1459 | "_view_name": "StyleView", 1460 | "description_width": "" 1461 | } 1462 | }, 1463 | "c11169fe911a4e9d9e8fa63d942955c5": { 1464 | "model_module": "@jupyter-widgets/controls", 1465 | "model_module_version": "1.5.0", 1466 | "model_name": "DescriptionStyleModel", 1467 | "state": { 1468 | "_model_module": "@jupyter-widgets/controls", 1469 | "_model_module_version": "1.5.0", 1470 | "_model_name": "DescriptionStyleModel", 1471 | "_view_count": null, 1472 | "_view_module": "@jupyter-widgets/base", 1473 | "_view_module_version": "1.2.0", 1474 | "_view_name": "StyleView", 1475 | "description_width": "" 1476 | } 1477 | }, 1478 | "c177f88508ae48bc9d5b11bd35b8e19a": { 1479 | "model_module": "@jupyter-widgets/base", 1480 | "model_module_version": "1.2.0", 1481 | "model_name": "LayoutModel", 1482 | "state": { 1483 | "_model_module": "@jupyter-widgets/base", 1484 | "_model_module_version": "1.2.0", 1485 | "_model_name": "LayoutModel", 1486 | "_view_count": null, 1487 | "_view_module": "@jupyter-widgets/base", 1488 | "_view_module_version": "1.2.0", 1489 | "_view_name": "LayoutView", 1490 | "align_content": null, 1491 | "align_items": null, 1492 | "align_self": null, 1493 | "border": null, 1494 | "bottom": null, 1495 | "display": null, 1496 | "flex": null, 1497 | "flex_flow": null, 1498 | "grid_area": null, 1499 | "grid_auto_columns": null, 1500 | "grid_auto_flow": null, 1501 | "grid_auto_rows": null, 1502 | "grid_column": null, 1503 | "grid_gap": null, 1504 | "grid_row": null, 1505 | "grid_template_areas": null, 1506 | "grid_template_columns": null, 1507 | "grid_template_rows": null, 1508 | "height": null, 1509 | "justify_content": null, 1510 | "justify_items": null, 1511 | "left": null, 1512 | "margin": null, 1513 | "max_height": null, 1514 | "max_width": null, 1515 | "min_height": null, 1516 | "min_width": null, 1517 | "object_fit": null, 1518 | "object_position": null, 1519 | "order": null, 1520 | "overflow": null, 1521 | "overflow_x": null, 1522 | "overflow_y": null, 1523 | "padding": null, 1524 | "right": null, 1525 | "top": null, 1526 | "visibility": null, 1527 | "width": null 1528 | } 1529 | }, 1530 | "da5f298b8e72402b9b9e47d69245375f": { 1531 | "model_module": "@jupyter-widgets/base", 1532 | "model_module_version": "1.2.0", 1533 | "model_name": "LayoutModel", 1534 | "state": { 1535 | "_model_module": "@jupyter-widgets/base", 1536 | "_model_module_version": "1.2.0", 1537 | "_model_name": "LayoutModel", 1538 | "_view_count": null, 1539 | "_view_module": "@jupyter-widgets/base", 1540 | "_view_module_version": "1.2.0", 1541 | "_view_name": "LayoutView", 1542 | "align_content": null, 1543 | "align_items": null, 1544 | "align_self": null, 1545 | "border": null, 1546 | "bottom": null, 1547 | "display": null, 1548 | "flex": null, 1549 | "flex_flow": null, 1550 | "grid_area": null, 1551 | "grid_auto_columns": null, 1552 | "grid_auto_flow": null, 1553 | "grid_auto_rows": null, 1554 | "grid_column": null, 1555 | "grid_gap": null, 1556 | "grid_row": null, 1557 | "grid_template_areas": null, 1558 | "grid_template_columns": null, 1559 | "grid_template_rows": null, 1560 | "height": null, 1561 | "justify_content": null, 1562 | "justify_items": null, 1563 | "left": null, 1564 | "margin": null, 1565 | "max_height": null, 1566 | "max_width": null, 1567 | "min_height": null, 1568 | "min_width": null, 1569 | "object_fit": null, 1570 | "object_position": null, 1571 | "order": null, 1572 | "overflow": null, 1573 | "overflow_x": null, 1574 | "overflow_y": null, 1575 | "padding": null, 1576 | "right": null, 1577 | "top": null, 1578 | "visibility": null, 1579 | "width": null 1580 | } 1581 | }, 1582 | "e06413c2e35b4042b0bf750de2f1ed1b": { 1583 | "model_module": "@jupyter-widgets/controls", 1584 | "model_module_version": "1.5.0", 1585 | "model_name": "HBoxModel", 1586 | "state": { 1587 | "_dom_classes": [], 1588 | "_model_module": "@jupyter-widgets/controls", 1589 | "_model_module_version": "1.5.0", 1590 | "_model_name": "HBoxModel", 1591 | "_view_count": null, 1592 | "_view_module": "@jupyter-widgets/controls", 1593 | "_view_module_version": "1.5.0", 1594 | "_view_name": "HBoxView", 1595 | "box_style": "", 1596 | "children": [ 1597 | "IPY_MODEL_596dfbcf4c2342599ba2be4e9e7f361b", 1598 | "IPY_MODEL_785f072742e94dc3a7f59ce3da1ddcdd", 1599 | "IPY_MODEL_ea51ef4ea6af4cd78241d4345e0bded1" 1600 | ], 1601 | "layout": "IPY_MODEL_4160850600f74231b9acd9c424fa1e60" 1602 | } 1603 | }, 1604 | "e67e6576faf3477fba118d9de8932023": { 1605 | "model_module": "@jupyter-widgets/controls", 1606 | "model_module_version": "1.5.0", 1607 | "model_name": "DescriptionStyleModel", 1608 | "state": { 1609 | "_model_module": "@jupyter-widgets/controls", 1610 | "_model_module_version": "1.5.0", 1611 | "_model_name": "DescriptionStyleModel", 1612 | "_view_count": null, 1613 | "_view_module": "@jupyter-widgets/base", 1614 | "_view_module_version": "1.2.0", 1615 | "_view_name": "StyleView", 1616 | "description_width": "" 1617 | } 1618 | }, 1619 | "ea51ef4ea6af4cd78241d4345e0bded1": { 1620 | "model_module": "@jupyter-widgets/controls", 1621 | "model_module_version": "1.5.0", 1622 | "model_name": "HTMLModel", 1623 | "state": { 1624 | "_dom_classes": [], 1625 | "_model_module": "@jupyter-widgets/controls", 1626 | "_model_module_version": "1.5.0", 1627 | "_model_name": "HTMLModel", 1628 | "_view_count": null, 1629 | "_view_module": "@jupyter-widgets/controls", 1630 | "_view_module_version": "1.5.0", 1631 | "_view_name": "HTMLView", 1632 | "description": "", 1633 | "description_tooltip": null, 1634 | "layout": "IPY_MODEL_2f2c6d02cf974db6abeab9d8781256a7", 1635 | "placeholder": "​", 1636 | "style": "IPY_MODEL_e67e6576faf3477fba118d9de8932023", 1637 | "value": " 948/952 [00:14<00:00, 66.95 examples/s]" 1638 | } 1639 | }, 1640 | "f582d18d1c954eba86b7fb6c061254fa": { 1641 | "model_module": "@jupyter-widgets/base", 1642 | "model_module_version": "1.2.0", 1643 | "model_name": "LayoutModel", 1644 | "state": { 1645 | "_model_module": "@jupyter-widgets/base", 1646 | "_model_module_version": "1.2.0", 1647 | "_model_name": "LayoutModel", 1648 | "_view_count": null, 1649 | "_view_module": "@jupyter-widgets/base", 1650 | "_view_module_version": "1.2.0", 1651 | "_view_name": "LayoutView", 1652 | "align_content": null, 1653 | "align_items": null, 1654 | "align_self": null, 1655 | "border": null, 1656 | "bottom": null, 1657 | "display": null, 1658 | "flex": null, 1659 | "flex_flow": null, 1660 | "grid_area": null, 1661 | "grid_auto_columns": null, 1662 | "grid_auto_flow": null, 1663 | "grid_auto_rows": null, 1664 | "grid_column": null, 1665 | "grid_gap": null, 1666 | "grid_row": null, 1667 | "grid_template_areas": null, 1668 | "grid_template_columns": null, 1669 | "grid_template_rows": null, 1670 | "height": null, 1671 | "justify_content": null, 1672 | "justify_items": null, 1673 | "left": null, 1674 | "margin": null, 1675 | "max_height": null, 1676 | "max_width": null, 1677 | "min_height": null, 1678 | "min_width": null, 1679 | "object_fit": null, 1680 | "object_position": null, 1681 | "order": null, 1682 | "overflow": null, 1683 | "overflow_x": null, 1684 | "overflow_y": null, 1685 | "padding": null, 1686 | "right": null, 1687 | "top": null, 1688 | "visibility": null, 1689 | "width": null 1690 | } 1691 | } 1692 | } 1693 | } 1694 | }, 1695 | "nbformat": 4, 1696 | "nbformat_minor": 0 1697 | } 1698 | --------------------------------------------------------------------------------