美文网首页
多模态模型补充-CLIP

多模态模型补充-CLIP

作者: 第一个读书笔记 | 来源:发表于2021-06-23 11:50 被阅读0次

    CLIP [OpenAI 21.01]

    Learning Transferable Visual Models From Natural Language Supervision

    https://arxiv.org/pdf/2103.00020.pdf
    https://github.com/openai/CLIP

    本来打算放在多模态模型汇总-按需更新里面的,发现CLIP内容比较多,实验很丰富,解读很详细,还是单独介绍一下。

    以下都是直觉翻译和认知加工,如有问题,欢迎指正。
    花了好几天,仍然没读完...

    私以为本文的几个亮点:

    1. 双流模型,单独提取图片和文本feature;
    2. 对比学习;
    3. 将分类模型转换成图文匹配任务,用文本来弱监督图片分类。

    背景

    一般的目标检测,图片分类等CV任务,都会预设有哪些类别,要识别哪些种类。实际图片信息是很丰富的,除了这些预设的类别,其他的视觉信息没有被充分利用,如果还要识别图上其他类别,就需要再加标签。

    如果图片有文本描述,通过文本监督学习更多的图片信息不失为一个好方法。

    1. Mori et al. (1999) 训练图文对,预测文本中的nouns和adjectives,探索基于图片检索的方式改进内容;
    2. Quattoni et al. (2007) 训练图文对,预测文本描述,来学习分类权重空间,学习更多视觉表达;
    3. Srivastava & Salakhutdinov (2012) 训练多模态Deep Boltzmann Machines,数据为top of low-level image和对应文本tag特征,学习深层表达;
    4. Joulin et al. (2016) 用CNN训练图文对,预测文本表述,来学习图片表达;
    5. 还有些将标题,描述和hashtag等元数据,和图片一起训练,预测这些元数据的模型;Li et al.(2017)扩展了这个方法,除了预测individual words,还会预测n-grams,并显示这种系统在zero-shot transfer到其他分类数据集上的能力,即基于这些数据集的dictionary学习视觉n-grams,预测目标类别能拿到最高分;
    6. VirTex, ICMLML等模型展现了transformer模型在语言模型,masked语言模型,对比学习中的潜力。

    虽然1~6展示了多模态(图文)学习在学习模态表征上的能力,目前通过自然语言监督学习视觉表达的研究还是比较少。

    1. 这种方式得到的模型结果不是最佳,比如 Li et al. (2017) 通过zero-shot方式,在ImageNet数据集上,只得到11.5%的准确率,但SOTA是88.4%;
    2. 文本数据是无限的,但是视觉数据的标签是有限的,打标签很费人力。

    本文提出CLIP,Contrastive Language–Image Pre-training,用4亿对来自网络的图文数据集,将文本作为图像标签,进行训练。进行下游任务时,只需要提供和图上的concepts对应的文本描述,就可以进行zero-shot transfer。
    模型在30个CV数据集上做了实验,实验任务包括OCR, action recognition in videos, geo-localization, and many types of fine-grained object classification。模型在大部分的任务上都达到最佳。而且,一般不用再做specific training,就可以和其他baseline 模型媲美。

    Model

    数据:4亿个网络公开的图文对。为覆盖到更多的视觉concepts, 用了50w个query在搜索引擎搜索图片,一个query差不多有2w张图片。
    输入:一个batch有N个图像文本对;

    CLIP 模型框架

    模型:对比学习,预测N\times N对图文数据,将图片分类任务转换成图文匹配任务:

    1. 双流,2个encoder分别处理文本和图片数据,text encoder使用Transformer,image encoder用了2种模型,ResNetVision Transformer(ViT)
      a. 5种ResNet:ResNet-50, ResNet-101, EfficientNet-style的ResNet,包括RN50x4, RN50x16, RN50x64;
      b. 3种ViT:ViT-B/32, ViT-B/16, ViT-L/14;
    2. encoder representation直接线性投影到multi-modal embedding space;
    3. 计算2模态之间的cosine similarity,让N个匹配的图文对相似度最大,不匹配的图文对相似度最小;
    4. 对称的cross-entropy loss;
    5. 数据增强:对resized图片进行random square crop。

    伪代码如下:

    CLIP 伪代码

    实验

    1. Zero-shot Transfer

    图片分类的zero-shot指的是对未知类别进行推理。
    本文的zero-shot指的是对未知任务进行推理,通过zero-shot transfer衡量任务学习的能力。
    Visual N-Grams (Li et al., 2017) 是第一个将zero-shot transfer应用到图片分类任务上的模型。模型用于学习长度为1~5grams的共142806个visual n-grams,对输入的图片,最大化对应的n-grams的probability。

    同样的,CLIP在进行zero-shot transfer时,将数据集中的类别标签转换为文字描述,主要步骤如下:

    1. 输入:一张图片 + 所有类别转换的文本(100个类别就是100个文本描述);
    2. 转换向量:经过2个encoder,分别输出image和text的feature embedding;
    3. 计算cosine similarity;
    4. 预测类别:multinomial logistic regression classifier。

    模型结果:以下3个数据集,CLIP的表现都要高于Visual N-Grams。

    CLIP vs Visual N-Grams

    PROMPT ENGINEERING AND ENSEMBLING
    有些CV分类数据集,类别用ID表示,有的有映射的文本描述。像Flower102和GTSRB数据集,缺乏映射关系,导致有些数据不能进行zero-shot transfer;

    同义词也会困扰模型:如果文本输入只是一个类别,因为缺乏上下文,text encoder就不能很好的区分词义。比如Oxford-IIIT Pet 数据集中的boxer指代一种狗,但因为缺乏上下文信息,CLIP的text encoder学习的不够充分,以至于将boxer识别成一种运动。

    CLIP的训练数据集中,很少出现一张图片对应一个单词的现象。一般来说,都是用一句话来形容图片。为了减少训练集和其他任务数据集的gap,使用prompt template

    Prompt template: “A photo of a {label}.”
    比如,类别为狗,则输入文本为“A photo of a dog.”。
    通过这种方式,模型在ImageNet上,提高了1.3%的准确率。

    如果提供更细粒度的类别信息(可以理解为文本描述中加属性/类别标签),比如上文的“A photo of a {label}.”,细化到“A photo of a {label}, a type of pet.”或者‘A photo of a big {label}”。按照这种方式,在ImageNet数据集上,构建了80种不同形式的prompt template,准确率又提高了3.5%。

    ANALYSIS OF ZERO-SHOT CLIP PERFORMANCE

    1. zero-shot classifier表现怎么样?
      参照模型Linear Probe on ResNet50:ResNet-50 + logistic regression。
      下图显示了,在27个数据集中,CLIP在16个数据上表现更好。


      zero-shot CLIP vs. Linear Probe on ResNet50
    2. zero-shot CLIP怎么做prediction?
      zero-shot prediction
      基于输入的图片,在类别描述中检索,找到最合适的类别。

    "Ref:https://github.com/openai/CLIP"
    import os
    import clip
    import torch
    from torchvision.datasets import CIFAR100
    
    # Load the model
    device = "cuda" if torch.cuda.is_available() else "cpu"
    model, preprocess = clip.load('ViT-B/32', device)
    
    # Download the dataset
    cifar100 = CIFAR100(root=os.path.expanduser("~/.cache"), download=True, train=False)
    
    # Prepare the inputs
    image, class_id = cifar100[3637]
    image_input = preprocess(image).unsqueeze(0).to(device)
    text_inputs = torch.cat([clip.tokenize(f"a photo of a {c}") for c in cifar100.classes]).to(device)
    #cifar每个类别,输入图片,检索匹配的类别
    
    # Calculate features
    with torch.no_grad():
        image_features = model.encode_image(image_input)
        text_features = model.encode_text(text_inputs)
    
    # Pick the top 5 most similar labels for the image
    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(5)
    
    # Print the result
    print("\nTop predictions:\n")
    for value, index in zip(values, indices):
        print(f"{cifar100.classes[index]:>16s}: {100 * value.item():.2f}%")
    
    """
    Top predictions:
               snake: 65.31%
              turtle: 12.29%
        sweet_pepper: 3.83%
              lizard: 1.88%
           crocodile: 1.75%
    """
    

    Linear-probe evaluation
    通过CLIP的image_encoder得到视觉向量,结合标签做Logistic Regression。

    "Ref:https://github.com/openai/CLIP"
    import os
    import clip
    import torch
    
    import numpy as np
    from sklearn.linear_model import LogisticRegression
    from torch.utils.data import DataLoader
    from torchvision.datasets import CIFAR100
    from tqdm import tqdm
    
    # Load the model
    device = "cuda" if torch.cuda.is_available() else "cpu"
    model, preprocess = clip.load('ViT-B/32', device)
    
    # Load the dataset
    root = os.path.expanduser("~/.cache")
    train = CIFAR100(root, download=True, train=True, transform=preprocess)
    test = CIFAR100(root, download=True, train=False, transform=preprocess)
    
    def get_features(dataset):
        all_features = []
        all_labels = []
        
        with torch.no_grad():
            for images, labels in tqdm(DataLoader(dataset, batch_size=100)):
                features = model.encode_image(images.to(device))
    
                all_features.append(features)
                all_labels.append(labels)
    
        return torch.cat(all_features).cpu().numpy(), torch.cat(all_labels).cpu().numpy()
    
    # Calculate the image features
    train_features, train_labels = get_features(train)
    test_features, test_labels = get_features(test)
    
    # Perform logistic regression
    classifier = LogisticRegression(random_state=0, C=0.316, max_iter=1000, verbose=1) # c自定义
    classifier.fit(train_features, train_labels)
    
    # Evaluate using the logistic regression classifier
    predictions = classifier.predict(test_features)
    accuracy = np.mean((test_labels == predictions).astype(np.float)) * 100.
    print(f"Accuracy = {accuracy:.3f}")
    

    2. Data Overlap Analysis

    预训练的数据集是否和下游数据集有重叠?如果有重叠,就会导致数据泄露,下游实验的结果就不可信。本文作者分析了训练集和下游任务的重叠程度,以及这种重叠对模型效果的影响。

    1. 对每个evaluation的数据集,做一个duplicate detector。对和训练集相似度高的数据进行人工审核,并确定一个threshold,保证高精度的同时最大化召回。通过这个threshold,将数据集ALL(evaluation的数据集)分解成2个子集:
      a. Overlap:和训练集的相似度高于threshold的数据;
      b. Clean:相似度低于threshold的数据。
    2. 计算CLIP zero-shot在ALL,Overlap和Clean这三种数据集上的准确率,ALL-Clean的准确率差距作为衡量标准;
    3. 因为overlap的程度比较轻,因此进行binomial significance test,使用Clean的准确率作为null hypothesis,计算Overlap的p-value。

    作者在35个数据集上做了分析,其中,有9个数据集和训练集没有数据重叠。像e MNIST, CLEVR和GTSRB这类偏synthetic或者specialized的数据,往往不会被视为正常的图片,和训练集基本没有重叠。
    重叠率最高的是Country211,重叠率达21.5%,它是从YFCC100M数据集剥离出来的,虽然重叠程度很高,但这种重叠率只带来0.2%的准确率的提升。也许是因为Country211主要是为了衡量geo-localization的ability,但在训练集中,文本描述并没有提及到image的location。

    Overlap分析

    虽然但是,作者也提到是不是duplicate detector做的不够好。

    1. detector选择threshold时,考虑保精度同时要求有高召回,但也没有办法去检查完召回到的400million的样本;
    2. Overlap和Clean数据集分布可能发生很大变化,比如Kinetics-700数据集,重叠的数据集都是black transition frames,所以上图左,Detected Data Overlap,Kinetics-700的准确率,相比Clean,降低了20%。

    Limitation

    1. 不是和SOTA的比较:以上的数据分析,都是和a linear classifier on top of ResNet-50 features进行比较,大部分的数据集,都有对应的SOTA模型。为了达到SOTA,zero-shot CLIP估计要提高1000x的算力,当前情况不支持;
    2. 在部分fine-grained分类上表现不佳:
      a. 前面实验分析发现,模型不能很好的区分cars,species of flowers, 以及variants of aircraft;
      b. abstract和systematic任务表现不好,比如统计图上object的数量;
      c. 在训练集中基本不会出现的比较novel的任务,表现欠佳,比如classifying
      the distance to the nearest car in a photo;
    3. 训练集中没有出现的图片类型(out-of-distribution),表现不好,比如OCR识别数字效果可以,但是MNIST的准确率只有88%;
      ...

    相关文章

      网友评论

          本文标题:多模态模型补充-CLIP

          本文链接:https://www.haomeiwen.com/subject/vrayyltx.html