Google 的 WebRTC VAD 算法(尤其是“侵略性”)
Posted
技术标签:
【中文标题】Google 的 WebRTC VAD 算法(尤其是“侵略性”)【英文标题】:Google's WebRTC VAD algorithm (esp. "aggressiveness") 【发布时间】:2019-04-12 17:10:59 【问题描述】:我知道 Google 的 WebRTC VAD 算法使用的是高斯混合模型 (GMM),但我的数学知识很薄弱,所以我不太明白这意味着什么。说它是一种基于统计的机器学习模型是否正确,对于 VAD 来说,它是经过训练可以识别语音和噪声的模型吗?
我正在写一篇论文,并创建了一个脚本,该脚本利用 API 来区分声音和噪音。它有效,但我需要在我的论文中从一个非常基本的层面解释它用于做出决定的机制。
最紧迫的是,我需要在某种程度上知道“积极性”设置对算法的作用。它真的只是规定了一个置信度阈值吗?它有任何声学影响吗?
更新:
我的超基本理解是:谷歌可能在一堆预先标记的“噪音”和“语音”上训练他们的模型并存储每个的特征;然后它会获取一个未知样本,看看它更像是噪声数据还是语音数据。我不知道测量的特征是什么,但我假设至少测量了音高和幅度。
它使用 GMM 来计算它属于一个群体或另一个群体的概率。
进取心可能会设置用于做出决定的阈值,但我不完全知道这部分是如何工作的。
相关代码在这里:https://chromium.googlesource.com/external/webrtc/+/refs/heads/master/common_audio/vad/vad_core.c
“aggressiveness”设置决定了以下常量(我展示了模式 0 和 3 进行比较):
// Constants used in WebRtcVad_set_mode_core().
//
// Thresholds for different frame lengths (10 ms, 20 ms and 30 ms).
//
// Mode 0, Quality.
static const int16_t kOverHangMax1Q[3] = 8, 4, 3 ;
static const int16_t kOverHangMax2Q[3] = 14, 7, 5 ;
static const int16_t kLocalThresholdQ[3] = 24, 21, 24 ;
static const int16_t kGlobalThresholdQ[3] = 57, 48, 57 ;
// Mode 3, Very aggressive.
static const int16_t kOverHangMax1VAG[3] = 6, 3, 2 ;
static const int16_t kOverHangMax2VAG[3] = 9, 5, 3 ;
static const int16_t kLocalThresholdVAG[3] = 94, 94, 94 ;
static const int16_t kGlobalThresholdVAG[3] = 1100, 1050, 1100 ;
我不太明白悬垂和本地/全局阈值如何发挥作用。这些是严格的统计参数吗?
【问题讨论】:
如果您要解释它的含义,那么您必须了解 GMM 的作用——我们无法为您做到这一点。至于“攻击性”,你在源代码中发现了什么?有什么你看不懂的特定片段吗? 嗨 Lukasz,感谢您的回复。这是我正在查看的源文件:github.com/wiseman/py-webrtcvad/blob/master/cbits/webrtc/…——我相信是函数GmmProbability
最终负责确定给定的音频帧是语音还是噪声。同时,WebRtcVad_set_mode_core
处理“agressiveness”参数并根据该值分配各种属性。我无法理解的是这些值在何处或如何用于做出 VAD 决定。我计划明天更详细地更新我的问题
【参考方案1】:
跟踪代码,您会看到上面列出的预设 4 个值,它们会根据“aggressiveness”而改变:kOverHangMax1,2*, kLocalThreshold*, kGlobalThreshold*
这些映射到这 4 个内部数组(以激进度为索引):
self->over_hang_max_1[], self->over_hang_max_2[], self->individual[], self->total[]
进一步查看vad_core.c
中的第 158 行,我们看到根据帧长度使用不同的值。 frame_length
是正在分析的音频的“原子”或“块”:
// Set various thresholds based on frame lengths (80, 160 or 240 samples).
if (frame_length == 80)
overhead1 = self->over_hang_max_1[0];
overhead2 = self->over_hang_max_2[0];
individualTest = self->individual[0];
totalTest = self->total[0];
else if (frame_length == 160)
overhead1 = self->over_hang_max_1[1];
overhead2 = self->over_hang_max_2[1];
individualTest = self->individual[1];
totalTest = self->total[1];
else
overhead1 = self->over_hang_max_1[2];
overhead2 = self->over_hang_max_2[2];
individualTest = self->individual[2];
totalTest = self->total[2];
直觉
因此,音频块(240 个样本)越大,算法就越“激进”,而 80 个样本帧越小,“攻击性越低”:但这是为什么呢?直觉是什么?
calling-code(使用vad_core
)为其提供frames_length
音频块。因此,如果您正在 VAD-ing 的音频文件长达 10 分钟,则该音频上的滑动窗口将生成 frame_length
块并将其传递给此代码。
音频以 8000Hz 采样率运行,当frame_length
很小 (80) 时,分辨率 (10ms) 是细粒度的,VAD 信号将非常精确。将准确跟踪变化,并且 VAD 估计将“合理”......当frame_length
较大(240)时,分辨率更“粗糙”,VAD 信号将不太协调,较小(
因此,比起攻击性,我更愿意谈论它如何“谨慎”或“自信地”跟踪它正在估计的潜在语音信号。
我希望这有助于推理它在做什么。至于值本身,它们只是算法细节,会因音频帧大小的不同而有所不同。
【讨论】:
以上是关于Google 的 WebRTC VAD 算法(尤其是“侵略性”)的主要内容,如果未能解决你的问题,请参考以下文章
5┃音视频直播系统之 WebRTC 中的协议UDPTCPRTPRTCP详解
11┃音视频直播系统之 WebRTC 进行文本聊天并实时传输文件
12┃音视频直播系统之 WebRTC 实现1对1直播系统实战