01
任务概述
你能否想象有朝一日,计算机能够根据它所看到的图片自动生成对应的描述文本?而图中所展示的正是笔者自己训练的Imgae Caption模型的生成效果。
Image Caption即我们常说的看图说话:给定一张图片,生成该图片对应的自然语言描述。该任务涉及到了图像与自然语言两个模态,然而图像空间与自然语言空间本就十分庞大,并且两者之间存在巨大的语义鸿沟。如何将两个庞大的语义空间进行对齐,这是该任务的重点。本文将对ClipCap模型进行介绍,并且对论文在Flickr30k中文数据集上进行实验复现和效果展示。

论文链接:
https://arxiv.org/abs/2111.09734
代码仓库详见:

https://github.com/yangjianxin1/ClipCap-Chinese
对于Image Caption任务,一般采取Encoder-Decoder模型,Encoder负责对图像进行编码,Decoder则根据图像编码进行文本生成。笔者认为一个好的Image Caption模型,必须解决以下两个问题:
  1. 图像编码器与文本解码器能否分别学习到一个良好的表征空间,将图像与文本编码到一个合适的语义空间?
  2. 图像空间与文本空间存在巨大的语义鸿沟,如何将图像空间与文本空间有效地联系在一起,将图像与文本进行有效的映射?
对于该任务最直观的做法便是,设计一个图像编码器和一个文本生成器,然后拿到图像-文本数据集,直接重头开始训练一个模型。但该做法效率非常低下,存在以下缺陷:
  1. 编码器与解码器的所有参数都需要重新进行训练,训练耗时长,效率低。
  2. 需要大量的图文数据,否则模型效果必然不佳。
  3. 模型收敛速度慢,图像空间与文本空间本来就非常大,单独训练图像编码器或者文本解码器尚且需要消耗巨大的资源,更不必说还需要将两个巨大的空间进行语义对齐。
02
论文概述
模型概述
为了解决上述问题,ClipCap提出了一种基于Mapping Network的Encoder-Decoder模型,其中Mapping Network扮演了图像空间与文本空间之间的桥梁。模型主要分为三部分:
  1. 图像编码器:采用CLIP模型,负责对输入的图像进行编码,得到一个图片向量clip_embed。
  2. Mapping Network:扮演图像空间与文本空间之间的桥梁,负责将图片向量clip_embed映射到文本空间中,得到一个文本提示向量序列prefix_embeds。
  3. 文本解码器:采用GPT2模型,根据提示向量序列prefix_embeds,生成caption。
论文中直接使用了预训练好的CLIP与GPT2-Large权重,两者分别是非常优秀的图像编码器和文本生成器,能够将图像与文本映射到较好的语义空间中。然而两个模型是使用不同的任务进行训练的,语义空间没有进行对齐。对于该问题,作者设计了两种Mapping Network,负责将图像与文本空间进行对齐。

MLP Mapping Network
使用多层全连接层作为CLIP与GPT2模型之间的桥梁。具体做法如下:首先将图片向量clip_embed经过两层全连接层,映射成提示向量prefix_embeds,该向量作为提示信息输入到GPT2模型中,然后GPT2模型根据prefix_embeds生成图片对应的caption。
Transformer Mapping Network
使用Transformer作为CLIP与GPT2模型之间的桥梁。具体做法如下:
  1. 首先将图片向量clip_embed经过一层全连接层,映射成提示向量序列prefix_embeds。
  2. 作者还引入了一个可学习的向量序列constant_embeds,目的是为了让其能够在多头注意力中,捕获到prefix_embeds中携带的语义信息。将prefix_embeds与constant_embeds进行concat操作,然后输入到Transforemer中,让prefix_embedsconstant_embeds进行充分的交互。
  3. 将prefix_embeds在Transformer对应的输出作为最终的prefix_embeds,作为GPT2模型的提示信息,生成最终的caption。
03
实验介绍
本项目主要复现了MLP+GPT2 tuning与Bert+GPT2 no_tuning在Flickr30k中文数据集上的效果。并且获得了不错的效果,验证了ClipCap模型的有效性。
实验细节
本项目的实验设置如下:
  1. 图像编码器与文本编码器分别使用CLIP与中文GPT2模型。并且分别加载预训练的模型权重。
  2. Mapping Network分别使用MLP与Bert进行实现(原文的Transformer本质上也是8层多头注意力进行堆叠)
  3. 训练时,CLIP的模型权重均被冻结。在MLP+GPT2 tuning的训练中MLP与GPT2的权重均进行finetune;而在Bert+GPT2 no_tuning的训练中,只对Bert的权重进行finetune,并且Bert没有加载预训练权重,为随机初始化。Bert为8层多头注意力的堆叠
  4. 训练时的batch size为40,epoch为40,学习率为2e-5,prefix_len为10,constant_len为10,clip_size为512,warmup_step为5000。
  5. 在生成阶段,对于每张图片,使用topp采样(核采样)生成10个候选的caption, 其中p设为0.8。
数据集介绍
训练所使用的是Flickr30k中文数据集,其中图片使用原有的数据,而对于caption,是由机器翻译而得到的中文caption。该数据集包含3万张图片,每张图片对应5个caption,共15万个caption。caption长度分布如下图:
由于caption是使用机器翻译的,所以数据集中会存在翻译结果不佳的问题。翻译不佳的caption如下:
1003428081  至少有四个房间的窗帘玩乐器演奏单簧管等乐器1003428081  四名妇女在一个客厅其中三个是清楚地演奏一种乐器1003428081  一群老年妇女发挥单簧管一起为他们读出乐谱100444898  一个大的结构已经坏了正在铺设一个巷道1007205537  看门人推小车在管理员工具10082348  在一个咖啡杯小便一个人站100845130  五人走在五彩的天空背景
除此之外,据笔者观察,数据集中存在很大一部分数据是以【一个、一群、一对】等数量词为开头的caption,所以该数据集是有偏的,会影响模型的泛化性。例如:
106691539  一个外科手术的外科医生和病人1067180831  一只黑白相间的狗正试图在一个低切码中捕捉到一个黄色和紫色的物体1067180831  一只黑色的狗正跳起来去抓一只紫色和绿色的玩具1067180831  一只黑白相间的狗一只黄色的玩具跳了起来1067180831  一只狗跳起来抓玩具1067675215  一个人躺在一个棕色的和皮卡之间的门黄在停车场的垫子1067675215  一个赤裸上身的男子躺在一条繁忙的马路中间1067675215  一个穿着蓝色短裤的人在停车场外面躺了下来1067675215  一个穿着蓝色短裤的人躺在街上1067790824  一条白色和黑色的狗一只棕色的狗在沙地上
基于flickr中文caption存在以上问题,后续会尝试使用更高质量的中文数据集进行训练。
训练过程分析

下图描述了MLP+GPT2 tuning与Bert+GPT2 no_tuning的训练过程中,模型在验证集上的loss的变化曲线。
我们可以作出简单的总结:
  1. 仅从验证集loss的角度,可以看到,相比于Bert+GPT2 no_tuning,MLP+GPT2 tuning的收敛速度更快,并且能够达到更好的效果。这也比较符合常理,因为在MLP+GPT2 tuning中,MLP与GPT2模型的参数是一起训练的,使得文本空间往图像空间靠拢。而在Bert+GPT2 no_tuning中, 只有Bert的参数在进行训练,而GPT2是固定的,Bert独自承担着将图像空间与文本空间对齐的任务,因此Bert的训练难度更高。
  2. 训练到30-40k步的时候,模型趋于收敛,继续训练模型loss不降反升,说明此时模型已经过拟合了。后续可以尝试使用更大的数据集来解决该问题。
04
效果展示与分析
效果对比

下图展示了MLP+GPT2 tuning与Bert+GPT2 no_tuning模型的生成效果。每张图对应两个生成的caption,其中第一行为MLP+GPT2 tuning的生成结果,第二行为Bert+GPT2 no_tuning的生成结果。
为了更直观地对两个模型的生成效果进行比较,我们对同一张图片生成了10个caption。观察生成结果,我们可以明显看到MLP+GPT2 tuning的生成效果好于Bert+GPT2 no_tuning。
MLP+GPT2 tuning生成的10个case如下:
一个穿红色衬衣和牛仔裤的人在木制的建筑物外面走一个穿着牛仔裤和恤衫的年轻人站在一个棕色的混凝土结构外一个穿红色衬衣的人正在走下楼梯一个穿着牛仔裤和一件红色恤衫的人在楼梯上走着一个穿着蓝色牛仔裤和红色恤衫的人在外面一个人走在一个高高的篱笆上一个人站在一个残桩上一个水桶一个穿着牛仔裤和恤衫的年轻人站在一个木门旁边一个手推车一个男人正走在一个停车场一个人带着一顶红色的帽子和一条红色的围巾看起来他正走在一个小木屋里
Bert+GPT2 no_tuning生成的10个case如下:
一个穿着红色衬衫的人在一个自行车棚一个穿红色衬衫的男人在一个空旷的街道一个年轻的男人走在一个小的院子一个穿着灰色裤子和灰色衬衫的人是在一个农庄里走的一个穿红色衬衫的年轻人走在红色衬衫外面的围栏外一个穿着灰色和黑色夹克的男人走在一个地方一个人在房间里打着什么一个人踩在一个红色的高跟鞋的门槛上一个年轻人从楼上的建筑物开始跑步穿着拖鞋在院子里一个穿着衬衫和蓝色牛仔裤的男人正在操作他的人
多结果展示
为了更好地分析MLP+GPT2 tuning模型的生成效果,我们从flickr blog网站随机下载了三张图片,对于每张图片生成10条caption,并且不做修改地进行展示。
示例一
可以看到模型生成的前几个caption,不仅语义与图片相符,而且流畅度也不错。即使后面几个caption在流畅度方面存在不足,但是却都能捕获到图片中【女人、白色衣服】这一关键信息,这说明模型具备将图像空间与文本空间进行语义对齐的能力。
一个女人穿着白色的衣服走到田野里一个穿着白衣服的女人在外面散步一个穿着白色连衣裙的女人一个穿着白色连衣裙的女人走在一个岩石的田野里一个穿着白衣服的女人走下一条土路一个穿着白色衣服的女人正走在一棵大树下一个穿着白衣服的女人正走着一棵树一个女人正走着一个白色的花在一个山谷一个女人在一个白色的衣服和一顶白色的帽子在田野里散步一个穿着白衣服的女人正走着一棵棕色的灌木
示例二
可以看到,在下列生成的10个caption里,几乎所有caption都捕获到了关键信息【电脑】,并且绝大部分caption都能较为准确地对图片进行描述
一个人在电脑上工作在一个办公室里工作的女性一个戴着耳机的人在电脑上工作一个女人坐在一个苹果笔记本电脑前一个女人用一台笔记本电脑在电脑上做了一些工作一个年轻人用一台笔记本电脑做演示一个人坐在一台笔记本电脑上一个穿着黑色衬衫的男人在他的电脑上工作一个人在电脑上的数据一个女人在看电脑屏幕而在她的笔记本电脑
示例三
可以看到,模型倾向于以【一个】作为开头去生成caption,这是由于训练集本身就是有偏的,大部分数据都是以数量词作为开头,并且训练集中风景类的训练数据较少。对于该图片,虽然模型生成的大部分caption都无法准确地描述语义信息,但是却生成了【湖、桥、夕阳、日落、水】等与图片语义相关的关键词, 所以模型在一定程度上还是能够将图片与文本的语义信息联系起来。
一艘船在湖上钓鱼一个人在一座桥上的湖上看日落有一艘船在一个码头上看到一个水船上的夕阳和船的背景一个人在水里钓鱼船上有很多水的背景在日落时一艘船在水中航行一个人站在码头旁的一个水上看着一条船上的夕阳日落时分一个人站在一个湖上的船上一个人正站在一个码头上看着水和帆船
更多效果展示

下图展示了MLP+GPT2 tuning模型的更多的生成样例
05
结语

本文分享了笔者基于ClipCap所实现的一个Image Caption项目,介绍了论文思想、实现细节、实验结果与分析。
Flickr30中文caption数据是由机器翻译获得的,质量上存在缺陷,后续可以考虑使用更加高质量的数据进行模型训练。并且根据训练过程分析可以知道,由于训练数据量较小,模型存在过拟合的风险,后续可以考虑使用更高量级的数据进行训练,相信能够获得更好的效果。
原论文中使用的生成模型为GPT2-Large,包含36层Attention。本项目使用的GPT2模型包含12层Attention,后续可以考虑使用参数量更大的生成模型,以提高生成效果。
笔者对本项目所使用的数据集、预训练模型权重、训练好的ClipCap模型权重进行了整理,公众号后台回复【001】即可获取下载链接。
这是笔者的第一篇推文,希望以后能够坚持下来,以这种方式和大家分享更多有趣的NLP项目和技术,也作为自己的技术沉淀。
关注我们,炼丹速度加倍
继续阅读
阅读原文