Learning Transferable Visual Models From Natural Language Supervision
训练阶段
模型架构分为两部分,图像编码器和文本编码器,图像编码器可以是比如 resnet50,然后文本编码器可以是 transformer。
训练数据是网络社交媒体上搜集的图像文本对。在训练阶段,对于一个batch 的数据,首先通过文本编码器和图像编码器,得到文本和图像的特征,接着将所有的文本和图像特征分别计算内积,就能得到一个矩阵,然后从图像的角度看,行方向就是一个分类器,从文本角度看,列方向也是一个分类器。最终,我们得到了一个batch中的文本和图像的匹配关系。
目标函数
最大化同一对图像和文本特征的内积,也就是矩阵对角线上的元素,而最小化与不相关特征的内积,即最小化非对角线上的元素。
测试阶段
在测试阶段,直接将训练好的CLIP用于其他数据集而不需要finetune。和训练阶段类似,首先将需要分类的图像经过编码器得到特征,然后对于目标任务数据集的每一个标签,或者你自己定义的标签,都构造一段对应的文本,如上图中的 dog 会改造成 “A photo of a dog”,以此类推。
然后经过编码器得到文本和图像特征,接着将文本特征与图像特征做内积,内积最大对应的标签就是图像的分类结果。这就完成了目标任务上的 zero-shot 分类。
测试例子:识别杯子的二分类任务
import os
import clip
import torch
from torchvision.datasets import CIFAR100
from PIL import Image
#这是放图片的路径
img_pah = 'C:\\Users\\31\\Desktop\\cup1.jpeg'
#这是对于图片的描述
classes = ['man', 'woman']
#加载模型
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load('ViT-B/32', device)
#准备输入集
image = Image.open(img_pah)
image_input = preprocess(image).unsqueeze(0).to(device)
text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in classes]).to(device) #生成文字描述
#特征编码
with torch.no_grad():
image_features = model.encode_image(image_input)
text_features = model.encode_text(text_inputs)
#选取参数最高的标签
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1) #对图像描述和图像特征
values, indices = similarity[0].topk(1)
#输出结果
print("\nTop predictions:\n")
print('classes:{} score:{:.2f}'.format(classes[indices.item()], values.item()))
CLIP不是真正意义上的zero-shot?
在400M个文本图像配对的训练中,模型肯定看到了大量打着相关文本标签的图像,而且图像的应用范围比ImageNet要广得多——这也是为什么方法能够在一些高级场景(如clipart)轻松超越ImageNet预训练模型。(源自CLIP模型的使用和训练-利用CLIP实现zero-shot的分类任务_clip训练-CSDN博客)
换句话说:由于局部大量带标签的数据(图片和文本),模型其实通过训练通过有监督的手段其实已经掌握了识别大部分类别的能力。比如说上面的代码例子,他能够识别这张图片是不是杯子,而我不用提供任何带标签的例子给它,主要还是因为模型在训练的时候那400M的数据里面带了有标签的杯子数据,所以才说这不是真正意义上的zero-shot
又一个回答:
学术界认为只要不能测试集的数据刻意去进行训练就认为是零样本学习,即使训练集庞大的语料库可能包含与测试集类似的数据。
这也是为什么说现在很多模型的这个零样本能力你看着很强,这其实可能有一个很大原因,就是因为模型足够大,见过的数据足够多,它就背的东西就越多,它背的东西越多,它是有可能正好就撞到你这个测试集上去了。确实是有这样的一个情况,但是我会觉得其实这种情况没有那么多,你不能觉得这些都是模型碰巧背出来的深度学习模型的。这个泛化能力还是比较强的。..像他们这么高的指标,其实就算再换一些数据集,你就算比如说造一些在互联网上从未有过的一些图片,它其实依然还是可以泛化的不错的。
多模太与交叉注意力应用
对同一特征点1从不同角度去拍,在我们拿到这些不同视觉的特征后,就可以知道如何从第一个位置到第二个位置,再到第三个位置
参考资料
文章论文
https://arxiv.org/pdf/2103.00020.pdf