引言
视频理解面临的核心挑战之一是计算效率问题:视频数据量庞大,处理长视频需要消耗大量计算资源。与图像模型不同,视频模型需要额外建模时间维度,这使得计算复杂度呈倍数增长。
轻量级视频模型旨在在保持模型性能的同时降低计算成本。本文系统介绍几种经典的轻量级视频网络设计,包括SlowFast Networks、R(2+1)D、CSN等,分析它们的设计原理和架构特点。
计算效率的挑战
3D卷积的计算量
对于视频输入 ,使用3D卷积核 的计算量为:
其中 是输出的时间/空间维度。
对比2D vs 3D卷积:
| 模型 | 卷积类型 | 参数量 | FLOPs |
|---|---|---|---|
| ResNet-50 (图像) | 2D | 25.6M | 4.1G |
| R3D-50 (视频) | 3D | 46.9M | 62.6G |
| R(2+1)D-50 (视频) | 分解3D | 28.9M | 43.5G |
效率优化方向
轻量级视频模型的主要优化方向:
- 分解3D卷积:将卷积分解为空间卷积和时间卷积
- 通道分离:分离时间/空间通道以减少计算
- 多路径设计:设计快慢通道分别处理不同信息
- 稀疏采样:减少输入帧数以降低计算
SlowFast Networks
核心思想
SlowFast Networks1 由Facebook AI Research提出,灵感来自灵长类视觉系统的Midget ganglion cells(小神经节细胞):
- P细胞(Parvocellular):小感受野,高空间分辨率,低时间分辨率 → 对应Slow pathway
- M细胞(Magnocellular):大感受野,低空间分辨率,高时间分辨率 → 对应Fast pathway
视觉系统洞察:
┌────────────────────────────────────┐
│ 人类视觉系统 │
│ P细胞: 精细空间细节,慢速变化 │
│ M细胞: 粗略空间信息,快速变化 │
└────────────────────────────────────┘
↓ 类比 ↓
┌────────────────────────────────────┐
│ SlowFast 网络 │
│ Slow pathway: 高帧率采样 │
│ Fast pathway: 低帧率采样 │
└────────────────────────────────────┘
网络架构
Slow pathway
- 帧率:每8帧采样1帧()
- 空间分辨率:高分辨率
- 通道数:高通道数()
- 功能:捕获语义信息(空间细节、物体类别)
Fast pathway
- 帧率:每1帧采样1帧
- 空间分辨率:低分辨率(通过空间降采样实现)
- 通道数:低通道数(,通常)
- 功能:捕获运动信息(快速变化、时间动态)
侧向连接
两路径之间通过**侧向连接(Lateral Connections)**进行信息交互:
输入视频
│
├──→ Slow pathway (每8帧1帧)
│ │
│ └──→ [高语义,低时间分辨率]
│ ↑
│ Lateral Connection
│ ↓
└──→ Fast pathway (每1帧1帧)
│
└──→ [低语义,高时间分辨率]
侧向连接的具体操作:
class LateralConnection(nn.Module):
"""
SlowFast的侧向连接
"""
def __init__(self, dim_slow, dim_fast):
super().__init__()
# Fast → Slow: 需要降维
self.proj_fast_to_slow = nn.Sequential(
nn.conv3d(dim_fast, dim_slow, kernel_size=1),
nn.BatchNorm3d(dim_slow)
)
# 时间降采样:从Fast的帧率降到Slow的帧率
self.temporal_downsample = nn.MaxPool3d(
kernel_size=(alpha, 1, 1), # alpha = 帧率比
stride=(alpha, 1, 1)
)
def forward(self, feat_slow, feat_fast):
# feat_slow: [B, C, T//alpha, H, W]
# feat_fast: [B, beta*C, T, H, W]
# Fast → Slow投影
feat_fast_proj = self.proj_fast_to_slow(feat_fast)
# [B, C, T, H, W]
# 时间降采样
feat_fast_proj = self.temporal_downsample(feat_fast_proj)
# [B, C, T//alpha, H, W]
# 融合
return feat_slow + feat_fast_proj完整架构
SlowFast网络结构:
class SlowFastNetwork(nn.Module):
"""
SlowFast Network
"""
def __init__(self, alpha=8, beta=1/8, tau_fast=1):
super().__init__()
self.alpha = alpha # 帧率比
self.beta = beta # 通道比
# Slow pathway
self.slow = SlowPath()
# Fast pathway
self.fast = FastPath()
# 侧向连接
self.lateral = LateralConnectionLayers()
# 分类头
self.head = ClassificationHead()
def forward(self, x):
# x: [B, 3, T, H, W]
# Slow pathway
x_slow = self.slow(x[:, :, ::self.alpha, :, :]) # 采样
# [B, C, T//alpha, H, W]
# Fast pathway
x_fast = self.fast(x) # 全帧率
# [B, beta*C, T, H, W]
# 侧向连接
x_slow = self.lateral(x_slow, x_fast)
# 融合与分类
return self.head(x_slow)配置示例
SlowFast-R50配置:
| Stage | Slow Pathway | Fast Pathway |
|---|---|---|
| Conv1 | ||
| Res2 | ||
| Res3 | ||
| Res4 | ||
| Res5 |
通道数:,
性能分析
Kinetics-400结果:
| 模型 | Top-1 | FLOPs | 推理速度 |
|---|---|---|---|
| I3D-R50 | 74.3% | 108×G | 1× |
| Non-Local I3D | 77.7% | 359×G | 0.3× |
| SlowFast-R50 | 78.8% | 65×G | 1.5× |
| SlowFast-R101 | 79.8% | 106×G | 1.0× |
关键发现:
- SlowFast在相近精度下,FLOPs显著低于2D/3D方法
- Fast pathway的轻量化设计()是关键
- 侧向连接对性能贡献显著
R(2+1)D 分解3D卷积
核心思想
R(2+1)D2 提出了将3D卷积分解为空间2D卷积和时间1D卷积的思想:
标准3D卷积: [C_out, C_in, K_t, K_h, K_w]
│
↓ 分解
分解3D卷积:
┌────────────────────────────────┐
│ 2D空间卷积: [C_out, C_in, 1, K_h, K_w] │
│ 时间卷积: [C_out, C_out, K_t, 1, 1] │
└────────────────────────────────┘
数学推导
标准3D卷积操作:
R(2+1)D分解后的操作:
步骤1:空间投影(2D卷积)
步骤2:时间卷积(1D卷积)
架构设计
R(2+1)D的中间瓶颈维度设置:
class R2Plus1DBlock(nn.Module):
"""
R(2+1)D Block
"""
def __init__(self, in_channels, out_channels, kernel_size_t):
super().__init__()
# 中间维度: D = out_channels * kernel_size_t / 2
# 这个维度是经验设定的,用于平衡参数和表达能力
mid_channels = out_channels * kernel_size_t // 2
# 空间卷积 (2D) + 投影到中间维度
self.spatial_conv = nn.Conv3d(
in_channels, mid_channels,
kernel_size=(1, 3, 3), # 空间2D卷积
padding=(0, 1, 1)
)
self.bn1 = nn.BatchNorm3d(mid_channels)
# 非线性激活
self.relu = nn.ReLU(inplace=True)
# 时间卷积 (1D) + 投影到输出维度
self.temporal_conv = nn.Conv3d(
mid_channels, out_channels,
kernel_size=(kernel_size_t, 1, 1) # 时间1D卷积
)
self.bn2 = nn.BatchNorm3d(out_channels)
def forward(self, x):
x = self.spatial_conv(x)
x = self.bn1(x)
x = self.relu(x)
x = self.temporal_conv(x)
x = self.bn2(x)
return x配置对比
| 模型 | 3D卷积分解 | 中间瓶颈 | 参数量 | FLOPs |
|---|---|---|---|---|
| R3D-18 | 无 | - | 33.2M | 41.6G |
| R(2+1)D-18 | 是 | 可调 | 31.3M | 38.5G |
| R3D-34 | 无 | - | 68.6M | 85.8G |
| R(2+1)D-34 | 是 | 可调 | 63.5M | 76.5G |
与其他分解方法的对比
| 分解方法 | 分解方式 | 参数量 | 表达能力 |
|---|---|---|---|
| R(2+1)D | 中 | 强 | |
| P3D | (残差连接) | 中 | 中 |
| S3D | (独立) | 低 | 中 |
| CSN | 通道分离 | 低 | 中 |
Channel-Separated 3D Convolutions (CSN)
核心思想
CSN(Channel-Separated 3D Convolutions)3 基于深度可分离卷积的思想,将3D卷积的空间和时间维度分离:
标准3D卷积: [C_in, C_out, K_t, K_h, K_w]
│
↓ 通道分离
Channel-Separated 3D:
┌─────────────────────────────────────┐
│ 空间卷积: [C_in, C_in, 1, K_h, K_w] │ (逐通道)
│ 通道点卷积: [C_in, C_out, 1, 1, 1] │
└─────────────────────────────────────┘
数学表示
标准3D卷积:
CSN分解:
其中:
- (深度卷积)
- (点卷积)
计算量对比
| 卷积类型 | 计算量 | 参数量 |
|---|---|---|
| 标准3D | ||
| CSN |
节省比例:约 倍的参数和计算量
架构设计
class CSNBlock(nn.Module):
"""
Channel-Separated 3D Block
"""
def __init__(self, in_channels, out_channels, kernel_size_t):
super().__init__()
# 深度3D卷积 (空间分离)
self.depth_conv = nn.Conv3d(
in_channels, in_channels,
kernel_size=(1, 3, 3), # 仅空间维度
stride=(1, 2, 2),
padding=(0, 1, 1),
groups=in_channels # 深度可分离
)
# 逐点1D卷积 (通道混合)
self.point_conv = nn.Conv3d(
in_channels, out_channels,
kernel_size=(kernel_size_t, 1, 1)
)
self.bn1 = nn.BatchNorm3d(in_channels)
self.bn2 = nn.BatchNorm3d(out_channels)
self.relu = nn.ReLU(inplace=True)
def forward(self, x):
x = self.depth_conv(x)
x = self.bn1(x)
x = self.relu(x)
x = self.point_conv(x)
x = self.bn2(x)
return xI3D + Transformer 混合架构
设计思路
结合CNN的特征提取能力和Transformer的时序建模能力:
┌─────────────────────────────────────────┐
│ 视频输入 [B, 3, T, H, W] │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 3D CNN Backbone (I3D/R(2+1)D) │
│ 提取空间特征 [B, C, T, H', W'] │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Token化: 空间维度压缩 │
│ [B, C, T, H', W'] → [B, T, N, C] │
│ N = H' × W' │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Temporal Transformer │
│ 建模帧间依赖 [B, T, N, C] │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 时序聚合 + 分类 │
└─────────────────────────────────────────┘
代表性工作
ViViT4:将Video Transformer分解为:
- 时空token化:3D视频 → 时空patch序列
- 时空编码:并行/交叉时空注意力
- 分类:使用[CLS] token
MViT5:多尺度ViT:
- 渐进式下采样:时间/空间维度逐步压缩
- 多尺度特征:类似Swin的层次化设计
性能对比
| 模型 | Top-1 (K400) | FLOPs | 特点 |
|---|---|---|---|
| I3D-R50 | 74.3% | 108×G | 纯CNN |
| SlowFast-R50 | 78.8% | 65×G | 双路径 |
| R(2+1)D-50 | 74.3% | 41×G | 分解卷积 |
| CSN-R50 | 74.5% | 44×G | 通道分离 |
| MViT-S | 80.2% | 78×G | 混合架构 |
帧采样与效率优化
均匀采样
最基础的采样策略:
def uniform_sample(frames, num_frames):
"""
均匀采样: 从T帧中均匀采样num_frames帧
"""
indices = torch.linspace(0, T-1, num_frames).long()
return frames[indices]稀疏采样
在训练和推理时使用不同的采样策略:
- 训练时:随机采样帧
- 推理时:均匀采样更多帧,取多个clip的平均
帧率适应
不同动作可能需要不同帧率:
- 慢动作:低帧率即可捕获
- 快动作:需要高帧率避免运动模糊
自适应帧率方法:
- 动态决定采样帧率
- 根据动作速度调整采样策略
方法对比与选择指南
效率-精度权衡
精度
↑
│ ○ MViT
│ ○ ○ SlowFast
│ ○ ○ R(2+1)D
│ ○
│○ ○ CSN
│
└────────────────→ 计算量
选择建议
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 高精度需求 | SlowFast, MViT | 最佳精度 |
| 边缘部署 | CSN, R(2+1)D | 低计算量 |
| 长视频处理 | SlowFast | 帧率分离设计 |
| 实时推理 | R(2+1)D | 良好效率 |
| 资源受限 | CSN | 最小计算 |
总结
轻量级视频模型通过多种技术手段降低计算成本:
- SlowFast Networks:双路径设计,Slow捕获语义,Fast捕获运动
- R(2+1)D:3D卷积分解为空间2D + 时间1D
- CSN:通道分离3D卷积,大幅减少参数量
- 混合架构:CNN特征提取 + Transformer时序建模
这些方法为不同应用场景提供了灵活的选择,在效率和精度之间取得良好平衡。
参考文献
Footnotes
-
Feichtenhofer X, Fan H, Malik J, et al. Slowfast networks for video recognition[C]//Proceedings of the IEEE/CVF international conference on computer vision. 2019: 6202-6211. ↩
-
Tran D, Wang H, Torresani L, et al. A closer look at spatiotemporal convolutions for action recognition[C]//Proceedings of the IEEE conference on Computer Vision and Pattern Recognition. 2018: 6450-6459. ↩
-
Tran D, Wang H, Torresani L, et al. Video classification with channel-separated convolutional networks[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2019: 5552-5562. ↩
-
Arnab A, Dehghani M, Heigold G, et al. Vivit: A video vision transformer[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2021: 6816-6826. ↩
-
Fan H, Xiong B, Mangalam K, et al. Multiscale vision transformers[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2021: 6824-6835. ↩