学习内容:
- 强化学习在HMN项目上的应用
- VLTinT: Visual-Linguistic Transformer-in-Transformer for Coherent Video Paragraph Captioning(AAAI2023)
学习时间:
- 3.20 ~ 3.25
学习笔记:
1.强化学习在HMN项目上的应用
在sample操作时,需要将video feature及其对应的masks送入decoder生成相应的预测word和attention,而HMN本身的transformerdecoder不适用于这些特征的输入,同时如果通过修改使当前decoder兼容sample操作时的输入会影响到模型第一阶段(非强化学习阶段)的训练,所以舍弃了这种做法,选择再创建一个新的decoder类以及对应的decoderlayer类:
class Decoder(nn.Module):
def __init__(self, vocab_size=28485, d_model=512, N=6, heads=8, dropout=0.1):
super().__init__()
self.N = N
self.embed = Embedder(vocab_size, d_model)
self.pe = PositionalEncoder(d_model, dropout=dropout)
self.layers = get_clones(DecoderLayer(d_model, heads, dropout), N)
self.norm = Norm(d_model)
self.cache = None
def _init_cache(self):
self.cache = {}
for i in range(self.N):
self.cache['layer_%d' % i] = {
'self_keys': None,
'self_values': None,
}
def forward(self, trg, e_outputs, src_mask, trg_mask, step=None):
if step == 1:
self._init_cache()
x = self.embed(trg)
x = self.pe(x, step)
attn_w = []
for i in range(self.N):
layer_cache = self.cache['layer_%d' % i] if step is not None else None
x, attn = self.layers[i](x, e_outputs, src_mask, trg_mask, layer_cache=layer_cache)
attn_w.append(attn)
return self.norm(x), sum(attn_w) / self.N
class DecoderLayer(nn.Module):
def __init__(self, d_model, heads, dropout=0.1):
super().__init__()
self.norm_1 = Norm(d_model)
self.norm_2 = Norm(d_model)
self.norm_3 = Norm(d_model)
self.dropout_1 = nn.Dropout(dropout)
self.dropout_2 = nn.Dropout(dropout)
self.dropout_3 = nn.Dropout(dropout)
self.attn_1 = MultiHeadAttention(heads, d_model, dropout=dropout)
self.attn_2 = MultiHeadAttention(heads, d_model, dropout=dropout)
self.ff = FeedForward(d_model, dropout=dropout)
def forward(self, x, e_outputs, src_mask, trg_mask, layer_cache=None):
x2 = self.norm_1(x)
x = x + self.dropout_1(self.attn_1(x2, x2, x2, trg_mask, layer_cache=layer_cache, attn_type='self')[0])
x2 = self.norm_2(x)
context, attn = self.attn_2(x2, e_outputs, e_outputs, src_mask, attn_type='context')
x = x + self.dropout_2(context)
x2 = self.norm_3(x)
x = x + self.dropout_3(self.ff(x2))
return x, attn
然后在train文件中,临时创建一个decoder对象,用来接收video feature及其对应的masks:
temp_decoder = Decoder() # 临时decoder对象
for i in range(1, 60):
np_mask = np.triu(np.ones((1, i, i)), k=1).astype('uint8')
trg_mask = Variable(torch.from_numpy(np_mask) == 0).cuda()
print('trg_mask', trg_mask.shape)
word, attn = temp_decoder(outputs[:, -1].unsqueeze(1), memory_bank, src_mask,
trg_mask[:, -1].unsqueeze(1).repeat(1, 64, 1), i) #调用decoder类中的forward函数
然而代码在运行时报错:
经查阅资料总结了可能原因:
-
deepcopy操作不适用于非叶结点,需要检查张量是属于叶结点还是非叶结点。
-
使用了nn.DataParallel(model)之后,在模型的 forward() 函数下使用 copy.deepcopy(self.module) 就会报上面的错误,解决方案是使用 copy.deepcopy(self.module) 最好不要在 forward() 中进行Copy,而是对实例进行Copy。
目前尝试了这两种方法,还没有解决问题。
2.VLTinT: Visual-Linguistic Transformer-in-Transformer for Coherent Video Paragraph Captioning(AAAI2023)
在今年AAAI2023录用了VLTinT这篇文章,其在短视频字幕生成任务的基础上进一步探索了视频段落字幕概括字幕。同时对模型提出了更高的要求:具有很强的时空事件提取能力。借此对未处理的长视频生成概括性的文字描述,且描述的内容遵循一定的时间顺序。
作者遵循人类观看视频时的感知过程,通过将视频场景分解为视觉(环境、人物、动物等)和非视觉成分(动作、关系等)来层次化的理解场景,并且提出了一种称为Visual-Linguistic(VL)的多模态视觉语言特征。在VL特征中,一个完整的视频场景主要由三种模态进行建模,包括:
- 代表周围整体场景的全局视觉环境表征(global visual environment)
- 代表当前发生事件的局部视觉主体表征(local visual agents)
- 描述视觉和非视觉元素的语言性场景元素(linguistic concepts)
作者设计了一种自回归Transformer结构(TinT)来对这三种模态进行表征和建模,可以同时捕获视频中事件内和事件间内容的语义连贯性。为了更加高效的训练模型,还配套提出了一种全新的VL多模态对比损失函数(VL loss),来保证学习到的嵌入特征与字幕语义相匹配,实验表明该模型在生成字幕的准确性和多样性方面达到了SOTA。
VLTinT 模型与其它常规方法的对比:
区别在于:
-
在编码时将视频场景分解为三种模态,实现视觉与非视觉元素的细粒度描述。
-
为了关注当前事件的关键信息,加入了混合注意机制(Hybrid Attention Mechanism,HAM)。
VLTinT模型结构概览
其中,VL Encoder主要负责对一段视频中的不同事件提取特征表示,而TinT Decoder主要负责对这些特征进行解码生成每个事件的文字描述,同时对事件内和事件间的一致性进行建模。这两个模块都通过本文提出的VL对比损失以端到端的方式进行训练。
实验结果
总结:
作者针对视频段落级字幕生成任务(VPC)提出了一种新式的Transformer in Transformer结构,该结构由一个VL编码器和TinT解码器组成。对视频场景划分三种独特模态进行分层次建模和学习,这种方式非常贴合人脑对视频数据的感知过程。为视频字幕领域提供了一个很好的研究思路,此外,在TinT解码器中的自回归结构可以有效地学习视频中事件内和事件间的不同依赖关系,也帮助提高了模型的整体性能。作者在未来展望中提到,可以将VLTinT模型提取的多模态视频特征扩展到其他用途更广泛的密集视频字幕生成任务中,以提高AI视频制作的工作效率。