EasyNLP带你玩转CLIP图文检索

本文涉及的产品
交互式建模 PAI-DSW,5000CU*H 3个月
简介: 本文简要介绍CLIP的技术解读,以及如何在EasyNLP框架中玩转CLIP模型。

作者:熊兮、章捷、岑鸣、临在

导读

随着自媒体的不断发展,多种模态数据例如图像、文本、语音、视频等不断增长,创造了互联网上丰富多彩的世界。为了准确建模用户的多模态内容,跨模态检索是跨模态理解的重要任务,采用一种模态的数据作为数据,检索另一种模态的数据。其中,图文检索是跨模态检索的一种主流任务,广泛应用于各种网络应用中,其难点在于跨模态的表示鸿沟(Representation Gap)。具体来说,文本和图像的数据处于不同的向量空间,无法直接去度量他们的相似性。OpenAI提出了CLIP(Contrastive Language-Image Pre-training)模型,在大规模图文数据集上进行了对比学习训练,在多个数据集上的准确度表明,CLIP优于各种基于ImageNet的模型,也具有良好的零样本学习(Zero-shot Learning)能力。


EasyNLP是阿里云机器学习PAI 团队基于 PyTorch 开发的易用且丰富的中文NLP算法框架,支持常用的中文预训练模型和大模型落地技术,并且提供了从训练到部署的一站式 NLP 开发体验。EasyNLP 提供了简洁的接口供用户开发 NLP 模型,包括NLP应用 AppZoo 和预训练 ModelZoo,同时提供技术帮助用户高效的落地超大预训练模型到业务。由于跨模态理解需求的不断增加,EasyNLP也将支持各种跨模态模型,特别是中文领域的跨模态模型,推向开源社区,希望能够服务更多的 NLP 和多模态算法开发者和研究者,也希望和社区一起推动 NLP /多模态技术的发展和模型落地。


本文简要介绍CLIP的技术解读,以及如何在EasyNLP框架中玩转CLIP模型。


CLIP模型详解

CLIP的模型结构相对比较简单,体现了“大道至简”的设计原则,其模型框架图如下图所示:


为了建立图像和文本的关联性,CLIP首先分别构建了图像和文本的Encoder,分别对图像和文本进行特征抽取。对于图像而言,CLIP使用的Backbone可以是经典的ResNet系列模型,也可以是更先进的Transfomer类模型,例如VIT等;对于文本,CLIP一般使用BERT类模型进行特征抽取,也包括RoBERTa等。在特征抽取之后,CLIP分别对提取的向量进行Normalization,从而可以直接进行内积相似度计算。在模型Loss Function层面,由于图像和文本向量都进行了Normalization,我们直接使用相乘来计算余弦距离,使得同一图文对的结果趋近于1,不同图文对的结果趋近于0;并且使用对比学习损失InfoNCE进行损失计算。


当模型预训练结束后,我们可以直接使用CLIP进行图文的检索,因为CLIP已经将图文的表示映射到同一个向量空间。CLIP的另一个优势在于可以进行Zero-shot Classification。如下图所示,我们设计输入文本“A photo of a {object}.”,并且使用目标图像作为输出。如果文本“A photo of a dog.”于当前图像最匹配(余弦相似度最高),我们可以说明,当前图像的物体是“dog”。由此可见,预训练后的CLIP模型可以直接用于图像分类,而不需要额外的训练。


CLIP模型的训练过程也可以直接参考原作者给出的伪代码实现:

EasyNLP中CLIP模型的实现


在EasyNLP框架中,我们在模型层构建了CLIP模型的Backbone,核心代码如下所示:

self.text_model = CLIPTextTransformer(text_config)
self.vision_model = CLIPVisionTransformer(vision_config)
self.visual_projection = nn.Linear(self.vision_embed_dim, self.projection_dim, bias=False)
self.text_projection = nn.Linear(self.text_embed_dim, self.projection_dim, bias=False

其中,CLIPTextTransformer和CLIPVisionTransformer分别是基于BERT和VIT的特征提取器。前向传播的过程也比较简洁:

vision_outputs = self.vision_model(...)
text_outputs = self.text_model(...)
image_embeds = vision_outputs[1]
image_embeds = self.visual_projection(image_embeds)
image_embeds = image_embeds / image_embeds.norm(dim=-1, keepdim=True)
text_embeds = text_outputs[1]
text_embeds = self.text_projection(text_embeds)
text_embeds = text_embeds / text_embeds.norm(dim=-1, keepdim=True)
logit_scale = self.logit_scale.exp()
logits_per_text = torch.matmul(text_embeds, image_embeds.t()) * logit_scale
loss = clip_loss(logits_per_text)

此外,由于CLIP模型本身具备文本和图像的编码器,我们直接调用他们的前向推理函数就可以实现特征的提取。对于文本我们有:

text_outputs = self.text_model(...)
pooled_output = text_outputs[1]
text_features = self.text_projection(pooled_output)

对图像的操作也与文本类似:

vision_outputs = self.vision_model(...)
pooled_output = vision_outputs[1]
image_features = self.visual_projection(pooled_output)

此外,我们在多个公开数据集上验证了EasyNLP框架中CLIP模型在各种任务上的精度。以零样本学习为例,我们使用EasyNLP加载了开源的openai/clip-vit-large-patch14模型,对比了Top-1精度和CLIP官方论文的结果,如下所示:


数据集

Top-1 Accuracy (复现结果)

CLIP 论文汇报结果

Food101

90.9

92.9

CIFAR100

78.6

77.9

EuroSAT

60.1

59.9

Oxford Pets

93.0

93.5

Fllickr30k-TR

85.3

88.0

Fllickr30k-IR

65.0

68.7


我们的实验也说明,如果采用特定数据集的数据对CLIP进行进一步Fine-tune,CLIP能取得更好的效果。以Fllickr30k数据集为例,CLIP模型在零样本学习和Fine-tune对比结果如下:


img2txt

(r1/r5/r10)

img2txt mean

txt2img

(r1/r5/r10)

txt2img mean

CLIP Fine-tune

91.0/99.0/99.7

95.57

76.38/94.06/97.28

89.24

CLIP Zero-shot

85.3/97.40/99.2

94.0

65.02/87.2/92.0

81.41


我们也在中文数据集上进行了预训练,并且评测了模型在COCO-CN和Fllickr30k-CN数据集上的效果。模型的设置与WukongViT对齐(详见参考文献),进行了复现,结果如下所示:


数据集

模型

img2txt mean

txt2img mean

COCO-CN

WukongViT

96.4

89.8

CLIP

96.1

88.4

Fllickr30k-CN

WukongViT

85.9

87.8

CLIP

86.0

86.1


由上述结果可见,EasyNLP框架训练的CLIP模型在下游任务的Finetune结果与WukongViT基本对齐。结果少量差异性的原因在于:1. MindSpore与PyTorch的内部实现差异性(WukongViT作者采用MindSpore实现)以及2. 超参数和随机种子的选择。

为了方便用户的使用,EasyNLP进一步提供了AppZoo层面的接口,使得用户可以在不实现任何代码的情况下调用CLIP模型,这一部分内容在下一节介绍。


CLIP模型使用教程

以下简要介绍在EasyNLP框架使用CLIP模型。由于用户数据一般于CLIP预训练数据在分布上存在差距。我们提供CLIP模型的训练和向量提取功能


安装EasyNLP

用户可以直接参考链接的说明安装EasyNLP算法框架。


数据准备

首先准备训练数据与验证数据,为tsv文件。这一文件包含以制表符\t分隔的两列,第一列为文本,第二列为图片的base64编码。用于提取向量接入向量检索系统的输入文件为单列,仅包含文本或图片的base64编码。

为了方便开发者,我们也提供了转换图片到base64编码的示例代码:

import base64
from io import BytesIO
from PIL import Image
img = Image.open(fn)
img_buffer = BytesIO()
img.save(img_buffer, format=img.format)
byte_data = img_buffer.getvalue()
base64_str = base64.b64encode(byte_data) # bytes

下列文件已经完成预处理,可用于测试:

# train
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/CLIP/MUGE_MR_train_base64_part.tsv
# valid
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/CLIP/MUGE_MR_valid_base64_part.tsv
# text
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/CLIP/MUGE_MR_test_base64_part_text.tsv
# image
https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/tutorials/CLIP/MUGE_MR_test_base64_part_image.tsv

模型训练和评测

我们采用以下命令对CLIP模型进行fine-tune:

easynlp \
  --mode train \
  --worker_gpu=1 \
  --tables=./MUGE_MR_train_base64_part.tsv,./MUGE_MR_valid_base64_part.tsv \
  --input_schema=text:str:1,image:str:1 \
  --first_sequence=text \
  --second_sequence=image \
  --checkpoint_dir=./clip_model/ \
  --learning_rate=1e-4  \
  --epoch_num=1  \
  --random_seed=42 \
  --logging_steps=100 \
  --save_checkpoint_steps 200 \
  --sequence_length=32 \
  --micro_batch_size=32 \
  --app_name=clip \
  --save_all_checkpoints \
  --user_defined_parameters='pretrain_model_name_or_path=clip_chinese_roberta_large_with_vit_large fix_vision=True mode=finetune'  

训练完成后模型被保存到./clip_model/。训练结束后,我们可以对模型进行评估:

easynlp \
  --mode evaluate \
  --worker_gpu=1 \
  --tables=./MUGE_MR_valid_base64_part.tsv \
  --input_schema=text:str:1,image:str:1 \
  --first_sequence=text \
  --second_sequence=image \
  --checkpoint_dir=./clip_model/ \
  --random_seed=42 \
  --logging_steps=100 \
  --save_checkpoint_steps=500 \
  --sequence_length=32 \
  --micro_batch_size=32 \
  --app_name=clip 

文本或图片特征提取

模型训练完毕后,我们可以将其用于文本或图片的特征提取,示例如下:

  1. 提取文本特征
easynlp \
      --mode predict \
      --worker_gpu=1 \
      --tables=./MUGE_MR_test_base64_part_text.tsv \
      --input_schema=text:str:1 \
      --output_schema=text_feat \
      --outputs=./text_feat.tsv \
      --first_sequence=text \
      --checkpoint_dir=./clip_model/ \
      --random_seed=42 \
      --logging_steps=100 \
      --save_checkpoint_steps=500 \
      --sequence_length=32 \
      --micro_batch_size=2 \
      --app_name=clip 
  1. 提取图片特征
easynlp \
      --mode predict \
      --worker_gpu=1 \
      --tables=./MUGE_MR_test_base64_part_image.tsv \
      --input_schema=image:str:1 \
      --output_schema=image_feat \
      --outputs=./image_feat.tsv \
      --first_sequence=image \
      --checkpoint_dir=./clip_model/ \
      --random_seed=42 \
      --logging_steps=100 \
      --save_checkpoint_steps=500 \
      --sequence_length=32 \
      --micro_batch_size=2 \
      --app_name=clip 

提取出的特征存储在一个tsv文件中,每行对应输入中的一个文本或一个图片,维度之间采用制表符\t分隔。


未来展望

在未来,我们计划在EasyNLP框架中公开以PyTorch实现的CLIP模型,覆盖各个常见中文领域,敬请期待。我们也将在EasyNLP框架中集成更多SOTA模型(特别是中文模型),来支持各种NLP和多模态任务。此外,阿里云机器学习PAI团队也在持续推进中文多模态模型的自研工作,欢迎用户持续关注我们,也欢迎加入我们的开源社区,共建中文NLP和多模态算法库!

Github地址:https://github.com/alibaba/EasyNLP


Reference

  1. Alec Radford, Jong Wook Kim, Chris Hallacy, Aditya Ramesh, Gabriel Goh, Sandhini Agarwal Girish Sastry, Amanda Askell, Pamela Mishkin, Jack Clark, Gretchen Krueger. Ilya Sutskever. Learning transferable visual models from natural language supervision. arXiv
  2. Chengyu Wang, Minghui Qiu, Taolin Zhang, Tingting Liu, Lei Li, Jianing Wang, Ming Wang, Jun Huang, Wei Lin. EasyNLP: A Comprehensive and Easy-to-use Toolkit for Natural Language Processing. arXiv
  3. Jiaxi Gu, Xiaojun Meng, Guansong Lu, Lu Hou, Minzhe Niu, Xiaodan Liang, Lewei Yao, Runhui Huang, Wei Zhang, Xin Jiang, Chunjing Xu, Hang Xu. Wukong: 100 Million Large-scale Chinese Cross-modal Pre-training Dataset and A Foundation Framework. arXiv


阿里灵杰回顾

相关实践学习
使用PAI-EAS一键部署ChatGLM及LangChain应用
本场景中主要介绍如何使用模型在线服务(PAI-EAS)部署ChatGLM的AI-Web应用以及启动WebUI进行模型推理,并通过LangChain集成自己的业务数据。
机器学习概览及常见算法
机器学习(Machine Learning, ML)是人工智能的核心,专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能,它是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域。 本课程将带你入门机器学习,掌握机器学习的概念和常用的算法。
相关文章
|
1月前
|
人工智能 自然语言处理 开发工具
通过ModelScope开源Embedding模型将文本转换为向量
本文介绍如何通过ModelScope魔搭社区中的文本向量开源模型将文本转换为向量,并入库至向量检索服务DashVector中进行向量检索。
|
1月前
|
自然语言处理 算法
文本分析-使用jieba库实现TF-IDF算法提取关键词
文本分析-使用jieba库实现TF-IDF算法提取关键词
41 0
|
2月前
|
机器学习/深度学习 人工智能 文字识别
通用场景OCR文本识别任务-baseline学习(PaddleOCR)
通用场景OCR文本识别任务-baseline学习(PaddleOCR)
55 0
|
6月前
|
机器学习/深度学习 算法 数据挖掘
图像嵌入(Image Embedding
机器学习中的图像嵌入(Image Embedding)是一种将图像数据转化为连续的、低维度的向量表示的方法,这些向量表示通常用于后续的机器学习任务,如分类、聚类、检索等。图像嵌入的目的是将高维度的图像数据转化为更易于处理的低维度数据,同时保留尽可能多的原始图像信息。常用的图像嵌入方法包括:
1053 3
|
9月前
|
自然语言处理 算法 Python
|
自然语言处理 安全 数据挖掘
PaddleNLP基于ERNIR3.0文本分类以CAIL2018-SMALL数据集罪名预测任务为例【多标签】
文本分类任务是自然语言处理中最常见的任务,文本分类任务简单来说就是对给定的一个句子或一段文本使用文本分类器进行分类。文本分类任务广泛应用于长短文本分类、情感分析、新闻分类、事件类别分类、政务数据分类、商品信息分类、商品类目预测、文章分类、论文类别分类、专利分类、案件描述分类、罪名分类、意图分类、论文专利分类、邮件自动标签、评论正负识别、药物反应分类、对话分类、税种识别、来电信息自动分类、投诉分类、广告检测、敏感违法内容检测、内容安全检测、舆情分析、话题标记等各类日常或专业领域中。 文本分类任务可以根据标签类型分为**多分类(multi class)、多标签(multi label)、层次分类
PaddleNLP基于ERNIR3.0文本分类以CAIL2018-SMALL数据集罪名预测任务为例【多标签】
|
10月前
|
机器学习/深度学习 编解码 自然语言处理
7 Papers & Radios | 推理速度比Stable Diffusion快2倍;视觉Transformer统一图像文本
7 Papers & Radios | 推理速度比Stable Diffusion快2倍;视觉Transformer统一图像文本
|
缓存 自然语言处理 Shell
【DSW Gallery】基于CK-BERT的中文序列标注
EasyNLP提供多种模型的训练及预测功能,旨在帮助自然语言开发者方便快捷地构建模型并应用于生产。本文以序列标注(命名实体识别)为例,为您介绍如何在PAI-DSW中使用EasyNLP。
【DSW Gallery】基于CK-BERT的中文序列标注
|
算法 PyTorch 算法框架/工具
【DSW Gallery】基于EasyCV的STDC图像语义分割示例
EasyCV是基于Pytorch,以自监督学习和Transformer技术为核心的 all-in-one 视觉算法建模工具,并包含图像分类,度量学习,目标检测,姿态识别等视觉任务的SOTA算法。本文将为您介绍如何在PAI-DSW中使用EasyCV训练轻量化语义分割模型STDC
【DSW Gallery】基于EasyCV的STDC图像语义分割示例
|
存储 机器学习/深度学习 自然语言处理
使用CLIP构建视频搜索引擎
CLIP(Contrastive Language-Image Pre-training)是一种机器学习技术,它可以准确理解和分类图像和自然语言文本,这对图像和语言处理具有深远的影响,并且已经被用作流行的扩散模型DALL-E的底层机制。在这篇文章中,我们将介绍如何调整CLIP来辅助视频搜索。
421 0

相关产品

  • 人工智能平台 PAI