clip moco 探究

CLIP

概述

CLIP(Contrastive Language–Image Pretraining)是 OpenAI 提出的一种多模态模型,能够将图像和文本映射到同一个向量空间,从而实现图像和文本的联合理解。CLIP 的核心思想是通过对比学习(Contrastive Learning)来训练模型,使得匹配的图像-文本对的向量相似度尽可能高,而不匹配的图像-文本对的向量相似度尽可能低。

损失函数

CLIP 的损失函数是对比损失(Contrastive Loss),具体实现如下:

图像到文本的对比损失:计算图像特征与文本特征的相似度。

文本到图像的对比损失:计算文本特征与图像特征的相似度。

最终损失是这两部分损失的平均值。

损失函数的数学形式

假设:

图像特征矩阵 I (形状为 B×D ),其中 B 是批量大小, D 是特征维度。 文本特征矩阵 T (形状为B×D)。 温度参数 τ (用于缩放相似度)。

计算相似度矩阵

图像到文本的相似度矩阵 S_{I\Rightarrow T} :

S_{I\Rightarrow T} = \frac{I\cdot T^T}{\tau}

文本到图像的相似度矩阵 S_{T\Rightarrow I} :

S_{T\Rightarrow I} = \frac{T\cdot I^T}{\tau}

计算对比损失

图像到文本的对比损失:

\zeta_{I\Rightarrow T} = -\frac{1}{B}\sum_{i-1}^{B}log\frac{exp(S_{I\Rightarrow T}[i, i])}{\sum_{j-1}^{B}exp(S_{I\Rightarrow T}[j,j])}

文本到图像的对比损失:

\zeta_{T\Rightarrow I} = -\frac{1}{B}\sum_{i-1}^{B}log\frac{exp(S_{T\Rightarrow I}[i, i])}{\sum_{j-1}^{B}exp(S_{T\Rightarrow I}[j,j])}

\zeta = \frac{1}{2}(\zeta_{T \rightarrow I} + \zeta_{I \rightarrow T})

代码实现

import torch
import torch.nn.functional as F

def clip_loss(image_features, text_features, temperature=0.07):
    """
    计算 CLIP 的对比损失。

    参数:
        image_features (torch.Tensor): 图像特征,形状为 (B, D)。
        text_features (torch.Tensor): 文本特征,形状为 (B, D)。
        temperature (float): 温度参数,默认为 0.07。

    返回:
        torch.Tensor: 对比损失。
    """
    # 归一化特征
    image_features = F.normalize(image_features, dim=-1)
    text_features = F.normalize(text_features, dim=-1)

    # 计算相似度矩阵
    logits_per_image = (image_features @ text_features.T) / temperature
    logits_per_text = logits_per_image.T

    # 创建标签(对角线为 1,其余为 0)
    batch_size = image_features.shape[0]
    labels = torch.arange(batch_size, device=image_features.device)

    # 计算图像到文本的对比损失
    loss_image = F.cross_entropy(logits_per_image, labels)
    # 计算文本到图像的对比损失
    loss_text = F.cross_entropy(logits_per_text, labels)

    # 总损失
    loss = (loss_image + loss_text) / 2
    return loss

CLIP能力归因分析

CLIP 能够实现 zero-shot 和 few-shot

归因于它的 预训练方式和特征表示:

(1) 大规模的对比学习(Contrastive Learning)

  • CLIP 通过对比学习,让模型在 文本-图像表示空间 之间建立了 广泛的概念对齐,而不是仅限于少数训练类别。

  • 这样,即使是 未见过的类别,CLIP 也能利用 概念相似性 进行分类。

(2) 语言引导的分类(Text-Guided Classification)

  • 传统分类器需要 固定类别数的分类头,而 CLIP 直接基于 自然语言描述 进行分类,不受固定类别限制。

  • 只要提供新的文本提示(Prompt),CLIP 就能适配新的任务。

(3) 共享的视觉-语言嵌入空间

  • CLIP 将图像和文本投影到 相同的特征空间(同样的dimension),并且在训练过程中学习了 丰富的跨模态表示(语义对齐表示)。

  • 这意味着,即使 没有见过的类别,它也可以利用语言的语义信息进行推理(主要是想象的图很难用图片描述,但是容易用语言描述,但语言已经在clip中和图片进行了对齐)。

能力

实现方式

zero-shot

通过 文本提示(Prompts) 进行推理,不需要微调,计算文本-图像相似度来完成分类。

Few-Shot

通过 少量示例 来调整匹配,快速适应新任务,不需要重新训练整个模型。

Note

  1. S_{I\Rightarrow T} 与S_{T\Rightarrow I}其实是互为转置矩阵的,但是这两个矩阵并是不对称矩阵。

  2. 代码中loss_image 与loss_text value其实是一样的,但是反向传播的梯度是不一样的loss_image 会获得更偏向image encoder的梯度, loss_text 会获得更偏向txt encoder的梯度,所以最终反向传播的loss是这两者求mean,确保image和text中的参数都能被有效更新

  3. 与supervision 的one-hot 标签相比,clip这种距离度量方式的学习本质上是一种soft target的方式,传统的label ,例如"猫", "狗",这种hard target将每个class离散开来(彼此独立)本质上熵值几乎为0,但是text描述的方式无形中增加熵值,用一种更连续的向量来表达,足够soft,例如“一只鼻子黑黑的高冷短毛猫” 与“一只鼻子黑黑的热情土狗”。

  4. 标签足够soft,获取的信息就更多,刻画就越准确

MOCO

概述

        MoCo(Momentum Contrast)是一种基于对比学习(Contrastive Learning)的自监督学习方法,由 Kaiming He 等人于 2019 年提出。它的核心思想是通过构建一个动态的字典(dynamic dictionary)来学习视觉表征,从而在没有标签数据的情况下训练出强大的视觉表征模型。MoCo 的目标是通过对比学习,将同一图像的不同增强视图(positive pairs)映射到相近的向量空间,而将不同图像的视图(negative pairs)映射到远离的向量空间。其中,正样本是通过augmentation变换得到的,负样本是通过构建动态字典得到的。

关键组件

动态字典(Dynamic Dictionary):

  • 字典中存储了大量的负样本(negative samples),用于对比学习。

  • 字典是通过一个动量编码器(Momentum Encoder)动态更新的。

动量更新(Momentum Update):

  • 动量编码器的参数是通过动量更新机制从查询编码器(Query Encoder)中缓慢更新的。

  • 这种方式可以保持字典的一致性(词典内样本表征的一致性),同时避免编码器的快速变化。

Pretext task

采用instance discrimination来作为代理任务,进行对比学习

  • 正样本对(Positive Pair): 由 同一图像的两种不同数据增强(Augmentations) 生成的特征表示。

  • 负样本对(Negative Pair): 由 不同图像 生成的特征表示。即字典队列中的所有embedding 与当前数batch中的每个sample 互为负样本

InfoNCE

假设:

你是一名老师,正在批改学生的作文,你的任务是判断某句话是 "学生自己写的" 还是 "从互联网上随机摘抄的"。

你的目标是:

  • 让你的模型能分辨哪些句子是 真实数据(positive example)。

  • 让你的模型能分辨哪些句子是 噪声数据(negative example)(随机从网络上抓取的句子,但是从网络上抓取的句子可能有各种不同类型的网站上抓取,如果按照分类的话可以非常多的类来源, 但你其实只关注是否是自己写的真的数据,是或者不是两类)。

假设你有 1000 篇文章,你要构造一个分类器 P(real|x) ,即 给定一句话 x,它是“学生原创” 的概率。

如果我们用 Softmax 分类器,需要计算:

P(real|x) = \frac{exp^{f(x)}}{\sum_{i=1}^{N}{exp^{f(x_i)}}}

其中f(x)是句子的logit, N是所有可能的类别数量(比如10000种文章的分布)

如果N 很大,比如有1亿中文章来源,那么就会造成softmax计算归一化分母及其昂贵,甚至不可实现

由此,引申出NCE loss来进行替代softmax。NCE 通过 二分类任务 来替代 Softmax 分类。现在,我们不再去计算 1000 个类别的 Softmax,而是直接让模型学习区分 真实句子 和 噪声句子。

NCE 采用 二元分类(Binary Classification) 方式:

P(y=1|x) = \frac{p_{model}(x)}{p_{model}(x) + kp_{noise}(x)}

P(y=0|x) = \frac{kp_{noise}(x)}{p_{model}(x) + kp_{noise}(x)}

NCE主要用二分类,将类别众多的问题转换为目标类和非目标类两种类别的问题

INFONCE本质上还是一种cross entropy,但是crossentropy内元素代表的是样本pair之间的距离,同时为了避免负类别过多,对与负pair对进行了采样,计算loss的时候采用的是多分类,不是二分类

工作流程

1. 数据增强

        对输入图像进行两次随机增强,生成两个视图 xq​(查询视图)和 xk(键视图)。 

2. 编码器

        查询编码器 fq​ 和动量编码器 fk​ 分别对 xq和xk​ 进行编码,得到特征向量 q=fq(xq)和 k=fk(xk)。

3.动态字典

        字典中存储了大量的负样本(来自之前的批次)。        

        将 k 加入字典,同时移除最旧的样本。

4.对比损失

        计算查询特征 qq 与字典中所有键特征的相似度

        使用 InfoNCE 损失来优化模型。

5. 动量更新

        动量编码器的参数通过动量更新机制从查询编码器中更新。

可以理解为moco 其实是将原来 在一个batch 内做对比loss 扩展到了batch中每个sample 与外部巨大词典中的sample 做对比loss,从而扩大了负类别的长度以及多样性,从而提升了结果

MoCo 的优势分析

(1)负样本数量增加
  • 通过动态字典,MoCo 可以访问大量的负样本,远远超过批次大小。

  • 这使得模型能够更好地学习到数据的全局分布。

(2)负样本多样性提升
  • 字典中的样本来自整个训练过程,覆盖了更多的数据分布。

  • 这提升了负样本的多样性,使得模型能够学习到更鲁棒的特征表示。

(3)计算效率高
  • 尽管字典的大小很大,但 MoCo 通过动量编码器和高效的对比损失计算,保持了较高的计算效率。

(4)结果提升

  • 通过增加负样本的数量和多样性,MoCo 在多个视觉任务(如图像分类、目标检测、语义分割等)上取得了显著的性能提升。

特性

MoCo (Momentum Contrast)

SimCLR (Simple Framework for Contrastive Learning)

Memory Bank

核心思想

通过动态字典(Dynamic Dictionary)和动量编码器(Momentum Encoder)扩展负样本的数量和多样性。

在单个批次内进行对比学习,使用数据增强生成正样本对。

使用一个固定的记忆库(Memory Bank)存储历史样本特征,作为负样本来源。

负样本来源

动态字典,存储大量历史样本特征。

当前批次内的其他样本。

记忆库,存储历史样本特征。

负样本数量

非常大(如 65536),远超批次大小。

受限于批次大小(通常为几十到几百)。

较大(如 65536),但记忆库是固定的,无法动态更新。

负样本多样性

高,来自整个训练过程。

较低,仅来自当前批次。

较高,但记忆库中的样本可能过时。

动量更新机制

使用动量编码器(Momentum Encoder)缓慢更新字典中的特征,保持一致性。

无动量更新机制。

无动量更新机制。

计算复杂度

较低,通过动态字典和动量编码器实现高效对比学习。

较高,需要在批次内计算所有样本对的相似度。

中等,记忆库需要存储和更新大量特征。

实现难度

中等,需要实现动态字典和动量编码器。

简单,易于实现。

中等,需要实现记忆库的存储和更新逻辑。

主要贡献

引入动态字典和动量编码器,显著提升负样本的数量和多样性。

提出简单的对比学习框架,强调数据增强和批次内对比的重要性。

提出使用记忆库存储历史样本特征,扩展负样本来源。

解决的问题

解决了批次内负样本数量有限和多样性不足的问题。

解决了自监督学习中正样本对生成和批次内对比的问题。

解决了批次内负样本数量有限的问题,但记忆库中的样本可能过时。

优点

- 负样本数量大、多样性高。
- 计算效率高。
- 在下游任务中表现优异。

- 实现简单。
- 强调数据增强的重要性。
- 在批次内对比效果显著。

- 负样本数量较大。
- 扩展了负样本来源。

缺点

- 实现复杂度较高。
- 需要额外的动量编码器。

- 负样本数量受限于批次大小。
- 计算复杂度较高。

- 记忆库中的样本可能过时。
- 无法动态更新记忆库中的特征。

典型应用场景

图像分类、表示学习

图像分类、表示学习等任务。

图像分类、表示学习等任务。

三种方式优缺点概括

SimCLR端到端方式 : 保证一致性,负样本缺乏多样性

Memory Bank:保证负样本多样性,但是缺乏一致性

MOCO:尽量保持一致性,保证负样本多样性

moco v2 更多的是在moco v1基础上加入更多的数据增强,以及参数trick,V3则更有向端到端+大batchsize 投降的意思

本文为原创文章,未经作者允许禁止转载。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值