algorithm - 如何检测语音录音与另一个语音录音的相似程度?

标签 algorithm machine-learning audio

我想构建一个程序来检测用户的录音与另一个录音的接近程度,以便纠正用户的发音。例如:

  • 我录下自己说“早上好”
  • 我让一个留学生录“早上好”
  • 比较他的录音和我的录音,看看他的发音是否足够好。

  • 我在一些语言学习工具中看到了这一点(我相信 Rosetta Stone 会这样做),但它是如何做到的?请注意,我们只处理语音(而不是音乐)。我应该研究哪些算法或库?

    最佳答案

    很多人似乎都在建议某种编辑距离,IMO 是一种完全错误的方法来确定两种语音模式的相似性,尤其是对于 OP 所暗示的那样短的模式。实际上,语音识别所使用的特定算法与您想在这里使用的算法几乎相反。语音识别中的问题是将许多相似的发音解析为相同的表示。这里的问题是采用一些略有不同的发音,并在它们之间获得某种有意义的距离。

    我已经为大规模数据科学做了很多这样的事情,虽然我无法评论专有程序是如何做到的,但我可以评论它在学术界是如何完成的,并提供一个简单的解决方案,并将给出您拥有此方法所需的功能和灵活性。

    首先:假设您拥有的是一些没有对其进行任何过滤的音频块。就像从麦克风中获取一样。第一步是消除背景噪音。对此有许多不同的方法,但我将假设您想要的是可以很好地工作而不会难以实现的东西。

  • 使用 scipy 的过滤模块过滤音频 here .麦克风拾取的许多频率对于语音分类根本没有用。我建议使用 Bessel 或 Butterworth 滤波器,以确保您的波形通过滤波保持不变。日常语音的基本频率通常在 800 到 2000 Hz ( reference ) 之间,因此合理的截止频率应该是 300 到 4000 Hz,以确保您不会丢失任何东西。
  • 寻找最不活跃的语音部分,并假设它是背景噪声的合理表示。此时,您将要对数据进行一系列傅立叶变换(或生成频谱图),并找到语音记录中平均频率响应最低的部分。获得该快照后,您应该从音频样本中的所有其他点中减去它。
  • 此时应该有一个音频文件,它主要是您的用户的语音,并且应该准备好与经过此过程的另一个文件进行比较。现在,我们要实际剪辑声音并将此剪辑与某个主剪辑进行比较。

  • 第二个:你会想要找出两个语音模式之间的距离度量,有很多方法可以做到这一点,但我假设我们有第一部分的输出和一些已经通过的主文件类似的处理。
  • 生成相关音频文件的频谱图 ( example )。其输出最终将是一个图像,可以表示为频率响应值的二维数组。频谱图本质上是随时间进行的傅立叶变换,其中颜色对应于强度。
  • 使用 OpenCV(具有 python 绑定(bind),example)在您的频谱图上运行 blob 检测。实际上,这将在您的频谱图中间寻找大的彩色 Blob ,并对此进行一些限制。实际上,这应该做的是返回原始二维数组的明显更稀疏的版本,该版本仅代表所讨论的语音。 (假设您的音频文件在录音的前端和后端会有一些拖尾内容)
  • 将两个 blob 归一化以解释语速差异。每个人都以不同的速度说话,因此您的 blob 可能沿 x 轴(时间)具有不同的大小。这最终会在您的算法中引入您不想要的语速检查级别。如果您还想确保它们以与原版相同的速度说话,则不需要此步骤,但我建议这样做。基本上,您想通过将时间轴乘以某个常数来拉伸(stretch)较短的版本,该常数只是您的两个 blob 的长度之比。
  • 您还应该根据最大和最小强度对两个 blob 进行归一化处理,以应对以不同音量说话的人。同样,这取决于您的判断力,但要解决此问题,您应该为您拥有的总强度跨度以及两个记录的最大强度找到相似的比率,并确保这两个值在您的二维数组之间匹配.

  • 第三:既然你有代表你的两个语音事件的二维数组,理论上应该包含它们的所有有用信息,是时候直接比较它们了。幸运的是,比较两个矩阵是一个很好解决的问题,有很多方法可以向前推进。
  • 我个人建议使用像 Cosine Similarity 这样的指标。确定您的两个 blob 之间的差异,但这不是唯一的解决方案,虽然它可以为您提供快速验证,但您可以做得更好。
  • 您可以尝试从另一个矩阵中减去一个矩阵,并评估它们之间有多少差异,这可能比简单的余弦距离更准确。
  • 这可能有点矫枉过正,但是您可以假设某些语音区域对于评估 blob 之间的差异或多或少很重要(如果有人使用长 i 而不是短 i 可能无关紧要,但是 ag 而不是 ak 可能是完全不同的词)。对于类似的事情,您需要为上一步中的差异数组开发一个掩码,并将所有值乘以该掩码。
  • 无论您选择哪种方法,您现在都可以简单地设置一些差异阈值,并确保两个 blob 之间的差异低于您想要的阈值。如果是,则捕获的语音足够相似,是正确的。否则让他们再试一次。

  • 我希望这会有所帮助,而且我不能向您保证这是一家公司使用的确切算法,因为该信息是非常专有的并且不对公众开放,但我可以向您保证,在学术界最好的论文,这些方法将使您在准确性和易于实现之间取得很好的平衡。如果您有任何问题,请告诉我,并祝您在 future 的数据科学开发中好运!

    关于algorithm - 如何检测语音录音与另一个语音录音的相似程度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17010516/

    相关文章:

    machine-learning - 我无法让 Caffe 工作

    machine-learning - Mahout 分类器训练数据的预处理

    c++ - IMFTransform::ProcessOutput 效率

    c# - 我执行的 KMP 算法有什么问题?

    python - 与 Pandas 数据框的关联规则

    arrays - 对 n 元素数组进行排序,使前 k 个元素按升序排列最低(就地算法)

    matlab - 在 MATLAB 中对音频进行重采样

    javascript - 如何将音频文件像流一样加载到 AudioContext 中?

    c++ - 对于 std::tr1::unordered_map,是否有任何类似于 std::map::lower_bound 的等效 std::algorithm?

    algorithm - 两点间简单路径的非递归DFS算法