语音信号识别动态时间规整算法 DTW 编程实现

                         

概述:

前段时间在百度DTW是怎么回事,在CSDN,博客园有很多文章,很多人讲不明白,模棱两可,给的代码也是错的,这让我非常着急,原本以为几小时就可以搞定,再把源代码自己写出来,就大工告成,结果把自己搞得头昏脑胀的,还是不清楚,没办法,狠了狠心完全脱离他们代码的思路,下决心按照DTW的公式自己写了程序,编程调试一天,功夫不负有心人,结果真的是很激动人心!

福利实现代码在原文底部,作者花费一天时间编码调试,没有bug,直接运行,思路简单清晰,一看就懂,转手就用,推进资源文章的水平是一种荣耀!

 

介绍:

Dynamic Time Warping
 

先给大家看看运行的结果吧,我调试了很多bug之后,第一眼看到它就感觉特别美,有一种震撼的感觉!

生成的最小距离图,其中的数字代表的是从左下角出发点到这个点的最小的距离。

回溯方法找到的最小的路径,沿着394一直走,就可以最小路程从左下角出发点走到终点右上角。

我来给大家说说怎么回事吧

首先呢哟两组数据需要对比,看看它们的匹配性,也就是有多像,但是数据长度不一定相等,某些局部也不是同步一致的。如:

    int a[]={8,10,21,67,91,18,5,9,10,13,21,78,91,10,5,9,10,13,21,78,91};
    int b[]={5,9,10,13,21,78,91,10,80,9,10,13,218,10,15,21,67,91,18};

这是不能直接上减下得到差值计算的,因为两个数据的长度不一定是相等的,某些局部也不一定会同步,比如不同人说话,语速不一样,清晰程度也不一样,我们得到声音数据之后,怎么通过比较,知道是谁说话呢?

如下的情形中:

在一个月黑风高的晚上,四周黑洞洞一片,一个只有五个互不相识单身男性的小区里面遭了贼,物业丢失了价值500万元的公共财产,经过警察侦查断定,小偷一定是小区里面的五个人其中之一,但是没有任何证据,只有小偷作案后,一阵狂笑声,周围的摄像头全部被破坏,只有录下了小偷的狂笑的声音,究竟会是谁?

警察将小偷狂笑声音数据a提取出来

分别要求小区五个人录下一段狂笑声音

标记数据b,c,d,e,f

这时候就需要数据对比,假设模板是a,现在有b,c,d,e,f数据需要比对,我们只要他们和模板a对比计算谁更匹配,就知道是谁是小偷了。

现在将数据如下对比:模板数据作为列,对比数据作为行

 先通过矩阵横竖相减求绝对值,得到结果如下:

这是相减求绝对值的结果,如果读者需要自己计算,可以参照下面这张图:

 

相减完之后,要计算匹配程度了.

下面的这篇讲得文章比较清晰(大概快速看完 ,看看我后面做的分析步骤)

转自@http://www.cnblogs.com/tornadomeet 

  DTW为(Dynamic Time Warping,动态时间归准)的简称。应用很广,主要是在模板匹配中,比如说用在孤立词语音识别,计算机视觉中的行为识别,信息检索等中。可能大家学过这些类似的课程都看到过这个算法,公式也有几个,但是很抽象,当时看懂了但不久就会忘记,因为没有具体的实例来加深印象。

      这次主要是用语音识别课程老师上课的一个题目来理解DTW算法。

  首先还是介绍下DTW的思想:假设现在有一个标准的参考模板R,是一个M维的向量,即R={R(1),R(2),……,R(m),……,R(M)},每个分量可以是一个数或者是一个更小的向量。现在有一个才测试的模板T,是一个N维向量,即T={T(1),T(2),……,T(n),……,T(N)}同样每个分量可以是一个数或者是一个更小的向量,注意M不一定等于N,但是每个分量的维数应该相同。

     由于M不一定等于N,现在要计算R和T的相似度,就不能用以前的欧式距离等类似的度量方法了。那用什么方法呢?DTW就是为了解决这个问题而产生的。

首先我们应该知道R中的一个分量R(m)和T中的一个分量T(n)的维数是相同的,它们之间可以计算相似度(即距离)。在运用DTW前,我们要首先计算R的每一个分量和T中的每一个分量之间的距离,形成一个M*N的矩阵。(为了方便,行数用将标准模板的维数M,列数为待测模板的维数N)。

然后下面的步骤该怎么计算呢?用个例子来看看。

这个例子中假设标准模板R为字母ABCDEF(6个),测试模板T为1234(4个)。R和T中各元素之间的距离已经给出。如下:

 

     既然是模板匹配,所以各分量的先后匹配顺序已经确定了,虽然不是一一对应的。现在题目的目的是要计算出测试模板T和标准模板R之间的距离。因为2个模板的长度不同,所以其对应匹配的关系有很多种,我们需要找出其中距离最短的那条匹配路径。现假设题目满足如下的约束:当从一个方格((i-1,j-1)或者(i-1,j)或者(i,j-1))中到下一个方格(i,j),如果是横着或者竖着的话其距离为d(i,j),如果是斜着对角线过来的则是2d(i,j).其约束条件如下图像所示:

 

     其中g(i,j)表示2个模板都从起始分量逐次匹配,已经到了M中的i分量和T中的j分量,并且匹配到此步是2个模板之间的距离。并且都是在前一次匹配的结果上加d(i,j)或者2d(i,j),然后取最小值。

     所以我们将所有的匹配步骤标注后如下:

     怎么得来的呢?比如说g(1,1)=4, 当然前提都假设是g(0,0)=0,就是说g(1,1)=g(0,0)+2d(1,1)=0+2*2=4.

     g(2,2)=9是一样的道理。首先如果从g(1,2)来算的话是g(2,2)=g(1,2)+d(2,2)=5+4=9,因为是竖着上去的。

     如果从g(2,1)来算的话是g(2,2)=g(2,1)+d(2,2)=7+4=11,因为是横着往右走的。

     如果从g(1,1)来算的话,g(2,2)=g(1,1)+2*d(2,2)=4+2*4=12.因为是斜着过去的。

     综上所述,取最小值为9. 所有g(2,2)=9.

     当然在这之前要计算出g(1,1),g(2,1),g(1,2).因此计算g(I,j)也是有一定顺序的。

其基本顺序可以体现在如下:

 

     计算了第一排,其中每一个红色的箭头表示最小值来源的那个方向。当计算了第二排后的结果如下:

 

     最后都算完了的结果如下:

     到此为止,我们已经得到了答案,即2个模板直接的距离为26. 我们还可以通过回溯找到最短距离的路径,通过箭头方向反推回去。如下所示:

     到这里,估计大家动手算一下就会明白了。其实很简单,通过例子的学习后再回去看那些枯燥的理论公式就发现很容易了。

     在实际应用中,比如说语音识别中的孤立词识别,我们首先训练好常见字的读音,提取特征后作为一个模板。当需要识别一个新来的词的时候,也同样提取特征,然后和训练数据库中的每一个模板进行匹配,计算距离。求出最短距离的那个就是识别出来的字了。

 

计算过程:

首先要看懂这个公式:

 

这个是求最值得一步步迭代过程

看不懂的使用简单的四行五列数据模拟计算,这就是迭代计算了。

 

我将计算过程贴出来,大家可以作为参考,代码放在最后面的链接处。

第1步

第2步

第3步

 

第四步:



.....

.....

然后到计算完毕结果如下:

 

匹配的最短路径距离为:394,通过回溯可以求得最短路径!

路径图就是按照394这条路线走的,最短路径!

欢迎大家留言讨论

实现的代码:

点击下载https://download.csdn.net/download/yangming2466/10746983

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值