CLIP

数据集

WIT(WebImageText)包含4亿文本-图像对,从网络上搜索得到

预训练策略

这张图算是经典永流传了,对于输入的N个图像文本对,用左边矩阵的形式构建出N个正对和N2−N个负对,计算他们的余弦距离,并最小化正对的距离,最大化负对的距离
具体的训练策略蛮有意思,他居然用的SCE Loss(勘误,这里是对称的 交叉熵损失,而非SCE,对称意为分别对两个模态计算logits和label的交叉熵损失并做平均),伪代码如下

# image_encoder - ResNet or Vision Transformer
# text_encoder  - CBOW or Text Transformer
# I[n, h, w, c] - minibatch of aligned images
# T[n, l]       - minibatch of aligned texts
# W_i[d_i, d_e] - learned proj of image to embed
# W_t[d_t, d_e] - learned proj of text to embed
# t             - learned temperature parameter
# extract feature representations of each modality
I_f = image_encoder(I) #[n, d_i]
T_f = text_encoder(T)  #[n, d_t]
# joint multimodal embedding [n, d_e]
I_e = l2_normalize(np.dot(I_f, W_i), axis=1)
T_e = l2_normalize(np.dot(T_f, W_t), axis=1)
# scaled pairwise cosine similarities [n, n]
logits = np.dot(I_e, T_e.T) * np.exp(t)
# symmetric loss function
labels = np.arange(n)
loss_i = cross_entropy_loss(logits, labels, axis=0)
loss_t = cross_entropy_loss(logits, labels, axis=1)
loss   = (loss_i + loss_t)/2

这里面一些比较细节的东西:

  • 没有像过去的自监督方法一样用非线性的分类层(从各模态特征层到对比特征层),而是直接用的线性层做到同一空间的映射(按照论文的说法是用起来没差,猜想应该是只在自监督的表征学习里面有用)
  • 随机初始化,没有使用预训练模型(数据集大就是牛)
  • 唯一的数据增强是随机裁剪
  • 温度参数t是可学习的[[如何把一个向量(参数)写成可学习的?]]
    放一段网络上的实现代码:
class CLIPModel(nn.Module):
    def __init__(
        self,
        temperature=CFG.temperature,
        image_embedding=CFG.image_embedding,
        text_embedding=CFG.text_embedding,
    ):
        super().__init__()
        self.image_encoder = ImageEncoder()
        self.text_encoder = TextEncoder()
        self.image_projection = ProjectionHead(embedding_dim=image_embedding)
        self.text_projection = ProjectionHead(embedding_dim=text_embedding)
        self.temperature = temperature

    def forward(self, batch):
        # Getting Image and Text Features
        image_features = self.image_encoder(batch["image"])
        text_features = self.text_encoder(
            input_ids=batch["input_ids"], attention_mask=batch["attention_mask"]
        )
        # Getting Image and Text Embeddings (with same dimension)
        image_embeddings = self.image_projection(image_features)
        text_embeddings = self.text_projection(text_features)

        # Calculating the Loss
        # 值得注意的是,这里代码直接做点乘,这应当基于各模态的embedding都已经做过了归一化,即除以了每个向量对应的L2范数,把计算余弦相似度的分母部分做掉了
        logits = (text_embeddings @ image_embeddings.T) / self.temperature
        # 这一段是计算一个label矩阵,这里与伪代码中有所不同
        # 伪代码中的label是一个1xN的矩阵,用每个embedding的索引值表示它的类别
        # 这里是分别从两个模态计算各自模态中embedding之间的余弦相似度,再做平均,感觉上核心的意义是类似的:让对角线的数值高,其余位置的数值低
        images_similarity = image_embeddings @ image_embeddings.T
        texts_similarity = text_embeddings @ text_embeddings.T
        targets = F.softmax(
            (images_similarity + texts_similarity) / 2 * self.temperature, dim=-1
        )
	    # 计算Loss当然应该分不同的模态分别计算,由于上面定义label的方式不同,这里的loss计算也有所不同,当然targets转置不转置是一样的(其实感觉这个实现更合理一点),理论上按照他图里画的label应该是一个单位矩阵来着
        texts_loss = cross_entropy(logits, targets, reduction='none')
        images_loss = cross_entropy(logits.T, targets.T, reduction='none')
        loss =  (images_loss + texts_loss) / 2.0 # shape: (batch_size)
        return loss.mean()


def cross_entropy(preds, targets, reduction='none'):
    log_softmax = nn.LogSoftmax(dim=-1)
    loss = (-targets * log_softmax(preds)).sum(1)
    if reduction == "none":
        return loss
    elif reduction == "mean":
        return loss.mean()

推理预测策略

假定推理的任务是对一张图片,判断其类别,CLIP的做法是计算图片的特征向量和文本的特征向量,然后依次计算图片特征和一系列文本特征的余弦相似度,取最像的一个类别

当然,在这种分类任务上需要对类别文本做一定处理,因为训练的时候输入是个句子,在有具体类别的数据集上进行推理时可以构造一个prompt,写成A photo of a {object}的格式。

模型选择

  • Image Encoder选用了ResNet50和ViT做backbone,其中ResNet50进行了一些魔改(主要是EfficientNet),ViT魔改的少一点,在具体的实验里主要只是修改了图片划分patch的大小
  • Text Encoder改的就更少了,基本上就是加了个LN和初始化技巧
    • 值得注意的是他说用了masked self-attention,说是可以保留预训练模型的能力
      这里应当注意的是将transformer搬过来做迁移,是只用decoder,且所有的self attention都做mask操作,不与encoder交互(把他丢掉!)
    • 长度是77,超过的截取,不够的padding
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇