日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

fast-DTW算法

發布時間:2023/12/9 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 fast-DTW算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

之前已經介紹過了DTW算法,現在根據文章 toward accurate dynamic time warping in linear time and space,以及別人實現的fastdtw代碼分析fast-DTW算法。參考博客:http://www.cnblogs.com/kemaswill/archive/2013/04/18/3029078.html
簡單講講fast-DTW,該算法最主要有兩個部分,第一個是約束

將搜索空間約束在陰影位置,減少了搜索的次數。
第二個是抽象(abstraction),將圖像的像素合并,1/1–>1/2–>1/4–>1/8…知道可以確定路徑。如下圖,當像素合并為1/8時,已經可以確定路徑,即從左下角到右上角。接著再像素粒度細化,從1/8回到1/4確定該像素下的路徑,接著1/2,最后1/1。

接下來我們看看python實現的fastdtw算法。

def fastdtw(x, y, radius=1, dist=lambda a, b: abs(a - b)):min_time_size = radius + 2if len(x) < min_time_size or len(y) < min_time_size:return dtw(x, y, dist=dist)x_shrinked = __reduce_by_half(x)y_shrinked = __reduce_by_half(y)distance, path = fastdtw(x_shrinked, y_shrinked, radius=radius, dist=dist)window = __expand_window(path, len(x), len(y), radius)return dtw(x, y, window, dist=dist)

從代碼可以看出來這個過程實現是遞歸的,并且調用了三個函數,__expand_window,dtw,__reduce_by_half。我們先去弄懂這三個函數,再回頭來把整個fastdtw算法理順。
首先我們來看這個dtw算法。仔細理一理思路,就能很清晰的分析這個代碼了,window就是限制了的搜索范圍,只要在這個范圍內按照這個條件搜索就行。
D[i, j] = min((D[i-1, j][0]+dt, i-1, j), (D[i, j-1][0]+dt, i, j-1),(D[i-1, j-1][0]+dt, i-1, j-1), key=lambda a: a[0])
這其中用到了python的collections的defaultdict模塊,只要你傳入一個默認的工廠方法,那么請求一個不存在的key時, 便會調用這個工廠方法使用其結果來作為這個key的默認值。尋找路徑的時候是從終點尋到起點即可。

def dtw(x, y, window=None, dist=lambda a, b: abs(a - b)):len_x, len_y = len(x), len(y)if window is None:window = [(i, j) for i in xrange(len_x) for j in xrange(len_y)]window = ((i + 1, j + 1) for i, j in window)D = defaultdict(lambda: (float('inf'),))D[0, 0] = (0, 0, 0)for i, j in window:dt = dist(x[i-1], y[j-1])D[i, j] = min((D[i-1, j][0]+dt, i-1, j), (D[i, j-1][0]+dt, i, j-1),(D[i-1, j-1][0]+dt, i-1, j-1), key=lambda a: a[0])path = []i, j = len_x, len_ywhile not (i == j == 0):path.append((i-1, j-1))i, j = D[i, j][1], D[i, j][2]path.reverse()return (D[len_x, len_y][0], path)

接著,看看constraint是怎么實現的,即dtw中的window。這一部分沒太弄明白,我運行了一下這個程序,當2x2–> 4x4擴大的時候,path是整個大小,而4x4–>8x8擴大的時候path大小為56。我表示很驚訝,要是我寫這個代碼,寫出來的path大小不會這么多。

paper里面寫時間復雜度的時候提到

假設我們是在8*8的的大小下尋找搜索空間,按照paper的公式來說應該是56個,而按照圖示和描述應該是44個,不信自己可以去數一數。當然我也知道當N趨于無窮時,搜索空間的差異就顯得很小了。

def __expand_window(path, len_x, len_y, radius):path_ = set(path)for i, j in path:for a, b in ((i + a, j + b)for a in xrange(-radius, radius+1)for b in xrange(-radius, radius+1)):path_.add((a, b))window_ = set()for i, j in path_:for a, b in ((i * 2, j * 2), (i * 2, j * 2 + 1),(i * 2 + 1, j * 2), (i * 2 + 1, j * 2 + 1)):window_.add((a, b))window = []start_j = 0for i in xrange(0, len_x):new_start_j = Nonefor j in xrange(start_j, len_y):if (i, j) in window_:window.append((i, j))if new_start_j is None:new_start_j = jelif new_start_j is not None:breakstart_j = new_start_jreturn window

最后返回去看整個代碼,fastdtw就是一直遞推調用自己,同時將兩個序列二分壓縮,直到達到可以直接計算出path的大小時,返回每一次調用。然后將粒度細化,就是圖二的整個過程。

總結

以上是生活随笔為你收集整理的fast-DTW算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。