世界杯来了,让 Towhee 带你多语言「以文搜球」!

2023/9/30 16:36:38

四年一度的世界杯已正式拉开战幕,各小组比赛正如火如荼地进行中。在这样一场球迷的盛宴中,不如让 Towhee 带你「以文搜球」,一览绿茵场上足球战将们的风采吧~

「以文搜球」是跨模态图文检索的一部分,如今最热门的跨模态图文检索模型莫过于 CLIP,关于模型的原理详解和相关使用教程,推荐参考从零到一,教你搭建从零到一,教你搭建「以文搜图」搜索服务系列文章。

世界杯是一场全球的盛宴,这里有来自不同地区、使用着不同语言的朋友们。那我们在“搜球”的时候如何能支持其他语言的文本,比如中文?甚至同时支持多种语言的「以文搜球」呢?

中文版搜球

如果观察目前主流的图文跨模态模型,我们会发现它们的架构基本都包含了文本编码器和视觉编码器,分别用于提取文本和图片的特征。那么面对不同语言的文本,模型只需要使用不同的文本数据训练文本编码器,使其适配对应的视觉编码器,就能让文本和图片向量映射到相同的特征空间。

为了方便用户使用,Towhee 用更加友好的 Python 接口包装了一些预训练模型。用户可以根据目标任务直接选择不同算子提取图片与文本向量,其中支持了中文输入。这里我们以算子 image_text_embedding.taiyi 为例,用 10 张图片搭建一个简单的「以文搜图」服务。

  • 数据:10 张图片来自图像数据集 ImageNet 中的“soccer_ball”类别,包括了足球相关的图片。

  • 特征提取:image_text_embedding.taiyi 能够将中文或图片转换成向量,使用同一个模型生成的向量拥有同样的特征空间。

  • 向量数据库:这里搭建的「以文搜图」系统使用了 Milvus 实现向量存储与检索,包括匹配对应的图片路径。

1. 准备工作

为了之后的向量存储和检索,我们需要事先启动 Milvus 服务,具体教程可以参考 Milvus 官网文档。此外,我们还需要安装相关的 Python 依赖,包括 Towhee 和 Pymilvus(注意根据自己的环境安装其他所需要的依赖包)。

python -m pip install towhee pymilvus

最后,我们需要准备一个 Milvus 集合,用于之后的向量存储和检索。在创建集合的时候,你可以根据自己的需求配置不同的参数。下面是用 Python 创建 Milvus 集合的代码示例,该集合配置如下:

  • 集合名:唯一且不重复,用于指定集合

  • 数据表格:
    • id:主键,由系统自动生成唯一且不重复的整数(无需插入)

    • embedding:图片向量,由 512 维浮点数组成

    • path:图片路径,由字段组成

  • 索引:基于 embedding 列数据创建 IVF_FLAT 索引(参数 "nlist":2048),同时选择 IP 内积 衡量向量之间的相似度(距离越大表示越相似)

from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility

HOST = 'localhost'
PORT = '19530'
COLLECTION_NAME = 'text_image_search'
INDEX_TYPE = 'IVF_FLAT'
METRIC_TYPE = 'IP'
DIM = 512
TOPK = 3

def create_milvus(exist_ok=False):
    try:
        connections.connect(host=HOST, port=PORT)
    except Exception:
        raise RunTimeError(f'Fail to connect Milvus with {HOST}:{PORT}')
    
    if utility.has_collection:
        collection = Collection(COLLECTION_NAME)
        if exist_ok:
            print(f'Using existed collection: {COLLECTION_NAME}.')
            return collection
        else:
            print('Deleting previous collection...')
            collection.drop()
            
    # Create collection
    print('Creating collection...')
    fields = [
        FieldSchema(name='id', dtype=DataType.INT64, description='embedding ids', is_primary=True, auto_id=True),
        FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, description='image embeddings', dim=DIM),
        FieldSchema(name='path', dtype=DataType.VARCHAR, description='image path', max_length=500)
        ]
    schema = CollectionSchema(fields=fields, description='text image search')
    
    collection = Collection(name=COLLECTION_NAME, schema=schema)

    # Create index
    print('Creating index...')
    index_params = {
        'metric_type': METRIC_TYPE,
        'index_type': INDEX_TYPE,
        'params':{"nlist":2048}
    }

    collection.create_index(field_name='embedding', index_params=index_params)
    
    print(f'Milvus collection is ready: {COLLECTION_NAME} ({INDEX_TYPE}, {METRIC_TYPE}).')
    return collection
    
    collection = create_collection()

2. 插入数据

当准备工作完成后,我们可以利用 Towhee 接口 实现一下流程:

  1. 根据图片路径读取并解码图片

  2. 利用预训练模型生成图片向量

  3. 将向量与对应的图片路径插入事先准备好的 Milvus 集合

import towhee

# Insert
insert = (
    towhee.glob['path']('path/to/soccer_ball/*.JPEG')
          .image_decode['path', 'image']()
          .image_text_embedding.taiyi['image', 'vec'](
                   model_name='taiyi-clip-roberta-102m-chinese',
                   modality='image')
          .ann_insert.milvus[('vec', 'path'), 'milvus_res'](
                   uri=f'tcp://{HOST}:{PORT}/{COLLECTION_NAME}')
#           .select['path', 'image', 'milvus_res']()
#           .show()
)

print(f'Total vectors in collection: {collection.num_entities}')

至此我们已经成功将 10 张样本图片对应的向量和路径存入数据库,一个可供「以文搜图」的系统就搭建好了。

3. 检索测试

接下来,让我们简单地用中文查询进行检索测试:

import towhee

query = (
    towhee.dc['text'](['输入查询语句'])
          .image_text_embedding.taiyi['text', 'vec'](
                   model_name='taiyi-clip-roberta-102m-chinese',
                   modality='text')
          .ann_search.milvus['vec', 'milvus_res'](
                   uri=f'tcp://{HOST}:{PORT}/{COLLECTION_NAME}',
                   metric_type=METRIC_TYPE,
                   limit=TOPK,
                   output_fields=['path'])
          .flatten('milvus_res')
          .runas_op['milvus_res', ('image_path', 'score')](lambda x: (x.path, x.score))
          .image_decode['image_path', 'image']()
          .select['text', 'image', 'score']()
          .show()
)

通过查询“小孩玩足球”“小男孩玩足球”“小男孩抱着足球”,我们对比前三名的搜索结果可以观察到该系统成功实现了文本描述与图片内容的匹配。当文本描述出图片之间的差别时,相似度之间的差异会变得更加明显。

 

 

多语言版搜球

对比英文版本的「以文搜图」,我们可以发现其实只需要替换向量化的算子就能够实现中文查询。同理可见,如果有一个算子使用了支持多种语言的预训练模型,我们就可以搭建一个同时支持多种语言查询的「以文搜图」服务。

下面就是这样一个例子,同时也展示了如何在 Towhee 流水线中使用自定义算子。该自定义算子使用了 towhee.models.clip 中一个支持多语言文本的预训练模型 ‘clip_vit_b32’,能够将不同语言的文本与图像匹配。

  • 自定义算子:

from towhee.models.clip import create_model
from torchvision import transforms
from PIL import Image
import numpy()

model = create_model('clip_vit_b32', pretrained=True, device='cpu')

def encode_text(x):
    features = model.encode_text(x, multilingual=True).squeeze(0).detach().cpu().numpy()
    return features

def encode_image(x):
    tfms = transforms.Compose([
        transforms.Resize(224, interpolation=transforms.InterpolationMode.BICUBIC),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize(
           (0.48145466, 0.4578275, 0.40821073), (0.26862954, 0.26130258, 0.27577711))
        ])
    img = Image.open(x)
    x = tfms(img).unsqueeze(0)
    features = model.encode_image(x).squeeze(0).detach().cpu().numpy()
    return features
  • 插入数据:

import towhee

# Insert
insert = (
    towhee.glob['path']('path/to/soccer_ball/*.JPEG')
          .runas_op['path', 'vec'](func=encode_image)
          .ann_insert.milvus[('vec', 'path'), 'milvus_res'](uri=f'tcp://{HOST}:{PORT}/{COLLECTION_NAME}')
          .select['path', 'milvus_res']()
          .show()
)

print(f'Total vectors in collection: {collection.num_entities}')
  • 文本查询:

import towhee

query = (
    towhee.dc['text'](['输入查询语句'])
          .runas_op['text', 'vec'](func=encode_text)
          .ann_search.milvus['vec', 'milvus_res'](
                   uri=f'tcp://{HOST}:{PORT}/{COLLECTION_NAME}',
                   metric_type=METRIC_TYPE,
                   limit=TOPK,
                   output_fields=['path'])
          .flatten('milvus_res')
          .runas_op['milvus_res', ('image_path', 'score')](lambda x: (x.path, x.score))
          .image_decode['image_path', 'image']()
          .select['text', 'image', 'score']()
          .show()
)

分别查询中文、英文、西班牙语、法语的“小男孩玩足球”,我们可以获得几乎相同的查询结果。 

通过本文,我们学习了如何用 Towhee 搭建一个简单的「以文搜球」系统,成功地支持了中文等多种语言的输入。还不快快试着搭建一个「搜球」系统吗?

如果需要应用到实际业务,大家可以用更多的方法优化模型、优化系统,比如用业务数据微调模型、加速推理服务、实现并列运行、加入异常处理机制等。


http://www.jnnr.cn/a/154093.html

相关文章

百行代码实现VLC简易视频播放器【详细环境配置过程+可执行源码注释完整】

文章目录❓什么是VLC🚀VLC 库的集成⭐VLC环境配置演示【win10系统vs2017win64】🍎VLC 库的基本使用🎂视频播放器实现⭐自定义函数Unicode2Utf8讲解🏠总结❓什么是VLC VLC 是 Video Lan Client 的缩写,原先是几个法国的…

ES6解析赋值

ES6中新增了一种数据处理方式,可以将数组和对象的值提取出来对变量进行赋值,这个过程时将一个数据结构分解成更小的部分,称之为解析。 1.对象解析赋值: 在ES5中,要将一个对象的属性提取出来,需要经过一下几个过程。 …

springcloud22:sentinal的使用

sentinal对比(分布式系统的流量防卫) 监控保护微服务 Hystrix 需要自己去手工搭建监控平台,没有一套web界面可以进行细粒度化的配置,流控,速率控制,服务熔断,服务降级… 整合机制:se…

让学前端不再害怕英语单词(四)

|| 欢迎关注csdn前端领域博主: 前端小王hs || email: 337674757qq.com || 前端交流群: 598778642前三章直通车↓↓↓ 让学前端不再害怕英语单词(一) 让学前端不再害怕英语单词(二) 让学前端不再害怕英语单词&#xff0…

2022年 SecXOps 安全智能分析技术白皮书 学习笔记 免费下载地址

核心能力 为了加快安全分析能力更全面、更深入的自动化 ,SecXOps 的目标在于创建一个集成的用于 Security 的 XOps 实践,提升安全分析的场景覆盖率和运营效率。SecXOps 技术并不 015 SecXOps 技术体系 是 Ops 技术在安全领域的简单加和,SecXO…

C语言练习之递归实现n的k次方

文章目录前言一、思路二、代码以及运行截图1.代码2.运行截图总结前言 使用C语言递归计算N的k次方 一、思路 求n的k次方的原理就是: n^k nn……*n(k个n进行相乘) 可以得到一个公式: f(k){1k0n∗f(k)k>0f(k) \left\{\begin{…

详解 InnoDB Cluster 主机名问题

详解 InnoDB Cluster 主机名问题 文章目录详解 InnoDB Cluster 主机名问题导言测试过程结论导言 因在写 【InnoDB Cluster】修改已有集群实例名称及成员实例选项 时发现主机名这块有一些问题,在其中进行了部分测试,但为使其内容精简,故将此部…

JSP学习日记

JSP简述 Java Sever Pages----->Java服务器界面 用于前后端结合 jsp为什么淘汰? 由于JSP的前后端耦合性极高,编写代码非常臃肿。前后端的代码放在一起,所以JSP可以看成是已经被淘汰的技术。 为什么还要学jsp? 由于一些公司…

【机器学习项目实战10例】(三):基于K近邻的葡萄酒质量检测项目

💥 项目专栏:【机器学习项目实战10例】 文章目录 一、基于K近邻的葡萄酒质量检测项目二、数据集介绍三、导包四、读取数据五、绘制空间分布六、划分训练集、测试集七、构建K近邻模型八、绘制聚类效果九、网格搜索一、基于K近邻的葡萄酒质量检测项目 葡萄酒数据集是一个经典…

APP逆向案例之(三)sign 参数破解

说明:某新闻APP sign 参数 抓包发现包含内容: url: https://124.*.*.*/api/categorynews/lists 参数: 其中 sign 参数是需要变化的否则访问失败,其余都是固定的 page: 3, size: 10, category: -2, from: -1, lng: 116.363…

Date对象

文章目录Date日期对象Date对象的创建格式化日期3.获取Date总的毫秒数(时间戳),是距离1970年1月1日过了多少毫秒数。二:常用时间获取方法三:日期设置方法四:时间转字符串菜鸟工具:https://www.runoob.com/jsref/jsref-o…

有监督学习神经网络的回归拟合——基于红外光谱的汽油辛烷值预测(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

Java#27(Arrays)

目录 一.Arrays 操作数组的工具类 二.Lambda表达式 1.注意: 2.省略规则 一.Arrays 操作数组的工具类 方法名 作用 public static String toString(数组) 把数组拼接…

代码随想录65——额外题目【二叉树】:129求根节点到叶节点数字之和、1382将二叉搜索树变平衡、100相同的树、116填充每个节点的下一个右侧节点指针

文章目录1.129求根节点到叶节点数字之和1.1.题目1.2.解答2.1382将二叉搜索树变平衡2.1.题目2.2.解答3.100相同的树3.1.题目3.2.解答4.116填充每个节点的下一个右侧节点指针4.1.题目4.2.解答4.2.1.递归解法4.2.2.迭代方法1.129求根节点到叶节点数字之和 参考:代码随…

机器学习笔记之贝叶斯线性回归(一)线性回归背景介绍

机器学习笔记之贝叶斯线性回归——线性回归背景介绍引言回顾:线性回归场景构建从概率密度函数认识最小二乘法回顾:最小二乘估计回顾:线性回归与正则化关于线性回归的简单小结贝叶斯线性回归贝叶斯方法贝叶斯方法在线性回归中的任务贝叶斯线性…

cocos creator实现浏览星球的功能,附源码

预览效果: 技术要点: 主摄像机的视场轴需要设置为水平。在场景下创建一个空节点用于挂载控制器脚本图片已进行各概念的说明 在“collisionNodeArray”属性下,放置需要点击的星球节点,系统会自己绑定碰撞器。 也可自己提前绑定。 布…

现代密码学导论-16-选择明文攻击和CPA安全

目录 PCA不可区分实验 DEFINITION 3.21 PCA安全的加密方案 LR预言机实验 DEFINITION 3.22 多明文PCA安全的加密方案 THEOREM 3.23 定义3.21和定义3.22等价 PCA不可区分实验 通过运行G(1^n)获得密钥k敌手A被给定输入1^n并拥有访问预言机Enck()的权利,敌手A输出一…

Day12--自定义组件-渲染my-search组件的基本结构

1.自定义搜索组件 我的操作: 1》在uni_modules中右键新建uni_modules插件: 2》看看效果图: ************************************************************************************************************** 2.在分类页面的 UI 结构中&…

Linux进程管理【进程的相关介绍片、ps、 kill 、pstree】【详细整理】

目录进程相关介绍显示系统执行的流程 psps 详解![请添加图片描述](https://img-blog.csdnimg.cn/cd9f10bf36684b419f2f94068afb9a03.png)案例终止进程kill 和 killall基本语法常见选型案例查看进程数pstreepstree [选项],可以更加直观的来查看进程信息进程相关介绍 …

[计算机毕业设计]远程监督的跨语言实体关系抽取

前言 📅大四是整个大学期间最忙碌的时光,一边要忙着准备考研,考公,考教资或者实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过…
最新文章