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

news2025/7/11 18:44:54

四年一度的世界杯已正式拉开战幕,各小组比赛正如火如荼地进行中。在这样一场球迷的盛宴中,不如让 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.coloradmin.cn/o/38463.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Leetcode刷题Day5休息 Day6----------哈希表

Leetcode刷题Day5休息 & Day6----------哈希表 1. 哈希表理论基础 数组、Set、Map 如果数据量小------------数组 如果数据量大------------Set 如果有Key、value------------Map 文章讲解:https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86…

【雷达检测】基于复杂环境下的雷达目标检测技术(Matlab代码实现)

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

数据之道读书笔记-06面向“自助消费”的数据服务建设

数据之道读书笔记-06面向“自助消费”的数据服务建设 数据底座建设的目标是更好地支撑数据消费,在完成数据的汇聚、整合、联接之后,还需要在供应侧确保用户更便捷、更安全地获取数据。一方面业务人员希望尽可能快速地获取各种所需的数据,另一…

基于双目相机拍摄图像的深度信息提取和目标测距matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB程序 1.算法描述 双目相机一般由左眼和右眼两个水平放置的相机组成。当然也可以做成上下两个目,但我们见到的主流双目都是做成左右的。在左右双目的相机中,我们可以把两个相机都看作针…

大数据毕设选题 - 深度学习图像超分辨率重建(opencv python cnn)

文章目录0 前言1 什么是图像超分辨率重建2 应用场景3 实现方法4 SRResNet算法原理5 SRCNN设计思路6 代码实现6.1 代码结构组织6.2 train_srresnet6.3 训练效果7 最后0 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章! &#x…

读写分离和主从复制

这是只有一个数据库的情形,此时增删改查都是针对这个数据库而言 存在两个问题:所有压力都是由一台数据库承担,数据库压力很大 而且,一旦这个数据库发生故障,数据丢失,拿数据就全都没了 现在有两个数据库&…

总结使人进步,4句真章的理解和实践

在“总结使人进步,遵循事物的客观发展规律;祸福相依,知行合一”这篇文章里,首次全面提出了4句真章。 这么多年,最有感触的4句话。 一、4句真章 1、总结使人进步 2、遵循事物的发展规律 3、祸福相依 4、知行合一 …

muduo库中实现Protbuf编码器与消息分发器

文章目录1. protobuf的type name反射机制2. Protobuf编码器2.1 protbuf传输格式2.2 message转换为Buffer2.3 Buffer转换为message2.4 onMessage和send3. 消息分发器dispatcher3.1 成员变量3.2 onProtobufMessage3.3 registerMessageCallback4. 简单RPC4.1 query.proto4.2 serve…

QT:debug日志—打不开头文件以及qDebug和Q_CLASSINFO的使用

这个是因为链接器在给定路径上搜索不到对应的头文件,而大多数的Qt相关的头文件都集中在一个include文件夹里: 我电脑上的路径是:C:\Qt\Qt5.9.7\5.9.7\msvc2017_64\include 然后我们在项目设置里: 注意,这边要加上\*&…

Linux系统配置及服务管理-06-存储管理

基本分区 磁盘简介 磁盘/硬盘/disk是一个东西,不同于内存的是容量比较大。 类型 从工作原理区分 机械 机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,磁头控制器,数据转换…

钢材缺陷检测系统-ui界面

钢材缺陷检测系统-ui界面 之前写过这个博客: 工业缺陷检测项目实战(二)——基于深度学习框架yolov5的钢铁表面缺陷检测 里面介绍了使用yolov5进行训练的步骤。今天我们一起学习利用qt将缺陷检测封装为一个系统。 效果 首先看看效果: 我们运行,先可以看…

26岁月薪从7k到17K,这一切都要从那年失业讲起...

女生,目前在成都做了快4年的测试 先来说说我自己是怎么入行的以及我学到的一些经验分享,希望能帮助到更多的朋友们 我大学学的并不是计算机相关专业,学的市场营销,毕业后大部分同学都去做销售或者商务BD了,奈何自己性…

Redis复习笔记

文章目录Redis一、redis入门1.1、NoSQL的引言1.2、为什么是NoSQL1.3、NoSQL的四大分类1.3.1 键值(Key-Value)存储数据库1.3.2 列存储数据库1.3.3 文档型数据库1.3.4 图形(Graph)数据库1.4 NoSQL应用场景1.5 什么是Redis1.6 Redis特点1.7 Redis 安装二、redis数据库相关指令2.1 …

vue-swiper组件化:解决异步请求数据时swiper过早初始化问题:

最初始的swiper组件封装&#xff1a; <body><div id"box"><swiper></swiper></div><script>Vue.component("swiper", {template: <div class"swiper"><div class"swiper-wrapper">…

PC_磁盘HDD_SSD/存储介质(材料工艺)

文章目录外存磁盘存储器组成磁盘驱动器磁盘控制器盘片platter存储区域磁盘结构磁道track道距位密度扇区sector&#x1f388;/块Block&#x1f386;磁头(Head)圆柱面cylinder磁记录原理磁盘性能指标记录密度磁盘的容量非格式化容量格式化容量数据传输率磁盘转速旋转周期T例平均存…

自学网络安全?一般人我还是劝你算了吧

前言 本人纯屌丝一枚&#xff0c;在学网络安全之前对电脑的认知也就只限于上个网&#xff0c;玩个办公软件。这里不能跑题&#xff0c;我为啥说自学网络安全&#xff0c;一般人我还是劝你算了吧。因为我就是那个一般人。 基础真的很简单&#xff0c;是个人稍微认点真都能懂&a…

SpringBoot 常用配置

SpringBoot的配置文件格式 SpringBoot的配置文件支持properties和yml&#xff0c;甚至他还支持json。 更推荐使用yml文件格式&#xff1a; yml文件&#xff0c;会根据换行和缩进帮助咱们管理配置文件所在位置 yml文件&#xff0c;相比properties更轻量级一些 yml文件的劣势&am…

SpringBoot——自定义start场景启动器

需求分析&#xff1a;为什么要学习场景启动器&#xff1f; SpringBoot要引用外部组件&#xff0c;只需要拿到其场景启动器的依赖&#xff0c;再编写一些配置文件即可。 eg:SpringBoot中要使用redis就需要引入redis的场景启动器依赖 <dependency><groupId>org.spri…

Kafka - 05 Kafka生产者| 消息发送方式 | 序列化器 | 分区器 | 拦截器 |生产者配置参数

文章目录1. Java客户端数据生产流程解析2. 消息发送方式3. 序列化器4. 分区器5. 拦截器6. 发送原理剖析7. Kafka生产者参数配置1. Java客户端数据生产流程解析 首先要构造一个 ProducerRecord 对象&#xff0c;该对象可以声明主题Topic、分区Partition、键 Key以及值 Value&…

刷爆力扣之检查数组对是否可以被 k 整除

刷爆力扣之检查数组对是否可以被 k 整除 HELLO&#xff0c;各位看官大大好啊&#xff0c;我是阿呆 &#x1f648;&#x1f648;&#x1f648; 今天开始阿呆将会记录下力扣刷题过程&#xff0c;收录在专栏算法中 &#x1f61c;&#x1f61c;&#x1f61c; 该专栏按照不同类别标…