GPT Plus Money!B O O M

连接图像和文本,更多的多模态文章可以看博主整理过的系列(跨界出圈 | 谈谈BERT跨模态预训练),本篇文章主要整理一下OpenAI发表的2篇文章。其中CLIP 能够完成图像与文本类别的匹配,DALL·E 则可以直接基于文本描述生成图像,且性能十分优异。

CLIP

  • 论文:Learning Transferable Visual Models From Natural Language Supervision
  • 地址:https://arxiv.org/pdf/2103.00020.pdf
  • 代码:https://github.com/openai/CLIP

首先是CLIP,直接看模型吧,分为三步:Contrastive Pretraning,Create dataset classifier from label text和use for zero-shot prediction。

第一部分的整体架构如上图,是图文匹配的双流分支,一边是图像编码器(如resnet50或者ViT等),另一边是文本编码器(如Transformer)得到特征,然后对一个batch的文图pair对数据算内积得到匹配矩阵,这个矩阵行方向就是对图像的分类器,而从文本角度看列方向也是类似的分类器。最后使对角线的蓝色部分概率最大化就行(使匹配的pair内积相似度最大化),对比学习[1]博主已经整理过 不做赘述。

这一步是主要是利用大量的训练数据(直接从网上得到的句子-图像对)得到特征的表示。接下来的两步是测试过程,流程如下图:

和训练阶段类似,首先将需要分类的图像经过编码器得到特征,然后把目标任务数据集的每一个标签转为一个对应的文本(因为CLIP的Pretraning数据是句子,对于分类任务的单词label是不适用的),如上图中的 dog 这一label会改造成 'A photo of a dog',并且dog这个词被mask,尝试通过模型算内积相似度来预测出这个词,也就能做好分类了,由于是生成句子的感觉,所以其实它十分适合做zero-shot 的分类。

同时,基于 CLIP 还可以自由定义自己的分类器!也就是说可以很方便的利用CLIP和很多工作结合,比如等会要整理的 DALL-E 中就用到了 CLIP来提特征。

简单看看CLIP里面的逻辑流程

def forward(self, image, text):
        image_features = self.encode_image(image) #编码image
        text_features = self.encode_text(text) #编码text

# norm一下特征
        image_features = image_features / image_features.norm(dim=-1, keepdim=True)
        text_features = text_features / text_features.norm(dim=-1, keepdim=True)

# 计算内积相似度logits
        logit_scale = self.logit_scale.exp()
        logits_per_image = logit_scale * image_features @ text_features.t()
        logits_per_text = logit_scale * text_features @ image_features.t()

# shape = [global_batch_size, global_batch_size]
        return logits_per_image, logits_per_text

为什么效果好?

  • 数据集量大。Contrastive Pretraning部分使用的数据是作者从社交媒体上搜集的大约4亿对的数据,且不需要人来标注(很省人力也扩大了泛化性)。对于每个图像都有多达32,768个文本候选,本以为SimCLR够大 CLIP是2倍.....
  • 学习object而不是预测整个的文本描述。即把dog变成 'A photo of a dog'这种形式,然后预测dog,可以加速对比学习的速度到4-10倍。
  • Vision Transformer。这个博主也整理过不赘述:传送门[2]。代码中作者使用ViT,使用它也是可以比普通的resnet速度快3倍,这都可以使CLIP在更大数据集上,更长时间上进行烧钱(训练)。

DALL-E

  • 论文:Zero-Shot Text-to-Image Generation
  • 地址:https://arxiv.org/pdf/2102.12092.pdf
  • 代码:https://github.com/openai/DALL-E

然后是DALL-E模型,CLIP主要可以做分类检索等任务,而它则可以直接根据文本生成效果非常好的图像。motivation是目标是训练一个transformer进行自动建模,即将文本以及图片的tokens转换为单一的数据流,所以主要是需要考虑如何对2D的图片也转为单数据流。

也是直接看模型,如上图可以分为三个阶段:dVAE,Transformer和CLIP。

  • 「Stage One」。dVAE用来为图像的每个patch生成token表示(得到单数据流)。具体来说是将256×256的图片分为32×32个patch,然后使用训练好的离散变分自编码器dVAE模型将每个patch映射到大小为8192的词表中,最终将一张图片转为有1024个token的表示。这一阶段会让transformer的上下文尺寸(context size)减少192倍,同时还不会大幅降低“视觉”质量。
  • 「Stage Two」。Transformer架构采用类似GPT-3的生成式预训练方法。如图会首先使用BPE-encoder对文本进行嵌入,得到256个token(不够就padding),然后concat图像token进行拼接,然后直接输入到训练好的具有120亿参数的Transformer模型中对联合分布进行建模(64层,每层62头,每头64维,最后的维度为3968)。
  • 「sample and ranking」。最后可以对模型生成的图像进行采样,然后使用CLIP模型对采样结果进行排序,从而得到与文本最匹配的生成图像。

值得注意的一些trick:

  • Gumbel-Softmax。映射图像patch到词表是离散的,所以要用条件放松的ELB(evidence lower bound)。
  • 在VAE编码器的末端和解码器的开始使用1×1卷积
  • 将编码器和解码器重分块的输出激活乘一个小常量
  • 对文本-图像 token 的交叉熵损失进行归一化
  • 因为主要图像建模,因此将文本的交叉熵损失乘以1/8,将图像的交叉熵损失乘以7/8
  • 使用Adam算法,以指数加权的迭代平均法进行优化
  • 混合精度训练,为了节省GPU内存并提高吞吐量
  • 分布式优化

还有大佬复现code:https://github.com/lucidrains/DALLE-pytorch

这个复现的库可直接调用训练,似乎非常好用,如果你有足够的卡那么pip一下即可:

pip install dalle-pytorch

import torchfrom dalle_pytorch import CLIP

clip = CLIP(    dim_text = 512,    dim_image = 512,    dim_latent = 512,    num_text_tokens = 10000,    text_enc_depth = 6,    text_seq_len = 256,    text_heads = 8,    num_visual_tokens = 512,    visual_enc_depth = 6,    visual_image_size = 256,    visual_patch_size = 32,    visual_heads = 8) #设置CLIP的参数

text = torch.randint(0, 10000, (4, 256))images = torch.randn(4, 3, 256, 256)mask = torch.ones_like(text).bool()

loss = clip(text, images, text_mask = mask, return_loss = True) #直接训练CLIPloss.backward()

本文参考资料

[1]

对比学习: https://nakaizura.blog.csdn.net/article/details/108941999

[2]

Vision Transformer: https://nakaizura.blog.csdn.net/article/details/113095927

END -

(0)

相关推荐