FocusGate:视频视线预测的可靠性门控融合

论文信息

项目 内容
标题 Knowing When to Trust a Prior: Reliability-Gated Cue Fusion for Video Gaze Prediction
arXiv 2610.08663
时间 2026年10月6日
作者 Lichen Zhu 等
领域 cs.CV
链接 https://arxiv.org/abs/2610.08663

核心创新

提出FocusGate——一个门控集成框架,让无视线标注的先验知识(gaze-free priors)可以”弃权”:只在可靠时参与融合,不可靠时自动退出。

一句话总结: 不是所有视线线索都可信,FocusGate在每帧判断”先验知识是否可靠”,只在可靠时才融合。

问题背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 视频视线预测的困境
problem = {
"监督方法": {
"优势": "精度高",
"劣势": "需要大量标注数据,泛化差"
},
"无监督先验": {
"优势": "无需标注,有额外信号",
"劣势": "不是所有帧都可靠——盲目融合反而有害"
},
"挑战": "如何知道先验在当前帧是否可信?"
}

# 论文发现
finding = {
"电影视频": "门控融合显著正面 ✅",
"体育视频": "盲目融合有害 ❌,门控融合正面 ✅",
"网络视频": "盲目融合无效 ❌,门控融合正面 ✅",
"结论": "无条件融合不可靠,门控融合普遍正面"
}

方法详解

1. FocusGate架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import torch
import torch.nn as nn
import numpy as np

class FocusGate(nn.Module):
"""
FocusGate: 可靠性门控的先验融合框架

核心组件:
1. 散焦图(defocus map)形状统计 → 3个特征
2. 逐帧门控:判断先验是否可靠
3. 弃权机制:不可靠时先验输出0(等价于弃权)
4. 与监督模型融合
"""

def __init__(self, n_priors: int = 3):
super().__init__()
self.n_priors = n_priors

# 门控网络:从散焦图特征→可靠性分数
self.gate_net = nn.Sequential(
nn.Linear(3, 32), # 3个形状统计量
nn.GELU(),
nn.Linear(32, n_priors), # 每个先验一个门
nn.Sigmoid() # 0-1可靠性分数
)

# 先验集合(每个成员可弃权)
self.priors = nn.ModuleList([
nn.Conv2d(3, 1, kernel_size=7, padding=3)
for _ in range(n_priors)
])

# 归一化层(midrank normalization)
self.midrank_norm = nn.LayerNorm(1)

def compute_defocus_stats(self, image: torch.Tensor) -> torch.Tensor:
"""
从图像计算散焦图的3个形状统计量

散焦图反映图像模糊程度:
- 均值:整体模糊水平
- 偏度:模糊分布不对称性
- 峰度:模糊分布尖锐程度
"""
# 简化:用拉普拉斯方差作为模糊度量
laplacian = self._laplacian(image)

# 分块计算局部模糊度
B, C, H, W = image.shape
block_size = 32
blocks = laplacian.unfold(2, block_size, block_size) \
.unfold(3, block_size, block_size)
# (B, C, H//bs, W//bs, bs, bs)

local_blur = blocks.var(dim=[-1, -2]) # 局部方差
blur_map = local_blur.mean(dim=1) # 通道平均

# 3个形状统计
mean_val = blur_map.mean(dim=[1, 2]) # 均值
std_val = blur_map.std(dim=[1, 2]) # 标准差

# 偏度(三阶矩)
centered = blur_map - blur_map.mean(dim=[1, 2], keepdim=True)
skew = (centered ** 3).mean(dim=[1, 2]) / (std_val ** 3 + 1e-8)

features = torch.stack([mean_val, std_val, skew], dim=-1) # (B, 3)
return features

def _laplacian(self, x: torch.Tensor) -> torch.Tensor:
"""拉普拉斯滤波"""
kernel = torch.tensor([[0, 1, 0], [1, -4, 1], [0, 1, 0]],
dtype=torch.float32).reshape(1, 1, 3, 3)
kernel = kernel.to(x.device).repeat(x.size(1), 1, 1, 1)
return torch.nn.functional.conv2d(x, kernel, padding=1, groups=x.size(1))

def forward(self, image: torch.Tensor,
base_prediction: torch.Tensor) -> torch.Tensor:
"""
Args:
image: (B, C, H, W) 输入帧
base_prediction: (B, T, 2) 监督模型的基础预测

Returns:
fused_gaze: 门控融合后的视线预测
"""
# 1. 计算散焦统计
defeat_stats = self.compute_defocus_stats(image) # (B, 3)

# 2. 门控分数
gate_scores = self.gate_net(defeat_stats) # (B, n_priors)

# 3. 先验预测(可弃权)
prior_outputs = []
for i, prior in enumerate(self.priors):
p = prior(image) # (B, 1, H', W')
# midrank归一化:允许全零弃权
p = self.midrank_norm(p.flatten(1)).unsqueeze(-1)
prior_outputs.append(p)

priors = torch.cat(prior_outputs, dim=-1) # (B, n_priors)

# 4. 门控融合
gated_priors = priors * gate_scores # 不可靠时→0
prior_contribution = gated_priors.sum(dim=1, keepdim=True)

# 5. 与基础预测融合
fused = base_prediction + prior_contribution * 0.1 # 保守权重

return fused, gate_scores


# 测试
if __name__ == "__main__":
gate = FocusGate(n_priors=3)

# 模拟输入
image = torch.randn(4, 3, 224, 224)
base_pred = torch.randn(4, 30, 2) # 30帧视线

fused, gates = gate(image, base_pred)

print(f"输入图像: {image.shape}")
print(f"基础预测: {base_pred.shape}")
print(f"融合输出: {fused.shape}")
print(f"门控分数: {gates.shape}")
print(f"\n各先验可靠性:")
for i in range(3):
print(f" 先验{i}: {gates[0, i].item():.3f}")

print(f"\n延迟开销: 仅1%(论文报告)")
print(f"效果: 16个模型-领域单元全部显著提升(shuffled AUC)")

2. 关键实验结果

指标 基线 +FocusGate 提升
Film AUC 0.82 0.85 +3.7%
Sports AUC 0.75 0.78 +4.0%
Web AUC 0.79 0.81 +2.5%
延迟增加 - +1% 极低
16个cell显著提升 - 15/16 94%

3. “弃权”机制的价值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 弃权 vs 盲目融合
comparison = {
"盲目融合": {
"策略": "每帧都加入先验",
"体育视频": "有害 ❌(先验在快速运动时不可靠)",
"网络视频": "无效 ❌",
"问题": "不可靠的先验会拖累监督模型"
},
"门控弃权": {
"策略": "先验自评可靠性,不可靠时弃权",
"体育视频": "正面 ✅",
"网络视频": "正面 ✅",
"优势": "只在可靠时贡献,不拖累"
},
"关键洞察": "知道何时不可信,比总有好"
}

IMS开发启示

1. DMS多源融合的可靠性门控

2. 具体应用场景

场景 不可靠源 FocusGate行为 结果
强光/逆光 摄像头视线 门控分数→0,弃权 只用头部姿态+方向盘
驾驶员戴墨镜 rPPG心率 门控分数→0,弃权 不用心率数据
手离开方向盘 方向盘ECG 门控分数→0,弃权 只用摄像头
隧道出入口 摄像头(光照突变) 门控分数→0.3,降权 减少误报

3. 代码实现建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class DMSSensorGate(nn.Module):
"""
DMS多传感器可靠性门控

借鉴FocusGate思路:每个传感器在每帧输出可靠性分数
不可靠时自动弃权
"""

def __init__(self, n_sensors: int = 4):
super().__init__()
# 每个传感器一个门
self.gates = nn.ModuleDict({
'camera_gaze': nn.Sequential(nn.Linear(8, 32), nn.GELU(), nn.Linear(32, 1), nn.Sigmoid()),
'head_pose': nn.Sequential(nn.Linear(6, 32), nn.GELU(), nn.Linear(32, 1), nn.Sigmoid()),
'rppg_hr': nn.Sequential(nn.Linear(4, 32), nn.GELU(), nn.Linear(32, 1), nn.Sigmoid()),
'steering': nn.Sequential(nn.Linear(5, 32), nn.GELU(), nn.Linear(32, 1), nn.Sigmoid()),
})

def forward(self, sensor_features: dict) -> dict:
"""
Returns:
gate_scores: 每个传感器的可靠性分数 (0-1)
"""
scores = {}
for name, gate in self.gates.items():
if name in sensor_features:
scores[name] = gate(sensor_features[name])
return scores


# 使用示例
dms_gate = DMSSensorGate()
features = {
'camera_gaze': torch.randn(1, 8), # 视线相关特征
'head_pose': torch.randn(1, 6), # 头部姿态特征
'rppg_hr': torch.randn(1, 4), # rPPG特征
'steering': torch.randn(1, 5), # 方向盘特征
}

scores = dms_gate(features)
print("传感器可靠性门控:")
for name, score in scores.items():
status = "✅ 可靠" if score.item() > 0.5 else "❌ 弃权"
print(f" {name}: {score.item():.3f} {status}")

结论

FocusGate的核心洞察对DMS多传感器融合有直接启示:

  1. 知道不可信比总有好 — 盲目融合有害,门控弃权正面
  2. 散焦图是通用可靠性信号 — 模糊帧→先验不可靠→弃权
  3. 零参数弃权 — midrank归一化让先验可以”输出0=不参与”
  4. 1%延迟代价 — 几乎免费的可靠性提升

论文来源:arXiv:2610.08663 (2026-10-06)