几天前,我有一种想要回顾一张我记忆犹新的旧照片的愿望,但我不知道在哪里可以找到…自从这张照片被拍摄后,我换了两次手机,换了一次笔记本电脑,我很确定我当时已经通过Messenger把它发给了某人,但是是谁呢?如果能用一个简单的描述性查询搜索我所有的图片并找到它,那该有多方便啊!…
计算机视觉的最新进展提高了图像嵌入(密集矢量表示)的相关性,使用最近的剪辑模型,为我的本地图片实现类似Google的图像搜索现在很容易实现。
无需深入研究细节(更多信息,请参阅博客帖子和论文:https://openai.com/blog/clip/),Clip是一个神经网络,旨在通过自然语言监督来学习图像特征。基本上,它使用互联网上带有相关字幕的公共图像,将文本嵌入类似Bert的语言模型,并将图像嵌入视觉转换器。请注意,所使用的技术可以应用于其他NLP和CV模型体系结构。利用多个图像/文本嵌入对,可以通过批量负对比训练来微调视觉和文本嵌入模型,类似于在信息检索的NLP领域中可以做的事情。基本上,目标是使图像嵌入与其关联的文本嵌入相对应(点积),并且与其他图像的所有(1)不同。
剪辑通常用于“零镜头”分类;给定图像和字幕列表,它会推断图像的最佳字幕是什么。在上面的例子(2)中,与“飞机的照片”、“鸟的照片”、“汽车的照片”相比,“狗的照片”是最好的图片说明。…
我对图像搜索引擎的想法(这里并不新鲜)是颠覆这一点,而不是基于图像对字幕进行分类,而是基于文本查询对图像进行分类。该过程将如下所示:
- 找到给定目录中的所有图像
- 使用预先训练的剪辑视觉转换器计算每个图像的嵌入,并将它们与图像路径一起存储以供将来参考。https://openai.com/blog/clip/
- 在运行时,使用剪辑文本转换器将用户查询转换为文本嵌入。
- 计算文本嵌入与所有存储的图像嵌入的点积,根据其获得的分数对所有图像进行排序,并返回排名最高的N个图像的路径。
这个过程以及一些额外的特性是在我的Github存储库中实现的:https://github.com/ManuelFay/ImageSearcher. https://github.com/ManuelFay/ImageSearcher
在索引阶段,代码使用oslibrary查找给定目录和子目录中的所有图片,使用转换器和Pickle库嵌入和存储矢量化表示。在运行时,将加载酸洗过的嵌入,并根据嵌入的查询进行匹配,然后返回排名第n位的图像。提供了Flask/Gunicorn API,以便能够高效地使用具有外部接口的搜索引擎。还提供了一个简单的Google Image Search,类似于Vue.js构建的Web界面。
示例
为了获取大量的图片,我从Facebook下载了我的Messenger档案,获得了过去几年里我发送和接收的大约1万张图片。
搜索引擎允许进行非常描述性的查询。排名靠前的图像排在第一位。请注意,这些图片都是从我的大约10,000张本地图片中提供的,因此选项池是有限的。
元查询也是可能的。在这里,我们请求无人机拍摄的照片:
这是一个很快的下午项目,但剪辑模型的精确度给我留下了深刻的印象。要自己测试它,请使用https://github.com/ManuelFay/ImageSearcher.中的代码欢迎对改进和额外功能的贡献! https://github.com/ManuelFay/ImageSearcher