赞
踩
时隔许久,又开始写学习笔记了,计算机视觉发展日新月异,一段时间不学习就发现落下好多。言归正传,未来一个月打算研究一下多模态和大模型方向,以此来记录一下学习心得,仅供自己学习使用。(会有复制粘贴别的大佬发表的文章用来学习,若有侵权请联系)
paper:arxiv.org/pdf/2103.00020.pdf
blog:https://openai.com/research/clip
code:https://github.com/openai/CLIP
CLIP(Contrastive Language-Image Pre-training)是一种基于对比学习的多模态模型,它的训练数据是 文本-图像对(例如:这是一只狗+狗图)。通过对比学习,让模型学到文本-图像的对应关系。
为了训练CLIP,OpenAI从互联网收集了共4个亿的文本-图像对,论文称之为WebImageText。训练完成的CLIP模型可以直接迁移到自己的任何数据集上,完全不需要图像标签微调即可实现zero-shot分类。
CLIP包括两个模型:Text Encoder和Image Encoder,其中Text Encoder用来提取文本的特征,可以采用NLP中常用的text transformer模型;而Image Encoder用来提取图像的特征,可以采用常用CNN模型或者vision transformer。
对比学习非常灵活,只需要正样本和负样本的定义。其中,配对的图片-文本对就是正样本(斜对角线),其他为负样本。具体获得如下所示:
通过提取的文本特征和图像特征进行对比学习。对于一个包含N个文本-图像对的训练batch,将N个文本特征和N个图像特征两两组合,CLIP模型会预测出个可能的文本-图像对的相似度,这里的相似度直接计算文本特征和图像特征的余弦相似性(cosine similarity),即上图所示的矩阵。这里共有N个正样本,即真正属于一对的文本和图像(矩阵中的对角线元素),而剩余的−N个文本-图像对为负样本。
然后,模型就可以通过对比学习的方式进行训练,CLIP的训练目标就是最大N个正样本的相似度,同时最小化−N个负样本的相似度。
上文介绍了CLIP的训练,那么如何对训练好的模型进行迁移呢?与CV中常用的先预训练然后在自己的数据集上微调不同,CLIP可以直接实现zero-shot的图像分类,即不需要对自己的数据集在进行任何训练,就能在某个具体下游任务上实现分类,这也是CLIP亮点和强大之处。具体操作如下:
由于CLIP经过训练后只能得到图像和文本的特征,没有分类头,没有分类头如何推理呢?作者通过自然语言的方法prompt tenplate为具体的任务构建了动态的分类器。如上图所示,根据新任务的分类标签构建每个类别的描述文本:A photo of {label}
,然后将这些文本送入Text Encoder得到对应的文本特征,如果类别数目为N,那么将得到N个文本特征;将要预测的图像送入Image Encoder得到图像特征,然后与N个文本特征计算缩放的余弦相似度(和训练过程一致),然后选择相似度最大的文本对应的类别作为图像分类预测结果,进一步地,可以将这些相似度看成logits,送入softmax后可以到每个类别的预测概率。
为什么要为分类标签构建每个类别的描述文本:A photo of {label}?
因为CLIP在预训练的时候文本就是句子,如果迁移学习给的是词语会影响精度。
StyleCLIP:通过语言描述可以对图片作出修改
CLIPDraw:语言指导图像生成
目标检测:vild\glip v1\glip v2
物体分割:Lseg\groupvit
视频检索:基于文本搜索图像 video clip\anction clip\clip4clip
Lseg框架图(loss计算还是依赖手工标注标签,并不是依靠对比文本,监督信号还是mask)
groupvit框架图(监督信号是文本)
下载代码根据readme配置环境
创建一个简的demo,实现zero-shot:
- device = "cuda" if torch.cuda.is_available() else "cpu"
- model, preprocess = clip.load("ViT-B/32", device=device)
-
- image = preprocess(Image.open("3.jpg")).unsqueeze(0).to(device)
- text = clip.tokenize(["An Audi car", "A Mercedes car"]).to(device)
-
- with torch.no_grad():
- image_features = model.encode_image(image)
- text_features = model.encode_text(text)
-
- logits_per_image, logits_per_text = model(image, text)
- probs = logits_per_image.softmax(dim=-1).cpu().numpy()
-
- print("Label probs:", probs)
- print("An Audi car") if probs[0][0] > probs[0][1] else print("A Mercedes car")
输出结果:
官方代码解读见此链接:AI多模态基础架构:CLIP—文本图像迁移模型的新高度 - 知乎 (zhihu.com)
AI多模态基础架构:CLIP—文本图像迁移模型的新高度 - 知乎 (zhihu.com)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。