论文阅读 - 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所示,這個是一條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得到了最好的實驗結果。BBB和DDD的范圍和λ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所示。
(1)位置分辨率的改進
這里說白了就是根據速度來調整一個bar要被分成幾份。從圖4-2中的橫向可以看出,tempo越大的,bar position就被分的越稀疏,反之越密。劃分方式我們從具體madmom的實現來看,不看論文里說的,論文里說的有些模糊。
上面代碼片中的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所示。
當Φ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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 九、ES6的箭头函数
- 下一篇: 加入 Git 版本管理(git的基本使用