Press "Enter" to skip to content

现代语义搜索图像

使用Python、Pinecone、Hugging Face和Open AI CLIP模型创建云照片语义搜索应用的一篇教程文章。

作者提供的图片

您希望从几年前的照片中找到“那张特定的照片”。您记得关于环境的一些细节。Apple照片没有提供语义搜索功能,而且Google照片仅限于几个预设的物体分类器。对于这种类型的搜索,两者都不太适用。我将用我在Google照片中进行的两个不寻常的查询:“甜甜圈生日蛋糕”和“被滚雪球打破的嘴唇”来演示问题。然后我将分享如何构建自己的语义图像搜索应用。

示例#1

我喜欢生日蛋糕。我也喜欢甜甜圈。去年,我有一个绝妙的主意,将两者结合在一起作为我的生日蛋糕。我们来试试找到它。

Google照片查询:“甜甜圈生日蛋糕”

结果:六张没有甜甜圈的蛋糕图片,后面是我想要的那张。

作者提供的图片

语义搜索应用查询:“甜甜圈生日蛋糕”

结果:两张图像和一个视频,正是我想要的。

作者提供的图片

示例#2

我和我十几岁的儿子以及他的一群朋友一起去滑雪。他们爬上了一个废弃的火车隧道。我大喊道:“同时扔雪球,我来录慢动作视频!”没有预料到的是,我没有想到我会成为二十个有力臂膀的十几岁男孩的靶子。

Google照片查询:“被滚雪球打破的嘴唇”

结果:

作者创建的图片

当前的Google图像分类模型仅限于它训练过的单词。

语义搜索应用查询:“被滚雪球打破的嘴唇”

结果:被打破的嘴唇的图片(未显示)和前面的视频分别是结果一和结果二。

作者提供的图片

OpenAI CLIP模型和应用架构

CLIP使模型能够学习将图像像素与文本关联,并且使其具备寻找类似“甜甜圈蛋糕”和“被打破的嘴唇”等的能力-这些都是在训练图像分类器时绝不会考虑到的项目。它代表Contrastive Language-Image Pretraining,是一个开源的多模态零样本模型。它在数以百万计的带有描述性字幕的图像上进行了训练。

通过给定图像和文字描述,该模型可以预测图像最相关的文字描述,而无需针对特定任务进行优化。

来源:Nikos Karfitsas,Towards Data Science

你在大多数在线教程中找到的CLIP架构已经足够用于POC,但不适合企业级。在这些教程中,CLIP和Hugging Face处理器将内嵌在内存中以作为运行相似度分数和检索的向量存储。

由作者创建的图片

像Pinecone这样的向量数据库是扩展这样的应用的关键组件。它提供了简化、稳健、企业级的功能,如批量和流数据处理、内嵌管理、低延迟检索和元数据过滤。

由作者创建的图片

构建应用

有关该应用的代码和支持文件可以在GitHub上找到:https://github.com/joshpoduska/llm-image-caption-semantic-search。使用它们来构建一个语义搜索应用程序,用于云照片。

该应用程序在性能足够的笔记本电脑上本地运行。我在MacBook Pro上进行了测试。

构建应用所需的组件

  • Pinecone 或类似的向量数据库用于嵌入存储和语义搜索(Pinecone的免费版本足够本教程使用)
  • Hugging Face 模型和流程
  • 用于创建图像和查询文本嵌入的 OpenAI CLIP 模型(可从Hugging Face获得)
  • Google Photos API 用于访问个人的Google照片

开始之前的有用信息

访问你的图片

Google Photos API有几个关键的数据字段。更多详细信息请参见API参考

  • Id是不可变的
  • baseUrl允许您访问媒体项的字节。它们在60分钟内有效。

使用pandas、JSON和requests库的组合可以直接用来加载您的图像ID、URL和日期的DataFrame。

生成图像嵌入

使用Hugging Face和OpenAI的CLIP模型,这一步是整个应用程序中最简单的。

from sentence_transformers import SentenceTransformerimg_model = SentenceTransformer('clip-ViT-B-32')embeddings = img_model.encode(images)

创建元数据

语义搜索通常通过元数据过滤进行增强。在本应用程序中,我使用照片的日期提取年份、月份和日期。这些被存储在DataFrame字段中的字典。Pinecone查询可以使用这个字典来根据字典中的元数据筛选搜索。

这是我的pandas DataFrame的第一行,包含图像字段、向量和元数据字典字段。

Image by the author

加载嵌入

Pinecone有关于异步和并行加载的优化。基本的加载函数很简单,如下所示。

index.upsert(vectors=ids_vectors_chunk, async_req=True)

查询嵌入

要使用CLIP模型查询图像,我们需要传递语义查询的文本给它。这可以通过加载CLIP文本嵌入模型来实现。

text_model = SentenceTransformer('sentence-transformers/clip-ViT-B-32-multilingual-v1')

现在我们可以为我们的搜索短语创建一个嵌入,并将其与存储在Pinecone中的图像的嵌入进行比较。

# create the query vectorxq = text_model.encode(query).tolist()# now queryxc = index.query(xq,                filter= {                "year": {"$in":years_filter},                "month": {"$in":months_filter}                        },                top_k= top_k,                include_metadata=True)

结论

CLIP模型非常了不起。它是一个通用知识、零样本模型,已经学会以一种使其摆脱在预定义类别上训练图像分类器的约束条件的方式将图像与文本关联起来。当我们将其与像Pinecone这样的企业级向量数据库的强大功能相结合时,我们可以创建具有低延迟和高保真度的语义图像搜索应用程序。这只是每天涌现的生成AI令人兴奋的应用之一。

Leave a Reply

Your email address will not be published. Required fields are marked *