论文:Chinese CLIP: Contrastive Vision-Language Pretraining in Chinese
代码:https://github.com/OFA-Sys/Chinese-CLIP
出处:阿里达摩院
时间:2022.11
贡献:
CLIP 的成功极大地促进了对比学习在视觉-语言模型预训练上的研究和应用
不同于传统生成式预训练,CLIP 是一种基于对比学习的模型,在从网络上收集的约 4 亿个 image-text pair 上进行预训练,而且有很好的 zero-shot 迁移能力
由于 CLIP 能够在视觉和文本之间建立联系,所有页改变了多模态表达学习和计算机视觉的相关研究
在 CLIP 之后有很多的工作,如 DALL-E,StyleCLIP,SLIP,CLIP4Clip 等
尽管如此,但在中国还没有一个专为中文多模态学习设计的模型
所以,本文中提出了 Chinese CLIP (CN-CLIP),模型在大量的中文文本-图像对儿上进行了预训练
数据:
模型大小:
训练方式:
测试数据集:
首先介绍一下 CLIP 的训练方法:
CLIP 的扩展:
CLIP 成功的另外一个原因在于预训练使用的超大尺度的训练集
由在 CLIP 上进行的实验可知,通过增大数据量、增长训练周期都可以提供模型在 zero-shot 学习任务上的效果
训练数据集:
最简单的训练方法是从头开始训练,就是会受到训练数据的数量和质量的限制
为了利用现有的预训练模型优势:
如何基于开源模型来预训练:
Chinese CLIP 如何进行预训练:两阶段预训练方法,如图 1 所示
有 5 种不同的模型尺寸,从 77 ~ 958 million 参数量,无特殊说明情况下预训练图像大小为 224x224
数据集:
评价指标:
官方 github 中给了一段推理代码:
import torch
from PIL import Image
import cn_clip.clip as clip
from cn_clip.clip import load_from_name, available_models
print("Available models:", available_models())
# Available models: ['ViT-B-16', 'ViT-L-14', 'ViT-L-14-336', 'ViT-H-14', 'RN50']
device = "cuda" if torch.cuda.is_available() else "cpu"
# model 选择和 预处理
# 预处理:resize to (224,224), convert to rgb, normalize (mean, std)
model, preprocess = load_from_name("ViT-B-16", device=device, download_root='./')
model.eval()
image = preprocess(Image.open("examples/pokemon.jpeg")).unsqueeze(0).to(device)
# image 是经过预处理后的图,大小为 [1, 3, 224, 224]
text = clip.tokenize(["杰尼龟", "妙蛙种子", "小火龙", "皮卡丘"]).to(device)
# clip.tokenize 是对类别 list 进行 token 处理,这里有 4 个类别,得到的就是 [4, 52] 的向量表示
with torch.no_grad():
logits_per_image, logits_per_text = model.get_similarity(image, text)
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
print("Label probs:", probs) # [[1.268734e-03 5.436878e-02 6.795761e-04 9.436829e-01]]
这里面涉及到了相似度提取:model.get_similarity
,位于 model.py
中
def get_similarity(self, image, text):
image_features = self.encode_image(image) # Vision Transformer, image_features.shape=[1, 512]
text_features = self.encode_text(text) # BERT, image_features.shape=[4, 512]
# normalized features
image_features = image_features / image_features.norm(dim=1, keepdim=True)
text_features = text_features / text_features.norm(dim=1, keepdim=True)
# cosine similarity as logits
logit_scale = self.logit_scale.exp()
logits_per_image = logit_scale * image_features @ text_features.t() # [1, 4] tensor
logits_per_text = logits_per_image.t() # [4, 1] tensor
# shape = [global_batch_size, global_batch_size]
# logits_per_image: 每个类别对应的概率
return logits_per_image, logits_per_text