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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

论文阅读 - Joint Beat and Downbeat Tracking with Recurrent Neural Networks

發布時間:2024/7/5 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 论文阅读 - Joint Beat and Downbeat Tracking with Recurrent Neural Networks 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1 概述
  • 2 信號預處理
  • 3 分類神經網絡
  • 4 動態貝葉斯網絡(HMM)
    • 4.1 原始的bar pointer model
    • 4.2 原始的bar pointer model的缺點
    • 4.3 改進后的模型
  • 5 預測
  • 參考資料

1 概述

最近在做音樂卡點相關的項目,需要對音樂的基本特征進行理解,比如beats和downbeats就是最基本的特征。madmom是我找到的一個對beats和downbeats的檢測都有實現的第三方庫,于是就認真學習了一下,把其中用到的方法和自己的理解記錄下來。

madmom中的beats和downbeats檢測就是復現了Joint Beat and Downbeat Tracking with Recurrent Neural Networks這篇論文,其核心思想就是HMM,如果對HMM沒有扎實的理解的話,建議先看我寫的另一篇搞懂HMM。本文不會對HMM的基本概念做詳細的說明。

在說論文之前,我先來說明一些音樂上的專用術語,對齊一些概念,便于后文的敘述。有些術語在本文中可能不會再次出現,但有助于理解音樂,就一并寫上了。

名詞名詞解釋
拍子(beat)在音樂中,時間被分成均等的基本單位,每個單位叫做一個“拍子”或稱一拍。
強拍(downbeat)音樂中的強拍。是beats的子集。一般是每個小節的起始beat
小節(measure/bar)音樂是由強拍和弱拍交替進行的,是按照一定的規律構成最小的節拍組織一小節,然后以此為基礎循環往復。一個小節一般有2拍,3拍,4拍或者6拍等等
節拍(meter)beats per measure,一首歌的節拍,一般表示為1/4拍或者2/4拍或者3/8拍等等。比如3/4拍表示4分音符為1拍,每小節有3拍,節拍強度為強、弱、弱。
全局節奏(tempo)一般用bpm(beats per minute)來做單位,表示每分鐘有多少個beats,用來衡量音樂的速度,一首音樂可以由不同的tempo演奏。
局部節奏(tempi)每兩個相鄰的beats之間可以是有不同的1/16音符,或是1/8音符,或是1/4等組成的,這個就是局部節奏
onset一個音符被樂器或者人發出聲音的那個時刻點。
峰值(peak)onset包絡圖的峰值,具體可見peak_pick。

再說回這篇論文。這篇論文概括地說就是把信號切成多個frames,每個frame會在RNN網絡之后對應一個概率輸出,表示該frame是beat還是downbeat還是都不是。HMM會在發射概率的計算中借助于這個RNN結果,把frame在measure當中的相對位置和tempi作為隱變量,得到最佳的隱變量路徑,并把該路徑解碼為beats和downbeats。

下面會分步驟說明一下每個步驟,著重是HMM和預測部分。這兩部分理解起來有點繞。

2 信號預處理

這部分其實就是一個類似于MFCC提取語音信號特征的過程,作為RNN的輸入,這里簡單說下。先是用漢寧窗對信號做了有交疊的分割,分成了100fps(frame per second),并基于此做了短時傅里葉變換(STFT)。丟棄了相位特征,只保留幅值特征,因為人耳是聽不出相位的。為了保證時域和頻域的精度,做STFT時,分別用了1024,2048和4096三種窗口大小。把頻段限制在了[30, 17000]Hz的的范圍,并給每個八度分了3,6和12個頻段,分別對應于1024,2048和4096三種窗口大小。同時也對頻譜進行了一階差分,也作為特征concat進去。最終,輸入網絡的特征維度為314。

3 分類神經網絡

這部分用了由LSTM搭建而成的網絡,目的是給每個frame進行分類,輸出兩個概率值,(是beat的概率,是downbeat的概率),取較大的作為該frame的分類。為了避免混淆,downbeat不屬于beat。

同時,也設置了θ=0.05\theta=0.05θ=0.05的閾值,只有大于該閾值,才會被判為是beat或者downbeat。這是為了減小音樂頭尾有空白的干擾。

既然每個frame是beat還是downbeat的概率都知道了,那我直接取每個frame最大概率的類別,兩個概率都比較小的就認為既不是beat也不是downbeat,這事不就成了?

理想很美好,現實并非如此,不要被論文中的圖片給誤導了,來看下模型的實際輸出是長啥樣的。

圖3-1 RNN網絡輸出示意圖

模型的輸出如上圖3-1所示,這個是一條30s左右的實際樣例。上半個圖是每個frame為beat的概率,下半個圖是每個frame為downbeat的概率。只看downbeat這部分的話,不難看出概率比較高的frame之間的間距有長有短,而在一個小節(bar)當中,強拍(downbeat)應該只會出現一次,次強拍的出現會對其產生干擾。RNN不知道強拍的出現是有周期性的,所以需要HMM來判斷究竟哪些位置是強拍,哪些位置是弱拍,哪些位置什么都不是。

從另一個角度來思考,RNN這里并不知道音樂的meter是幾幾拍,沒有這個信息,要RNN直接判斷強拍和弱拍的難度是很大的。下一節的HMM的作用就是根據RNN的結果,去選一組最優的beats和downbeats。

4 動態貝葉斯網絡(HMM)

這是重點部分,我們來詳細講一下。Joint Beat and Downbeat Tracking with Recurrent Neural Networks對這部分的說明很不清晰,我們直接看它沿用的An Efficient State-Space Model for Joint Tempo and Meter Tracking中的說明即可。

4.1 原始的bar pointer model

早在2006年的時候,Bayesian Modelling of Temporal Structure in Musical Audio就提出過用HMM解決beat tracking問題的方法。現在的方法,就是在它的基礎上優化的,我們先來看看最早版本的HMM是怎么設計的。

我們令第kkk個frame的隱變量為xk=[Φk,Φ˙k]\bold{x}_k=[\Phi_k, \dot{\Phi}_k]xk?=[Φk?,Φ˙k?]。Φk∈{1,2,...,M}\Phi_k \in \{1,2,...,M\}Φk?{1,2,...,M}表示第kkk個frame在某個小節(bar)中的相對位置,1表示起始位置,MMM表示結束位置,這個bar被分成了M個相對位置,一般是均分的。Φ˙k∈{Φ˙min,Φ˙min+1,...,Φ˙max}\dot{\Phi}_k \in \{\dot{\Phi}_{min}, \dot{\Phi}_{min} + 1, ..., \dot{\Phi}_{max}\}Φ˙k?{Φ˙min?,Φ˙min?+1,...,Φ˙max?}表示第kkk個frame的tempi,Φ˙min\dot{\Phi}_{min}Φ˙min?Φ˙max\dot{\Phi}_{max}Φ˙max?是人為設置的上下界。說的通俗一點,把Φk\Phi_kΦk?看成位移的話,Φ˙k\dot{\Phi}_kΦ˙k?就是速度,k+1k+1k+1個frame的位置Φk+1\Phi_{k + 1}Φk+1?就是Φk+Φ˙k\Phi_k + \dot{\Phi}_kΦk?+Φ˙k?。說的音樂一點,就是Φ˙k\dot{\Phi}_kΦ˙k?表示了第kkk個frame是一個幾分之幾的音符,比如1/8音符,如果知道這首歌是4/4拍的話,第kkk個frame就走了(1/8)/(4?1/4)=1/8(1/8) / (4*1/4) = 1/8(1/8)/(4?1/4)=1/8個小節(bar),這里使用離散的MMM個數值來表示了。

觀測變量就是我們的frames的特征序列,記為{y1,y2,...,yK}\{\bold{y}_1, \bold{y}_2, ..., \bold{y}_K\}{y1?,y2?,...,yK?}。我們想要找到一串隱變量的序列x1:K?={x1?,x2?,...,xK?}\bold{x}_{1:K}^*=\{\bold{x}_1^*, \bold{x}_2^*, ..., \bold{x}_K^*\}x1:K??={x1??,x2??,...,xK??}使得

x1:K?=argmax?x1:KP(x1:K∣y1:K)(4-1)\bold{x}_{1:K}^* = arg\max_{\bold{x}_{1:K}} P(\bold{x}_{1:K} | \bold{y}_{1:K}) \tag{4-1} x1:K??=argx1:K?max?P(x1:K?y1:K?)(4-1)

(4?1)(4-1)(4?1)可以用viterbi算法來解,不清楚的可以參看我的搞懂HMM。求解式(4?1)(4-1)(4?1)需要知道三個模型,一個是初始概率模型P(x1)P(\bold{x}_1)P(x1?),第二個是狀態轉移模型P(xk∣xk?1)P(\bold{x}_k|\bold{x}_{k-1})P(xk?xk?1?),第三個是發射概率P(yk∣xk)P(\bold{y}_k|\bold{x}_k)P(yk?xk?)。

(1)初始概率
初始概率P(x1)P(\bold{x}_1)P(x1?),作者用了均勻分布初始化,后面用數據學就行,沒啥說的。

(2)轉移概率
轉移概率是個比較關鍵的概率,我們來仔細看下

P(xk∣xk?1)=P(Φk,Φ˙k∣Φk?1,Φ˙k?1)=P(Φk∣Φ˙k,Φk?1,Φ˙k?1)P(Φ˙k∣Φk?1,Φ˙k?1)\begin{aligned} P(\bold{x}_k | \bold{x}_{k-1}) &= P(\Phi_k, \dot{\Phi}_k | \Phi_{k-1}, \dot{\Phi}_{k-1}) \\ &=P(\Phi_k | \dot{\Phi}_k, \Phi_{k-1}, \dot{\Phi}_{k-1})P(\dot{\Phi}_k | \Phi_{k-1}, \dot{\Phi}_{k-1}) \end{aligned} P(xk?xk?1?)?=P(Φk?,Φ˙k?Φk?1?,Φ˙k?1?)=P(Φk?Φ˙k?,Φk?1?,Φ˙k?1?)P(Φ˙k?Φk?1?,Φ˙k?1?)?

我們把Φk\Phi_kΦk?理解成位移,Φ˙k\dot{\Phi}_kΦ˙k?理解成速度,這應該也是為啥這兩個變量的符號只差了一個一階導的符號的原因。

Φk\Phi_kΦk?kkk時刻的位置,它由上一刻的位置Φk?1\Phi_{k-1}Φk?1?和上一刻的速度Φ˙k?1\dot{\Phi}_{k-1}Φ˙k?1?決定,與kkk時刻的速度無關,故有

P(Φk∣Φ˙k,Φk?1,Φ˙k?1)=P(Φk∣Φk?1,Φ˙k?1)P(\Phi_k | \dot{\Phi}_k, \Phi_{k-1}, \dot{\Phi}_{k-1}) = P(\Phi_k | \Phi_{k-1}, \dot{\Phi}_{k-1}) P(Φk?Φ˙k?,Φk?1?,Φ˙k?1?)=P(Φk?Φk?1?,Φ˙k?1?)

Φ˙k\dot{\Phi}_kΦ˙k?kkk時刻的速度,它只與k?1k-1k?1時刻的速度有關,速度不太會突變,與位置無關,故有

P(Φ˙k∣Φk?1,Φ˙k?1)=P(Φ˙k∣Φ˙k?1)P(\dot{\Phi}_k | \Phi_{k-1}, \dot{\Phi}_{k-1}) = P(\dot{\Phi}_k | \dot{\Phi}_{k-1}) P(Φ˙k?Φk?1?,Φ˙k?1?)=P(Φ˙k?Φ˙k?1?)

于是有

P(xk∣xk?1)=P(Φk∣Φk?1,Φ˙k?1)P(Φ˙k∣Φ˙k?1)(4-2)P(\bold{x}_k | \bold{x}_{k-1}) = P(\Phi_k | \Phi_{k-1}, \dot{\Phi}_{k-1})P(\dot{\Phi}_k | \dot{\Phi}_{k-1}) \tag{4-2} P(xk?xk?1?)=P(Φk?Φk?1?,Φ˙k?1?)P(Φ˙k?Φ˙k?1?)(4-2)

P(Φk∣Φk?1,Φ˙k?1)P(\Phi_k | \Phi_{k-1}, \dot{\Phi}_{k-1})P(Φk?Φk?1?,Φ˙k?1?)就是一個位移的計算,可以定義為

P(Φk∣Φk?1,Φ˙k?1)={1,if(Φk?1+Φ˙k?1?1)%M+10,otherwise(4-3)P(\Phi_k | \Phi_{k-1}, \dot{\Phi}_{k-1}) = \begin{cases} 1, &if \ (\Phi_{k-1} + \dot{\Phi}_{k-1} - 1) \% \ M + 1\\ 0, &otherwise \end{cases} \tag{4-3} P(Φk?Φk?1?,Φ˙k?1?)={1,0,?if?(Φk?1?+Φ˙k?1??1)%?M+1otherwise?(4-3)

也就是Φk=(Φk?1+Φ˙k?1?1)%M+1\Phi_k = (\Phi_{k-1} + \dot{\Phi}_{k-1} - 1) \% \ M + 1Φk?=(Φk?1?+Φ˙k?1??1)%?M+1的意思。這里取余是為了在下一個bar中,位置重新計數。為啥要先減1再取余再加1?我猜測是為了避免產生Φk=0\Phi_k=0Φk?=0的情況,使得Φk\Phi_kΦk?的取值在{1,2,...,M}\{1,2,...,M\}{1,2,...,M},只是為了符號的統一。

P(Φ˙k∣Φ˙k?1)P(\dot{\Phi}_k | \dot{\Phi}_{k-1})P(Φ˙k?Φ˙k?1?)是一個速度變化的概率,定義為

P(Φ˙k∣Φ˙k?1)={1?p,Φ˙k=Φ˙k?1p2,Φ˙k=Φ˙k?1+1p2,Φ˙k=Φ˙k?1?1(4-4)P(\dot{\Phi}_k | \dot{\Phi}_{k-1}) = \begin{cases} 1 - p, & \dot{\Phi}_k=\dot{\Phi}_{k-1} \\ \frac{p}{2}, & \dot{\Phi}_k=\dot{\Phi}_{k-1} + 1 \\ \frac{p}{2}, & \dot{\Phi}_k=\dot{\Phi}_{k-1} - 1 \end{cases} \tag{4-4} P(Φ˙k?Φ˙k?1?)=??????1?p,2p?,2p?,?Φ˙k?=Φ˙k?1?Φ˙k?=Φ˙k?1?+1Φ˙k?=Φ˙k?1??1?(4-4)

ppp是速度發生變化的一個概率,我們人為限制了速度只能在距離為1的速度上轉移或者保持不變。在邊界Φ˙min\dot{\Phi}_{min}Φ˙min?Φ˙max\dot{\Phi}_{max}Φ˙max?上,略有不同,保持速度不超界即可。ppp是需要學習得到的。

圖4-1 原始狀態轉移示意圖

原始狀態轉移示意圖如圖4-1所示,可以很明顯滴看出位置和速度的關系。

(3)發射概率
這里是結合RNN的結果的地方。我們假設第kkk個frame為beat的概率是bkb_kbk?,為downbeat的概率是dkd_kdk?,既不是beat也不是downbeat的概率為nkn_knk?。那么發射概率就為

P(yk∣xk)={bk,sk∈Bdk,bk∈Dnkλ0?1,otherwise(4-5)P(\bold{y}_k | \bold{x}_k) = \begin{cases} b_k, &s_k \in B \\ d_k, &b_k \in D \\ \frac{n_k}{\lambda_0 - 1}, & otherwise \end{cases} \tag{4-5} P(yk?xk?)=??????bk?,dk?,λ0??1nk??,?sk?Bbk?Dotherwise?(4-5)

BBB表示xkx_kxk?被認為是beat的集合,DDD表示xkx_kxk?被認為是downbeat的集合。怎么樣的xkx_kxk?會被認為是beat或是downbeat呢?這點論文中沒有細說,我看了A Multi-model Approach to Beat Tracking Considering Heterogeneous Music Styles中的做法,大概猜測了一下,是將位置在小節等分點附近的states作為beat或者downbeat,每個小節的第一個等分點附近為downbeat(每小節的第一拍為強拍),其他的等分點附近為beat。這個附近有多近,其實是個可以人為設置的范圍。按幾等份算,則是一個用戶需要提前輸入的參數,比如一首歌是3/4拍的,那每個小節就有3拍,就三等分,又比如一首歌是6/8拍的,那每個小節就有6拍,就六等份。如果不知道是幾幾拍的音樂的話,就一個個算過去,取概率最大的,這個在下一節會講。

λ0\lambda_0λ0?是個超參數,論文中取λ0=16\lambda_0=16λ0?=16得到了最好的實驗結果。BBBDDD的范圍和λ0\lambda_0λ0?相關。

4.2 原始的bar pointer model的缺點

(1)位置(時間)分辨率
原文中說是時間分辨率,我這里直接說成位置分辨率了,這樣比較方便理解。作者認為不同的速度下,需要的位置分辨率是不同的。速度快的,每次都大步大步跨,需要的位置分辨率很低;速度慢的,每次跨的步幅小,需要的位置分辨率就高了。一句話說,就是不同的速度條件下,要不同的位置分辨率。

(2)速度分辨率
原文中的tempo就是我這里的速度。作者認為人耳對于速度的變化感知,在不同的速度下是不一樣。比如在速度為1的時候,速度加個1,變成2,聽起來就變化很明顯了。但是在速度為10的時候,速度價格1,變成11,聽起來都沒什么變化。也就是人耳的聽覺不是linear的,而是log linear的。

(3)速度的穩定性
使用HMM時,有一個齊次馬爾科夫假設,認為Φk\Phi_kΦk?只依賴于Φ˙k\dot{\Phi}_kΦ˙k?,這可能會導致同一個beat里,速度經過幾個frames之后就產生比較大的變化,也就是速度的穩定性無法保證。

4.3 改進后的模型

論文針對4.2中提出的三點對模型進行了改進,改進都是針對狀態轉移的計算的。改進后的狀態轉移示意圖,如下圖4-2所示。

圖4-2 改進后的狀態轉移示意圖

(1)位置分辨率的改進
這里說白了就是根據速度來調整一個bar要被分成幾份。從圖4-2中的橫向可以看出,tempo越大的,bar position就被分的越稀疏,反之越密。劃分方式我們從具體madmom的實現來看,不看論文里說的,論文里說的有些模糊。

""" max_bpm:用戶輸入,表示最大的beats per minute,默認為215 min_bpm:用戶輸入,表示最小的beats per minute,默認為55 fps:用戶輸入,frame per secondmin_interval:計算得到,最小的frame per beat max_interval:計算得到,最大的frame per beat """ # convert timing information to construct a beat state space min_interval = 60. * fps / max_bpm # second per beat * frame per second = frame per beat max_interval = 60. * fps / min_bpm

上面代碼片中的min_interval和max_interval就是由最大的bpm和最小的bpm確定的每個beat被分為多少個frames。一個bar有多少個beats也是用戶輸入的,所以一個bar的bar positions也就根據速度的不同確定了。

(2)速度分辨率的改進
速度在min_bpm和max_bpm的范圍內,按log linear的方式進行了劃分。具體的實現可以看這一段https://github.com/CPJKU/madmom/blob/master/madmom/features/beats_hmm.py#L66。應該說實現中,沒有速度這個東西,都轉變成了位置。不同bpm下有不同的位置點,log linear的對象是位置。

(3)速度穩定性
作者為了保證速度的穩定性,速度只能在每個beat的位置上發生改變,改變時依賴于一個分布,這個分布是在實驗中試了幾個得到的。

Φk∈B\Phi_k \in BΦk?B

P(Φ˙k∣Φ˙k?1)=f(Φ˙k,Φ˙k?1)(4-6)P(\dot{\Phi}_k | \dot{\Phi}_{k-1}) = f(\dot{\Phi}_k, \dot{\Phi}_{k-1}) \tag{4-6} P(Φ˙k?Φ˙k?1?)=f(Φ˙k?,Φ˙k?1?)(4-6)

其中f(Φ˙k,Φ˙k?1)f(\dot{\Phi}_k, \dot{\Phi}_{k-1})f(Φ˙k?,Φ˙k?1?)可以是各種各樣的函數,效果比較好的是

f(Φ˙k,Φ˙k?1)=exp(?λ×∣Φ˙kΦ˙k?1?1∣)(4-7)f(\dot{\Phi}_k, \dot{\Phi}_{k-1}) = exp(-\lambda \times |\frac{\dot{\Phi}_k}{\dot{\Phi}_{k-1}} - 1|) \tag{4-7} f(Φ˙k?,Φ˙k?1?)=exp(?λ×Φ˙k?1?Φ˙k???1)(4-7)

不難看出,當Φ˙k?1=Φ˙k\dot{\Phi}_{k-1} = \dot{\Phi}_kΦ˙k?1?=Φ˙k?時概率最大。λ∈[1,300]\lambda \in [1, 300]λ[1,300]是一個超參數,不同λ\lambdaλf(Φ˙k,Φ˙k?1)f(\dot{\Phi}_k, \dot{\Phi}_{k-1})f(Φ˙k?,Φ˙k?1?)的結果如下圖4-3所示。

圖4-3 不同參數下f的結果圖

Φk?B\Phi_k \notin BΦk?/?B
P(Φ˙k∣Φ˙k?1)={1,Φ˙k=Φ˙k?10,otherwise(4-8)P(\dot{\Phi}_k | \dot{\Phi}_{k-1}) = \begin{cases} 1, & \dot{\Phi}_k = \dot{\Phi}_{k-1} \\ 0, & otherwise \end{cases} \tag{4-8} P(Φ˙k?Φ˙k?1?)={1,0,?Φ˙k?=Φ˙k?1?otherwise?(4-8)

表示速度不變。

5 預測

madmom很清晰地把整個模型分成了兩塊,DBNDownBeatTrackingProcessor和RNNDownBeatProcessor。RNNDownBeatProcessor就是我們的RNN網絡,DBNDownBeatTrackingProcessor是HMM的部分。從宏觀上講,beats和downbeats的位置是由RNN大致確定,然后由HMM根據周期性這個條件去決定最后的位置的。RNN可以理解為是針對局部的理解,HMM是針對全局的決策。

在預測的時候,我們會告訴模型這首歌每個bar的beat有幾個,如果不確定的話,就把beats_per_bar=[2,3,4,6]全填上,讓模型每個跑一邊,然后取概率最大的就行了。

在每個beats_per_bar下,我們算一個最佳的隱變量路徑

x1:K?=argmax?x1:K(x1:K∣y1:K)(5-1)\bold{x}_{1:K}^* = arg\max_{x_{1:K}}(\bold{x}_{1:K} | \bold{y}_{1:K}) \tag{5-1} x1:K??=argx1:K?max?(x1:K?y1:K?)(5-1)

解這個用viterbi算法就可以了。

最終的結果就是

B?={k:xk?∈B}(5-2)B^* = \{k : \bold{x}_k^* \in B\} \tag{5-2} B?={k:xk??B}(5-2)

D?={k:xk?∈D}(5-2)D^* = \{k : \bold{x}_k^* \in D\} \tag{5-2} D?={k:xk??D}(5-2)

確定了B?B^*B?D?D^*D?之后,還會根據RNN的結果,把點修正到附近的概率峰值點上。

驗證模型的時候,把誤差在70ms以內的點都認為是正確的。madmom的效果還是很不錯的。

參考資料

[1] madmom implementation
[2] Joint Beat and Downbeat Tracking with Recurrent Neural Networks
[3] An Efficient State-Space Model for Joint Tempo and Meter Tracking
[4] 百度百科-音樂節拍
[5] Bayesian Modelling of Temporal Structure in Musical Audio
[6] A Multi-model Approach to Beat Tracking Considering Heterogeneous Music Styles

總結

以上是生活随笔為你收集整理的论文阅读 - Joint Beat and Downbeat Tracking with Recurrent Neural Networks的全部內容,希望文章能夠幫你解決所遇到的問題。

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