如何基于Groundtruth与Predicted标签数据帧计算类别平均延迟
原代码问题分析
- 没有按照延迟定义做h/H的归一化,仅累加了帧差,得到的不是标准化的延迟值
- 双重循环逻辑存在重复累加问题,同一个groundtruth变化点可能对应多个预测变化点,会导致计算结果偏大
- 没有提取每个动作的总时长H,无法完成延迟的标准化计算
- 没有覆盖预测始终不正确的边界情况
正确实现方案
核心思路如下:
- 先从groundtruth中拆分所有独立动作段,每个段存储
[类别标签,起始帧索引,结束帧索引],计算每个动作的总时长H = 结束帧索引 - 起始帧索引 + 1 - 对每个动作段,从起始帧开始向后检索,找到第一个满足「从该帧到当前动作结束,预测标签始终等于真实类别」的帧索引f,该帧就是分类器最终做出正确决策的帧
- 计算当前动作的延迟为
(f - 起始帧索引)/H,若整个动作段内没有找到符合条件的f,可根据需求选择将延迟记为1(最大延迟)或者跳过该样本 - 所有动作延迟的平均值即为最终的平均延迟
优化后代码实现
import pandas as pd import numpy as np # 读取数据并拍平为一维数组 groundtruth = pd.read_csv('groundtruth.csv', sep=",", header=None).transpose().values.flatten() prediction = pd.read_csv('prediction.csv', sep=",", header=None).transpose().values.flatten() # 拆分标签序列为独立动作段 def get_action_segments(arr): segments = [] if len(arr) == 0: return segments current_c = arr[0] start = 0 for idx in range(1, len(arr)): if arr[idx] != current_c: segments.append((current_c, start, idx-1)) current_c = arr[idx] start = idx # 补充最后一个动作段 segments.append((current_c, start, len(arr)-1)) return segments gt_segments = get_action_segments(groundtruth) latency_list = [] # 逐段计算延迟 for c, s, e in gt_segments: H = e - s + 1 if H <= 1: continue # 跳过单帧无效动作段 # 查找第一个有效决策帧 f = None for candidate_f in range(s, e+1): if np.all(prediction[candidate_f:e+1] == c): f = candidate_f break # 计算当前动作延迟 if f is not None: h = f - s latency = h / H else: latency = 1.0 # 全程预测错误记为最大延迟,也可替换为continue跳过该样本 latency_list.append(latency) # 计算平均延迟 average_latency = np.mean(latency_list) print(f"平均延迟为:{average_latency:.4f}")
方案优势
- 时间复杂度为O(N),N为总帧数,远低于原代码的O(M*K)(M为groundtruth变化点数量,K为预测变化点数量)
- 严格符合延迟定义的归一化要求,计算结果准确
- 边界情况处理完整,覆盖了预测错误、无效短片段等场景
- 逻辑清晰易读,便于后续调整错误样本的处理规则
内容的提问来源于stack exchange,提问作者Mejdi Dallel
相关产品推荐
相关产品推荐

