3 大分支架构解读:action-detection 中活动分类、完整性评估与位置回归
【免费下载链接】action-detectiontemporal action detection with SSN项目地址: https://gitcode.com/gh_mirrors/ac/action-detection
时序动作检测(Temporal Action Detection)的目标,是从一段未剪辑的长视频中定位出每个动作发生的起止时间,并判断动作类别。action-detection 项目正是为此而生的开源实现,它完整复现了 ICCV 2017 论文《Temporal Action Detection with Structured Segment Networks》(SSN)的核心思想。SSN 模型最精妙的设计,在于它把每个候选视频片段(Proposal)交给3 个分工明确的输出分支去处理:活动分类、完整性评估与位置回归。理解这三大分支,就等于掌握了 SSN 的骨架。本文就用最通俗的方式,带你逐一拆解它们的职责、源码实现与协同方式。
为什么 SSN 需要"三头并进"?🤔
先看一个直观问题:一段视频里,如果模型只预测"这是灌篮动作",却不告诉你"从第几秒开始、到第几秒结束",那检测结果毫无价值。反过来,就算边界框得准,类别分错了也一样白搭。
因此 SSN 把任务拆成了 3 个子问题,用 3 个独立的全连接层(FC)分别作答:
| 分支 | 英文名 | 回答的问题 | 输出形状 |
|---|---|---|---|
| 活动分类 | Activity Classification | 这段视频是什么动作? | 类别数 + 1(含背景) |
| 完整性评估 | Completeness | 这段视频是不是完整动作? | 类别数 |
| 位置回归 | Location Regression | 动作边界应该怎么微调? | 类别数 × 2(起止偏移) |
这三个分支都定义在模型核心文件 ssn_models.py 的SSN类中,看到那三行nn.Linear就找到了它们的"出生地":
self.activity_fc = nn.Linear(...) # 活动分类头 self.completeness_fc = nn.Linear(...) # 完整性评估头 self.regressor_fc = nn.Linear(...) # 位置回归头分支一:活动分类——先回答"是什么"🎯
活动分类分支是三个分支中最容易理解的:它接收从视频片段中提取的特征,输出一个向量,向量的每个维度对应一个动作类别的得分。
值得注意的是,它的输出维度是类别数 + 1,多出来的那一维代表"背景类(Background)"。因为在真实视频中,大量候选片段其实不包含任何动作,模型必须有能力说"这一段什么都不是"。
在 ssn_dataset.py 的数据采样逻辑里,候选片段被明确分成三类:前景(fg)、背景(bg)、不完整(incomplete)。其中背景片段的标签就是 0,恰好对应活动分类头多出来的那一维。训练时,这个分支使用标准的CrossEntropyLoss交叉熵损失(见 ssn_train.py),让模型学会区分"这是灌篮"和"这不是灌篮"。
分支二:完整性评估——判断"完不完整"📏
完整性评估是 SSN 最具特色的设计,也是它优于普通动作识别方法的关键。
同样是"打篮球"这个动作:可能有一个候选片段只截到了起跳投篮的瞬间,另一个候选片段则完整覆盖了从运球、起跳到投篮落地的全过程。前者是"不完整"的动作,后者才是理想的检测结果。
完整性分支的作用,就是给每个片段打一个"完整度"分数。它使用的不是普通交叉熵,而是带在线难例挖掘(OHEM)的合页损失(Hinge Loss),实现在 ops/ssn_ops.py 的OHEMHingeLoss类中。OHEM 的思路很聪明:一批训练样本里,简单样本太多、难样本太少,模型会偷懒。所以它只挑损失最大的那部分"困难样本"来更新梯度,让模型始终处于被挑战的状态。
结合 data/dataset_cfg.yaml 可以看到,THUMOS14 数据集上incomplete_ratio: 6,即每 1 个前景样本会配 6 个不完整样本,通过海量负样本教会模型"什么是不完整的动作"。
分支三:位置回归——精修"起止边界"🎯
有了类别、有了完整度,还差最后一步:把时间边界调准。候选片段(Proposal)通常来自滑动窗口或自底向上的生成算法,边界比较粗糙。位置回归分支就是那个"精修师"。
它同样基于完整度特征,输出类别数 × 2的值——每类动作对应一对偏移量(起始偏移 + 结束偏移),用来微调片段的起点和终点,使边界更贴合真实动作。训练时使用ClassWiseRegressionLoss(类内 Smooth L1 损失,见 ops/ssn_ops.py),并且只会对前景片段计算回归损失,背景和不完整样本的回归目标都置为 0。
在 ssn_test.py 推理阶段,回归输出的偏移量还会利用训练时统计的均值/标准差进行反归一化(reg_scores * stats[1] + stats[0]),还原成真实帧数偏移。
三大分支如何协同工作?🔄
训练时,SSN 采用结构化的时序金字塔池化(STPP)把每个片段切分成三段:起始段(Starting)、主体段(Course)、结束段(Ending),分别提取特征。然后三个分支各取所需特征,输出各自的预测,最终总损失是三者的加权和(见 ssn_train.py):
loss = act_loss + 0.1 * comp_loss + 0.1 * reg_loss推理时,三个分数会按论文公式融合成最终的检测置信度,再配合时序 NMS 去重,得到每个动作的类别、起止时间和置信度(评估脚本 eval_detection_results.py 会计算不同 IoU 阈值下的 mAP)。
快速上手:三步跑通完整流程 🚀
- 生成候选片段:先用 gen_sliding_window_proposals.py 生成滑动窗口提案,再用 gen_bottom_up_proposals.py 生成更精细的 TAG 提案列表。
- 训练 SSN:运行
python ssn_train.py thumos14 RGB -b 16 --lr_steps 20 40 --epochs 45,训练参数可通过 ssn_opts.py 自定义(如关闭回归分支用--no_regression)。 - 测试评估:
python ssn_test.py thumos14 RGB checkpoint.pth.tar result.pkl输出每个提案的三类分数,最后用python eval_detection_results.py thumos14 result.pkl报告 mAP。
小结
活动分类负责"认对动作",完整性评估负责"挑完整片段",位置回归负责"调准边界"——三大分支各司其职、缺一不可,这正是 SSN 在 THUMOS14 上取得 mAP@0.5IoU 高达 32.5%(RGB+Flow)的关键。读完这篇解读,再回头看 ssn_models.py 和 ops/ssn_ops.py,你会发现源码里的每一层设计,都对应着这三个朴素而深刻的问题。🎓
【免费下载链接】action-detectiontemporal action detection with SSN项目地址: https://gitcode.com/gh_mirrors/ac/action-detection
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考