DTW(dynamic time warping)动态时间归整-详解(MATLAB和python)

DTW(dynamic time warping)动态时间归整-详解(MATLAB和python)

  • 在语音识别中,简单的将输入模板与相应的参考模板直接做比较存在很大的缺点。因为语音信号具有相当大的随机性,即使是同一个人在不同时刻发的同一个语音,也不可能具有完全相同的时间长度,因此时间归正处理是必不可少的。动态时间规整(dynamic time warping)是把时间归正和距离测度计算结合起来的一种非线性归整技术。它也是语音识别中一种很成功的匹配算法。
  • 动态时间规整是采用动态规划技术(dynamic programming,DP),将一个复杂的全局最优化问题转化为许多局部最优化问题,一步一步地进行决策。
  • DTW的基本思想:将时间规整与距离测度结合起来,采用动态规整技术,比较两个大小不同的模式,解决语音识别中语速多变的难题。

DTW怎么计算?

  • (1)初始化,对起点值进行初始化。
  • (2)递推求累加距离。
  • (3)回溯求出所有的匹配点对。

下面我们来总结一下DTW动态时间规整算法的简单的步骤:

  1. 首先肯定是已知两个或者多个序列,但是都是两个两个的比较,所以我们假设有两个序列A={a1,a2,a3,…,am} B={b1,b2,b3,…,bn},维度m>n

  2. 然后用欧式距离计算出每序列的每两点之间的距离,D(ai,bj) 其中1≤i≤m,1≤j≤n

DTW(dynamic time warping)动态时间归整-详解(MATLAB和python)_第1张图片
3. 接下来就是根据上图将最短路径找出来。从D(a1,a2)沿着某条路径到达D(am,bn)。找路径满足:假如当前节点是D(ai,bj),那么下一个节点必须是在D(i+1,j),D(i,j+1),D(i+1,j+1)之间选择,并且路径必须是最短的。计算的时候是按照动态规划的思想计算,也就是说在计算到达第(i,j)个节点的最短路径时候,考虑的是左上角也即第(i-1,j)、(i-1,j-1)、(i,j-1)这三个点到(i,j)的最短距离。
4. 接下来按照回溯法输出路径,从D(a1,b1)到D(am,bn)。他们的总和就是就是所需要的DTW距离。

举例:

已知:两个列向量a=[8 9 1]’,b=[ 2 5 4 6]’,其中’代表转置,也就是把行向量转换为列向量了

求:两个向量利用动态时间规整以后的最短距离
第一步:计算对应点的欧式距离矩阵d【注意开根号】

     6     3     4     2
     7     4     5     3
     1     4     3     5

第二步:计算累加距离D【从6出发到达5的累加距离】

     6     9    13    15
    13    10    14    16
    14    14    13    18

计算方法如下:
D(1,1)=d(1,1)=6

D(1,2)=D(1,1)+d(1,2)=9

D(2,2)=min(D(1,2),D(1,1),D(2,1))+d(2,2)=6+4=10

D(m,n)=min(D(m-1,n),D(m-1,n-1),D(m,n-1))+d(m,n)

MATLAB程序

程序里面尽可能的做了详细注释:
dtw.m

function [Dist,D,k,w]=dtw(r,t)
%
% [Dist,D,k,w]=dtw(r,t)
%
% Dynamic Time Warping Algorithm
% Dist is unnormalized distance between t and r
% D is the accumulated distance matrix
% k is the normalizing factor
% w is the optimal path
% t is the vector you are testing against
% r is the vector you are testing
% r和t是测试向量和模板向量,此为待输入量
%
 
[row,M]=size(r); if (row > M) M=row; r=r'; end;
[row,N]=size(t); if (row > N) N=row; t=t'; end;
d=sqrt((repmat(r',1,N)-repmat(t,M,1)).^2); %repmat函数是为了把矩阵进行重复放置,
%d就是对应点的距离矩阵                                                                  %把矢量转化为矩阵,便于求矩阵的差值
d
D=zeros(size(d));
D(1,1)=d(1,1);
 
for m=2:M
    D(m,1)=d(m,1)+D(m-1,1); %计算垂直方向对应点的距离,相邻值加上步长
end
for n=2:N
    D(1,n)=d(1,n)+D(1,n-1); %计算水平方向上对应点的距离,相邻值加上步长
end
for m=2:M   %计算对角线上的对应点的距离,此时应该找相邻3点的最小距离相加
    for n=2:N
        D(m,n)=d(m,n)+min(D(m-1,n),min(D(m-1,n-1),D(m,n-1))); % this double MIn construction improves in 10-fold the Speed-up. Thanks Sven Mensing
    end
end
D
 % D矩阵就是累加距离D
Dist=D(M,N);  %D矩阵的最左下方的D(M,N)即为所求的最小距离
n=N;
m=M;
k=1;
w=[M N]; 
while ((n+m)~=2) %找出最佳路径并输出
    if (n-1)==0
        m=m-1;
    elseif (m-1)==0
        n=n-1;
    else 
      [values,number]=min([D(m-1,n),D(m,n-1),D(m-1,n-1)]);
      switch number   %values值为输出的最小值,number为最小值在所在的位置索引
      case 1
        m=m-1;
      case 2
        n=n-1;
      case 3
        m=m-1;
        n=n-1;
      end
  end
    k=k+1;
    w=[m n; w]; % this replace the above sentence. Thanks Pau Mic
                        %w为最终的最优路径
end
    
end

主函数如下:

clear
clc
a=[8 9 1]';
b=[2 5 4 6]';
[Dist,D,k,w] = dtw(a,b);
fprintf('最短距离为%d\n',Dist)
fprintf('最优路径为')
w

输出结果如下:


d =

     6     3     4     2
     7     4     5     3
     1     4     3     5


D =

     6     9    13    15
    13    10    14    16
    14    14    13    18

最短距离为18
最优路径为
w =

     1     1
     2     2
     3     3
     3     4

结果完全符合推理过程。

python程序

python中有一个fastdtw库,可以利用该库函数实现dtw。

  • fastdtw的安装
pip install fastdtw
  • 示例代码如下:
import numpy as np
from scipy.spatial.distance import euclidean
from fastdtw import fastdtw
x = np.array([8, 9, 1])
y = np.array([2, 5, 4, 6])
distance, path = fastdtw(x, y, dist=euclidean)
print(distance)
print(path)

输出结果:

18.0
[(0, 0), (1, 1), (2, 2), (2, 3)]

和上面的MATLAB代码计算的结果相同,只是MATLAB的索引值是从1开始的,python中索引值是从0开始的。最终的最短路径是一样的。

参考

【1】https://blog.csdn.net/zb1165048017/article/details/49226315
【2】语音信号处理 -韩纪庆

你可能感兴趣的:(知识汇总,DTW,动态时间规整)