简介: 本文简要介绍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-c...

valid

https://atp-modelzoo-sh.oss-c...

text

https://atp-modelzoo-sh.oss-c...

image

https://atp-modelzoo-sh.oss-c...
模型训练和评测
咱们采纳以下命令对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
文本或图片特征提取
模型训练结束后,咱们能够将其用于文本或图片的特征提取,示例如下:

提取文本特色
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 

提取图片特色
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/Ea...

Reference
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
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
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开源中文NLP算法框架EasyNLP,助力NLP大模型落地
阿里灵杰:预训练常识度量较量夺冠!阿里云PAI公布常识预训练工具
原文链接:http://click.aliyun.com/m/100...

本文为阿里云原创内容,未经容许不得转载。