目录
现存的视觉语言预训练存在两个不足:
任务领域
数据集领域
相关研究
知识蒸馏
Method
单模态编码器:
基于图像的文本编码器:
基于图像的文本解码器:
三重目标优化
图像文本对比损失:让匹配的图像文本更加相似
图像文本匹配损失:判断图像文本是否匹配
语言建模损失:根据图像生成文本描述
减少ViT前向传播计算:每个图像-文本对仅仅计算一次Transformer
参数共享:文本编码器和解码器共享参数(除了注意力层之外)
训练框架
实验
编辑
现存的视觉语言预训练存在两个不足:
任务领域
大多数直接采用基于编码器的模型,典型的就是CLIP,通过放大不匹配的图像文本对的损失,来抑制错误的匹配,重要的是图像和文本的编码工作,基本不牵扯到解码上去。其目的也仅仅在于寻求匹配的图像文本对,要经过较多的处理才能方便应用于下游任务。不太适用于进行文本生成任务。
而编码器解码器模型,较多的使用于文本生成任务,在自然语言处理中很常见,典型的就是机器翻译,在我们的生活中已经很常用了,编码器将输入转化为隐藏表示,隐藏表示的优势在于容易处理,解码器再将经过处理的编码进行恢复,同时文本摘要也是一个常见的领域应用,模型通常是Seq2Seq+Transformer,但是这种强大的特征提取并恢复的能力肯定是不能仅仅在自然语言处理领域有所作为。
不过值得注意的是,编码器解码器(Encoder+Decoder)模型在视觉语言领域也有应用,典型的包括图像字幕生成,也是利用CNN+Transfomer,注意力机制擅长处理文本之间的长距离依赖问题,当然在图像处理领域捕捉不同区域之间的关联也很有用。
数据集领域
显然本文是对CLIP的diss文章,解释了CLIP的痛点问题,在数据集上,传统的CLIP使用的是在网络上收集来的4亿对文本图像匹配的数据集,虽然能减少很多人工标注的成本,(文章中解释是弱监督,说明CLIP在使用弱监督学习,仍能取得很好的效果,同时也说明CLIP具有很好的泛化性,包括任务泛化和类别泛化,但是不可避免在特定领域,如果能选用适当的数据集的话,效果会更哈,虽然CLIP委婉的解释了难以收集到合适的数据集仍能带来很好的效果,但是明眼人都能看出来,语言视觉模型对训练集的质量还是有很高的要求的)。
BLIP虽然也不能逐个进行标注,显然,文本语言匹配的问题也无法进行完全正确的标注,要是其具有更好的任务泛化能力,太过精准的标注反而会牢牢地固定模型的适用范围。
所以我们采用了一个折中的方案,也就是过滤掉一些低质量的标注,对于低质量标注的定义,后面会说,
相关研究
知识蒸馏
通过使用教师模型(强大的教师模型,可以认为deepseek就是教师模型,能力很强)的软标签(或者隐藏信息)来训练一个学生模型,简单来说是教师模型辅导学生模型来学习他,使其变得更加聪明,而不是从0开始自己摸索。小模型具有轻量级的特点,参数更小(比如bito),教师模型不仅仅输出分类结果还输出概率分布结果。
损失计算函数如下:
伪代码解释为:
def train_student(student_model,teacher_model,train_loader,optimizer,alpha,T):
student_model.train()
teacher_model.eval()
for images,labels in train_loader:
images,labels=images.cuda(),labels.cuda()
with torch.no_grad():
teacher_logits=teacher_model(images)
student_logits=teacher_model(images)
loss=distillation_loss(student_logits,teacher_logits,labels,alpha,T)
optimizer.zero_grad()
loss.backward()
optimizer.step()
教师模型先进行输出,学生模型再进行输出,输出结果计算知识蒸馏损失。
Method
使用ViT作为图像编码器,将图片分割为小块,然后将其编码为嵌入向量进行处理。额外的cls表示全局图像特征,类似于BERT处理文本时候的token。之后使用transformer进行处理。
使用多模型编码器解码器:MED是一个多任务的Transformer,能支持三种不同的工作方式:
单模态编码器:
分别对文本和图像进行编码,不进行交互。
基于图像的文本编码器:
在文本的Transformer中加入一个跨模态的注意力层,先进行文本自注意力计算,然后再加入图像信息。额外添加cls,token进行图像文本联合训练。
基于图像的文本解码器:
解码过程中只能看到之前的token,适用于生成任务。(也可以叫做视觉驱动的文本生成)。
function ViT_Encoder(image):
patches=split_into_patches(image)#将图像切割成patches
embedings=LinearProjection(patches)#映射为高纬度向量
cls_token=learnable_embeding()
sequence=concat(cls_token,embedings)#组成序列
output=Transformer(sequence)#进行Transformer编码
return output[CLS]
function Text_Encoder(text):
tokens=tokenize(text)#进行文本分词
tokens=add_special_token(token,"[CLS}")
embedding=ToKenEmbedding(tokens)#生成词嵌入
output=Transformer(embeddings)
return output[CLS]#返回[CLS]作为文本特征
class MED:
function__init__():
self.image_encoder=ViT_Encoder()
self.text_encoder=Text_Encoder()
function Unimodal_Encoding(image,text):
image_feat=self.image_encoder(image)#提取图像特征
text_feat=self.text_encoder(text)
return image_feat,text_feat
function Image_Grounded_Text_Encoding(image,text):
image_feat=self.image_encoder(image)
text_feat=self.text_encoder(text)
multmodal_feat=CrossAttention(image_feat,text_feat)#跨模块注意力
return multimodal_feat
function Image_Grounded_Text_Decoding(image,text):
image_feat=self.image_encoder(image)
text_token=tokenize(text)
decoder_output=TransformerDecoder(image_feat,text_tokens)#进行文本解码
return decoder_output
function Train():
for (image,text) in dataset:
model=MED()
image_feat,text_feat=model.Unimodal_Encoding(image,text)#进行独立编码
multimodal_feat=model.Image_Grounded_Text_Encoding(image,text)#训练文本理解
generated_text=model.Image_Grounded_Text_Decoding(image,text)#训练文本生成
loss=ComputeLoss(Generated_text,text)#计算损失
update_model(loss)#反向传播
三重目标优化
既然有三种损失函数,就对应有三种优化方式,但是要使他们进行信息融合共同作用于这个最终的模型,就要联合优化三种目标函数。
三个核心目标是:
图像文本对比损失:让匹配的图像文本更加相似
图像文本匹配损失:判断图像文本是否匹配
语言建模损失:根据图像生成文本描述
减少ViT前向传播计算:每个图像-文本对仅仅计算一次Transformer
参数共享:文本编码器和解码器共享参数(除了注意力层之外)
伪代码如下:
#图像-文本对比损失
function Image_Text_Contrastive_Loss(image,text):
image_feat=Vit_Encoder(image)
text_feat=Text_Encoder(text)
similarity_matrix=compute_consine_similarity(image_feat,text_feat)
loss=contrastive_loss(similarity_matrix)#计算对比损失
return loss
#图像文本匹配损失
funciton Image_Text_Matching_loss(image,text):
image_feat=ViT_Encoder(image)
text_feat=Text_Encoder(text)
multimodal_feat=CrossAttention(image_feat,text_feat)#跨模块注意力
logits=LinearLayer(multimodal_feat)
loss=BinaryCrossEntropy(logits,true_label)
return loss
#语言建模损失(文本生成)
function Language_Modeling_loss(image,text):
image_feat=ViT_Encoder(image)
text_tokens=tokenize(text)
generated+text=TransformerDecoder(image_feat,text_tokens)
loss=CrossEntropyloss(generated_text,text)
return loss
#训练过程
function Train():
for(image,text) in dataset:
model=MED()
image_feat=ViT_Encoder(image)
text_feat=Text_Encoder(text)
loss_itc=Image_Text_Contrastive_Loss(image,text)
loss_itm=Image_Text_Macthing_Loss(image,text)
loss_lm=Language_Modeling_Loss(image,text)
total_loss=loss_it+loss_itm+loss_lm
update_model(total_loss)
训练框架
使用CapFit方法(Captioning and Filtering)机制,优化大规模自动收集的图像-文本数据,提高视觉-语言模型的学习质量。
数据存在难以平衡的问题:人工标注的数据数量较少(COCO)虽然质量高,但是数量上让人很难堪。网页通过爬虫或其他手段进行抓取的数据数量虽然大,但是质量较低,含有较多的噪声。
BLIP的解决方案是使用图像-文本解码器生成高质量的合成文本,注意使用的是合成文本。
去除原始文本和合成文本中不匹配的文本,使用ITM任务,判别哪些文本不符合图像内容将其过滤掉。
网页自动抓取的文本对是,人工标注的图像文本对是
.
实验
BLIP预训练模型在图文检索,图像字幕生成,视觉问答等任务上性能比较:
第二列表示是否使用过滤器或者生成器,TR@1表示给定一张图像,检索到文本Top-1结果的准确率。IR@1表示给定一段文本,检索到图片Top-1结果的准确率。而后是图像字幕生成任务,B@4表示生成字幕与参考字幕的相似度,数值越高表示文本更接近于人类的标注,CIDEr衡量生成字幕和多个参考字幕之间的相似度,同样也是值越大越好。SPICE衡量语义结构,模型生成的句子是否能准确表述图片的核心思想。(此处表示消融实验,对组件效果的评价)。私以为使用✔B或者✔L表示使用ViT-B/L/16作为视觉主干网络,但是在第三列给出了主干网络,所以这点我还是没搞明白。或者是作者多此一举。
绿色部分表示filter选择使用的部分,红色部分表示被抛弃的部分。
表示不同生成方法对检索与字幕任务的影响,生成策略包括None:直接生成,Beam:束搜索,生成文本时保留K个概率最高的选项,在最后选择最优路径,虽然多样性较低,但是生成的文本会更加流畅,Nucleus核采样:基于概率累计选取重要的词进行随机采样,多样性会更高,但是存在引入噪声的弊端。第二列表示各种方法中生成文本噪声的占比。可见后者的泛化能力最强。
表格表示不同程度的参数共享对性能的影响(用于文本的编码和解码):
全部共享的参数最少,(所以Transformer采用相同的参数),CA表示交叉注意力层,SA表示自注意力层。None表示都不共享,不共享自注意力层是最优的方案,参数量适中同时更加高效。
经典参数共享:
参数共享方式 | 示例 | 优点 | 缺点 |
---|---|---|---|
CNN 卷积核共享 | 图像分类 | 减少参数,提高计算效率 | 不能适应不同大小的局部特征 |
RNN 时间步共享 | 机器翻译 | 适应变长输入,减少参数 | 可能限制长期依赖的学习 |
Transformer 层共享 | 视觉-语言模型(BLIP) | 降低计算量,优化推理速度 | 可能降低模型表达能力 |
表示在参数共享和解耦情况下的性能比对:
参数共享下噪声数据较少,解耦就会有较多的噪声,解耦表示各自独自训练,不共享参数,模型可以独立优化不同的目标。可想而知,解耦的情况下效果会更好,分别处理自己独立的任务。
表格对比不同视觉语言模型在图像文本检索任务上表现的性能。
看起来与上一个实验很像,但是区别在于是否微调:
实验 | Zero-shot Retrieval (当前实验) | Fine-tuned Retrieval (上一个实验) |
---|---|---|
数据集 | Flickr30K(1K test set) | COCO(5K test set) & Flickr30K(1K test set) |
模型是否微调 | ❌ 未在目标数据集上微调(Zero-shot) | ✅ 已在目标数据集(COCO / Flickr30K)上微调 |
测试任务 | 直接在 Flickr30K 测试,衡量模型泛化能力 | 先在 COCO / Flickr30K 上微调,再测试 |
目标 | 衡量模型的泛化能力(即使没见过 Flickr30K 也能有效检索) | 衡量模型在目标数据集上的最优性能 |
模型泛化能力影响 | 受 预训练数据量和质量 影响更大 | 受 微调策略和数据匹配度 影响更大 |
衡量模型在文本-视频检索任务或视觉对话任务中的表现:
指标 | 含义 | 数值高低对性能的影响 |
---|---|---|
MRR(Mean Reciprocal Rank,平均倒数排名) | 衡量模型返回的第一个正确答案的排名 | 越高越好 |
R@1(Recall@1) | Top-1 召回率,正确答案出现在首个返回结果的概率 | 越高越好 |
R@5(Recall@5) | Top-5 召回率,正确答案出现在前 5 个返回结果的概率 | 越高越好 |
R@10(Recall@10) | Top-10 召回率,正确答案出现在前 10 个返回结果的概率 | 越高越好 |
MRL(Mean Rank, 平均排名) | 正确答案在检索结果中的平均排名 | 越低越好 |
BLIP在视频问答任务中的表现,主要对比在零样本和微调的情况下的表现:测评指标是回答的准确率。但是。。。BLIP在微调之后进行测评的数据未提供,只能从理论上分析,微调之后的效果更好,但是明显此处是论文的一个败笔。