epic_kitchens_sounds数据集中对segment标签的处理:时间维度和特征维度的转换
epic_kitchens_sounds数据集中对segment标签的处理
epic_kitchens数据集中def __getitem__(self, idx)
函数中有以下代码:
#feat_stride:temporal stride of the feats
#num_frames:number of frames for each feat#feats是读入进来的音频特征.npz文件
feats = feats[::self.downsample_rate, :] # 下采样
feat_stride = self.feat_stride * self.downsample_rate # 特征步长
feat_offset = 0.5 * self.num_frames / feat_stride # 特征偏移量if video_item['segments'] is not None:segments = torch.from_numpy(video_item['segments'] * video_item['fps'] / feat_stride - feat_offset)labels = torch.from_numpy(video_item['labels'])else:segments, labels = None, None
解释:
num_frames
:一个滑动窗口包含的帧数,即一个特征包含的帧数。feat_stride
:特征步长,就是滑动窗口滑动的步长。video_item['segments']
表示的是声音片段的起止时间,单位都是秒。feat_offset = 0.5 * self.num_frames / feat_stride
:这行代码计算的是特征时间窗口的中心偏移量,它的作用是将时间戳从原始帧的起始位置调整到特征窗口的中心位置,以提高时间定位的准确性。举个例子说明:-
假设:视频参数:fps=30,segments=2.0s(第2秒), 特征参数:num_frames=16,feat_stride=8
-
计算帧索引:
frame_index = 2.0 * 30 = 60(第60帧)
-
计算 feat_offset:
feat_offset = 0.5 * 16 / 8 = 1.0
-
无偏移补偿时:
raw_feat_index = 60 / 8 = 7.5
这意味着第60帧被映射到第7.5个特征点(滑动窗口),但实际第7个特征点覆盖的窗口是:- 起始帧:7 * 8 = 56
- 中心帧:56 + 0.5*16 = 64
- 结束帧:56 + 16 = 72
问题:60帧更接近第6个特征点的中心(6*8 + 8 = 56),但直接映射到7.5会导致错位。
-
补偿偏移后:
final_feat_index = 7.5 - 1.0 = 6.5
第6个特征点覆盖 [48, 64) 帧,中心在 48 + 8 = 56 帧。
第7个特征点覆盖 [56, 72) 帧,中心在 56 + 8 = 64 帧。
60帧 距离第6个特征点中心(56帧)更近,因此 6.5 是更合理的索引。
-
- 因为
video_item['segments']
是以秒为单位的,但模型输入的是提取出来的音频特征,所以需要把segments从时间维度转换到特征维度,即segments = torch.from_numpy( video_item['segments'] * video_item['fps'] / feat_stride - feat_offset
。