Spaces:
Running on Zero
Running on Zero
| """ | |
| Peak-End Aggregation (temporal aggregation). | |
| Given the per-frame attention weights produced by Key Moment Discovery, the | |
| video-level feature is the weighted average of frame features followed by a | |
| projection: | |
| f_video = Σ_t w_t · f_t -> proj -> LayerNorm | |
| """ | |
| import torch | |
| import torch.nn as nn | |
| class PeakEndAggregation(nn.Module): | |
| """ | |
| Temporal aggregation via a single unified attention weight. | |
| forward receives ``attention_weights`` (from KeyMomentDiscovery) and does a | |
| weighted pooling over frame features, then projects to ``output_dim``. | |
| """ | |
| def __init__(self, embed_dim=768, output_dim=768): | |
| super().__init__() | |
| self.output_dim = output_dim | |
| # Projection: map the weighted-pooled feature to output_dim. | |
| self.proj = nn.Sequential( | |
| nn.Linear(embed_dim, embed_dim), | |
| nn.GELU(), | |
| nn.Linear(embed_dim, output_dim), | |
| ) | |
| self.output_norm = nn.LayerNorm(output_dim) | |
| def forward(self, frame_features, attention_weights): | |
| """ | |
| Args: | |
| frame_features: [B, T, embed_dim] frame features | |
| attention_weights: [B, T] per-frame attention weight | |
| Returns: | |
| video_feature: [B, output_dim] aggregated video feature | |
| """ | |
| weighted_features = torch.bmm( | |
| attention_weights.unsqueeze(1), # [B, 1, T] | |
| frame_features, # [B, T, embed_dim] | |
| ).squeeze(1) # [B, embed_dim] | |
| video_feature = self.proj(weighted_features) | |
| video_feature = self.output_norm(video_feature) | |
| return video_feature | |