关于机器学习:EasyNLP带你玩转CLIP图文检索

51次阅读

共计 6900 个字符,预计需要花费 18 分钟才能阅读完成。

导读

随着自媒体的一直倒退,多种模态数据例如图像、文本、语音、视频等一直增长,发明了互联网上丰富多彩的世界。为了精确建模用户的多模态内容,跨模态检索是跨模态了解的重要工作,采纳一种模态的数据作为数据,检索另一种模态的数据。其中,图文检索是跨模态检索的一种支流工作,广泛应用于各种网络应用中,其难点在于跨模态的示意鸿沟(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 对齐(详见参考文献),进行了复现,后果如下所示:

由上述后果可见,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 
  2. 提取图片特色

    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

  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 开源中文 NLP 算法框架 EasyNLP,助力 NLP 大模型落地
    • 阿里灵杰:预训练常识度量较量夺冠!阿里云 PAI 公布常识预训练工具

正文完
 0