多模态大模型(一)——只用Transformer Encoder的方法(CLIP、ViLT、ALBEF、VLMo)

CLIP: Contrastive Language-Image Pre-training 连接文本和图像的桥梁

CLIP是OpenAI在2021年提出的预训练模型,用于评估给定图像和给定文本描述的匹配程度。
其使用大量(4亿)从网页中爬取的图像-文本对数据进行对比学习。

典型的双塔模型,有两个Encoder,一个图像的,一个文本的,经过各自Encoder编码后经过简单的点乘代表不同模态的交互(相似性)。

训练时,假设一个 batch 有 N N N 对(图像,文本)对,可以有 N × N N \times N N×N 种组合方式,对比学习把原始数据集中的 N N N 个组合作为正样本(下图对角线),把其他的 N 2 − N N^2 - N N2N 种组合作为负样本(下图非对角线)。模型训练的目标就是最大化对角线上的分数,并最小化对角线外的分数。

在这里插入图片描述

因为 CLIP 在两个 encoder 后只进行了简单的内积作为模态的交互,对于复杂点的任务就不那么 work 了,一个顺其自然的发展就是去增强不同模态的交互/融合,也就是可以用一个神经网络来替换内积。

CLIP详细介绍见 CLIP——多模态预训练模型介绍


ViLT:Vision-and-Language Transformer Without Convolution or Region Supervision 一种极简多模态学习框架

1. ViLT成为里程碑式的工作

把模态的特征抽取做到了极小化,把主要的计算量都放到了后面的模态融合上,大大提高了模型的推理速度。其主要贡献就是把目标检测,也就是这篇论文里反复强调的Region Feature(区域性特征),从多模态学习的框架中移除了

2. ViLT将模型简化加速到了什么程度?

在这里插入图片描述

文本:直接把文本通过一个embedding矩阵,变成一个个的word embedding就好了,就可以直接和visual embedding扔到最后的transformer里去做模态之间的融合。

视觉

  • Region Feature(区域特征):最流行的方式,一般都是先给定一个图像,通过一个卷积神经网络的backbone,最后在通过一些ROI抽到一些区域性特征。
    • 相当于是做了一个​目标检测的任务,因为抽出来的特征都是区域性的,都是一个个的bounding box,所以就跟文本那边的单词一样都是离散形式的,可以想象成是一个序列,接下来就可以把这个序列直接扔给transformer去做模态之间的融合。
    • 之前的多模态学习里,大家喜欢把图像这边建模成为一个目标检测的任务,但是它带来的缺点也是显而易见的,作者下来就在运行时间这做了一个对比,会发现用了目标检测的方法,整个模型的运行时间才900毫秒,但是视觉部分的运行时间就占到了810毫秒,文本只占了15毫秒,所以说为了达到很好的效果,模型在视觉这边浪费了太多计算资源
  • Grid Feature(网格特征):说白了就是把一个图片扔给一个卷积神经网络,然后就把它最后一层比如说7*7的特征图拿出来,拉直了以后变成一个序列长度为49的序列了。如果你想要更多的序列,你也可以用之前的卷积层,比如之前14*14,那你就会有一个长度为196的序列。
    • 好处就是直接用一个卷积神经网络的特征图就够了,就不需要后面这一系列,直接和目标检测相关的东西了,所以一下计算复杂度就锐减到45毫秒。
  • Patch Projection:ViLT模型的做法。
    • 在之前的ViT中,作者对比了前面只用一个简单的linear projection层,和使用一个res50去抽取这些图像像素级别的特征,最后发现了两个结果差不多,甚至是这种可以学习的linear projection层表现得更好。
    • 因此,ViLT把前面的CNN backbone直接就换成了一个非常简单的linear embedding层,这个时候图像和文本就完全对应起来了,图像也是打成patch然后通过一个linear embedding层,得到图像初始的token,文本也是通过一个linear embedding层,得到初始的word token,这样就可以直接都扔给transformer了。
    • 这个patch linear embedding非常的快速,只要0.4毫秒,基本上什么时间都不费。

因为虽然ViLT把这个模型做的这么简单,但它真的训练时间会很短吗?并不是,它需要64张32g的v100的卡,非常贵的一个配置,而且还要训练三天才能训练完,甚至比之前的很多方法训练时间都要久

它效果怎么样?其实在图中也可以看到,它的效果也一般,尤其是跟之前用区域特征的方法,也是远远不如的。但是它最重要的特征,也就是运行时间上千倍的减少,作为最大的卖点,这也是ViLT的最大优势。

3. ViLT的引入

多模态领域也采取先预训练再微调的方式,因为在这种模式之下,预训练比较重要,因为他要在更多的数据集上去做训练,从而能提供一个很好的初始化,甚至能够直接zero shot去做下游任务。

而多模态模型一般都是用这种图像-文本对去进行预训练的,他们的目标函数基本上就是这种image text matching,也就是图像文本匹配的loss,还有就是NLP专属的这种mask language modeling,也就是bert使用的掩码学习。一旦预训练完成,拿到了预训练好的模型,接下来就是做一些微调。

具体怎么处理文本和图像?

文本:因为从17年开始大家就已经用transformer去做文本了,而且基本上transformer已经一统江湖了,文本就只能这么做。

图像:因为要做这种图文预训练,图像的像素就必须变成某一种形式,比如说一种离散的,带有很高语义的这种特征形式,能跟language token匹配起来,这样才能一股脑的扔进transformer,然后transformer自己跟自己自注意力去学。 你不能直接把图像的像素扔给transformer,因为vit中就提到过,如果这么做,序列的长度就太长了,transformer根本接受不了,所以说如何把图像的像素变成带有语义性、离散型的特征就是大家主要要研究的问题了

1、ViT

对于vit这篇论文来说,为了避免这种情况的发生,它不是在图像像素上去做,而是把图像分成了16*16这种patch大小,让这个patch去得到一个特征,然后把特征扔给transformer去学习。

2、ViT之前的做法:目标检测器

但是vit已经是2021年的工作,那在这之前,大家是怎么去考虑这个问题的?大部分的VLP的工作都是依赖于一个目标检测器

那么为什么选择目标检测器?
原因一:你不是想要一个语义性强的,而且是离散的这种特征表示形式吗,目标检测就是一个天然的离散化的过程,你给我一个图片,我还给你n个bounding box,这些bounding box就是一个又一个的物体,有明确的语义信息,而且它是离散化的,直接用ROI去抽特征就好了。

原因二:跟下游任务也有关系,因为对于当时的vision language下游任务来说,大部分可能就是VQA、visual captioning、image text retrieval 这些任务往往和物体有非常直接的关系。比如说对VQA任务而言,问题可能就是问这张图片里有没有这个物体;对于视觉定位(visual grounding)任务而言,文本query可能就是问物体在图片的哪个地方,其实这本身就已经是一个目标检测的问题了,然后对于visual reasoning、image text retrieval这些任务而言其实都跟物体有着非常强烈的联系,一旦检测到某个物体,你很有可能就能匹配到那张正确的图片。所以一切的一切,这些已有的数据集它都有非常强的对物体的依赖性,所以说选择目标检测系统作为多模态的一部分也是非常合理的。

但是用目标检测的思路去抽图像特征确实是太贵,所以也有一些工作尝试去把计算量降下来,其中就有一个工作就叫做pixelbert,它其实就是用了一个在imagenet上预训练好的一个残差网络,然后直接把残差网络最后得到的特征图,当成是一个离散的序列就跟vit hybrid一样:先用一个卷积神经网络去抽一些特征,然后再把这些特征当成sequence token,扔给一个transformer去学,这样计算量就只有backbone了,而没有后面的这些目标检测相关的东西,比如ROI、NMS这些东西,操作速度能快不少。但是不论你是用一个简单的残差网络抽特征,还是用一个复杂的目标检测的流程去抽特征,作者都认为它还是太贵了。

ViLT的提出动机

截止到目前为止,大部分工作还是聚焦在如何通过提升视觉编码器,从而能提升最后的性能的。 在训练的过程中,大家可以提前把这个目标检测这个特征都抽好,然后存在本地的硬盘上,训练的时候直接用就好了,这样看起来真正训练时是没有那么贵的。在真实世界中去做应用的时候,数据都是每时每秒在实时生成的新数据,对于新数据,都要去抽取特征,那个时候在做推理的时候,这个时间就不可忽略了,你没有办法提前抽取好存在硬盘上,所以说局限性还是非常大的,于是乎,作者说我们的重心就转移到怎么设计一个更轻量更简单的图像特征抽取的方法

ViLT受启发于ViT的工作,利用这种把图像打成patch,然后用一个简单的linear projection层去把patch变成embedding的方式,从而取消掉了繁琐的图像特征抽取的过程,它的做法和ViT是一模一样的,所以从某种意义上来说,ViLT这篇论文也是ViT之后一个手快的,在多模态领域里的扩展应用。

ViLT的贡献

  • ViLT是迄今为止最简单的用来做vision language的模型,因为它除了做模态之间融合的transformer,它就没有再用别的模型了,而不像之前一样还需要一个残差网络,甚至还有一些额外的目标检测的网络结构在里面,所以说ViLT的这种设计,带来了非常显著的运行时间和参数量的减少
  • 在减少计算复杂度的同时,还能保证性能。因为之前也有一些工作,能把运行速度降得比较低,但是他们的性能都差了很远,而我们能够在不使用这种区域特征,或者残差网络特征的情况下达到和之前差不多的效果,这是第一次。
  • 在训练的时候用了更多的数据增强的方式,比如说在文本那边,我们就用了整个词mask掉的方式,在图像这边我们尝试使用了RandmAugment,这两种数据增强的方式之前在多模态领域都没有被用过。

【贡献点三理解】因为多模态学习总要考虑到图像文本对之间匹配的问题,不论是给图像这边做了增强还是给文本做了增强,你很有可能得到的新的图像文本它的语义就不对了。
举个最简单的例子,草地上有一只小白兔,这时候图像做一下数据增强,把颜色改了一下,它可能就不是白色的兔子了,也不是绿色的草地了,这时候新生成的图像文本对就不是一个正确的对了。所以因为有这个问题呢,之前做多模态学习的人就没有考虑用过强的数据增强的方式,因为他们担心这种问题会发生,但是ViLT这里就巧妙的利用了这些数据增强的方式,稍微改了一点,然后发现效果还是非常好,即使你有很多图像文本对,你用上数据增强以后,效果还是会更好,这对于当时的多模态领域来说也是第一次。

4. ViLT背景知识

其首先对视觉-语言模型基于以下两点做了分类:

  1. 在参数或者计算成本上,两种模态是否保持平衡。
  2. 在网络深层中,两种模态是否相互作用,即两个模态怎么融合。

在这里插入图片描述

(a) VSE系列的工作为代表,他们的文本端非常轻量,视觉端还是非常贵,也就是图中所示的VE远大于TE,然后他们的融合也是非常轻量,就是一个简单的点乘或者一个非常浅层的神经网络。

(b) 代表性工作:CLIP模型。主要的特点就是图像和文本的表达力度是一样的,他用的这两个模型在计算量上基本上是等价的,这也就是他这里说的VE=TE,但是他们在做模态融合的时候也是非常轻量,就直接把两个得到的特征做个点乘就结束了。
所以处理CLIP这个模型非常适合去做抽特征,或者retrieval的任务,但是如果去做别的多模态的下游分类任务,比如说VQA或者visual reasoning,它的效果就略逊一筹,因为毕竟只是抽到两个特征,你得把他们好好的融合一下,你才能知道他们之间的对应关系是什么,一个不可学习的简单的点乘,是没办法做到深层次的分析的。

(c) ViLBERT,UNITER,Oscar其实都属于这一系列工作。文本端非常轻量,图像端基本就用的目标检测的系统,非常的贵,不仅抽特征贵,在后面做模态融合的时候也非常贵,就是后面又跟了一个transformer,就是他可能有两个模型,前面有一个visual backbone,后面还有一个大的transformer,但是就像我们在图1里看到的一样,它的性能确实不错,把各个多模态的下游任务的性能全都刷的非常高。

(d) 对于大部分的这种视觉文本的多模态下游任务来说,模态融合一定要比较大,你得好好做这种模态融合,你最后的效果才能好,跟你之前抽的特征关系不太大,然后再加上这个vision transformer的出现,patch embedding layer直接就工作的很好,所以ViLT直接就把patch embedding拿过来,所以视觉这边抽特征也很轻量,现在他们之间的关系就变成MI>VE和TE,而且VE和TE是等价的。

之前的方法是怎么做模态融合的?

  1. single-stream:顾名思义就是只用一个模型,那怎么用一个模型处理两个输入呢,最简单的就是我把这两个输入直接concat起来,把两个序列直接变成一个序列,就可以用一个模型去处理了,至于他们之间怎么交互我们不管,transformer自己去学就好了。
  2. dual-stream:有两个模型,这两个模型先各自对各自的输入做一些处理,充分去挖掘单独模态里包含的信息,然后在后面的某一个时间点,在做融合,比如说加一些transformer layer。

融合之前特征怎么抽取?

对于大部分VLP模型来说,他们文本端都是用一个预训练好的bert里的tokenizer,所以都是一样的,而且还很轻量。

对于图像端:

针对区域特征,将一个目标检测系统嵌入到多模态学习大概分为三步:

  1. 就是说当你给定一个图像之后,它先通过一个backbone,比如一个resnet101去抽一些特征。
  2. 抽完特征之后第二步是有一个rpn网络抽一些ROI出来,然后再做一次NMS把ROI降到一个固定的数量,这个数量其实就是序列的长度,得到这些bonding box。
  3. 第三步就是把这些,把这些bondingbox通过ROI head就能得到一些一维的向量,而这些就是本文里说的region feature。

虽然这种方法听起来很合理,你把一个连续的图片变成了一些离散的bonding box,然后每个box都有一个对应的特征,所以说这就跟文本那边匹配起来了,但是整个过程非常贵,即使现在目标检测我们想把它做的更轻量,或者做的更实时化,而且现在很多模型确实也跑得很快,但是你整个这一套操作下来,你肯定是不如一个简单的CNN的backbone,或者说只有一层的patch embedding来的快。

对于grid feature(网格特征)

就是怎么用一个预训练好的CNN,直接把他的特征图抽出来,就能拿到grid feature,但可惜用grid feature虽然比用region feature要便宜一些,但它还是相对而言比较贵的,而且它的性能也非常不好,我们刚才在图一里看到,它有的任务降了十几个点,这个性能的下降大家一般是不愿意接受的。

ViLT方法

借鉴ViT的patch embedding层,我直接就用一层patch projection层就把这个图像特征抽了,比之前用一个卷积神经网络的backbone或者甚至用一个目标检测的系统去做要快很多倍,而且效果基本还能持平。

5. ViLT模型

在这里插入图片描述

ViLT模型是一个single stream的方法,它只有一个模型就是transformer encoder

ViLT模型的输入

它的输入都在下面,分别一个是文本,一个是图像。

文本就是说,如果你有一个句子,先过一个Bert的tokenizer(),就会得到一些word embedding,也就是文本这边的序列,假设我们文本这边的序列长度是L,这个H就是那个token embedding的维度,一般对于transformer这个base模型来说他就是768,所以这里的这个输入其实就是一个L×H的矩阵。

同样的道理,因为有了vison transformer之后,这个图像也可以打成patch,每一个patch过一个patch embedding就会变成这样一系列的token,假设图像这边的token长度是N,它的维度也是H就是768,所以图像这边就是N×H的矩阵。

  • 灰色:代表模态,0就是指的文本模态,1就指的是图像模态。
  • 深绿色:位置编码。对于文本来说也有位置编码123456,对于图像来说也有patch的embedding也是123456。
  • *号:cls token,classing embedding

【Note】看起来这三个东西是放在一起的,好像感觉是在拼接,但其实不是,这三个东西是加在一起的,也就是模态类型和位置编码和文本本身的embedding是加在一起的,至于在哪concat呢,每三个作为一个整体concat在一起变成了整个的序列,这样就完成了transformer模型的输入,这个输入序列的长度是多少呢,其实就是1+L+1+N,整个的输入就是(L+N+2)*H,序列长度L,图像token的长度N ,token的维度H。

输入的序列是这么长,经过transformer之后呢,输出的序列还是这么长。

怎么训练ViLT模型?

至于怎么训练ViLT这个模型,文章说他们用了两个loss,但其实在图文匹配loss,这里还用了一个小的loss(Word Patch Alignment)。

1. Image Text Matching loss

图文匹配loss是人为设计的一个任务,就是说,本来文字和图片应该是配对的,如果这时候把图片随机换成数据集里任意一张别的图片,那你这张随机的新的图片和原来的旧的文本,它就不是一个对了,这个时候把ground truth和新生成的不配对数据都通过网络得到一些特征,看看能不能根据模型给我的特征去判断出来哪个是真的图片文本对,哪个是假的图片文本对,所以这里其实是一个二分类的任务,所以顾名思义,也就是看图片文本到底匹配不匹配。

2. Word Patch Alignment loss

也是想算一下图文之间的相似度如何,但它是通过另外一种方法算的,利用了optimal transport就是最优运输理论,这是一个能把几何和概率连在一起的很好的工具。
可以理解为作者就是把文本和图像的输出当做一个概率分布,然后计算一下他们这两个分布之间的距离,因为输入是一个图文对,那么按道理来说是匹配的,所以作者也就希望这里的距离越小越好。

3. Masked Language Modeling loss

文本上面的目标函数,也就是NLP常用的完形填空,就是随机mask掉一个单词,然后想把这个单词重建出来。

训练过程中好用小技巧

1. 文本上whole word masking

如果你有一个单词,比如说giraffe,你先用tokenizer,比如说bpe或者bert这些,把它p成小的词根的时候,他就变成了这种 [“gi”,“##raf”,“##fe”],就跟我们汉字能p成偏旁部首一样,这些小部分才是真正的token,这个时候你要说在这个token的序列上把raf给mask掉,其实以gi开头,以fe结尾的单词不多,那就会导致模型很容易就猜出来,根本就不用学。这就会导致一个什么问题呢?就是说我真的在做多模态这些任务的时候,我根本不需要借助图像这边的信息,就可以直接判断中间的是raf,那这个loss就失去意义了,就有点像是学了一个shortcut。

为了避免这种情况的发生,将整个单词给mask掉,这个时候如果想把giraffe重建出来,你肯定得借助图像的信息,因为如果原来的句子是在草原上有一个长颈鹿,如果把长颈鹿直接抹掉,他可以换成任何一个动物,所以这时候句子重建就变的非常困难,只能通过图像那边获得信息。通过把nlp那边mask掉整个单词的方式,非常巧妙地进一步加强了图像和文本之间的联系。

2. 图像上数据增强

在之前的那些多模态的方法里,借鉴于目标检测系统的多模态学习,它是没法使用数据增强的,因为他们在训练的时候都是提前把特征抽出来存在本地硬盘里了,原图长什么样,这个特征就是什么样,如果你想把原图做数据增强,那特征就要重新抽取,这就变得很麻烦而且很贵了,所以没人这么做过。

ViT用了最好的数据增强Randaugment,但是作者这里也做了稍微的改动,我们之前也说过多模态学习主要是看图像和文本的匹配,你这个图像如果做了数据增强,会导致和文本不匹配了,作者这里针对这个问题做了很小的改动,用了之前Randaugment里所有的策略但是有两个不用,就是color inversion和cutout,这样就最大程度的保证了图像和文本尽可能的还能匹配在一起,作者这里肯定也是进行了相当多的调参,最后才得到最优的结果。

6. ViLT模型的缺点

1、第一个缺点就是它的这个性能不够高。 ViLT在很多任务上是比不过 c 类里的这些方法的,原因之前其实我们也讲过很多遍了,对于现有的这些多模态任务而言,有可能是这个数据集的BIAS,也有可能是这个任务就需要更多的这个视觉能力,但总之我们是需要更强的这个视觉部分。简单来说。就是我们视觉的那个模型应该要比文本的那个模型要大,最后的这个效果才能好。但是在ViLT里,文本端用的 tokenizer 其实是很好的,但是 visual embedding 是random initialize。所以它的效果自然就很差
2、虽然说它的推理时间很快,但其实它的训练时间非常非常的慢。在非常标准的一个 4 million 的 set 上。vilt需要64张 32 G的GPU训练三天。所以它在训练上的这个复杂度和训练上的这个时间丝毫不亚于这个 c 列的方法,而是有过之而无不及。所以它只是结构上简化了这个多模态学习,但没有真的让这个多模态学习让所有人都玩得起。


ALBEF: Align Before Fuse: Vision and Language Representation Learning with Momentum Distillation 先对齐后融合

1. ALBEF的研究动机及主要贡献

研究动机

大部分已有的方法都是用一个 transform 模型去当做这个多模态的一个编码器,去同时编码这个视觉的 token 和这个文本的token。这里的视觉token,也就是视觉特征,其实就是 region base 的这个图像特征,因为在那个时候大部分之前的这个工作都还是用这个目标检测器的

虽然ALBEF 跟 ViLT 它的这个出发动机都是不想要这个目标检测的模型,但是细节上还是有差异的。

  • ViLT只是说用了这个目标检测模型以后速度太慢了,想让推理时间变得更快一些。
  • ALBEF是认为用了这个预训练的目标检测器之后,视觉特征和文本特征其实不是aligned。因为目标检测器是提前训练好的,然后就只用抽特征,它没有再进行这种 end to end 的训练,所以这就导致视觉特征和文本特征可能相隔得很远。那这个时候把这两个特征同时扔给多模态的这个编码器之后,有可能这个编码器就不好学,对于这个多模态的编码器来说,可能去学这种图像文本之间的这种交互信息就会变得很challenging。

主要贡献

  • ALBEF 解决了多模态领域中图像和文本对齐、交互的问题。
    • 在 ALBEF 之前,多模态方法通常使用 transformer 的多模态编码器来同时编码视觉和文本特征,由于目标检测器是提前训练好的,因此视觉和文本特征并不是对齐的。图像和文本特征可能距离很远,这使得多模态编码器难以学习到它们之间的交互。为了解决这个问题,ALBEF 通过一个对比损失(也就是 CLIP 中的 ITC 损失)在进行多模态交互之前对齐图像和文本数据
  • 网上爬取的大量图文对通常噪声很大(图文不匹配)。ALBEF 采用动量蒸馏(momentum distillation)的自训练方法来从网络图文对数据中学习,以缓解原始数据中的噪声问题。
    • 从理论上讲,ALBEF 通过互信息最大化的角度解释了不同的多模态任务,说明不同任务实际上为图文对提供了不同的视角,类似于数据增强,使得训练得到的多模态模型能够理解不同模态下的语义,具备语义保持的能力。

noisy web data 与 momentum distillation

1. Noisy Web data 到底有多Noisy?它为什么是 Noisy 的?

所有这个图像文本对就是从网上直接爬下的这些图像文本对,在很多情况下,那个文本并没有很好的去描述这个图像。能从网上大规模爬下来的那些文本,其实它有名字叫做Alt text,也就是Alternative text,就是另外一种形式的文本

如果你有一幅青山绿水的画,上面有几个人在玩儿,他就会说有几个人在一个山下面玩儿,旁边有一个小溪,文本是不会这样去写的,因为这样的文本不具备关键词,也就是说对于那些搜索引擎来说它具不具备价值?对于搜索引擎来说最具备价值的东西都是关键词,即需要的:比如说你喝的饮料,你不能说我在喝饮料,你得说我在喝可口可乐,或者你自己在说我在喝冰红茶,或者是哪个牌子的冰红茶,这样子当大家去搜的时候,他就会搜到这张图片。同样的道理你去哪个著名的旅游景点打卡的时候,你也不能说我看到了一座山,也不是搜索引擎想看到的,他想看到的是你去了哪座山,你去了哪个旅游景点。所以这个时候。其实从搜索引擎下来的这些图片文本对,它里面的文本都是这种具备搜索属性的,但是不是那种特别好的描述性的一个句子,他们有时候甚至真的没有去描述这张图片里是什么内容。它可能就是一些关键词,一些hash tag。

2. 怎么解决这个Noisy问题?——用momentum distillation

也就是一种自训练的方式去学习。自训练一般就是用Pseudo labels,即伪标签。
那伪标签怎么得到?肯定是有额外的一个模型去提供这个伪标签。那在ABLEF中,除了已有模型外,作者采用了MoCo论文中提到的momentum encoder的形式,使用Momentum model生成pseudo target,从而达到自训练的结果

2. ALBEF模型实现

在这里插入图片描述

图像模型:给定任何一张图片,那按照 vision Transformer 的做法,把它打成patch,然后通过 patch Embedding layer,然后送给一个 vision Transformer:其实这就是一个非常标准的 12 层的 vision Transformer 的base 模型。【如果这里的图片是 224 × 224 的话,那它这里的这个 sequence lens 就是196,然后加上额外的一个这个 CLS token,那就是197,然后它的特征维度就是768,所以说这里面这个绿黄色的这个特征就是 197 × 768。但是在这篇论文里,作者也说了,在预训练阶段他们用的图片是 256 × 256,所以说这里绿色的这个 sequence lens 就会相应的再长一些。】这个预训练参数是用的DEIT,也就是 data efficient vision Transformer 那篇论文里在 imagenet 1k 数据集上训练出来的一个初始化参数。

文本模型:希望这个文本编码器的比这个图像编码器要弱一些,将BERT模型分成两个部分,只用前 6 层去做文本编码,把剩下的那 6 层 Transformer encoder 就直接当成这个模态融合的过程,这样一举两得,跟之前的方法保持同样的计算复杂度。文本模型是用一个 Bert 模型去做初始化,然后它中间的这个特征维度也是768,然后它也有这么一个 CLS token,代表了整个句子的这个文本信息。

Momentum模型:为了给 ITC loss 提供更多的negative。除了这个 ViT 和 Bert 这份模型参数之外,它还在Momentum模型对应的有一个 ViT 和 Bert 另外的一份模型参数。而这个Momentum模型参数是由左边在训练的模型参数通过 moving average 得到的,这跟MoCo是一样的。通过把 moving average 的那个参数设得非常高,在论文里是 0. 995,从而来保证 momentum model 不会那么快的更新,所以说它产生的特征就更加的稳定,不仅可以拿来做更稳定的 negative sample,而且还可以去做momentum distillation。

3. ALBEF的目标函数

1. ITC loss: Image Text Contrastive

说到对比学习,我们之前就知道,只要你能定义一个正样本对,然后定义很多负样本对,然后我们就可以去对比了,我们希望这个正样本对之间的距离越来越近,希望正负样本对之间的距离越来越远。

那首先我们要做的就是去抽取这种全局特征,然后在特征之间去做这种 embedding space 上的拉近和拉远

1- 提取图像和文本的全局特征表示。在 ALBEF里,首先一个图像 i 它通过这个 vision Transformer 之后就会得到特征,把这个黄色这个 CLS token 也就当做它的全局特征,也就是一个 768 × 1 的一个向量。那文本这边也一样,先是tokenize,之后就把这个文本 text 变成一个 tokenization 的序列,然后把它扔给一个 Bert 的前六层,得到了一系列的特征,那这边黄色的是 CLS token,也就当做了这个文本的全局特征,是一个 768 × 1 的向量。

2- 进行downsample和normalization,将 768 × 1 的向量变成 256 × 1 的向量在这里插入图片描述,这就是正样本的两个特征。其负样本全都存在一个Q(队列)里,有65536个负样本。但是因为它没有gradient,是由Momentum model产生的,所以并不占用很多内存。因为有很多很多的负样本,然后通过这种正负样本之间的这个对比就可以去对这个模型进行第一阶段的学习了。

这其实也就是作者在这篇文章中说的 align before fuse 的 align。也就是说在我们把这个图像特征和这个文本特征扔到这个 Multi model Fusion 的 encoder 之前,就已经通过这个 ITC loss——这个对比学习的loss,让这个图像特征和文本特征尽可能的拉近了,尽可能的在同一个 embedding space 里了。

在这里插入图片描述

这个ITC loss完全就是按照MoCo来的,就是算了一个 Cross Entropy loss。
那有了这个ITC loss 之后,其实这个 vision transform 的 12 层和这个 Bert 的前六层其实都可以训练了。

2. ITM loss: Image Text Matching

但是Bert的这个后六层,也就是这个多模态的这个融合部分该怎么训练?需要用到这个image text matching loss。其实很简单,给定一个图片,给定一个文本,这个图像文本通过这个 ALBEF的模型之后,就会出来一个特征,那在这个特征之后加一个分类头,也就是一个 FC 层。然后去判断到底这个 i 和 t 是不是一个对,那说白了这个 ITM 就是一个二分类任务

在这里插入图片描述

那这个 loss 虽然听起来很合理,但是实际操作的时候你会发现这个 loss 太简单了。
因为判断正样本可能还有点难度,但是判断谁和谁是负样本,这个就太简单了。 如果你不对这个负样本做什么要求,那基本上很多很多的这个图片/文本,它都可以当成是现在图像/文本内的负样本,所以这个分类任务很快它的准确度就提升了很高很高。那在预训练的时候,训练再久其实也没有任何意义了。

ALBEF是怎么实现的负样本选择?

ALBEF这篇论文里,它就是采取了最常用的一个方法,就是通过某种方式去选择最难的那个负样本,也就是最接近于正样本的那个负样本。 具体来说,ALBEF的batchsize是512,那对于 ITM 这个 loss 来说,它的这个正样本对就是 512 个。对于这个 Mini batch 里的每一张图像,去哪儿找它的这个 hard negative 的文本?这个时候 ITM 还依赖于之前的这个ITC,他就把这张图片和同一个 batch 里所有的文本都算一遍 cosine similarity,然后在这里选择一个除了他自己之外相似度最高的那个文本当做这个negative。也就是说其实这个文本和这个图像已经非常相似了,它基本都可以拿来当正样本用,但是我非说它是一个负样本,也就是 hard negative 的定义。那这个时候 ITM loss 就变得非常 challenging 了,然后让这个模型更好的去判断谁到底是一个图像文本对,也就是他这里说的 image text matching。

3. MLM loss:Masked Language Modeling

Bert 里用的完形填空,那其实就是把原来完整的句子这个 t 变成一个 t’,也就是说有些单词被mask 掉。然后把这个缺失的句子和图片一起,通过ALBEF模型把之前的这个完整的句子给预测出来。在这里其实它不是像 NLP 那边单纯的一个 MLM 了,它其实也借助了图像这边的信息去帮助它更好的恢复这个哪个单词被 mask 掉。

在这里插入图片描述

【Note】在计算ITC loss 和 ITM loss 时,输入都是原始的 i 和 t ,但是在计算 MLM loss 时,它的输入是原始的 i 和 mask 过的 t’ 。 这意味着什么呢?这说明 ALBEF这个模型每一个训练的iteration,其实它做了两次模型的forward。一次模型的forward 是用了这个原始的 i 和t,另一次模型的 forward 是用了原始的 i 和mask过 的 t’。不光是 ALBEF这篇论文会有这种多次前向的这个过程,其实 vilt 包括之前的很多模型,它都会做好几次前向,甚至做三次前向过程。这也是其中一个原因,这也就是为什么多模态学习普遍的方法的训练时间都比较长,因为为了算好几个不同的loss,需要做好几次不同的 forward 去满足各种各样的条件。

在这里插入图片描述

4. 动量蒸馏Momentum Distillation

提出动机
为什么要做这个动量蒸馏,动机是什么?主要就是这个Noisy Web data。
前面也提到过,从网上爬取下来的图像文本对,经常是weekly correlated的,它们之间的关联不是那么强,有的时候甚至都不匹配。经常的情况就是文本有的时候会包含很多单词,其实跟图像没什么关系,或者说图像里也包含很多的物体,但是在文本里并没有得到体现。

这种 noise 的 data 会造成什么影响?主要就是在算这个目标函数的时候,有时候就会有偏差。
比如说我们在算这个ITC,就是对比学习的 loss 的时候。对于一张图片来说,它的这个所谓的负样本文本其实很有可能也描述了这个图像里的很多内容,它可能不是爬下来的那个 ground truth 的那个 image text pair,但是其实这个文本可能已经很好的描述了这个图像,甚至可能比ground truth 描述的还好,但是我们非要把它当成是一个负样本,那这个时候就会对 ITC 的学习造成很大的影响。
另外对于这个 MLM loss 来说,完形填空,那其实我们做过那么多年的完形填空,也知道有很多时候这个空里是可以填很多单词的,有的时候是会存在这种比ground truth 还要描述这个图片更好,或者说差不多好的这个文字出现。

所以综合这些考量,用这种 one hot label (就是从网上爬下来的,就是这个图片和这个文本就是一对,其他跟它都不是一对的),这种 one hot label 对于 ITC 和 MLM 这两个 loss 来说是不好的,因为有的负样本也包含了很多很多的信息,一味的在算 loss 的时候去惩罚这些负样本,其实会让模型的学习非常的困难。

动量模型的引入

既然这个问题是由 Noisy data 里的 one hot label 带来的,很直接的一个想法就是如果能找到额外的监督信号,最好它不是 one hot,它是 multi hot,或者说它就是另外一个模型的这个输出不就好了吗?

这两年比较火的一种方式叫做 self training,就是自训练,就很自然的能够应用到这个场景里来解决这个问题。ALBEF也就采取了这种方式,就是先构建一个 动量模型,然后用这个动量模型去生成这种 Pseudo targets。那这个Pseudo targets 其实就是一个Softmax score,它就不再是一个 one hot label 了。

动量模型怎么构建?

其实就是在已有的模型之上去做 Exponential Moving Average (EMA)。这个技术其实是很成熟的,大部分的这个代码库里都是支持这个 EMA 的,包括这个 DEIT、swing Transformer 都是自带EMA 的。
它的目的就是在这个模型训练的时候,我们希望在训练原始 model 的时候,我们不光是让它的预测跟 ground truth 的 one hot label 去尽可能的接近,还想让它这个预测跟动量模型出来的这个 Pseudo targets 去尽可能的match,那这样就能达到一个比较好的折中点。 就是说很多的信息我们从 one hot label 里去学,但是当这个 one hot 的 label 是错误的或者是 noisy 的时候,我们希望这个稳定的 momentum model 能够提供一些改进。

1. ITC loss
原来我们的 ITC loss 就是这个 L i t c \mathcal{L}_{itc} Litc。但是因为它是基于 one hot label,所以这个时候我们想希望再算一个 Pseudo target loss 去弥补它的一些缺陷和不足。

在这里插入图片描述
把这个 ground truth 了换成 q (就是Pseudo targets)。因为现在q 不再是一个 one hot label,而是一个 Softmax score,所以这里计算这个 KL divergence,而不是cross entropy。

2. MLM loss

同样的道理,对于MLM loss来说,也是用这个新生成的这个 Pseudo targets 去代替了原来的 ground truth。

在这里插入图片描述

所以最终ALBEF的这个训练 loss 其实有 5 个,就是有两个ITC,两个MLM,一个ITM。
那这个时候大家可能会想为什么 ITM loss 我们不也给它一个自训练,给它一个这个动量模型的版本?是 因为 ITM 这个 loss 本身它就是基于 ground truth 的,它必须要知道你是不是一个pair,它就是一个二分类任务。 而且在 ITM 里我们又做了 hard negative这跟 momentum model其实又有点conflict,所以说ITM并没有动量的这个版本。

生成的Pseudo Targets

目的:证明这些 Pseudo target 其实是比 ground truth 那个 image text pair 要更好的,能起到更好的这个监督训练作用。
在这里插入图片描述

上面这一行主要是讲 MIM loss,对于第一张图片来说,如果我们把文本里的就 polar bear in the 什么地方这个给 mask 掉,它的那个 ground truth 是说 in the wild 就是在野外的一个北极熊。但其实由这个动量模型产生的这个 top five 的这个 Pseudo targets 来说,其实有的时候更准确,比如说在动物园或者在游泳池里、在水里、在池塘里,这些应该是比这个 ground truth 的 wild更具备描述性的。尤其是你拿这个图像文本对来学习模型的话,其实后面的这些这个pool, water pond 这些应该是比这个 wild 要好很多的,因为它确实描述了这个图片里的这个水。
那后面的这两个例子也差不多的情况,比如说最后一个例子,在这个森林里有一个瀑布, ground truth 是说有一个很远的瀑布。但是你从描述这个图片本身出发,其实后面的这些pseudo targets 应该是更好的。比如说一个小瀑布或者一个美丽的瀑布,或者这种隐约的瀑布,其实都远比这个 remote 这个单词要描述的更形象。这个是对于完形填空,就说这个空里其实有很多别的单词是比这个 ground truth 要表现更好的。

下面这一行是ITC loss,对于ITC loss 来说,当你有一个图片的时候,有一个对应的 ground truth 文本,而下面那些就是从整个这个数据集里去挑出来的别的pseudo targets。然后我们会发现其实这个 ground truth 说有一辆车在路上抛锚了,并不能很好地描述这张图片,因为这张图片里的主体还有另外一个人,但是所有的这些 pseudo targets都很好的描述出来了。有一个年轻的女人,把这个主体人给描述出来了,而且这里面也都有车,甚至还把这个树也描述出来了。所以这就再次验证了我们之前说的那个问题就说从网上爬下来的这些图像文本对,很多时候文本是并不能描述图片了。


VLMo: Unified Vision-Language Pre-Training with Mixture-of-Modality-Experts 灵活才是王道

这篇论文的贡献其实有两点,那一个就是模型结构上的改进,也就他这里说的这个 mixture of modelity expert。另外一个就是训练方式上的改进,他们做的这种分阶段的这个模型预训练,这两个改进其实都师出有名,都有非常强的这个研究动机。

1. VLMo提出动机

1. 为什么要引入这个 mixture of expert?
在多模态学习领域,大概有两个主流的模型结构:

  1. 像clip、align 这种的,他们采取了一个 dual encoder,就是双塔结构:图形有一个模型,文本有一个模型,然后模态之间的交互就是被一个非常简单的 cosine similarity 去做的。它的好处非常明显,尤其是对检索任务来说极其有效,因为它可以提前把那些特征都抽好,然后接下来直接算 similarity 就好了,矩阵乘法还不是飞快。所以说极其适合这种大规模的这个图像文本的检索,非常具有这个商业价值。但是它的缺点也由此而体现,就是说如此 shallow 的交互,也就是说只算了一个 cosine similarity,是无法做这种多模态之间非常难的这个各种情形的
  2. 单塔结构,就是fusion encoder的方式,就是先把这个图像和文本分开处理一下,但是当做模态交互的时候,用一个 transformer encoder 去好好的做一下模态之间的这个交互,这样就弥补了之前双塔模式的缺陷。但是它也有问题,就是当你去做检索任务的时候又出麻烦了,因为你只有一个模型,你必须同时做这个推理,所以当你这个图像文本对特别多,数据集特别大的时候,你就要把 all possible 图像文本对同时的去编码,然后去算 similarity score,然后才能去做这个检索。所以说它的这个推理时间就会非常非常的慢,所以对于大规模数据集来说,去做检索的话基本就不太现实了。

那鉴于这种情况,一个很直接的想法就是说既然你各有各的优缺点,那能不能把你放到同一个框架里去? 然后在做推理的时候,我想把你当做这个 dual encoder 来用,我就把你当 dual encoder 来用,我想把你当 Fusion encoder 来用,我就把你当 Fusion encoder 来用,那如果能达到这个灵活性,那岂不是特别美好?所以说作者这里就引出了他们这篇文章提出的而这个 mixture of modelity expert。 简单来说就是这个自注意力所有的模态都是共享的。但是在这个feed forward FC层,每个模态就会对应自己不同的expert,就是视觉具有视觉的 vision expert, language 就有language expert,Multi model 就有 Multi model 对应的expert。 这样在训练的时候,哪个模态的数据来了,我就训练哪个模态的expert。然后在推理的时候,我也能根据现在输入的数据去决定我到底该使用什么样的模型结构,这样就非常优雅的解决了第一个研究难题。

2. 多模态训练数据不足问题
我们都看到了 NLP 那边用了Transformer,随着这个数据的增加,而这个结果就会不停的变好再变好。在视觉这边虽然暂时没有看到就是这么好的这个 scaling 的性能,但是对于多模态来讲,因为它里面也有文本,所以说做多模态学习的人,希望看到当训练数据集越多的时候,这个模型的性能就越好。CLIP 其实已经在某种程度上验证了这一点了,所以大家自然是会想在更多的数据集上去做预训练的。但可惜在当时就是 ALBEF和 VLMo的时候, Lion 团队还没有推出 Lion 400 million 或者 Lion 5 billion 这样开源的数据集,clip 用的那个w i t 数据集也并没有开源。所以说对于研究者来说,他们自己如果想去构造这么大规模的一个数据集,这个 effort 是非常大的,那这个时候一条曲线救国的道路很自然的就摆在面前 虽然多模态的训练数据集不够,比如说只有 4 million 的 setting 或者 14 million 的setting。但是在单个的modality 里,就是视觉或者NLP 里有大把大把的数据可以去用 即使你是想有监督的训练,视觉里也有 imagenet 22K 有 14 million 的数据,那就已经比多模态这边最大的 14 million 的 setting 还要大。那如果你是说想要无监督的预训练,那可用的数据更是多得数不胜数,那文本那边儿也是多得数不胜数。

所以说基于这个研究动机,本文 VLMo 作者就提出了一个 stagewise pre-training strategy,就是说我分阶段去训练。既然你这个视觉和 NLP 领域都有自己各自的这么大的数据集,那就先把这个 vision expert 在视觉数据集这边训好,然后再去把 language expert 在 language 那边的数据集上 text only data 上训练好。那这个时候模型本身的参数已经是非常好的被初始化过了,再在这个多模态的数据上去做一下 pre-training,效果应该就会好很多。而事实也确实如此,这个 stagewise 的 pre-training strategy 给VLMO带来了很大的提升。

2. VLMo模型

在这里插入图片描述

一、模型结构上的改进

图一的左边是VLMo的核心,它也是一个 Transformer encoder 的结构,但是他在每个 Transformer block 里面做了一些改动。那具体来说,其实我们都知道一个标准的 Transformer block 里面就是先有一个 layer norm,然后有一个 MSA multihead self attention,然后再layer norm,然后再跟一个 FFN feed forward network,然后最后有一个residual,这个就是一个标准的Transformer block 了。这些都是一样的,唯一一个不同就是在 feed forward network这块:它不是一个feed forward network,而是针对不同的输入不同的modality,它有 vision FFN、language FFN 和 vision-language FFN,也就是这里说的 switching modelity expert,从而构建出了它的这一个 transformer block,然后最后构建出了 VLMo整个的模型结构。

【Note】虽然后面这个 FFN层没有 share weights,它是各自 modelity 有各自的FFN层,但是之前 self attention 层是完全 share weights 的。也就是说不论你是图像信号还是这个文本信号,还是图像文本信号,你任何的这个 token sequence 进来,这个 self attention 的 model weights全都是一样的,通通都是share weights的。

Transformer 这个自注意力的操作,它真的是用了最少的这个inductive Bias(模型在数据学习过程中对某些假设或模式的偏好),所以它不挑输入。 基本上我们现在已经看到了很多的证据,就是说同样的 self attention weights,它可以用来做不同的图像、文本、音频、视频很多这样的任务,你是不需要重新去训练这个自注意力参数的。

VLMo也是用了 image text contrast ITC,还有 image text matching ITM 和 mask language model MLM 这三个 loss 去训练的模型。而且它还从 ALBEF里借鉴了这个 hard negative mining 的思想,所以说它也是用 ITC 去做了更好的这个ITM,所以说训练 loss 是完全一致的。那至于它是怎么去算这个loss,它的这个 Fusion encoder 到底长什么样,其实跟 ALBEF也差不多,只不过更灵活了一些。

  • 比如说我们计算ITC的时候,VLMo直接就化身为了 CLIP 模型,就是图像这边就单独只有图像的输入,然后进去了一个VIT,它里面的 FFN 都用的是 vision FFN ,这个L如果你用的是指 vision Transformer base,那就是 12 层的一个Transformer。那文本这边,就是文本的token,单独进去这个 language model 后面用的是 language expert,这个就是一个 12 层的bert base。所以说如果你只看这个 ITC 这块儿,它就是一个 CLIP 模型。
  • 然后当我们去看这个 ITM 或者说这个 MLM 的时候,它又化身成了 Fusion encoder 的形式,就是说这个图像和文本的这个输入一起进去,一起进这个 Multi head self attention,但这里的这个 self attention 跟之前的 self attention 之间通通都是 share weights的,都是一样的,不管你是什么modelity,自注意力的参数都是不变的,都是share的。然后在前面的 L-F 层,就在 L-F 个 transform block 里,它是对这个 vision 和 language 信号分别去做模型的,所以这就是分别去用这个 vision expert 和这个language expert。只有在最后的这 F 层,他才去用了这个 vision language expert。

那我们看完整套的这个模型结构之后,我们就会发现 VLMo 这篇论文的好处,它就是灵活。 但是它的灵活也不是白来了,那就像我们在 ALBEF里说的一样,因为它有的时候用这个 mask 的输入,有的时候不用这个 mask 输入,所以 ALBEF里就要做两次forward。而在VLMo里面,它应该也是至少做了两次甚至三次的这个前向过程。作者在后面说VLMo这个 base 模型在 4 million 的 setting 下训练,用 64 张 V100 的卡也要训练两天,所以说又回到ViLT那个级别的,训练量比ALBEF 要慢。

二、模型的训练策略

作者想利用 uni-modality 里那些大量的这些图片文本去做这种很好的预训练,提供一个更好的模型初始化。所以说作者就先去做了这个 vision pre-training,然后去做 language pre-training,然后最后才去做这个 vision language pre-training。

在这里插入图片描述

这里面特别有趣的一个点就是在训练的过程中,到底哪些层是冻住的,哪些层是不冻住的? 蓝色的这个虚线就代表是 frozen FFN,然后这个橘黄色的虚线代表 frozen 的self attention。

做第一阶段的 vision pre-training 的时候,因为是刚开始训练,肯定没有什么需要 freeze 的,因为所有的东西都是随机初始化的。那所以说这 12 层的 transformer block,也就是包括前面的自注意力,和后面的 vision expert 都是打开训练的

当第二阶段去做这个文本的预训练的时候,我们会看到 vision expert 被冻住了,因为现是文本数据,不需要去训练那个 vision expert,所以 vision expert 的那个 FFN层参数就固定下来了,是要去训练这个language expert 的。但是非常有意思的事是把这个 self attention 给冻住了,意思就是说完全拿一个在视觉 token sequence 上训练好的一个自注意力模型,可以直接拿来对这个文本数据进行建模,我都不需要微调,这个 self attention 就工作的很好,就能让这个模型一样能把这个完形填空做得很好。但是如果反过来行不行?就是先在 language 上去训练,然后再在 vision 上冻住去做,好像结果不太好。 但是如果是先用 vision 训练,然后再在 text 上直接去用这个 self attention 已经在很多工作里证明是有效的。

到了第三阶段,因为这时候做的就是我们想要的这个多模态了,所以说该打开的就全打开了。不光是这个 self attention,还是后面的这 3 个 expert 就都打开去做 fine tuning 了,那这个就是VLMo的第二个 contribution 分阶段的预训练策略。

3. VLMo总结

总之VLMo还是非常有效的,它在 4 million的数据集上的表现就已经非常亮眼了,它跟 ALBEF去做这种公平对比的时候,是比 ALBEF全线都要高的要 2 到 3 个点,所以算是 significant improvement。


References

  1. 浅析多模态大模型的前世今生
  2. ViLT 论文精读【论文精读】
  3. 多模态论文串讲·上【论文精读·46】只用 Transformer encoder 的一些方法viLT、clip、ALBEF、VLMO
  4. 多模态论文串讲·上【论文精读·46】
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值