使用
module_cross.py 中的
Transformer 类进行时序交互。
代码对应:
# Sequential type: Time Transformer Encoder
seq_length = visual_output.size(1)
position_ids = torch.arange(seq_length, dtype=torch.long, device=visual_output.device)
position_ids = position_ids.unsqueeze(0).expand(visual_output.size(0), -1)
frame_position_embeddings = self.frame_position_embeddings(position_ids)
visual_output = visual_output + frame_position_embeddings
extended_video_mask = (1.0 - video_mask.unsqueeze(1)) * -1000000.0
extended_video_mask = extended_video_mask.expand(-1, video_mask.size(1), -1)
visual_output = visual_output.permute(1, 0, 2) # NLD -> LND
visual_output = self.transformerClip(visual_output, extended_video_mask)
visual_output = visual_output.permute(1, 0, 2) # LND -> NLD
visual_output = visual_output + visual_output_original
注意: 根据配置文件 (
msrvtt-7k.yaml),这里堆叠了
4层 Transformer Block。
单层步骤:Pre-LN → Self-Attention → Residual → Pre-LN → MLP (QuickGELU) → Residual。
初始化技巧: 为了防止深层网络数值爆炸,Attention 和 MLP 的输出投影层权重被缩放了 $1/\sqrt{2L}$ (约 0.35)。
下方展示的是第 1 层的内部细节,以及经过 4 层处理后的最终输出。
2.3 Layer 1: FFN (Feed-Forward Network) & Residual
架构说明 (Pre-LN): 本模型使用的是 Pre-LN 结构,与原始 Transformer 的 "Add & Norm" (Post-LN) 不同。
流程: Input $\xrightarrow{Norm}$ FFN $\xrightarrow{Add}$ Output
即: $x = x + \text{FFN}(\text{LayerNorm}(x))$
这里的 MLP (Multi-Layer Perceptron) 即为标准 Transformer 中的 FFN 部分。