如何使用神經網絡彈奏出帶情感的音樂?
神經網絡在音樂方面的應用已經不是一個新鮮的話題了。在音頻檢索領域中,人們一直在嘗試著用神經網絡對一系列音樂元素進行建模 [1],例如和弦、音高等等。正如作者所提及的,人們在 1943 年開始用神經網絡解決語音識別的問題。但是在那個年代,沒有足夠的計算能力來得到較好的結果,所以神經網絡的方法在那個時候并不流行。而現在,由于 GPU 計算資源和可獲得的大數據,結果可以變得相當好,于是作者就希望使用像圖 1 中的神經網絡來進行一個音樂實驗,來實現音樂風格的神經轉換。在這篇文章中,作者給出了非常詳細的分析和什么會這樣思考,本文也表明使用作者提出的方法,我們可以得到良好的結果。
圖 1. 深度神經網絡
音樂和神經網絡
谷歌的一個名為 Google Magenta[2] 的項目正在使用 AI 作曲家來產生開創性的結果,它使用神經網絡來生成旋律。這證明了神經網絡是成功的應用。其驚人的性能讓作者認為神經網絡還可以做一些有趣的音樂預測。
隨后作者分析了音樂中的兩個重要元素,音樂構成和音樂表現。音樂構成關注的是音樂本身,它的指的是能夠定義一首歌曲的音符。如作者所說,你可以將它看作是圖 2 中的樂譜。
圖 2. 一段樂譜圖
然而這對音樂家而言只是***步。這些樂譜如何被演奏家演奏,這才是音樂工作的靈魂。因為演奏者演奏者演奏得各不相同,所以我們用音樂風格來描述個人化的音樂演奏。
什么是音樂風格
音樂風格很難定義,因為不能把音樂風格像音高一樣被參數化。如果你曾聽過很多經典的鋼琴曲,那么你會發現一個新手和一個資深的鋼琴家會奏出大不相同的強弱力度(dynamics),這里指的是音樂響度的變化。一個音符的響度可以通過控制敲擊琴鍵的輕重程度來實現。在音樂符號中這些不同級別的強弱力度一般用意大利字母表示。這些字母被稱為情感符。不同的人會有不同的感覺,所以這里的特定的強弱集合都有著各自的情感表現。因此情感表現就意味著一組***的強弱力度,而強弱力度也就成了風格的重要特征。
圖 3:樂譜中的強弱力度范圍
此外,人們還用一些流派來標記音樂,例如經典音樂、爵士音樂等等。由此我們可以發現,在一些特定的音樂風格中是存在一些規則的,因此人們可以通過強弱力度來識別音樂風格。這也意味著人么可以用流派來歸類音樂風格。
我們可以拿強弱力度來干什么?
在參考文獻 [3,4,5] 中,他們在嘗試著生成音樂構成的那一部分,但是并沒有音樂表現的那一部分。所以作者在這篇文章中通過添加強弱信息使用樂器數字接口(MIDI)來像人一樣演奏音樂。
是人還是機器人在演奏呢?
作者設計并訓練模型來為活頁樂譜合成強弱力度(dynamics)。作者展示了一種樂譜的兩個不同的演奏,其中一個來自于人,另一個來自于機器。并進行了盲測,即看一看你能不能區分出哪一個是人演奏的,哪一個是機器演奏的。如作者提到的那樣。只有不到一半的受試者能夠正確地區分出來。我也聽過這兩種音樂,不幸的是,我能夠很輕易地區分出來哪一個是人演奏的。因為由機器演奏的那一段中仍然存在很奇怪的強弱力度,并且我能夠確保人類不會做出那樣的演奏。即便如此,這個結果還是足以令人印象深刻了。
背景知識
1. 神經元
圖 4 所示是神經網絡中最基本的計算單元--神經元。
圖 4. 人工神經元
輸入與對應權重 w 的乘積和,然后再加上偏置單元 b。凈輸入可以通過方程 1 計算得到:
神經元的輸出通過使用方程 2 所示的激活函數 g() 來計算:
Sigmoid 函數是最常用的激活函數。這個函數將任意實數作為輸入,并將它們壓縮在 0 到 1 之間。我們可以在圖 5 中看到,一個很小的數字可以被替代成接近于 0 的結果,一個很大的數字可以被替代為接近于 1 的結果。其他常見的激活函數還有 Tanh 和 Relu。
圖 5. sigmoid 激活函數
2. 前饋神經網絡
前饋神經網絡(FNN)是最常用的結構。神經元逐層相連。***層是輸入層,***一層是輸出層。輸入層和輸出層之間是隱藏層。圖 6 所示是一個只有一層隱藏層的前饋神經網絡。在前饋神經網絡中有一個假設:即每一個輸入都是和其余輸入相互獨立。
3. 循環神經網絡
一個簡單的前饋神經網絡的主要局限性是缺乏記憶。這是因為前饋神經網絡假設輸入之間是彼此獨立的。但是在音樂中,樂譜是在全局結構下寫成的,因為音樂家是基于他想要表達的某種情感來譜曲的,所以音符序列不能簡單地認為音符序列是獨立的。循環神經網絡(RNN)可以解決這類問題。循環神經網絡有狀態(states),以及一個被稱作循環權重的反饋回路。這個結構在計算當前輸出的時候還利用了前一時刻的狀態。這意味著循環神經網絡有一個短期記憶機制來記住過去的計算結果,并將它用來計算當前的結果。圖 7 展示了這個機制。
圖 7. 按時間展開的循環神經網絡
4. 雙向循環神經網絡
音樂家有能力預測樂譜中的走向,這有助于對即將到來的情感符號做好準備。但是對于簡單的循環神經網絡而言,它是按順序讀取輸入的。所以需要有一個能夠訪問即將到來時間步驟的神經網絡。有一種叫做雙向循環神經網絡(Bi-Directional RNN)的結構。如圖 8 所示,這個結構結合了兩個循環神經網絡層。
圖 8. 雙向循環神經網絡
***層被稱為前向層,它以原始的順序讀取輸入。第二層叫做反向層,它以反向順序讀取輸入。對于作者提出的目標而言,這個結構貌似是一個不錯的選擇。
5. 長短期記憶網絡
根據參考文獻 [7,8],循環神經網絡***的問題就是它無法記住長期依賴的關系。為了解決這個問題,文獻 [9] 中提出了長短期記憶網絡(LSTM),為了控制類似于該記住多少,該遺忘多少的問題,LSTM 中提供了門控機制。
圖 9. 一個 LSTM 單元
架構設計
***我們開始設計整個系統的架構。作者在這篇文章中使用了雙向-長短期記憶網絡(Bi-Directional LSTM)。分別用兩個網絡實現對音樂流派和風格的分析,分別叫做 GenreNet 和 StyleNet。
1. GenreNet
流派具有可定義的音樂風格,所以作者使用這個特點來設計學習一首樂曲演奏強弱力度的基本模型。如圖 10 所示,這個模型中有兩個主要的層:雙向 LSTM(Bi-Directional LSTM)和線性層。
圖10. GenreNet
雙向 LSTM 層結合了 LSTM 網絡的優點,它對學習相關的依賴提供了記憶,雙向結構還使得模型在學習的時候同時考慮了未來的信息。這使得模型的輸出可以作為另一層網絡的輸入。線性層就是被用來把雙向 LSTM 的輸出值的范圍從 [-1,1] 變得更大。
2. StyleNet
這個網絡被用來學習一些在 Genre 網絡上無法訓練得到的更加復雜的風格信息。StyleNet 中有 GenreNet 的子網絡,它們被用在 StyleNet 中來學習特定流派的風格。在 StyleNet 中,有一個解釋層,它可以被 GenreNet 子網絡共享。這大大減少了網絡需要學習的參數。并且 StyleNet 就像是一個能夠將音樂轉換為不同風格的轉換工具。如圖 11 所示,這是一個多任務學習模型。
圖 11. StyleNet
3. 數據
作者在這篇文章中使用了 MIDI 格式的音樂文件,因為這種格式的文件包含了音樂屬性。有一個叫做速率(velocity)的參數來存儲強弱力度。它類似于音量,但是取值范圍在 0~127 之間。作者在本文中用速率來檢測強弱力度。
在本文中,作者創建了一個鋼琴數據集。MIDI 文件的流派被限定在經典和爵士這兩種里面。作者采用的 MIDI 文件全部來自于雅馬哈鋼琴電子競賽。如圖 12 所示,通常情況人類表演至少擁有 45 中不同的速率。作者將不同速率的數量的最小閾值設置為 20。
圖 12. 左:下載到的 MIDI 文件中的速率的數量。右:表演 MIDI 文件中速率的數量
***,我們我們在這篇文章中選擇了 4/4 拍,因為它是最常見的一種節拍,所以作者可以擁有比其他節拍更多的數據。
我們所用的數據集總共包含 349 個經典曲鋼琴曲和爵士鋼琴曲。
MIDI 編碼方案
在得到了鋼琴數據集之后,接下來的一部就是設計輸入輸出矩陣。
1. 量化
首先,數據集應該被量化,這使得作者能夠拿矩陣來表征樂譜。但是但是這樣做會導致一個結果,那就是我們會丟失樂譜相關的定時信息。文章中作者將樂譜的時間戳近似到了最接近的第 1/16 個音符。然后我們呢就可以捕獲樂譜。圖 13 展示了量化之前和量化之后的樂譜表征的不同。
圖 13. 量化
2. 輸入矩陣表征
輸入將會攜帶有關樂譜音高、開始時間以及結束時間等相關信息。樂譜總共有三個狀態,所以作者使用二進制向量來表示這三個狀態。「on」被編碼為 [1,1],「sustained」被編碼為 [0,1],「off」被編碼為 [0,0]。
樂譜音高也需要被編碼,我們會創建一個矩陣,其中***維是關于 MIDI 音高數量的值,第二維是關于 1/16 音符量化為時間步驟的值。這些在圖 14 中可以看到。
圖 14. 輸入輸出表征
3. 輸出矩陣的表征
輸出矩陣攜帶著輸入的速率。如圖 14 所示,矩陣的列也表示音高,行表示時間步驟。音高維度只有 88 個音符,因為我們這次只需要表示速率。然后我們以***的速率 127 把數據進行分割,***輸出速率被解碼為一個 MIDI 文件。
訓練
作者給出了訓練網絡的每一個細節過程。這里我僅僅向你們展示一些關鍵步驟。輸入應該是 176 個節點的寬度和一層的深度。用 tensorflow 建立具有兩個 GenreNet 單元的模型(經典和爵士)。每一個 GenreNet 有 3 層。使用 Mini-batch,大小為 4。將學習率設置為 0.001. 使用 Adam 優化器來進行隨機優化。作者使用數據集中的 95% 來訓練,剩下的 5% 來做驗證。另外,在如圖 15 所示的實驗中,dropout rate 設置為 0.8。這樣的 dropout rate 使模型能夠學到潛在的模式。模型被訓練了 160 個 epoch,最終的損失值和驗證損失值分別為 0.0007 和 0.001。
在圖 16 中,作者展示了訓練誤差和驗證誤差。
圖 16. 訓練誤差率和驗證誤差率
作者還展示了很多訓練過程的快照,所以我們可以在快照中發現經典音樂和爵士音樂的不同。圖 17 是快照之一。
圖 17. 訓練過程的一次快照
結果
測試結果的關鍵就是看看 StyleNet 是否能夠生成像人一樣的表演。作者在這里使用了圖靈測試來測試結果 [11]。作者組織了一個叫做「鑒別人類演奏」的調查。這兩部分總共有 9 個問題,如圖 18 所示,參與者需要在 10 秒內聽完一個音樂片段。
圖 18. [鑒別人類演奏] 測試
在測試中參與者需要鑒別出人類的演奏。如圖 19 所示,大約平均 53% 的參與者能夠聽出人類的演奏。
圖 19. [鑒別人類的演奏] 測試結果
為了讓這個調查更加完整,作者還添加了一項名為「不能確定」的選項來確保參與者不是在瞎蒙。如圖 20 所示,這一次作者發現只有 46% 的人能夠鑒別出人類的演奏。這意味著 StyleNet 模型能夠通過圖靈測試,它可以生成與人類并無區別的演奏。
圖 20. 最終鑒別測試結果
我學會演奏小提琴已經有 19 年了,所以我特別贊同作者關于音樂的兩大元素的觀點,也就是說,音樂構成和音樂表現。有時候表演會更加困難一些。在聽完生成的演奏之后,我覺得 StyleNet 的表演的確是令人印象深刻的。我認為如果音符量化能夠做的更小,例如 1/32 甚至 1/64,那么它有可能得到更好的結果。此外,我覺得其中的一項挑戰就是你并不能確保 StyleNet 從人類的表演中學到了正確的風格。在作者提供的測試中,我能夠正確地分辨出人類的演奏的原因就是仍然有一部分音符的細節并沒被網絡學習到,而這些細節正是我用來判斷一段音樂是不是人類演奏的關鍵。我的建議是讓音樂家去聽 StyleNet 生成的音頻,我相信他們能夠給出一些專業的建議,然后這些專業的建議會幫助網絡學習得更好。
我還想將作者提出的工作與計算機視覺中的風格變換 [12,13] 做一個對比。他們的基本方法是相似的:它們都是用了兩個與風格對應的網絡,其他的都用于內容。但是對于圖像的風格轉換,這兩個網絡的不同點是很大的(一個用于內容重建,另一個用于風格重建)。對于內容重建,它會通過計算不同子集的卷積神經網絡捕捉不同尺寸的空間特征而生成,例如:conv1_1,[conv1_1, conv2_1],[conv1_1, conv2_1, conv3_1],[conv1_1, conv2_1, conv3_1,conv4_1],[conv1_1, conv2_1, conv3_1, conv4_1, conv5_1]。而在音樂的例子中,我認為使用 LSTM 生成音樂的主要思想就是捕捉音樂風格和音樂表現中的特征。總結一下:卷積神經網絡是典型的空間深度神經網絡,循環神經網絡是典型的時間深度神經網絡。在使用卷積神經網絡的時候,我們應該關注空間映射,圖像特別適合這個場景。然而對于音樂,我們需要對時間序列做分析,所以我們使用了循環神經網絡。
【本文是51CTO專欄機構“機器之心”的原創文章,微信公眾號“機器之心( id: almosthuman2014)”】