Video Caption(跨模态视频摘要/字幕生成)

在这里插入图片描述
Video Caption
视频摘要/视频字母生成属于多模态学习下的一个子任务,大体目标就是根据视频内容给出一句或多句文字描述。所生成的caption可用于后续的视频检索等等,也可以直接帮助智能体或者有视觉障碍的人理解现实情况。

在这里插入图片描述
典型的架构如上图(图自[ICCV2015] Sequence to Sequence – Video to Text,从视频帧到文本句子的端对端模型),该任务可以分解为两个子任务,一个是如何理解视频/多模态,并融合以得到更好的视觉表示,另一个是视频描述生成,如何得到质量高,甚至可控、稳定、又多样的句子。

主要涉及到3个问题:

  • (1)辅助语义信息监督,如何利用视觉语义概念来提高字幕质量的辅助目标;
  • (2)减轻客观目标失配问题的方法;
  • (3)密集字幕,它需要在视频中联合定位和描述多个事件。

接下来整理一些比较重要的论文。

在这里插入图片描述
[MM2016] Describing Videos using Multi-modal Fusion
如何理解视频,那么就把所有能得到的数据通通用上吧。模型架构如上图,encoder端用了video(全局)、image(局部)、aural(环境音)、speech(语音)和meta modality(种类),然后用一个融合网络进行多模态融合了之后,再输入到后面的decoder端得到句子。

当然这是16年的工作,现在在模态上还可以用更多的信息,如全局信息如光流,局部概念信息如action、event、activity,纯局部信息如object,relation等等,甚至还可以学习视频主题语义来增强。

在这里插入图片描述
[CVPR2017] Top-down Visual Saliency Guided by Captions
注意力从不会缺席,这篇文章通过计算“字幕引导的视觉显着性”(即注意力),从而在视觉输入中的对象与句子中的单词之间建立对应关系的程度 。具体的模型架构如上图,会分别在时间和空间上做两个注意力,即如视觉注意力是对输入的每个帧i和每个单词t产生时间显着性值,然后 通过从输入序列中删除除第i个描述符之外的所有描述符。最后的输出会与与原始单词概率分布进行比较来计算loss。

code:https://github.com/VisionLearningGroup/caption-guided-saliency

在这里插入图片描述
[CVPR2018] End-to-end dense video captioning with masked transformer
注意力可十分方便的升级成为Transformer。这篇文章就是通过改装Transformer,如上图,以逐帧图像的CNN特征到Transformer中,不然一样的是ffn后面接的是TCN,然后再输入到解码器生成caption。

在这里插入图片描述
[MM2019] Aligning Linguistic Words and Visual Semantic Units for Image Captioning
这篇文章继续细化图像中的object,relation和attribute(分别用目标检测器,属性分类器,关系检测器得到)来增强对视觉的理解,具体来说作者一个提出基于图卷积网络(GCNs)分别在语义和几何层面中显式建模对象交互,并充分利用语言词和视觉语义单元之间的对齐来进行图像caption生成。

模型图上图,其中三个概念分别代表:objects (“man”, “helmet”), their attributes (“helmet is red”), and relationships (“man hold bat”),即目标是某些局部区域,属性是目标对象的属性如red,而关系则是不同目标对象之间的交互关系。

而语义图(Semantic Graph)和几何图( Geometry Graph)的每个节点都对应于一个视觉语义单元,即一个对象、一个属性或两个对象之间的语义/几何上的交互。 然后用GCN去学习其上下文感知的嵌入,即首先决定当前单词大约是哪种类型的视觉语义单元(即对象、属性或交互),然后在这种类型下找到最相关的视觉语义单元,从而将当前单词与这些单元分层对齐。

然后通过Gated Fusion来控制这三个特征的重要性程度,最后接一个文本生成器得到caption。

在这里插入图片描述
[CVPR2019] Object-aware Aggregation with Bidirectional Temporal Graph for Video Captioning
找关系的文章,这篇也比较突出。主要思路就是提取出视频的关键object(空间上和时序上都统一),并且构建双向时序图优化特征,最后再融合使用整个视频提取出的全局特征来生成描述句子。

模型图上图,主要分为三个部分,双向时序图,目标感知聚合,和对caption解码生成。

  • 双向时序图。先使用目标检测处理视频的关键object(即提取出N个object区域),然后再利用相似性构建视频中的时序图,其中相似性有三个部分来衡量:区域的外观特征相似度,区域的IoU相似度和区域的面积尺寸相似度 s ( i , j ) = ( s a p p ( i , j ) + s i o u ( i , j ) + s a r e a ( i , j ) ) / 3 s(i,j)=(s_{app}(i,j)+s_{iou}(i,j)+s_{area}(i,j))/3 s(i,j)=(sapp(i,j)+siou(i,j)+sarea(i,j))/3双向的意思是,视频的正序和负序(逆帧)都会都会根据以上相似度来连接边。
  • 目标感知。这个是对双向时序图做特征优化的,使用的是C-GRU(CNN和GRU的结合,可以同时提时空信息)。
  • caption。然后使用attention模型对上一步生成的区域序列特征和全局区域特征融合,再输入到GRU得到最后的caption结果。

在这里插入图片描述
[CVPR2020] Object Relational Graph with Teacher-Recommended Learning for Video Captioning
当然关于视频目标的挖掘还可以做的更加复杂!这篇文章作者认为有两个特征表示不足的地方:

  • 视觉面缺乏物体的交互,从而缺乏足够的视觉表示。
  • 语言层面缺少与内容相关单词的充分训练问题。

所以提出基于关系目标图OEG的编码器以丰富视觉表示(直接看图就是用GCN捕捉物体交互后,再两个Attention…),并且同时设计了一种蒸馏方法,这样可以直接整合外部语言模型(teacher)将丰富的语义整合到字幕模型(student)中以解决词长尾问题。最后Attention LSTM得到视频描述的结果。

在这里插入图片描述
[IJCAI2020] Learning to Discretely Compose Reasoning Module Networks for Video Captioning
视频字幕生成需要更复杂的视觉时空推理,例如要生成“一个人在打篮球”这句话,需要首先定位和描述主题“人”,然后解释这个人是“投”,然后描述投的对象“篮球。所以作者提出推理模块网络(RMN)。为了进行时空视觉推理,RMN采用三个基本的时空推理模块:

  • a)locate模块,通过时空关注定位视频的单一区域,从而生成的视觉词,如图中的“人”、“篮球”;
  • b)relation模块,先检测视频各帧对象,然后通过两帧配对建模动作,生成动作词;
  • c)Func模块根据语言上下文生成功能词,如图中的“a”、“is”这种。

其次,为了沿着生成过程组成推理结构,RMN使用了一个动态的和离散的模块选择器,然后采用Gumbel采样使离散采样过程可微,然后用词性标注的POS标签约束模块选择器。

code:https://github.com/tgc1997/RMN

在这里插入图片描述
[ACL2017] Multi-Task Video Captioning with Video and Entailment Generation
这篇文章用多任务学习的想法来优化整个caption框架,整个框架共包括三个任务:

  • Unsupervised video prediction。无监督的未来帧预测,出发在于单独抽视频特征不能很好的提取出时序动作特征,所以用自监督的方法,使用video encoder 和video decoder,其中解码器decoder部分使用特征来还原输入视频的顺序;
  • Entailment Generation:。同义句生成/句子含义生成,也就是给句子生成含义相似的新句子,使用language encoder和 language decoder,然后和video端一样的功能,都是优化两边encoder的能力。
  • Video Captioning。我们要做的主任务,直接使用video encoder和language decoder即可。

多任务比单任务单模型的好处在于可以拟合出顺序推演的过程,从而可以增强缺乏时序表示和逻辑推演。

在这里插入图片描述
[MM2020] Learning Semantic Concepts and Temporal Alignment for Narrated Video Procedural Captioning
这篇同样也是多任务的路线,Motivation在于引入转录文字可以克服视觉物体的遗漏+补充文本语义的细粒度概念。挑战有三个

  • 1视频上下文很重要
  • 2视频和转录文字如何对齐
  • 3转录文字无明确信息怎么处理

模型图如上,框架上是全局文本特征+全局视频特征+每个word进如Transformer得到特征,然后用attention对齐全局文本和全局视频对此时的特征,最后拼接这三者得到特征。

然后做两个任务:一是语义概念预测,这里直接算预测的概念与ground truth的KL。二是文本摘要,这里利用概念库做是否copy的选择以克服长尾问题。

在这里插入图片描述
[AAAI2019] Learning to Compose Topic-Aware Mixture of Experts for Zero-Shot Video Captioning
继续补充外部知识,主要是为了将任务扩展到zero-shot,所以提出TAMoE)模型,模型架构如上图,主要由视频编码模块、基于TFIDF的主题嵌入模块和TAMOE摘要生成模块组成。

  • 视频编码。这个直接用C3D来做,并且预测动作标签。
  • 主题嵌入模块。通过动作标签可以从外部语料库中获取与主题相关的文档,并用于计算基于TFIDF的主题嵌入,这代表了动作的语义意义。
  • caption解码。将视频特征和主题嵌入作为输入,并通过动态组成多个专家Mixture-of-Experts (MoE)来生成字幕。这里的专家可以学习不同的主题嵌入,方便隐式地将从看到的活动中学到的知识转移到看不见的活动中。

code:https://github.com/eric-xw/Zero-Shot-Video-Captioning

在这里插入图片描述
[ECCV2020] Comprehensive image captioning via scene graph decomposition
这篇文章是相要同时平衡caption的diversity, grounding and controllability。特别是多样性caption应该怎么控制生成比较好?因为一个视频中不同人会有不一样的注重点,那么可以生成很多的描述。作者提出的做法是通过scene graph decomposition,关于scene graph博主有整理过就不做赘述,这里主要是通过把由从图像得到的场景图通过采样多个子图,之后由子图完成句子生成即可。

模型图如上,通过采样可以得到很多种不一样的sub-graph,可以通过给sub-graph打分来评判子图是否合理(其中这里是有向图),然后也是把得到的特征输入到后面的带attention的LSTM即可。

在这里插入图片描述
[CVPR2021] Towards Accurate Text-Based Image Captioning With Content Diversity Exploration
通过识别目标对象的ocr来增强caption。作者认为需要在意的问题是:

  • 1如何确定图像中哪部分是重要的,应该对谁生成描述;
  • 2捕捉图像中多样的文本及其关系是重要的;
  • 3如何生成多样性描述。

对应的方法是先对文本目标构建锚点图,然后对每个小子图生成句子,就能又多样又长的句子了,对应模型架构如上图。分为三个模块,第一个模块是是为了融合visual和text。第二个模块是生成锚点图(先根据预测分数选择锚点,然后根据锚点构建锚点图)。第三个模块是得到caption。

在这里插入图片描述
[CVPR2021] Open-book Video Captioning with Retrieve-Copy-Generate Network
首先作者提出关于Video Caption的现有技术缺点:

  • 1输入只是视频,无法得到更通用的表达。
  • 2知识是固定的,之后无法扩展。

这篇文章Open-book意思是不仅限于当前视频本身,而是视频先检索语料再动态复制再生成,会更加的全面灵活。模型结构如上图,最左上的是提取到video的motion和appearance特征,然后将其做一个video-to-text的检索,这个组件在右上角(双塔的检索模型,算similarity取topk的检索结果)。然后将视频feature和检索到的sentence进行融合输入到copy-mechanism generator里面,去生成每一个词,这个组件在右下角(主要是对visual部分得到视觉词做copy,而visual本身会跟sentence特征拼接去预测,两者结合得到最后的预测结果即可)。

在这里插入图片描述
Semantic Grouping Network for Video Captioning
继续补21年的文章,这篇文章主要的motivation是“Grouping”,即将每一帧作为一个独立的信息单元来考虑并不是理解视频的有效方法,人类通过根据语义将视频分割成信息单元来理解视频是很自然的。所以作者尝试通过根据人、对象或动作等含义将信息分组,而不是逐帧分组来理解视频。另一方面,作者同时强调了已经输出的句子也是十分的重要而一直不被重视,它的语义信息可以帮助来分组。所以作者提出SGN,模型图,如上,它通过围绕部分解码标题的短语对齐帧,将视频编码为语义组,并通过利用语义组作为信息单元来描述视频。

在这里插入图片描述
首先作者列出了如上几种caption的模式,以往对group的识别都是基于event的,如图b。对于冗余帧是直接抛弃的,如图c,而作者的做法是d,先分组,然后再结合部分解码来生成句子。

然后模型部分还想提一下的就是作者提出Contrastive Attention (CA) loss,这里作者认为语义组应该只包含与其短语高度相关的框架,以确保一个语义组在其成员之间具有连贯的意义,所以会对输入视频的负视频进行采样(故模型图的输入就有两段video)。

在这里插入图片描述
RSTNet: Captioning with Adaptive Attention on Visual and Non-Visual Words
同CVPR2021的文章。作者的动机来自两点:

  • 处理特征。图像的2D空间变成1D特征这一展平过程会造成的空间信息损失的问题。
  • 生成架构。对视觉词和非视觉词的处理不做区分,如man 和 with。

所以作者提出了一个视觉信息增强和多模态信息敏感的Transformer结构,Relationship-Sensitive Transformer (RSTNet),利用网格与网格之间相对位置的几何关系解决了特征展平操作造成的空间信息损失的问题,并且利用一个额外的注意力层度量视觉特征与语义特征的贡献,从而充分引导图像描述中视觉词和非视觉词的生成。模型图如上,主要比较重要的点是2个:

  • 网格特征。即最下面的黄色区域。会先切成网格,然后找网格之间的关系,最后生成特征。
  • 视觉特征和语义特征的区别。动态地测量视觉信号(黄色)和语言信号(蓝色)对预测每个单词(紫色/粉色)的贡献,这里也是用多头注意力来算。为什么能解决视觉词和非视觉词是因为,对于视觉词那么视觉重要,对于非视觉词是文本的上下文更重要,所以这里通过动态计算来做这一点。

在这里插入图片描述
Direction Relation Transformer for Image Captioning
博主继续补文,今天补来自MM21的文章。比较有意思的是作者提出应该挖掘对象区域间的方向性关系,比如“女人”和“马”之间的相对方向可以指导模型生成“一个骑马的女人”,而不是“一个站在马前的女人”。方向可以更好的理解图像中物体之间的相对位置,并有效地生成正确的caption。

所以作者提出Direction Relation Transformer去嵌入方向到attention中以实现定向感知。具体的做法框架如上图,大结构上还是Transformer-based的,主要在左上角的direction如何插入到attention的计算中。
在这里插入图片描述
关于方向的定义如上图,在二维空间中预先定义了4k个单位的方向向量,其中每个向量代表一个方向类别。以矩形坐标系的原点为中心,第i个单位方向向量可以表示为:
α i = ( c o s ( i ϕ 2 k ) , s i n ( i ϕ 2 k ) ) \alpha_i=(cos(\frac{i\phi}{2k}),sin(\frac{i\phi}{2k})) αi=(cos(2kiϕ),sin(2kiϕ))然后其嵌入Relative Direction Embedding Matrix的计算为两个box之间的角度 v m n = ( x m − x n Z , y m − y n Z ) v_{mn}=(\frac{x_m-x_n}{Z},\frac{y_m-y_n}{Z}) vmn=(Zxmxn,Zymyn) r m n = a r g m a x v m n ⋅ α i ∣ ∣ v m n ∣ ∣ ⋅ ∣ ∣ α i ∣ ∣ r_{mn}=argmax \frac{v_{mn}\cdot \alpha_i}{||v_{mn}||\cdot||\alpha_i||} rmn=argmaxvmnαivmnαi得到这个向量之后可以自由插入到KVQ中来参与模型。就作者的实验结果来看这三种都不差,最好的性能是融合到V中。

dataset
普通的数据集的话有如下几种。
在这里插入图片描述
最近博主看文章发现大家都不止满足于做普通的caption了,开始转于做各种稀奇古怪但又有一定实践价值的新任务,比如程序化caption、多样化caption、独特化caption、多视角caption、常识性caption、问题控制型caption。。。于是在下一篇博文,博主找了几篇相关文章来整理一下这些丰富的任务变体们。


最后看一个比较简单的baseline,即开头那张两层LSTM的S2VT模型的架构

#按照S2VT的结构是2层LSTM,第一层是编码帧序列
#第二层是接受第一层的隐层状态+与0填充之后再编码(很多对应位置没有值,直接pad为0来填充)

class S2VTModel(nn.Module):
    def __init__(self, vocab_size, max_len, dim_hidden, dim_word, dim_vid=2048, sos_id=1, eos_id=0,
                 n_layers=1, rnn_cell='gru', rnn_dropout_p=0.2):
        super(S2VTModel, self).__init__()
        #可选择是LSTM或GRU两种
        if rnn_cell.lower() == 'lstm':
            self.rnn_cell = nn.LSTM
        elif rnn_cell.lower() == 'gru':
            self.rnn_cell = nn.GRU
        self.rnn1 = self.rnn_cell(dim_vid, dim_hidden, n_layers,
                                  batch_first=True, dropout=rnn_dropout_p)
        self.rnn2 = self.rnn_cell(dim_hidden + dim_word, dim_hidden, n_layers,
                                  batch_first=True, dropout=rnn_dropout_p)

        self.dim_vid = dim_vid #视频维度
        self.dim_output = vocab_size #词表大小
        self.dim_hidden = dim_hidden #隐层维度
        self.dim_word = dim_word #词维度
        self.max_length = max_len #最大长度
        self.sos_id = sos_id #开始符
        self.eos_id = eos_id #结束符
        self.embedding = nn.Embedding(self.dim_output, self.dim_word) #编码词表的词,因为是one-hot所以直接是词表大小

        self.out = nn.Linear(self.dim_hidden, self.dim_output) #用于输出的fc

    def forward(self, vid_feats, target_variable=None,
                mode='train', opt={}):
        batch_size, n_frames, _ = vid_feats.shape #视觉特征维度
        #两种pad填充,frame和word
        padding_words = Variable(vid_feats.data.new(batch_size, n_frames, self.dim_word)).zero_()
        padding_frames = Variable(vid_feats.data.new(batch_size, 1, self.dim_vid)).zero_()
        #两种开始状态,frame和word都为none
        state1 = None
        state2 = None
        #self.rnn1.flatten_parameters()
        #self.rnn2.flatten_parameters()
        output1, state1 = self.rnn1(vid_feats, state1) #第一层LSTM
        input2 = torch.cat((output1, padding_words), dim=2) #凭借输出的隐层和0填充的pad
        output2, state2 = self.rnn2(input2, state2) #然后输到第二层

        seq_probs = []
        seq_preds = []
        if mode == 'train': #训练模式
            for i in range(self.max_length - 1):
                # <eos> doesn't input to the network
                current_words = self.embedding(target_variable[:, i]) #嵌入当前词
                #重置参数的数据指针,使内存更contiguous(连续性),利用率高
                self.rnn1.flatten_parameters()
                self.rnn2.flatten_parameters()
                #逐词的输出都要通过pad,过两层LSTM得到结果
                output1, state1 = self.rnn1(padding_frames, state1) 
                input2 = torch.cat(
                    (output1, current_words.unsqueeze(1)), dim=2)
                output2, state2 = self.rnn2(input2, state2)
                logits = self.out(output2.squeeze(1)) #预测概率
                logits = F.log_softmax(logits, dim=1)
                seq_probs.append(logits.unsqueeze(1))
            seq_probs = torch.cat(seq_probs, 1)

        else: #测试模式
            current_words = self.embedding(
                Variable(torch.LongTensor([self.sos_id] * batch_size)).cuda())#嵌入当前词
            for i in range(self.max_length - 1):
                 #重置参数的数据指针,使内存更contiguous(连续性),利用率高
                self.rnn1.flatten_parameters()
                self.rnn2.flatten_parameters()
                #逐词的输出都要通过pad,过两层LSTM得到结果
                output1, state1 = self.rnn1(padding_frames, state1)
                input2 = torch.cat(
                    (output1, current_words.unsqueeze(1)), dim=2)
                output2, state2 = self.rnn2(input2, state2)
                logits = self.out(output2.squeeze(1))
                logits = F.log_softmax(logits, dim=1)
                seq_probs.append(logits.unsqueeze(1))
                _, preds = torch.max(logits, 1)
                current_words = self.embedding(preds) #得到结果词
                seq_preds.append(preds.unsqueeze(1))
            seq_probs = torch.cat(seq_probs, 1)
            seq_preds = torch.cat(seq_preds, 1)
        return seq_probs, seq_preds

完整的源码阅读笔记在:https://github.com/nakaizura/Source-Code-Notebook/tree/master/S2VT

另外有注释一个更完备的框架Video-guided Machine Translation(VMT),即最近发布一个中英数据集VATEX的代码,这个也可以改装了之后做video caption。源码解析笔记在同一个github:https://github.com/nakaizura/Source-Code-Notebook/tree/master/VMT 。


在这里插入图片描述
ClipCap: CLIP Prefix for Image Captioning
补文最新的2022年文章,CLIP做到image caption中,CLIP博主已经整理过,不做赘述。作者提出ClipCap模型,其模型结构如上,主要分为三部分:

  • 图像编码器:采用CLIP模型,负责对输入的图像进行编码,得到一个图片向量。
  • Mapping Network:扮演图像空间与文本空间之间的桥梁,负责将图片向量映射到文本空间中,得到一个文本提示向量序列prefix embeddings。
  • 文本解码器:采用GPT2模型,根据提示向量序列,生成caption。

paper:https://arxiv.org/abs/2111.09734
github:https://github.com/yangjianxin1/ClipCap-Chinese

  • 29
    点赞
  • 112
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值