🏏 Cricket Batting 高光检测 — 进展汇报

2026-06-12 · 端侧单 backbone 多 head 阶梯0 成功 · 冻结 YOLO + scene head 0.90 ≈ CLIP,零 pose 代价

本轮目标:给定 cricket 视频 + 高光 template,找出最匹配的高光帧。经一连串 spike, 把方案从「pose 细粒度匹配」重定向为「任意 batting vs 其他 二分类检测,CLIP 主导」, 并在真实广播域验证通过。下方是每一步的硬数据与结论。

① 任务重定向

原方案(已降级)

YOLO-pose → COCO-17 归一化 → 手工欧氏 mirror-invariant k-NN, 按 stroke 细分类匹配。

卡点:少数类欠采样、pose 距离是匹配器不是检测器(88% 漏拒)、 需要昂贵的 stroke×视角×相位标注。
新方案(主线 E5)
视频帧 冻结 MobileCLIP 轻 head batting 分数
二元标签便宜且现成;CLIP 看得见 bat/ball/场地;pose 降级为可选 form re-ranker。

② 三个 spike 的关键结论

Spike 1 · 学习度量(NCA per-joint) DROPPED

假设:学关节权重能提升 pose 匹配(尤其少数类)
配置(诚实 nested-LOO)macrobattingbowlingfielding
uniform baseline60.2%89%56%36%
NCA 无正则52.9%94%22%43%
NCA 最佳 (l2=0.5)61.6%94%56%36%
瓶颈是数据不是距离函数。 n=70 下学 17 个权重必然过拟合——无正则伤少数类 (bowling 56%→22%)、学到退化的「眼睛主导」权重;正则后仅 +1.4pp macro 且全在 batting。

Spike 2 · batting 流形覆盖曲线 数据洞察

问题:理论上需要多大数据量?子采样 47 个 batting 看覆盖斜率
库大小 N有把握覆盖 [email protected]median NN
12
0.209
20
0.183
30
0.172
46 (全部)
0.174
分布问题,非数量问题。 有把握覆盖在 N≈30 饱和到 ~45% 就不涨——随机加 batting 都落进 2 个密集 mode。且 batting median NN 0.17 几乎贴着 others 地板 0.198pose 无论多少数据都分不开背景

Spike 3 · CLIP vs pose 可分性闸门 GO

129 张 labeled 图 · batting 63 / 非batting 66 · 同一 LOO 协议
表征可分性AUC
冻结 MobileCLIP-S1(线性探针)
0.921
MobileCLIP(LOO 最近-batting)
0.899
YOLO pose(COCO-17)
0.693
CLIP 完胜 pose(+0.23 AUC)。 冻结 CLIP 上一个朴素线性 head 就能分开 batting 和背景—— 正是 pose 做不到的事。CLIP-led 二分类方案成立。质心法 batting 召回 100%,rest 特异度 70%(误报是工作面)。

③ Person-crop 与真实域验证

Person-crop WASH

表征线性探针 AUC
CLIP 全图0.921
CLIP 裁剪 pad=0.20.915
CLIP 紧裁 pad=00.883
裁剪无增益,紧裁反伤。 context(球场/bat/地面)携带 batting 信号。 原型先用全图;裁剪留到真实广播域再测。

域验证 @ CricketVision GO 确认

评测AUC
域内 CV 留视频法0.995
跨域 wetransfer→CV0.797
跨域 CV→wetransfer0.850
非单源假象。 域内 0.995 确认广播画面里 CLIP 同样可分。 注意:0.995 被易负样本抬高;跨域掉到 0.80 → head 要在目标域训练

④ E5 端到端检测器原型 跑通

冻结 CLIP + logistic head · 整段 P1_V33 逐帧检测(plan C→A)

训练 20 个 CV 视频 · 测试留出的 P1_V33(视频级切分,无泄漏)· 逐帧分数 + 时间 NMS
detector timeline
指标v1 原始+补负样本+delivery hard-neg
frame ROC-AUC0.9710.9740.983
Average Precision0.6260.6760.833
P@30 strict(峰在 GT 内)0.670.770.87
P@30 event(峰在 GT±1.5s)0.970.93
检测器跑通且强。 端到端在没见过的整段广播视频上 frame AUC 0.983, 时间线尖峰与 GT 段几乎完美对齐,召回强(漏的都是段边界帧)。
主要误报 = 投球端 delivery 宽景
false positive: delivery wide shot
与击球瞬间同机位同构图,单帧分不开"即将击球/正在击球"。 加 delivery 帧作 hard-neg 后 AP 0.63→0.83、strict 精度 0.67→0.87
注:event-recall 当前 0.40 是 K/阈值 artifact(65 个 GT 球只取 30 个峰),非真漏;待修。

⑤ 跨转播源泛化 泛化成立

训练只用 P1,测试 P2–P9(不同转播商/球场/台标)

这是单视频结果无法回答的决定性检验:检测器懂 batting,还是只懂 P1 这家转播?
测试源frame AUCAPP@30 strictP@30 event
P1(域内参照)0.9830.8330.870.93
P20.9790.7930.730.97
P30.9530.7520.870.87
P4 (最弱源)0.9660.6020.700.73
P50.9800.7360.830.83
P6 (ECB+DRS)0.9790.7730.970.97
P70.9570.7700.670.80
P90.9560.8381.001.00
跨源均值 (n=7) 0.967±.0110.752±.068 0.83±.120.88±.09
泛化成立。 frame AUC 几乎不掉(0.983→0.967,方差 ±0.011),在完全不同的转播商上 分 batting/非-batting 和 P1 一样好 → 学到的是「击球场景」非「P1 特征」。连最难的 ECB+DRS 源 (P6)event-精度都 0.97,hard-neg 抑制 delivery 的能力跨源迁移。
⚠️ 但"跨源"= 跨转播商,未跨机位风格——见下方 test_data 测试,这是个重要修正。

⑥ test_data 跨域测试 暴露真实边界

P1 训练的检测器在 4 组完全不同风格的视频上 · 无 GT,看分数分布

内容预期mean probfire rate
battingYouTube cricket batting0.030.01
Batting Pose自录 4K(看台手机拍)0.010.00
Balling自录 bowling0.000.00
Video Set 1非 cricket(家居/穿搭)~0 拒识0.060.03
意外负面结果:检测器把所有东西都拒了,包括真实 batting。 真 batting 组(0.01–0.03)甚至比非-cricket 干扰组(0.06)还低。CricketVision 上 AUC 0.967 的检测器, 在这里几乎全军覆没。
根因(看图):它学的是「广播比赛机位」,不是「batting」
Batting Pose = 看台手机拍(底部有拍摄者头影)。击球手是场中小人影, 全是人群+球场广告 → prob 0.01。和广播"投球端宽景"完全不同。
YouTube = 室内 net 练习近景,便服、网笼 → prob 0.02。也不是广播构图。
反证:当画面确实是广播宽景时,它照样 fire(AB de Villiers 的 top 峰帧,全是干净击球画面)
真实结论 = 它是「广播比赛机位的击球检测器」,不是通用 batting 检测器。 跨转播商不变(P1–P9 + YouTube 真广播都 fire),但跨机位风格完全失效(看台拍/net 特写/近景)。 是 PASS 还是 FAIL 取决于部署目标:若目标是广播比赛视频 → 已验证可用;若要覆盖球迷/训练/任意 cricket 视频 → 需要这些风格的训练数据。

⑦ 端侧单 backbone 多 head 阶梯0 成功

把「场景门控 + 姿态」合到一个 ~2.9M backbone,丢掉 MobileCLIP

动机:端侧两模型(MobileCLIP 21.5M + YOLO 2.9M ≈ 24M)太重。重的是 MobileCLIP,不是 YOLO。
推理实际跑的 backbone 算量
backbone参数端侧
MobileCLIP-S1 图像塔21.5M移动优化
YOLO11n-pose 整网2.87M很轻
DINOv2 ViT-S/14~22M纯ViT,更慢
DINOv2 ViT-B/14~86M4×重
DINOv2 端侧负优化 → drop。减重靶子是场景模型(MobileCLIP),不是加东西。
为什么要两类特征:CLIP 不编码姿态
测量(batting 图内)
corr(pose距离, CLIP距离)+0.09
同姿态 vs 异姿态 CLIP余弦Δ+0.013
CLIP 相似度 ≈ 场景外观,几乎不含姿态。场景(语义)与姿态(几何)是两类特征 → 本是两个 head 的活。
阶梯0:冻结 YOLO-pose backbone + 一个独立 scene 小 head(pose 路径不动)
scene head(冻结特征上)batting-scene AUCpose 代价
之前 embed()+线性(误导)0.6740
取对层(layer10)+线性 on GAP0.8550
MLP on GAP(极轻 head)0.9000
conv head on featmap0.8980
(参照) CLIP 线性探针0.921
阶梯0 成功:冻结 YOLO-pose backbone + 一个 GAP+小MLP 的 scene head = AUC 0.90, 基本追平 CLIP 0.921,而 pose 严格零损失(backbone+pose head 没动)。 → 可丢掉 21.5M 的 MobileCLIP,单 2.9M backbone 同时做场景门控+姿态,~8× 减重、零 pose 代价、连微调都不用
纠偏:之前的 0.674 是 model.embed() 默认层假象——取对层光线性就 0.855。 冻结 YOLO 特征里本就有足够场景信号。caveat:当前在 129 张 wetransfer 单源图上测,需广播帧域复测夯实。

⑧ 路径状态 · 下一步

CLIP 主导的 batting 二分类检测器 in_progress

  1. person-crop 验证 — wash,原型用全图(pad≥0.2 留到广播域复测)
  2. 补难负样本 — 定位主 FP=delivery 宽景,加 hard-neg 后 AP 0.63→0.83、P@30 0.67→0.87
  3. 真实域验证 — CV 域内 0.995 GO;跨域 0.80 → 目标域训练
  4. 端到端检测器原型 — frame AUC 0.983 / AP 0.833 / P@30 0.87(见上)
  5. 跨转播源泛化 — 训 P1 测 P2–P9,AUC 0.967(但仅跨转播商,非跨机位)
  6. test_data 跨域 — 暴露真实边界:广播机位 detector,非通用 batting detector
  7. 端侧单 backbone 多 head(阶梯0) — 冻结 YOLO + scene head 0.90 ≈ CLIP,零 pose 代价(见⑦)
  8. 广播域复测 scene head + 导出端侧模型 / 按部署目标定方向
关键认知更新:检测器 = 广播比赛机位的击球检测器。 跨转播商稳(AUC 0.967), 但跨机位风格(看台/net/近景)失效。下一步取决于真正的部署目标。
目标=广播比赛视频? 已验证可用,去量化 recall + 跨赛制(T20)扩源
目标=任意 cricket 视频? 需补看台/net/近景多机位训练数据 + pose⊕CLIP 融合(pose 对机位更不变)
注:pose 表征对机位风格比 CLIP 全图更鲁棒——这反而是 pose-as-feature 在通用场景下的价值点,值得重测融合。

附 · 产物与文档

📄 决策归档:docs/archive/analysis/2026-06-08-batting-detection-clip-redirect.md
📋 Backlog:docs/TODO.md — E4 dropped、E5 主线 in_progress
🔬 Spike 脚本:scripts/spike_metric_v1.py · spike_batting_coverage_v1.py · spike_clip_batting_v1.py / v2.py · spike_clip_domain_v1.py
📊 报告:results/spike_*/report.md

生成于 2026-06-08 · cricket_highlight · branch pose-template-library