import{s as rn,n as mn,o as pn}from"../chunks/scheduler.1f027d5a.js";import{S as hn,i as un,e as i,s as l,c as m,q as v,H as bt,h as cn,a as o,d as s,b as n,f as vt,g as p,j as r,r as j,u as jt,k as ft,v as Ja,l as d,m as a,n as h,t as u,o as c,p as f}from"../chunks/index.cedebf1a.js";import{C as fn}from"../chunks/CopyLLMTxtMenu.9763f102.js";import{D as dn,C as g}from"../chunks/DocNotebookDropdown.aa615a4d.js";import{H as T,E as gn}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.71ce9e32.js";function yn(Fa){let C,xt,Ct,kt,I,$t,W,_t,Z,Ut,z,Xa='<em>Authored by: <a href="https://huggingface.co/jamarks" rel="nofollow">Jacob Marks</a></em>',Jt,q,Ra='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_cover_image.jpg" alt="Art Analysis Cover Image"/>',It,H,Ba="Visual data like images is incredibly information-rich, but the unstructured nature of that data makes it difficult to analyze.",Wt,G,Va='In this notebook, we’ll explore how to use multimodal embeddings and computed attributes to analyze artistic styles in images. We’ll use the <a href="https://huggingface.co/datasets/huggan/wikiart" rel="nofollow">WikiArt dataset</a> from 🤗 Hub, which we will load into FiftyOne for data analysis and visualization. We’ll dive into the data in a variety of ways:',Zt,L,Aa='<li><p><strong>Image Similarity Search and Semantic Search</strong>: We’ll generate multimodal embeddings for the images in the dataset using a pre-trained <a href="https://huggingface.co/openai/clip-vit-base-patch32" rel="nofollow">CLIP</a> model from 🤗 Transformers and index the data to allow for unstructured searches.</p></li> <li><p><strong>Clustering and Visualization</strong>: We’ll cluster the images based on their artistic style using the embeddings and visualize the results using UMAP dimensionality reduction.</p></li> <li><p><strong>Uniqueness Analysis</strong>: We’ll use our embeddings to assign a uniqueness score to each image based on how similar it is to other images in the dataset.</p></li> <li><p><strong>Image Quality Analysis</strong>: We’ll compute image quality metrics like brightness, contrast, and saturation for each image and see how these metrics correlate with the artistic style of the images.</p></li>',zt,F,qt,X,Pa="To run this notebook, you’ll need to install the following libraries:",Ht,R,Gt,B,Na='To make downloads lightning-fast, install <a href="https://pypi.org/project/hf-transfer/" rel="nofollow">HF Transfer</a>:',Lt,V,Ft,A,Ya="And enable by setting the environment variable <code>HF_HUB_ENABLE_HF_TRANSFER</code>:",Xt,P,Rt,x,Ea="<b>Note:</b> This notebook was tested with <code>transformers==4.40.0</code>, <code>huggingface_hub==0.22.2</code>, and <code>fiftyone==0.23.8</code>.",Bt,N,Sa="Now let’s import the modules that we’ll need for this notebook:",Vt,Y,At,w,Ia,dt,Qa="datasets",Wa,k,Oa="FiftyOne’s 🤗 Hub integration",Za,Pt,tn='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo separator="true">,</mo><mn>000</mn></mrow><annotation encoding="application/x-tex">1,000</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.8389em;vertical-align:-0.1944em;"></span><span class="mord">1</span><span class="mpunct">,</span><span class="mspace" style="margin-right:0.1667em;"></span><span class="mord">000</span></span></span></span>',Nt,Yt,E,Et,S,Da="Print out a summary of the dataset to see what it contains:",St,Q,Qt,O,Ka=`Name:        wikiart
Media type:  image
Num samples: 1000
Persistent:  False
Tags:        []
Sample fields:
    id:       fiftyone.core.fields.ObjectIdField
    filepath: fiftyone.core.fields.StringField
    tags:     fiftyone.core.fields.ListField(fiftyone.core.fields.StringField)
    metadata: fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.metadata.ImageMetadata)
    artist:   fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    style:    fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    genre:    fiftyone.core.fields.EmbeddedDocumentField(fiftyone.core.labels.Classification)
    row_idx:  fiftyone.core.fields.IntField
`,Ot,D,el='Visualize the dataset in the <a href="https://docs.voxel51.com/user_guide/app.html" rel="nofollow">FiftyOne App</a>:',Dt,K,Kt,ee,tl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_wikiart_dataset.jpg" alt="WikiArt Dataset"/>',es,te,sl="Let’s list out the names of the artists whose styles we’ll be analyzing:",ts,se,ss,ae,al=`['Unknown Artist', 'albrecht-durer', 'boris-kustodiev', 'camille-pissarro', 'childe-hassam', 'claude-monet', 'edgar-degas', 'eugene-boudin', 'gustave-dore', 'ilya-repin', 'ivan-aivazovsky', 'ivan-shishkin', 'john-singer-sargent', 'marc-chagall', 'martiros-saryan', 'nicholas-roerich', 'pablo-picasso', 'paul-cezanne', 'pierre-auguste-renoir', 'pyotr-konchalovsky', 'raphael-kirchner', 'rembrandt', 'salvador-dali', 'vincent-van-gogh']
`,as,le,ls,ne,ll="When you find a piece of art that you like, it’s natural to want to find similar pieces. We can do this with vector embeddings! What’s more, by using multimodal embeddings, we will unlock the ability to find paintings that closely resemble a given text query, which could be a description of a painting or even a poem.",ns,ie,nl='Let’s generate multimodal embeddings for the images using a pre-trained CLIP Vision Transformer (ViT) model from 🤗 Transformers. Running <code>compute_similarity()</code> from the <a href="https://docs.voxel51.com/user_guide/brain.html" rel="nofollow">FiftyOne Brain</a> will compute these embeddings and use them to generate a similarity index on the dataset.',is,oe,os,re,il=`Computing embeddings...
 100% |███████████████| 1000/1000 [5.0m elapsed, 0s remaining, 3.3 samples/s]
`,rs,M,gt,ol="Alternatively, you could load the model directly from the 🤗 Transformers library and pass the model in directly:",za,me,qa,yt,rl='For a comprehensive guide to this and more, check out <a href="https://docs.voxel51.com/integrations/huggingface.html#transformers-library">FiftyOne’s 🤗 Transformers integration</a>.',ms,pe,ml="Refresh the FiftyOne App, select the checkbox for an image in the sample grid, and click the photo icon to see the most similar images in the dataset. On the backend, clicking this button triggers a query to the similarity index to find the most similar images to the selected image, based on the pre-computed embeddings, and displays them in the App.",ps,he,pl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_image_search.gif" alt="Image Similarity Search"/>',hs,ue,hl="We can use this to see what art pieces are most similar to a given art piece. This can be useful for finding similar art pieces (to recommend to users or add to a collection) or getting inspiration for a new piece.",us,ce,ul="But there’s more! Because CLIP is multimodal, we can also use it to perform semantic searches. This means we can search for images based on text queries. For example, we can search for “pastel trees” and see all the images in the dataset that are similar to that query. To do this, click on the search icon in the FiftyOne App and enter a text query:",cs,fe,cl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_semantic_search.gif" alt="Semantic Search"/>',fs,de,fl="Behind the scenes, the text is tokenized, embedded with CLIP’s text encoder, and then used to query the similarity index to find the most similar images in the dataset. This is a powerful way to search for images based on text queries and can be useful for finding images that match a particular theme or style. And this is not limited to CLIP; you can use any CLIP-like model from 🤗 Transformers that can generate embeddings for images and text!",ds,$,dl='💡 For efficient vector search and indexing over large datasets, FiftyOne has native <a href="https://voxel51.com/vector-search">integrations with open source vector databases</a>.',gs,ge,ys,ye,gl="By performing similarity and semantic searches, we can begin to interact with the data more effectively. But we can also take this a step further and add some unsupervised learning into the mix. This will help us identify artistic patterns in the WikiArt dataset, from stylistic, to topical, and even motifs that are hard to put into words.",Ms,Me,yl="We will do this in two ways:",ws,we,Ml="<li><strong>Dimensionality Reduction</strong>: We’ll use UMAP to reduce the dimensionality of the embeddings to 2D and visualize the data in a scatter plot. This will allow us to see how the images cluster based on their style, genre, and artist.</li> <li><strong>Clustering</strong>: We’ll use K-Means clustering to cluster the images based on their embeddings and see what groups emerge.</li>",bs,be,wl="For dimensionality reduction, we will run <code>compute_visualization()</code> from the FiftyOne Brain, passing in the previously computed embeddings. We specify <code>method=&quot;umap&quot;</code> to use UMAP for dimensionality reduction, but we could also use PCA or t-SNE:",vs,ve,js,je,bl=`Generating visualization...
`,Cs,Ce,vl="Now we can open a panel in the FiftyOne App, where we will see one 2D point for each image in the dataset. We can color the points by any field in the dataset, such as the artist or genre, to see how strongly these attributes are captured by our image features:",Ts,Te,jl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_visualize_embeddings.gif" alt="UMAP Visualization"/>',xs,xe,Cl='We can also run clustering on the embeddings to group similar images together — perhaps the dominant features of these works of art are not captured by the existing labels, or maybe there are distinct sub-genres that we want to identify. To cluster our data, we will need to download the <a href="https://github.com/jacobmarks/clustering-plugin" rel="nofollow">FiftyOne Clustering Plugin</a>:',ks,ke,$s,_,Ha,_s,sn='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>10</mn></mrow><annotation encoding="application/x-tex">10</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">10</span></span></span></span>',Us,Js,$e,Tl="We can then visualize the clusters in the app and see how the images group together based on their embeddings:",Is,_e,xl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_clustering.gif" alt="K-means Clustering"/>',Ws,Ue,kl="We can see that some of the clusters select for artist; others select for genre or style. Others are more abstract and may represent sub-genres or other groupings that are not immediately obvious from the data.",Zs,Je,zs,Ie,$l="One interesting question we can ask about our dataset is how <em>unique</em> each image is. This question is important for many applications, such as recommending similar images, detecting duplicates, or identifying outliers. In the context of art, how unique a painting is could be an important factor in determining its value.",qs,y,Ga,Mt,_l="compute_uniqueness()",La,Hs,an='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>',Gs,Ls,ln='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>',Fs,Xs,nn='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn></mrow><annotation encoding="application/x-tex">0</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">0</span></span></span></span>',Rs,Bs,on='<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn></mrow><annotation encoding="application/x-tex">1</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6444em;"></span><span class="mord">1</span></span></span></span>',Vs,As,We,Ps,Ze,Ul=`Computing uniqueness...
Uniqueness computation complete
`,Ns,ze,Jl="We can then color by this in the embeddings panel, filter by uniqueness score, or even sort by it to see the most unique images in the dataset:",Ys,qe,Es,He,Il='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_most_unique.jpg" alt="Most Unique Images"/>',Ss,Ge,Qs,Le,Wl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_least_unique.jpg" alt="Least Unique Images"/>',Os,Fe,Zl="Going a step further, we can also answer the question of which artist tends to produce the most unique works. We can compute the average uniqueness score for each artist across all of their works of art:",Ds,Xe,Ks,Re,zl=`Unknown Artist: 0.7932221632002723
boris-kustodiev: 0.7480731948424676
salvador-dali: 0.7368807620414014
raphael-kirchner: 0.7315448102204755
ilya-repin: 0.7204744626806383
marc-chagall: 0.7169373812321908
rembrandt: 0.715205220292227
martiros-saryan: 0.708560775790436
childe-hassam: 0.7018343391132756
edgar-degas: 0.699912746806587
albrecht-durer: 0.6969358680800216
john-singer-sargent: 0.6839955708720844
pablo-picasso: 0.6835137858302969
pyotr-konchalovsky: 0.6780653000855895
nicholas-roerich: 0.6676504687452387
ivan-aivazovsky: 0.6484361530090199
vincent-van-gogh: 0.6472004520699081
gustave-dore: 0.6307283287457358
pierre-auguste-renoir: 0.6271467146993583
paul-cezanne: 0.6251076007168186
eugene-boudin: 0.6103397516167454
camille-pissarro: 0.6046182609119615
claude-monet: 0.5998234558947573
ivan-shishkin: 0.589796389836674
`,ea,Be,ql="It would seem that the artist with the most unique works in our dataset is Boris Kustodiev! Let’s take a look at some of his works:",ta,Ve,sa,Ae,Hl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_kustodiev_view.jpg" alt="Boris Kustodiev Artwork"/>',aa,Pe,la,Ne,Gl="To round things out, let’s go back to the basics and analyze some core qualities of the images in our dataset. We’ll compute standard metrics like brightness, contrast, and saturation for each image and see how these metrics correlate with the artistic style and genre of the art pieces.",na,Ye,Ll='To run these analyses, we will need to download the <a href="https://github.com/jacobmarks/image-quality-issues" rel="nofollow">FiftyOne Image Quality Plugin</a>:',ia,Ee,oa,Se,Fl="Refresh the app and open the operators list again. This time type <code>compute</code> and select one of the image quality operators. We’ll start with brightness:",ra,Qe,Xl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_compute_brightness.gif" alt="Compute Brightness"/>',ma,Oe,Rl="When the operator finishes running, we will have a new field in our dataset that contains the brightness score for each image. We can then visualize this data in the app:",pa,De,Bl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_brightness.gif" alt="Brightness"/>',ha,Ke,Vl="We can also color by brightness, and even see how it correlates with other fields in the dataset like style:",ua,et,Al='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_style_by_brightness.gif" alt="Style by Brightness"/>',ca,tt,Pl="Now do the same for contrast and saturation. Here are the results for saturation:",fa,st,Nl='<img src="https://huggingface.co/datasets/huggingface/cookbook-images/resolve/main/art_analysis_filter_by_saturation.jpg" alt="Filter by Saturation"/>',da,at,Yl="Hopefully this illustrates how not everything boils down to applying deep neural networks to your data. Sometimes, simple metrics can be just as informative and can provide a different perspective on your data 🤓!",ga,U,El='📚 For larger datasets, you may want to <a href="https://docs.voxel51.com/plugins/using_plugins.html#delegated-operations">delegate the operations</a> for later execution.',ya,lt,Ma,nt,Sl='In this notebook, we’ve explored how to use multimodal embeddings, unsupervised learning, and traditional image processing techniques to analyze artistic styles in images. We’ve seen how to perform image similarity and semantic searches, cluster images based on their style, analyze the uniqueness of images, and compute image quality metrics. These techniques can be applied to a wide range of visual datasets, from art collections to medical images to satellite imagery. Try <a href="https://docs.voxel51.com/integrations/huggingface.html#loading-datasets-from-the-hub" rel="nofollow">loading a different dataset from the Hugging Face Hub</a> and see what insights you can uncover!',wa,it,Ql="If you want to go even further, here are some additional analyses you could try:",ba,ot,Ol='<li><strong>Zero-Shot Classification</strong>: Use a pre-trained vision-language model from 🤗 Transformers to categorize images in the dataset by topic or subject, without any training data. Check out this <a href="https://docs.voxel51.com/tutorials/zero_shot_classification.html" rel="nofollow">Zero-Shot Classification tutorial</a> for more info.</li> <li><strong>Image Captioning</strong>: Use a pre-trained vision-language model from 🤗 Transformers to generate captions for the images in the dataset. Then use this for topic modeling or cluster artwork based on embeddings for these captions. Check out FiftyOne’s <a href="https://github.com/jacobmarks/fiftyone-image-captioning-plugin" rel="nofollow">Image Captioning Plugin</a> for more info.</li>',va,rt,ja,mt,Dl='<li><a href="https://docs.voxel51.com/integrations/huggingface.html#huggingface-hub" rel="nofollow">FiftyOne 🤝 🤗 Hub Integration</a></li> <li><a href="https://docs.voxel51.com/integrations/huggingface.html#transformers-library" rel="nofollow">FiftyOne 🤝 🤗 Transformers Integration</a></li> <li><a href="https://voxel51.com/vector-search/" rel="nofollow">FiftyOne Vector Search Integrations</a></li> <li><a href="https://docs.voxel51.com/tutorials/dimension_reduction.html" rel="nofollow">Visualizing Data with Dimensionality Reduction Techniques</a></li> <li><a href="https://docs.voxel51.com/tutorials/clustering.html" rel="nofollow">Clustering Images with Embeddings</a></li> <li><a href="https://docs.voxel51.com/tutorials/uniqueness.html" rel="nofollow">Exploring Image Uniqueness with FiftyOne</a></li>',Ca,pt,Ta,ht,Kl='<a href="https://github.com/voxel51/fiftyone/" rel="nofollow">FiftyOne</a> is the leading open source toolkit for building high-quality datasets and computer vision models. With over 2M downloads, FiftyOne is trusted by developers and researchers across the globe.',xa,ut,en='💪 The FiftyOne team welcomes contributions from the open source community! If you’re interested in contributing to FiftyOne, check out the <a href="https://github.com/voxel51/fiftyone/blob/develop/CONTRIBUTING.md" rel="nofollow">contributing guide</a>.',ka,ct,$a,Tt,_a;return I=new dn({props:{classNames:"absolute z-10 right-0 top-0",options:[{label:"Google Colab",value:"https://colab.research.google.com/github/huggingface/cookbook/blob/main/notebooks/en/analyzing_art_with_hf_and_fiftyone.ipynb"}]}}),W=new fn({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),Z=new T({props:{title:"Analyzing Artistic Styles with Multimodal Embeddings",local:"analyzing-artistic-styles-with-multimodal-embeddings",headingTag:"h1"}}),F=new T({props:{title:"Let’s get started! 🚀",local:"lets-get-started-",headingTag:"h2"}}),R=new g({props:{code:"IXBpcCUyMGluc3RhbGwlMjAtVSUyMHRyYW5zZm9ybWVycyUyMGh1Z2dpbmdmYWNlX2h1YiUyMGZpZnR5b25lJTIwdW1hcC1sZWFybg==",highlighted:"!pip install -U transformers huggingface_hub fiftyone umap-learn",wrap:!1}}),V=new g({props:{code:"cGlwJTIwaW5zdGFsbCUyMGhmLXRyYW5zZmVy",highlighted:"pip install hf-transfer",wrap:!1}}),P=new g({props:{code:"aW1wb3J0JTIwb3MlMEFvcy5lbnZpcm9uJTVCJTIySEZfSFVCX0VOQUJMRV9IRl9UUkFOU0ZFUiUyMiU1RCUyMCUzRCUyMCUyMjElMjI=",highlighted:`import os
os.environ[<span class="hljs-string">&quot;HF_HUB_ENABLE_HF_TRANSFER&quot;</span>] = <span class="hljs-string">&quot;1&quot;</span>`,wrap:!1}}),Y=new g({props:{code:"aW1wb3J0JTIwZmlmdHlvbmUlMjBhcyUyMGZvJTIwJTIzJTIwYmFzZSUyMGxpYnJhcnklMjBhbmQlMjBhcHAlMEFpbXBvcnQlMjBmaWZ0eW9uZS56b28lMjBhcyUyMGZveiUyMCUyMyUyMHpvbyUyMGRhdGFzZXRzJTIwYW5kJTIwbW9kZWxzJTBBaW1wb3J0JTIwZmlmdHlvbmUuYnJhaW4lMjBhcyUyMGZvYiUyMCUyMyUyME1MJTIwcm91dGluZXMlMEFmcm9tJTIwZmlmdHlvbmUlMjBpbXBvcnQlMjBWaWV3RmllbGQlMjBhcyUyMEYlMjAlMjMlMjBmb3IlMjBkZWZpbmluZyUyMGN1c3RvbSUyMHZpZXdzJTBBaW1wb3J0JTIwZmlmdHlvbmUudXRpbHMuaHVnZ2luZ2ZhY2UlMjBhcyUyMGZvdWglMjAlMjMlMjBmb3IlMjBsb2FkaW5nJTIwZGF0YXNldHMlMjBmcm9tJTIwSHVnZ2luZyUyMEZhY2U=",highlighted:`<span class="hljs-keyword">import</span> fiftyone <span class="hljs-keyword">as</span> fo <span class="hljs-comment"># base library and app</span>
<span class="hljs-keyword">import</span> fiftyone.zoo <span class="hljs-keyword">as</span> foz <span class="hljs-comment"># zoo datasets and models</span>
<span class="hljs-keyword">import</span> fiftyone.brain <span class="hljs-keyword">as</span> fob <span class="hljs-comment"># ML routines</span>
<span class="hljs-keyword">from</span> fiftyone <span class="hljs-keyword">import</span> ViewField <span class="hljs-keyword">as</span> F <span class="hljs-comment"># for defining custom views</span>
<span class="hljs-keyword">import</span> fiftyone.utils.huggingface <span class="hljs-keyword">as</span> fouh <span class="hljs-comment"># for loading datasets from Hugging Face</span>`,wrap:!1}}),E=new g({props:{code:"ZGF0YXNldCUyMCUzRCUyMGZvdWgubG9hZF9mcm9tX2h1YiglMEElMjAlMjAlMjAlMjAlMjJodWdnYW4lMkZ3aWtpYXJ0JTIyJTJDJTIwJTIzJTIzJTIwcmVwb19pZCUwQSUyMCUyMCUyMCUyMGZvcm1hdCUzRCUyMnBhcnF1ZXQlMjIlMkMlMjAlMjMlMjMlMjBmb3IlMjBQYXJxdWV0JTIwZm9ybWF0JTBBJTIwJTIwJTIwJTIwY2xhc3NpZmljYXRpb25fZmllbGRzJTNEJTVCJTIyYXJ0aXN0JTIyJTJDJTIwJTIyc3R5bGUlMjIlMkMlMjAlMjJnZW5yZSUyMiU1RCUyQyUyMCUyMyUyMGNvbHVtbnMlMjB0byUyMHN0b3JlJTIwYXMlMjBjbGFzc2lmaWNhdGlvbiUyMGZpZWxkcyUwQSUyMCUyMCUyMCUyMG1heF9zYW1wbGVzJTNEMTAwMCUyQyUyMCUyMyUyMG51bWJlciUyMG9mJTIwc2FtcGxlcyUyMHRvJTIwbG9hZCUwQSUyMCUyMCUyMCUyMG5hbWUlM0QlMjJ3aWtpYXJ0JTIyJTJDJTIwJTIzJTIwbmFtZSUyMG9mJTIwdGhlJTIwZGF0YXNldCUyMGluJTIwRmlmdHlPbmUlMEEp",highlighted:`dataset = fouh.load_from_hub(
    <span class="hljs-string">&quot;huggan/wikiart&quot;</span>, <span class="hljs-comment">## repo_id</span>
    <span class="hljs-built_in">format</span>=<span class="hljs-string">&quot;parquet&quot;</span>, <span class="hljs-comment">## for Parquet format</span>
    classification_fields=[<span class="hljs-string">&quot;artist&quot;</span>, <span class="hljs-string">&quot;style&quot;</span>, <span class="hljs-string">&quot;genre&quot;</span>], <span class="hljs-comment"># columns to store as classification fields</span>
    max_samples=<span class="hljs-number">1000</span>, <span class="hljs-comment"># number of samples to load</span>
    name=<span class="hljs-string">&quot;wikiart&quot;</span>, <span class="hljs-comment"># name of the dataset in FiftyOne</span>
)`,wrap:!1}}),Q=new g({props:{code:"cHJpbnQoZGF0YXNldCk=",highlighted:'<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-built_in">print</span>(dataset)',wrap:!1}}),K=new g({props:{code:"c2Vzc2lvbiUyMCUzRCUyMGZvLmxhdW5jaF9hcHAoZGF0YXNldCk=",highlighted:"session = fo.launch_app(dataset)",wrap:!1}}),se=new g({props:{code:"YXJ0aXN0cyUyMCUzRCUyMGRhdGFzZXQuZGlzdGluY3QoJTIyYXJ0aXN0LmxhYmVsJTIyKSUwQXByaW50KGFydGlzdHMp",highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span>artists = dataset.distinct(<span class="hljs-string">&quot;artist.label&quot;</span>)
<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-built_in">print</span>(artists)`,wrap:!1}}),le=new T({props:{title:"Finding Similar Artwork",local:"finding-similar-artwork",headingTag:"h2"}}),oe=new g({props:{code:"Zm9iLmNvbXB1dGVfc2ltaWxhcml0eSglMEElMjAlMjAlMjAlMjBkYXRhc2V0JTJDJTIwJTBBJTIwJTIwJTIwJTIwbW9kZWwlM0QlMjJ6ZXJvLXNob3QtY2xhc3NpZmljYXRpb24tdHJhbnNmb3JtZXItdG9yY2glMjIlMkMlMjAlMjMlMjMlMjB0eXBlJTIwb2YlMjBtb2RlbCUyMHRvJTIwbG9hZCUyMGZyb20lMjBtb2RlbCUyMHpvbyUwQSUyMCUyMCUyMCUyMG5hbWVfb3JfcGF0aCUzRCUyMm9wZW5haSUyRmNsaXAtdml0LWJhc2UtcGF0Y2gzMiUyMiUyQyUyMCUyMyUyMyUyMHJlcG9faWQlMjBvZiUyMGNoZWNrcG9pbnQlMEElMjAlMjAlMjAlMjBlbWJlZGRpbmdzJTNEJTIyY2xpcF9lbWJlZGRpbmdzJTIyJTJDJTIwJTIzJTIzJTIwbmFtZSUyMG9mJTIwdGhlJTIwZmllbGQlMjB0byUyMHN0b3JlJTIwZW1iZWRkaW5ncyUwQSUyMCUyMCUyMCUyMGJyYWluX2tleSUzRCUyMmNsaXBfc2ltJTIyJTJDJTIwJTIzJTIzJTIwa2V5JTIwdG8lMjBzdG9yZSUyMHNpbWlsYXJpdHklMjBpbmRleCUyMGluZm8lMEElMjAlMjAlMjAlMjBiYXRjaF9zaXplJTNEMzIlMkMlMjAlMjMlMjMlMjBiYXRjaCUyMHNpemUlMjBmb3IlMjBpbmZlcmVuY2UlMEElMjAlMjAlMjAlMjAp",highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span>fob.compute_similarity(
<span class="hljs-meta">... </span>    dataset, 
<span class="hljs-meta">... </span>    model=<span class="hljs-string">&quot;zero-shot-classification-transformer-torch&quot;</span>, <span class="hljs-comment">## type of model to load from model zoo</span>
<span class="hljs-meta">... </span>    name_or_path=<span class="hljs-string">&quot;openai/clip-vit-base-patch32&quot;</span>, <span class="hljs-comment">## repo_id of checkpoint</span>
<span class="hljs-meta">... </span>    embeddings=<span class="hljs-string">&quot;clip_embeddings&quot;</span>, <span class="hljs-comment">## name of the field to store embeddings</span>
<span class="hljs-meta">... </span>    brain_key=<span class="hljs-string">&quot;clip_sim&quot;</span>, <span class="hljs-comment">## key to store similarity index info</span>
<span class="hljs-meta">... </span>    batch_size=<span class="hljs-number">32</span>, <span class="hljs-comment">## batch size for inference</span>
<span class="hljs-meta">... </span>    )`,wrap:!1}}),me=new g({props:{code:"ZnJvbSUyMHRyYW5zZm9ybWVycyUyMGltcG9ydCUyMENMSVBNb2RlbCUwQW1vZGVsJTIwJTNEJTIwQ0xJUE1vZGVsLmZyb21fcHJldHJhaW5lZCglMjJvcGVuYWklMkZjbGlwLXZpdC1iYXNlLXBhdGNoMzIlMjIpJTBBZm9iLmNvbXB1dGVfc2ltaWxhcml0eSglMEElMjAlMjAlMjAlMjBkYXRhc2V0JTJDJTIwJTBBJTIwJTIwJTIwJTIwbW9kZWwlM0Rtb2RlbCUyQyUwQSUyMCUyMCUyMCUyMGVtYmVkZGluZ3MlM0QlMjJjbGlwX2VtYmVkZGluZ3MlMjIlMkMlMjAlMjMlMjMlMjBuYW1lJTIwb2YlMjB0aGUlMjBmaWVsZCUyMHRvJTIwc3RvcmUlMjBlbWJlZGRpbmdzJTBBJTIwJTIwJTIwJTIwYnJhaW5fa2V5JTNEJTIyY2xpcF9zaW0lMjIlMjAlMjMlMjMlMjBrZXklMjB0byUyMHN0b3JlJTIwc2ltaWxhcml0eSUyMGluZGV4JTIwaW5mbyUwQSk=",highlighted:`<span class="hljs-keyword">from</span> transformers <span class="hljs-keyword">import</span> CLIPModel
model = CLIPModel.from_pretrained(<span class="hljs-string">&quot;openai/clip-vit-base-patch32&quot;</span>)
fob.compute_similarity(
    dataset, 
    model=model,
    embeddings=<span class="hljs-string">&quot;clip_embeddings&quot;</span>, <span class="hljs-comment">## name of the field to store embeddings</span>
    brain_key=<span class="hljs-string">&quot;clip_sim&quot;</span> <span class="hljs-comment">## key to store similarity index info</span>
)`,wrap:!1}}),ge=new T({props:{title:"Uncovering Artistic Motifs with Clustering and Visualization",local:"uncovering-artistic-motifs-with-clustering-and-visualization",headingTag:"h2"}}),ve=new g({props:{code:"Zm9iLmNvbXB1dGVfdmlzdWFsaXphdGlvbihkYXRhc2V0JTJDJTIwZW1iZWRkaW5ncyUzRCUyMmNsaXBfZW1iZWRkaW5ncyUyMiUyQyUyMG1ldGhvZCUzRCUyMnVtYXAlMjIlMkMlMjBicmFpbl9rZXklM0QlMjJjbGlwX3ZpcyUyMik=",highlighted:'<span class="hljs-meta">&gt;&gt;&gt; </span>fob.compute_visualization(dataset, embeddings=<span class="hljs-string">&quot;clip_embeddings&quot;</span>, method=<span class="hljs-string">&quot;umap&quot;</span>, brain_key=<span class="hljs-string">&quot;clip_vis&quot;</span>)',wrap:!1}}),ke=new g({props:{code:"IWZpZnR5b25lJTIwcGx1Z2lucyUyMGRvd25sb2FkJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGamFjb2JtYXJrcyUyRmNsdXN0ZXJpbmctcGx1Z2lu",highlighted:"!fiftyone plugins download https://github.com/jacobmarks/clustering-plugin",wrap:!1}}),Je=new T({props:{title:"Identifying the Most Unique Works of Art",local:"identifying-the-most-unique-works-of-art",headingTag:"h2"}}),We=new g({props:{code:"Zm9iLmNvbXB1dGVfdW5pcXVlbmVzcyhkYXRhc2V0JTJDJTIwZW1iZWRkaW5ncyUzRCUyMmNsaXBfZW1iZWRkaW5ncyUyMiklMjAlMjMlMjBjb21wdXRlJTIwdW5pcXVlbmVzcyUyMHVzaW5nJTIwQ0xJUCUyMGVtYmVkZGluZ3M=",highlighted:'<span class="hljs-meta">&gt;&gt;&gt; </span>fob.compute_uniqueness(dataset, embeddings=<span class="hljs-string">&quot;clip_embeddings&quot;</span>) <span class="hljs-comment"># compute uniqueness using CLIP embeddings</span>',wrap:!1}}),qe=new g({props:{code:"bW9zdF91bmlxdWVfdmlldyUyMCUzRCUyMGRhdGFzZXQuc29ydF9ieSglMjJ1bmlxdWVuZXNzJTIyJTJDJTIwcmV2ZXJzZSUzRFRydWUpJTBBc2Vzc2lvbi52aWV3JTIwJTNEJTIwbW9zdF91bmlxdWVfdmlldy52aWV3KCklMjAlMjMlMjBNb3N0JTIwdW5pcXVlJTIwaW1hZ2Vz",highlighted:`most_unique_view = dataset.sort_by(<span class="hljs-string">&quot;uniqueness&quot;</span>, reverse=<span class="hljs-literal">True</span>)
session.view = most_unique_view.view() <span class="hljs-comment"># Most unique images</span>`,wrap:!1}}),Ge=new g({props:{code:"bGVhc3RfdW5pcXVlX3ZpZXclMjAlM0QlMjBkYXRhc2V0LnNvcnRfYnkoJTIydW5pcXVlbmVzcyUyMiUyQyUyMHJldmVyc2UlM0RGYWxzZSklMEFzZXNzaW9uLnZpZXclMjAlM0QlMjBsZWFzdF91bmlxdWVfdmlldy52aWV3KCklMjAlMjMlMjBMZWFzdCUyMHVuaXF1ZSUyMGltYWdlcw==",highlighted:`least_unique_view = dataset.sort_by(<span class="hljs-string">&quot;uniqueness&quot;</span>, reverse=<span class="hljs-literal">False</span>)
session.view = least_unique_view.view() <span class="hljs-comment"># Least unique images</span>`,wrap:!1}}),Xe=new g({props:{code:"YXJ0aXN0X3VuaXF1ZV9zY29yZXMlMjAlM0QlMjAlN0IlMEElMjAlMjAlMjAlMjBhcnRpc3QlM0ElMjBkYXRhc2V0Lm1hdGNoKEYoJTIyYXJ0aXN0LmxhYmVsJTIyKSUyMCUzRCUzRCUyMGFydGlzdCkubWVhbiglMjJ1bmlxdWVuZXNzJTIyKSUwQSUyMCUyMCUyMCUyMGZvciUyMGFydGlzdCUyMGluJTIwYXJ0aXN0cyUwQSU3RCUwQSUwQXNvcnRlZF9hcnRpc3RzJTIwJTNEJTIwc29ydGVkKCUwQSUyMCUyMCUyMCUyMGFydGlzdF91bmlxdWVfc2NvcmVzJTJDJTIwa2V5JTNEYXJ0aXN0X3VuaXF1ZV9zY29yZXMuZ2V0JTJDJTIwcmV2ZXJzZSUzRFRydWUlMEEpJTBBJTBBZm9yJTIwYXJ0aXN0JTIwaW4lMjBzb3J0ZWRfYXJ0aXN0cyUzQSUwQSUyMCUyMCUyMCUyMHByaW50KGYlMjIlN0JhcnRpc3QlN0QlM0ElMjAlN0JhcnRpc3RfdW5pcXVlX3Njb3JlcyU1QmFydGlzdCU1RCU3RCUyMik=",highlighted:`<span class="hljs-meta">&gt;&gt;&gt; </span>artist_unique_scores = {
<span class="hljs-meta">... </span>    artist: dataset.<span class="hljs-keyword">match</span>(F(<span class="hljs-string">&quot;artist.label&quot;</span>) == artist).mean(<span class="hljs-string">&quot;uniqueness&quot;</span>)
<span class="hljs-meta">... </span>    <span class="hljs-keyword">for</span> artist <span class="hljs-keyword">in</span> artists
<span class="hljs-meta">... </span>}

<span class="hljs-meta">&gt;&gt;&gt; </span>sorted_artists = <span class="hljs-built_in">sorted</span>(
<span class="hljs-meta">... </span>    artist_unique_scores, key=artist_unique_scores.get, reverse=<span class="hljs-literal">True</span>
<span class="hljs-meta">... </span>)

<span class="hljs-meta">&gt;&gt;&gt; </span><span class="hljs-keyword">for</span> artist <span class="hljs-keyword">in</span> sorted_artists:
<span class="hljs-meta">... </span>    <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;<span class="hljs-subst">{artist}</span>: <span class="hljs-subst">{artist_unique_scores[artist]}</span>&quot;</span>)`,wrap:!1}}),Ve=new g({props:{code:"a3VzdG9kaWV2X3ZpZXclMjAlM0QlMjBkYXRhc2V0Lm1hdGNoKEYoJTIyYXJ0aXN0LmxhYmVsJTIyKSUyMCUzRCUzRCUyMCUyMmJvcmlzLWt1c3RvZGlldiUyMiklMEFzZXNzaW9uLnZpZXclMjAlM0QlMjBrdXN0b2RpZXZfdmlldy52aWV3KCk=",highlighted:`kustodiev_view = dataset.<span class="hljs-keyword">match</span>(F(<span class="hljs-string">&quot;artist.label&quot;</span>) == <span class="hljs-string">&quot;boris-kustodiev&quot;</span>)
session.view = kustodiev_view.view()`,wrap:!1}}),Pe=new T({props:{title:"Characterizing Art with Visual Qualities",local:"characterizing-art-with-visual-qualities",headingTag:"h2"}}),Ee=new g({props:{code:"IWZpZnR5b25lJTIwcGx1Z2lucyUyMGRvd25sb2FkJTIwaHR0cHMlM0ElMkYlMkZnaXRodWIuY29tJTJGamFjb2JtYXJrcyUyRmltYWdlLXF1YWxpdHktaXNzdWVzJTJG",highlighted:"!fiftyone plugins download https://github.com/jacobmarks/image-quality-issues/",wrap:!1}}),lt=new T({props:{title:"What’s Next?",local:"whats-next",headingTag:"h2"}}),rt=new T({props:{title:"📚 Resources",local:"-resources",headingTag:"h3"}}),pt=new T({props:{title:"FiftyOne Open Source Project",local:"fiftyone-open-source-project",headingTag:"h2"}}),ct=new gn({props:{source:"https://github.com/huggingface/cookbook/blob/main/notebooks/en/analyzing_art_with_hf_and_fiftyone.md"}}),{c(){C=i("meta"),xt=l(),Ct=i("p"),kt=l(),m(I.$$.fragment),$t=l(),m(W.$$.fragment),_t=l(),m(Z.$$.fragment),Ut=l(),z=i("p"),z.innerHTML=Xa,Jt=l(),q=i("p"),q.innerHTML=Ra,It=l(),H=i("p"),H.textContent=Ba,Wt=l(),G=i("p"),G.innerHTML=Va,Zt=l(),L=i("ul"),L.innerHTML=Aa,zt=l(),m(F.$$.fragment),qt=l(),X=i("p"),X.textContent=Pa,Ht=l(),m(R.$$.fragment),Gt=l(),B=i("p"),B.innerHTML=Na,Lt=l(),m(V.$$.fragment),Ft=l(),A=i("p"),A.innerHTML=Ya,Xt=l(),m(P.$$.fragment),Rt=l(),x=i("div"),x.innerHTML=Ea,Bt=l(),N=i("p"),N.textContent=Sa,Vt=l(),m(Y.$$.fragment),At=l(),w=i("p"),Ia=v("We’ll start by loading the WikiArt dataset from 🤗 Hub into FiftyOne. This dataset can also be loaded through Hugging Face’s "),dt=i("code"),dt.textContent=Qa,Wa=v(" library, but we’ll use "),k=i("a"),k.textContent=Oa,Za=v(" to get the data directly from the Datasets server. To make the computations fast, we’ll just download the first "),Pt=new bt(!1),Nt=v(" samples."),Yt=l(),m(E.$$.fragment),Et=l(),S=i("p"),S.textContent=Da,St=l(),m(Q.$$.fragment),Qt=l(),O=i("pre"),O.textContent=Ka,Ot=l(),D=i("p"),D.innerHTML=el,Dt=l(),m(K.$$.fragment),Kt=l(),ee=i("p"),ee.innerHTML=tl,es=l(),te=i("p"),te.textContent=sl,ts=l(),m(se.$$.fragment),ss=l(),ae=i("pre"),ae.textContent=al,as=l(),m(le.$$.fragment),ls=l(),ne=i("p"),ne.textContent=ll,ns=l(),ie=i("p"),ie.innerHTML=nl,is=l(),m(oe.$$.fragment),os=l(),re=i("pre"),re.textContent=il,rs=l(),M=i("div"),gt=i("p"),gt.textContent=ol,za=l(),m(me.$$.fragment),qa=l(),yt=i("p"),yt.innerHTML=rl,ms=l(),pe=i("p"),pe.textContent=ml,ps=l(),he=i("p"),he.innerHTML=pl,hs=l(),ue=i("p"),ue.textContent=hl,us=l(),ce=i("p"),ce.textContent=ul,cs=l(),fe=i("p"),fe.innerHTML=cl,fs=l(),de=i("p"),de.textContent=fl,ds=l(),$=i("div"),$.innerHTML=dl,gs=l(),m(ge.$$.fragment),ys=l(),ye=i("p"),ye.textContent=gl,Ms=l(),Me=i("p"),Me.textContent=yl,ws=l(),we=i("ol"),we.innerHTML=Ml,bs=l(),be=i("p"),be.innerHTML=wl,vs=l(),m(ve.$$.fragment),js=l(),je=i("pre"),je.textContent=bl,Cs=l(),Ce=i("p"),Ce.textContent=vl,Ts=l(),Te=i("p"),Te.innerHTML=jl,xs=l(),xe=i("p"),xe.innerHTML=Cl,ks=l(),m(ke.$$.fragment),$s=l(),_=i("p"),Ha=v("Refreshing the app again, we can then access the clustering functionality via an operator in the app. Hit the backtick key to open the operator list, type “cluster” and select the operator from the dropdown. This will open an interactive panel where we can specify the clustering algorithm, hyperparameters, and the field to cluster on. To keep it simple, we’ll use K-Means clustering with "),_s=new bt(!1),Us=v(" clusters."),Js=l(),$e=i("p"),$e.textContent=Tl,Is=l(),_e=i("p"),_e.innerHTML=xl,Ws=l(),Ue=i("p"),Ue.textContent=kl,Zs=l(),m(Je.$$.fragment),zs=l(),Ie=i("p"),Ie.innerHTML=$l,qs=l(),y=i("p"),Ga=v("While there are a million ways to characterize uniqueness, our image embeddings allow us to quantitatively assign each sample a uniqueness score based on how similar it is to other samples in the dataset. Explicitly, the FiftyOne Brain’s "),Mt=i("code"),Mt.textContent=_l,La=v(" function looks at the distance between each sample’s embedding and its nearest neighbors, and computes a score between "),Hs=new bt(!1),Gs=v(" and "),Ls=new bt(!1),Fs=v(" based on this distance. A score of "),Xs=new bt(!1),Rs=v(" means the sample is nondescript or very similar to others, while a score of "),Bs=new bt(!1),Vs=v(" means the sample is very unique."),As=l(),m(We.$$.fragment),Ps=l(),Ze=i("pre"),Ze.textContent=Ul,Ns=l(),ze=i("p"),ze.textContent=Jl,Ys=l(),m(qe.$$.fragment),Es=l(),He=i("p"),He.innerHTML=Il,Ss=l(),m(Ge.$$.fragment),Qs=l(),Le=i("p"),Le.innerHTML=Wl,Os=l(),Fe=i("p"),Fe.textContent=Zl,Ds=l(),m(Xe.$$.fragment),Ks=l(),Re=i("pre"),Re.textContent=zl,ea=l(),Be=i("p"),Be.textContent=ql,ta=l(),m(Ve.$$.fragment),sa=l(),Ae=i("p"),Ae.innerHTML=Hl,aa=l(),m(Pe.$$.fragment),la=l(),Ne=i("p"),Ne.textContent=Gl,na=l(),Ye=i("p"),Ye.innerHTML=Ll,ia=l(),m(Ee.$$.fragment),oa=l(),Se=i("p"),Se.innerHTML=Fl,ra=l(),Qe=i("p"),Qe.innerHTML=Xl,ma=l(),Oe=i("p"),Oe.textContent=Rl,pa=l(),De=i("p"),De.innerHTML=Bl,ha=l(),Ke=i("p"),Ke.textContent=Vl,ua=l(),et=i("p"),et.innerHTML=Al,ca=l(),tt=i("p"),tt.textContent=Pl,fa=l(),st=i("p"),st.innerHTML=Nl,da=l(),at=i("p"),at.textContent=Yl,ga=l(),U=i("div"),U.innerHTML=El,ya=l(),m(lt.$$.fragment),Ma=l(),nt=i("p"),nt.innerHTML=Sl,wa=l(),it=i("p"),it.textContent=Ql,ba=l(),ot=i("ul"),ot.innerHTML=Ol,va=l(),m(rt.$$.fragment),ja=l(),mt=i("ul"),mt.innerHTML=Dl,Ca=l(),m(pt.$$.fragment),Ta=l(),ht=i("p"),ht.innerHTML=Kl,xa=l(),ut=i("p"),ut.innerHTML=en,ka=l(),m(ct.$$.fragment),$a=l(),Tt=i("p"),this.h()},l(e){const t=cn("svelte-u9bgzb",document.head);C=o(t,"META",{name:!0,content:!0}),t.forEach(s),xt=n(e),Ct=o(e,"P",{}),vt(Ct).forEach(s),kt=n(e),p(I.$$.fragment,e),$t=n(e),p(W.$$.fragment,e),_t=n(e),p(Z.$$.fragment,e),Ut=n(e),z=o(e,"P",{"data-svelte-h":!0}),r(z)!=="svelte-c0uagn"&&(z.innerHTML=Xa),Jt=n(e),q=o(e,"P",{"data-svelte-h":!0}),r(q)!=="svelte-1xzj7ip"&&(q.innerHTML=Ra),It=n(e),H=o(e,"P",{"data-svelte-h":!0}),r(H)!=="svelte-1e7ek37"&&(H.textContent=Ba),Wt=n(e),G=o(e,"P",{"data-svelte-h":!0}),r(G)!=="svelte-1iyj6t"&&(G.innerHTML=Va),Zt=n(e),L=o(e,"UL",{"data-svelte-h":!0}),r(L)!=="svelte-1ag4oir"&&(L.innerHTML=Aa),zt=n(e),p(F.$$.fragment,e),qt=n(e),X=o(e,"P",{"data-svelte-h":!0}),r(X)!=="svelte-1qmzeog"&&(X.textContent=Pa),Ht=n(e),p(R.$$.fragment,e),Gt=n(e),B=o(e,"P",{"data-svelte-h":!0}),r(B)!=="svelte-x4dwdl"&&(B.innerHTML=Na),Lt=n(e),p(V.$$.fragment,e),Ft=n(e),A=o(e,"P",{"data-svelte-h":!0}),r(A)!=="svelte-m5ur8v"&&(A.innerHTML=Ya),Xt=n(e),p(P.$$.fragment,e),Rt=n(e),x=o(e,"DIV",{class:!0,"data-svelte-h":!0}),r(x)!=="svelte-plk5pn"&&(x.innerHTML=Ea),Bt=n(e),N=o(e,"P",{"data-svelte-h":!0}),r(N)!=="svelte-1o6b4mq"&&(N.textContent=Sa),Vt=n(e),p(Y.$$.fragment,e),At=n(e),w=o(e,"P",{});var J=vt(w);Ia=j(J,"We’ll start by loading the WikiArt dataset from 🤗 Hub into FiftyOne. This dataset can also be loaded through Hugging Face’s "),dt=o(J,"CODE",{"data-svelte-h":!0}),r(dt)!=="svelte-1q9fd75"&&(dt.textContent=Qa),Wa=j(J," library, but we’ll use "),k=o(J,"A",{href:!0,rel:!0,"data-svelte-h":!0}),r(k)!=="svelte-irkr0u"&&(k.textContent=Oa),Za=j(J," to get the data directly from the Datasets server. To make the computations fast, we’ll just download the first "),Pt=jt(J,!1),Nt=j(J," samples."),J.forEach(s),Yt=n(e),p(E.$$.fragment,e),Et=n(e),S=o(e,"P",{"data-svelte-h":!0}),r(S)!=="svelte-127sumy"&&(S.textContent=Da),St=n(e),p(Q.$$.fragment,e),Qt=n(e),O=o(e,"PRE",{"data-svelte-h":!0}),r(O)!=="svelte-1odavx8"&&(O.textContent=Ka),Ot=n(e),D=o(e,"P",{"data-svelte-h":!0}),r(D)!=="svelte-vuii1o"&&(D.innerHTML=el),Dt=n(e),p(K.$$.fragment,e),Kt=n(e),ee=o(e,"P",{"data-svelte-h":!0}),r(ee)!=="svelte-1cy8zue"&&(ee.innerHTML=tl),es=n(e),te=o(e,"P",{"data-svelte-h":!0}),r(te)!=="svelte-1g82nj1"&&(te.textContent=sl),ts=n(e),p(se.$$.fragment,e),ss=n(e),ae=o(e,"PRE",{"data-svelte-h":!0}),r(ae)!=="svelte-rh6f0n"&&(ae.textContent=al),as=n(e),p(le.$$.fragment,e),ls=n(e),ne=o(e,"P",{"data-svelte-h":!0}),r(ne)!=="svelte-n0vei3"&&(ne.textContent=ll),ns=n(e),ie=o(e,"P",{"data-svelte-h":!0}),r(ie)!=="svelte-suzdib"&&(ie.innerHTML=nl),is=n(e),p(oe.$$.fragment,e),os=n(e),re=o(e,"PRE",{"data-svelte-h":!0}),r(re)!=="svelte-mmre29"&&(re.textContent=il),rs=n(e),M=o(e,"DIV",{style:!0});var wt=vt(M);gt=o(wt,"P",{"data-svelte-h":!0}),r(gt)!=="svelte-1wi6mic"&&(gt.textContent=ol),za=n(wt),p(me.$$.fragment,wt),qa=n(wt),yt=o(wt,"P",{"data-svelte-h":!0}),r(yt)!=="svelte-17feko9"&&(yt.innerHTML=rl),wt.forEach(s),ms=n(e),pe=o(e,"P",{"data-svelte-h":!0}),r(pe)!=="svelte-1tpltlf"&&(pe.textContent=ml),ps=n(e),he=o(e,"P",{"data-svelte-h":!0}),r(he)!=="svelte-w8rr2"&&(he.innerHTML=pl),hs=n(e),ue=o(e,"P",{"data-svelte-h":!0}),r(ue)!=="svelte-13ty9jr"&&(ue.textContent=hl),us=n(e),ce=o(e,"P",{"data-svelte-h":!0}),r(ce)!=="svelte-1no06fa"&&(ce.textContent=ul),cs=n(e),fe=o(e,"P",{"data-svelte-h":!0}),r(fe)!=="svelte-8ah19l"&&(fe.innerHTML=cl),fs=n(e),de=o(e,"P",{"data-svelte-h":!0}),r(de)!=="svelte-5h5wzx"&&(de.textContent=fl),ds=n(e),$=o(e,"DIV",{class:!0,"data-svelte-h":!0}),r($)!=="svelte-18x11l8"&&($.innerHTML=dl),gs=n(e),p(ge.$$.fragment,e),ys=n(e),ye=o(e,"P",{"data-svelte-h":!0}),r(ye)!=="svelte-1r77spf"&&(ye.textContent=gl),Ms=n(e),Me=o(e,"P",{"data-svelte-h":!0}),r(Me)!=="svelte-1qcvkae"&&(Me.textContent=yl),ws=n(e),we=o(e,"OL",{"data-svelte-h":!0}),r(we)!=="svelte-5zfsmn"&&(we.innerHTML=Ml),bs=n(e),be=o(e,"P",{"data-svelte-h":!0}),r(be)!=="svelte-8r9m0o"&&(be.innerHTML=wl),vs=n(e),p(ve.$$.fragment,e),js=n(e),je=o(e,"PRE",{"data-svelte-h":!0}),r(je)!=="svelte-bhg5yk"&&(je.textContent=bl),Cs=n(e),Ce=o(e,"P",{"data-svelte-h":!0}),r(Ce)!=="svelte-87sjkb"&&(Ce.textContent=vl),Ts=n(e),Te=o(e,"P",{"data-svelte-h":!0}),r(Te)!=="svelte-guqvsc"&&(Te.innerHTML=jl),xs=n(e),xe=o(e,"P",{"data-svelte-h":!0}),r(xe)!=="svelte-zs2wz8"&&(xe.innerHTML=Cl),ks=n(e),p(ke.$$.fragment,e),$s=n(e),_=o(e,"P",{});var Ua=vt(_);Ha=j(Ua,"Refreshing the app again, we can then access the clustering functionality via an operator in the app. Hit the backtick key to open the operator list, type “cluster” and select the operator from the dropdown. This will open an interactive panel where we can specify the clustering algorithm, hyperparameters, and the field to cluster on. To keep it simple, we’ll use K-Means clustering with "),_s=jt(Ua,!1),Us=j(Ua," clusters."),Ua.forEach(s),Js=n(e),$e=o(e,"P",{"data-svelte-h":!0}),r($e)!=="svelte-18xo104"&&($e.textContent=Tl),Is=n(e),_e=o(e,"P",{"data-svelte-h":!0}),r(_e)!=="svelte-1ccs8bm"&&(_e.innerHTML=xl),Ws=n(e),Ue=o(e,"P",{"data-svelte-h":!0}),r(Ue)!=="svelte-li7lmx"&&(Ue.textContent=kl),Zs=n(e),p(Je.$$.fragment,e),zs=n(e),Ie=o(e,"P",{"data-svelte-h":!0}),r(Ie)!=="svelte-128i6zr"&&(Ie.innerHTML=$l),qs=n(e),y=o(e,"P",{});var b=vt(y);Ga=j(b,"While there are a million ways to characterize uniqueness, our image embeddings allow us to quantitatively assign each sample a uniqueness score based on how similar it is to other samples in the dataset. Explicitly, the FiftyOne Brain’s "),Mt=o(b,"CODE",{"data-svelte-h":!0}),r(Mt)!=="svelte-274r01"&&(Mt.textContent=_l),La=j(b," function looks at the distance between each sample’s embedding and its nearest neighbors, and computes a score between "),Hs=jt(b,!1),Gs=j(b," and "),Ls=jt(b,!1),Fs=j(b," based on this distance. A score of "),Xs=jt(b,!1),Rs=j(b," means the sample is nondescript or very similar to others, while a score of "),Bs=jt(b,!1),Vs=j(b," means the sample is very unique."),b.forEach(s),As=n(e),p(We.$$.fragment,e),Ps=n(e),Ze=o(e,"PRE",{"data-svelte-h":!0}),r(Ze)!=="svelte-326il2"&&(Ze.textContent=Ul),Ns=n(e),ze=o(e,"P",{"data-svelte-h":!0}),r(ze)!=="svelte-1v04iac"&&(ze.textContent=Jl),Ys=n(e),p(qe.$$.fragment,e),Es=n(e),He=o(e,"P",{"data-svelte-h":!0}),r(He)!=="svelte-1tb2ntu"&&(He.innerHTML=Il),Ss=n(e),p(Ge.$$.fragment,e),Qs=n(e),Le=o(e,"P",{"data-svelte-h":!0}),r(Le)!=="svelte-1vqafg6"&&(Le.innerHTML=Wl),Os=n(e),Fe=o(e,"P",{"data-svelte-h":!0}),r(Fe)!=="svelte-1wxy7d9"&&(Fe.textContent=Zl),Ds=n(e),p(Xe.$$.fragment,e),Ks=n(e),Re=o(e,"PRE",{"data-svelte-h":!0}),r(Re)!=="svelte-1n3row5"&&(Re.textContent=zl),ea=n(e),Be=o(e,"P",{"data-svelte-h":!0}),r(Be)!=="svelte-1e52zeb"&&(Be.textContent=ql),ta=n(e),p(Ve.$$.fragment,e),sa=n(e),Ae=o(e,"P",{"data-svelte-h":!0}),r(Ae)!=="svelte-13rc4gu"&&(Ae.innerHTML=Hl),aa=n(e),p(Pe.$$.fragment,e),la=n(e),Ne=o(e,"P",{"data-svelte-h":!0}),r(Ne)!=="svelte-9plt2b"&&(Ne.textContent=Gl),na=n(e),Ye=o(e,"P",{"data-svelte-h":!0}),r(Ye)!=="svelte-43mgrp"&&(Ye.innerHTML=Ll),ia=n(e),p(Ee.$$.fragment,e),oa=n(e),Se=o(e,"P",{"data-svelte-h":!0}),r(Se)!=="svelte-11qfm07"&&(Se.innerHTML=Fl),ra=n(e),Qe=o(e,"P",{"data-svelte-h":!0}),r(Qe)!=="svelte-ojjfuj"&&(Qe.innerHTML=Xl),ma=n(e),Oe=o(e,"P",{"data-svelte-h":!0}),r(Oe)!=="svelte-10dfbs0"&&(Oe.textContent=Rl),pa=n(e),De=o(e,"P",{"data-svelte-h":!0}),r(De)!=="svelte-1tiw0lq"&&(De.innerHTML=Bl),ha=n(e),Ke=o(e,"P",{"data-svelte-h":!0}),r(Ke)!=="svelte-euuo6"&&(Ke.textContent=Vl),ua=n(e),et=o(e,"P",{"data-svelte-h":!0}),r(et)!=="svelte-b6ayaa"&&(et.innerHTML=Al),ca=n(e),tt=o(e,"P",{"data-svelte-h":!0}),r(tt)!=="svelte-1wg7oa8"&&(tt.textContent=Pl),fa=n(e),st=o(e,"P",{"data-svelte-h":!0}),r(st)!=="svelte-1aj2nhz"&&(st.innerHTML=Nl),da=n(e),at=o(e,"P",{"data-svelte-h":!0}),r(at)!=="svelte-1f4cd5i"&&(at.textContent=Yl),ga=n(e),U=o(e,"DIV",{class:!0,"data-svelte-h":!0}),r(U)!=="svelte-126gsaj"&&(U.innerHTML=El),ya=n(e),p(lt.$$.fragment,e),Ma=n(e),nt=o(e,"P",{"data-svelte-h":!0}),r(nt)!=="svelte-ov7mgi"&&(nt.innerHTML=Sl),wa=n(e),it=o(e,"P",{"data-svelte-h":!0}),r(it)!=="svelte-c0pn89"&&(it.textContent=Ql),ba=n(e),ot=o(e,"UL",{"data-svelte-h":!0}),r(ot)!=="svelte-ryyicq"&&(ot.innerHTML=Ol),va=n(e),p(rt.$$.fragment,e),ja=n(e),mt=o(e,"UL",{"data-svelte-h":!0}),r(mt)!=="svelte-752r11"&&(mt.innerHTML=Dl),Ca=n(e),p(pt.$$.fragment,e),Ta=n(e),ht=o(e,"P",{"data-svelte-h":!0}),r(ht)!=="svelte-mmnfnj"&&(ht.innerHTML=Kl),xa=n(e),ut=o(e,"P",{"data-svelte-h":!0}),r(ut)!=="svelte-1n8g4zz"&&(ut.innerHTML=en),ka=n(e),p(ct.$$.fragment,e),$a=n(e),Tt=o(e,"P",{}),vt(Tt).forEach(s),this.h()},h(){ft(C,"name","hf:doc:metadata"),ft(C,"content",Mn),ft(x,"class","alert alert-block alert-info"),ft(k,"href","https://docs.voxel51.com/integrations/huggingface.html#huggingface-hub"),ft(k,"rel","nofollow"),Pt.a=Nt,Ja(M,"padding","10px"),Ja(M,"border-left","5px solid #0078d4"),Ja(M,"font-family","Arial, sans-serif"),Ja(M,"margin","10px 0"),ft($,"class","alert alert-block alert-info"),_s.a=Us,Hs.a=Gs,Ls.a=Fs,Xs.a=Rs,Bs.a=Vs,ft(U,"class","alert alert-block alert-info")},m(e,t){d(document.head,C),a(e,xt,t),a(e,Ct,t),a(e,kt,t),h(I,e,t),a(e,$t,t),h(W,e,t),a(e,_t,t),h(Z,e,t),a(e,Ut,t),a(e,z,t),a(e,Jt,t),a(e,q,t),a(e,It,t),a(e,H,t),a(e,Wt,t),a(e,G,t),a(e,Zt,t),a(e,L,t),a(e,zt,t),h(F,e,t),a(e,qt,t),a(e,X,t),a(e,Ht,t),h(R,e,t),a(e,Gt,t),a(e,B,t),a(e,Lt,t),h(V,e,t),a(e,Ft,t),a(e,A,t),a(e,Xt,t),h(P,e,t),a(e,Rt,t),a(e,x,t),a(e,Bt,t),a(e,N,t),a(e,Vt,t),h(Y,e,t),a(e,At,t),a(e,w,t),d(w,Ia),d(w,dt),d(w,Wa),d(w,k),d(w,Za),Pt.m(tn,w),d(w,Nt),a(e,Yt,t),h(E,e,t),a(e,Et,t),a(e,S,t),a(e,St,t),h(Q,e,t),a(e,Qt,t),a(e,O,t),a(e,Ot,t),a(e,D,t),a(e,Dt,t),h(K,e,t),a(e,Kt,t),a(e,ee,t),a(e,es,t),a(e,te,t),a(e,ts,t),h(se,e,t),a(e,ss,t),a(e,ae,t),a(e,as,t),h(le,e,t),a(e,ls,t),a(e,ne,t),a(e,ns,t),a(e,ie,t),a(e,is,t),h(oe,e,t),a(e,os,t),a(e,re,t),a(e,rs,t),a(e,M,t),d(M,gt),d(M,za),h(me,M,null),d(M,qa),d(M,yt),a(e,ms,t),a(e,pe,t),a(e,ps,t),a(e,he,t),a(e,hs,t),a(e,ue,t),a(e,us,t),a(e,ce,t),a(e,cs,t),a(e,fe,t),a(e,fs,t),a(e,de,t),a(e,ds,t),a(e,$,t),a(e,gs,t),h(ge,e,t),a(e,ys,t),a(e,ye,t),a(e,Ms,t),a(e,Me,t),a(e,ws,t),a(e,we,t),a(e,bs,t),a(e,be,t),a(e,vs,t),h(ve,e,t),a(e,js,t),a(e,je,t),a(e,Cs,t),a(e,Ce,t),a(e,Ts,t),a(e,Te,t),a(e,xs,t),a(e,xe,t),a(e,ks,t),h(ke,e,t),a(e,$s,t),a(e,_,t),d(_,Ha),_s.m(sn,_),d(_,Us),a(e,Js,t),a(e,$e,t),a(e,Is,t),a(e,_e,t),a(e,Ws,t),a(e,Ue,t),a(e,Zs,t),h(Je,e,t),a(e,zs,t),a(e,Ie,t),a(e,qs,t),a(e,y,t),d(y,Ga),d(y,Mt),d(y,La),Hs.m(an,y),d(y,Gs),Ls.m(ln,y),d(y,Fs),Xs.m(nn,y),d(y,Rs),Bs.m(on,y),d(y,Vs),a(e,As,t),h(We,e,t),a(e,Ps,t),a(e,Ze,t),a(e,Ns,t),a(e,ze,t),a(e,Ys,t),h(qe,e,t),a(e,Es,t),a(e,He,t),a(e,Ss,t),h(Ge,e,t),a(e,Qs,t),a(e,Le,t),a(e,Os,t),a(e,Fe,t),a(e,Ds,t),h(Xe,e,t),a(e,Ks,t),a(e,Re,t),a(e,ea,t),a(e,Be,t),a(e,ta,t),h(Ve,e,t),a(e,sa,t),a(e,Ae,t),a(e,aa,t),h(Pe,e,t),a(e,la,t),a(e,Ne,t),a(e,na,t),a(e,Ye,t),a(e,ia,t),h(Ee,e,t),a(e,oa,t),a(e,Se,t),a(e,ra,t),a(e,Qe,t),a(e,ma,t),a(e,Oe,t),a(e,pa,t),a(e,De,t),a(e,ha,t),a(e,Ke,t),a(e,ua,t),a(e,et,t),a(e,ca,t),a(e,tt,t),a(e,fa,t),a(e,st,t),a(e,da,t),a(e,at,t),a(e,ga,t),a(e,U,t),a(e,ya,t),h(lt,e,t),a(e,Ma,t),a(e,nt,t),a(e,wa,t),a(e,it,t),a(e,ba,t),a(e,ot,t),a(e,va,t),h(rt,e,t),a(e,ja,t),a(e,mt,t),a(e,Ca,t),h(pt,e,t),a(e,Ta,t),a(e,ht,t),a(e,xa,t),a(e,ut,t),a(e,ka,t),h(ct,e,t),a(e,$a,t),a(e,Tt,t),_a=!0},p:mn,i(e){_a||(u(I.$$.fragment,e),u(W.$$.fragment,e),u(Z.$$.fragment,e),u(F.$$.fragment,e),u(R.$$.fragment,e),u(V.$$.fragment,e),u(P.$$.fragment,e),u(Y.$$.fragment,e),u(E.$$.fragment,e),u(Q.$$.fragment,e),u(K.$$.fragment,e),u(se.$$.fragment,e),u(le.$$.fragment,e),u(oe.$$.fragment,e),u(me.$$.fragment,e),u(ge.$$.fragment,e),u(ve.$$.fragment,e),u(ke.$$.fragment,e),u(Je.$$.fragment,e),u(We.$$.fragment,e),u(qe.$$.fragment,e),u(Ge.$$.fragment,e),u(Xe.$$.fragment,e),u(Ve.$$.fragment,e),u(Pe.$$.fragment,e),u(Ee.$$.fragment,e),u(lt.$$.fragment,e),u(rt.$$.fragment,e),u(pt.$$.fragment,e),u(ct.$$.fragment,e),_a=!0)},o(e){c(I.$$.fragment,e),c(W.$$.fragment,e),c(Z.$$.fragment,e),c(F.$$.fragment,e),c(R.$$.fragment,e),c(V.$$.fragment,e),c(P.$$.fragment,e),c(Y.$$.fragment,e),c(E.$$.fragment,e),c(Q.$$.fragment,e),c(K.$$.fragment,e),c(se.$$.fragment,e),c(le.$$.fragment,e),c(oe.$$.fragment,e),c(me.$$.fragment,e),c(ge.$$.fragment,e),c(ve.$$.fragment,e),c(ke.$$.fragment,e),c(Je.$$.fragment,e),c(We.$$.fragment,e),c(qe.$$.fragment,e),c(Ge.$$.fragment,e),c(Xe.$$.fragment,e),c(Ve.$$.fragment,e),c(Pe.$$.fragment,e),c(Ee.$$.fragment,e),c(lt.$$.fragment,e),c(rt.$$.fragment,e),c(pt.$$.fragment,e),c(ct.$$.fragment,e),_a=!1},d(e){e&&(s(xt),s(Ct),s(kt),s($t),s(_t),s(Ut),s(z),s(Jt),s(q),s(It),s(H),s(Wt),s(G),s(Zt),s(L),s(zt),s(qt),s(X),s(Ht),s(Gt),s(B),s(Lt),s(Ft),s(A),s(Xt),s(Rt),s(x),s(Bt),s(N),s(Vt),s(At),s(w),s(Yt),s(Et),s(S),s(St),s(Qt),s(O),s(Ot),s(D),s(Dt),s(Kt),s(ee),s(es),s(te),s(ts),s(ss),s(ae),s(as),s(ls),s(ne),s(ns),s(ie),s(is),s(os),s(re),s(rs),s(M),s(ms),s(pe),s(ps),s(he),s(hs),s(ue),s(us),s(ce),s(cs),s(fe),s(fs),s(de),s(ds),s($),s(gs),s(ys),s(ye),s(Ms),s(Me),s(ws),s(we),s(bs),s(be),s(vs),s(js),s(je),s(Cs),s(Ce),s(Ts),s(Te),s(xs),s(xe),s(ks),s($s),s(_),s(Js),s($e),s(Is),s(_e),s(Ws),s(Ue),s(Zs),s(zs),s(Ie),s(qs),s(y),s(As),s(Ps),s(Ze),s(Ns),s(ze),s(Ys),s(Es),s(He),s(Ss),s(Qs),s(Le),s(Os),s(Fe),s(Ds),s(Ks),s(Re),s(ea),s(Be),s(ta),s(sa),s(Ae),s(aa),s(la),s(Ne),s(na),s(Ye),s(ia),s(oa),s(Se),s(ra),s(Qe),s(ma),s(Oe),s(pa),s(De),s(ha),s(Ke),s(ua),s(et),s(ca),s(tt),s(fa),s(st),s(da),s(at),s(ga),s(U),s(ya),s(Ma),s(nt),s(wa),s(it),s(ba),s(ot),s(va),s(ja),s(mt),s(Ca),s(Ta),s(ht),s(xa),s(ut),s(ka),s($a),s(Tt)),s(C),f(I,e),f(W,e),f(Z,e),f(F,e),f(R,e),f(V,e),f(P,e),f(Y,e),f(E,e),f(Q,e),f(K,e),f(se,e),f(le,e),f(oe,e),f(me),f(ge,e),f(ve,e),f(ke,e),f(Je,e),f(We,e),f(qe,e),f(Ge,e),f(Xe,e),f(Ve,e),f(Pe,e),f(Ee,e),f(lt,e),f(rt,e),f(pt,e),f(ct,e)}}}const Mn='{"title":"Analyzing Artistic Styles with Multimodal Embeddings","local":"analyzing-artistic-styles-with-multimodal-embeddings","sections":[{"title":"Let’s get started! 🚀","local":"lets-get-started-","sections":[],"depth":2},{"title":"Finding Similar Artwork","local":"finding-similar-artwork","sections":[],"depth":2},{"title":"Uncovering Artistic Motifs with Clustering and Visualization","local":"uncovering-artistic-motifs-with-clustering-and-visualization","sections":[],"depth":2},{"title":"Identifying the Most Unique Works of Art","local":"identifying-the-most-unique-works-of-art","sections":[],"depth":2},{"title":"Characterizing Art with Visual Qualities","local":"characterizing-art-with-visual-qualities","sections":[],"depth":2},{"title":"What’s Next?","local":"whats-next","sections":[{"title":"📚 Resources","local":"-resources","sections":[],"depth":3}],"depth":2},{"title":"FiftyOne Open Source Project","local":"fiftyone-open-source-project","sections":[],"depth":2}],"depth":1}';function wn(Fa){return pn(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class xn extends hn{constructor(C){super(),un(this,C,wn,yn,rn,{})}}export{xn as component};
