Openai连接文本和图像CLIP模型(Huggingface版)zero-shot分类代码案例
注:大家觉得博客好的话,别忘了点赞收藏呀,本人每周都会更新关于人工智能和大数据相关的内容,内容多为原创,Python Java Scala SQL 代码,CV NLP 推荐系统等,Spark Flink Kafka Hbase Hive Flume等等~写的都是纯干货,各种顶会的论文解读,一起进步。 今天和大家分享一篇关于Opinai神作CLIP模型 #博学谷IT学习技术支持#
前言
2021年见证了vision transformer的大爆发,随着谷歌提出ViT之后,一大批的vision transformer的工作席卷计算机视觉任务。除了vision transformer,另外一个对计算机视觉影响比较大的工作就是Open AI在2021年1月份发布的DALL-E和CLIP,这两个都属于结合图像和文本的多模态模型,其中DALL-E是基于文本来生成模型的模型,而CLIP是用文本作为监督信号来训练可迁移的视觉模型,这两个工作也像ViT一样带动了一波新的研究高潮。这篇文章将首先介绍CLIP的原理以及如何用CLIP实现zero-shot分类,然后我们将讨论CLIP背后的动机,最后文章会介绍CLIP的变种和其它的一些应用场景。
一、CLIP是什么?
CLIP的英文全称是Contrastive Language-Image Pre-training,即一种基于对比文本-图像对的预训练方法或者模型。CLIP是一种基于对比学习的多模态模型,与CV中的一些对比学习方法如moco和simclr不同的是,CLIP的训练数据是文本-图像对:一张图像和它对应的文本描述,这里希望通过对比学习,模型能够学习到文本-图像对的匹配关系。如下图所示,CLIP包括两个模型:Text Encoder和Image Encoder,其中Text Encoder用来提取文本的特征,可以采用NLP中常用的text transformer模型;而Image Encoder用来提取图像的特征,可以采用常用CNN模型或者vision transformer。作者看到一般使用vit较多,可能因为vit效果比CNN更好。 这里对提取的文本特征和图像特征进行对比学习。对于一个包含N个文本-图像对的训练batch,将N个文本特征和N个图像特征两两组合,CLIP模型会预测出N方个可能的文本-图像对的相似度,这里的相似度直接计算文本特征和图像特征的余弦相似性(cosine similarity),即上图所示的矩阵。这里共有N个正样本,即真正属于一对的文本和图像(矩阵中的对角线元素),而剩余的N方-N个文本-图像对为负样本,那么CLIP的训练目标就是最大N个正样本的相似度,同时最小化N方-N个负样本的相似度。 为了训练CLIP,OpenAI从互联网收集了共4个亿的文本-图像对。
二、如何用CLIP实现zero-shot分类
上面我们介绍了CLIP的原理,可以看到训练后的CLIP其实是两个模型,除了视觉模型外还有一个文本模型,那么如何对预训练好的视觉模型进行迁移呢?与CV中常用的先预训练然后微调不同,CLIP可以直接实现zero-shot的图像分类,即不需要任何训练数据,就能在某个具体下游任务上实现分类,这也是CLIP亮点和强大之处。用CLIP实现zero-shot分类很简单,只需要简单的两步:
根据任务的分类标签构建每个类别的描述文本:A photo of {label},然后将这些文本送入Text Encoder得到对应的文本特征,如果类别数目为[公式],那么将得到[公式]个文本特征; 将要预测的图像送入Image Encoder得到图像特征,然后与[公式]个文本特征计算缩放的余弦相似度(和训练过程一致),然后选择相似度最大的文本对应的类别作为图像分类预测结果,进一步地,可以将这些相似度看成logits,送入softmax后可以到每个类别的预测概率。
代码如下(示例):
from PIL import Image
from transformers import CLIPProcessor,CLIPModel
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
#这里加入自己图片的地址就行
image = Image.open('xxx.jpg')
#这里加入类别的标签类别
text = ['plane','car','dog','bird']
inputs = processor(text=text,images = image,return_tensors="pt",padding=True)
outputs = model(**inputs)
logits_per_image = outputs.logits_per_image
probs = logits_per_image.softmax(dim=1)
for i in range(len(text)):
print(text[i],":",probs[0][i])
可以看到结果还是相当不错的
使用CLIP进行zero-shot分类,另外一个比较重要的地方是文本描述的生成,上面的例子我们采用分类标签,但其实也有其它选择,比如我们直接用类别标签,这其实属于最近NLP领域比较火的一个研究:prompt learning或者prompt engineering,具体可以见我之前写过的一篇关于prompt learning的文章 https://blog.csdn.net/weixin_53280379/article/details/125113370?spm=1001.2014.3001.5502
三、其他CLIP的运用
1.视频理解 CLIP是基于文本-图像对来做的,但是它可以扩展到文本-视频,比如VideoCLIP就是将CLIP应用在视频领域来实现一些zero-shot视频理解任务。 2.图像生成 VQGAN+CLIP实现各种图像生成模型。特别好玩,和dall-e差不多效果。 等等其实还有好多,分割,检测其实能做的很多,也有很多非常好的论文。
总结
主要和大家分享一下Openai大热的连接文本和图像CLIP模型(Huggingface版)zero-shot分类代码案例,其实还是可以看到一些GPT的影子,模型本身比较简单,没什么难度,就是大力出奇迹的感觉,4亿个训练数据加上500GPU YEAR。或许是将来的趋势吧。可以运用到更多的下游任务。
|