この記事は、LeapMind Advent Calendar 2019の 15日目の記事です。
タイトルは釣りです。"俺"は今回紹介する音楽生成システム JamBot のことを指します。僕はコード理論全然わかんないです。
誰
おはようございま数理工学!今日も一日!!まっくす@minux302というものです。現在 LeapMind という会社で Deep Learning エンジニアをやらしてもらっております。
自分はイラストやピアノなどが趣味で、その延長で機械学習と組み合わせてなんか創りたいなーって日々思っています。(思っている暇があったら手を動かせ。)
例えば、弊社では週5日間まるっと使って創りたいものを作る HackDays というハッカソンがあり、その時はリズム感だけで誰でもリアルタイム演奏が楽しめるおもちゃを創りました。
このおもちゃに使用しているモデルは、コード進行(曲の雰囲気を決める要素みたいなもの)を考慮しながら音楽をリアルタイムで生成をするものとなっています。まだ全然完成してないのですがソースコードは一応ここにあります。
それに関連して、今回はコード進行を考慮して音楽生成を行う手法についての論文 JamBot: Music Theory Aware Chord Based Generation of Polyphonic Music with LSTMs について簡易的に紹介しようと思います。本当はこのモデルを元に色々ガチャガチャやっていたんですが、思うような結果が得られなかったのでそれはまた今度にいたします。(残骸へのリンク)
前提知識
コード is 何?
さっきからコード進行って言ってるけど、まずそのコードって何?と言う人もいると思うので簡単に説明します。あんまり詳しくないので厳密性にかけるかもしれませんが今回は許してください><
よく音楽の三要素はメロディ、ハーモニー、リズムなんて言いますけど、コードはこのハーモニーに関係する要素です。
図2に簡単な楽譜を載せますが、下段の音の塊がコードにあたります。メロディに対して伴奏みたいなもの、と思ってもらって大丈夫です。またコードはいくつかに種類分けされ、音の塊のまま扱うのも不便なので上段の記号(Dm, G7, C)のように表したりします。
で、このコードなんですがメロディとの間に強い関係を持っています。コードが決まればメロディが決まる、メロディが決まればコードが決まる、と言った具合にコインの表裏のような関係を持っています。この関係、またはルールをコード理論なんて言ったりします。
circle of 5th
これについては内容を理解する必要はなくて、こう言うものがあるんだぁ、くらいの認識で大丈夫です。
曲にはキーがあります。カラオケでキーを上げる、下げるなんてしますよね。
キーが変わると楽譜の上でどう言うことが起こるかと言うと、 # や b のつく数がかわったりします。それを綺麗にまとめたもを circle of 5th と呼びます(図3)。一番上の C を基準に、時計に周りに進むと # の数が増え、反時計周りに進むと b の数が増えていることがわかると思います。
概要
それでは内容に入って行きましょう。今回の論文をまとめると以下のようになります。
既存の音楽生成手法でコードを考慮するものはいくつかあったが、それらはコード理論をルールとしてモデルに明示的に組み込んでいた。一方本手法ではデータからコードの関係を学習して音楽生成を行う。学習で得られたコードの分散表現が circle of 5th と近い関係になっていることから、本手法のモデルはデータのみからコード理論を学習することができ、それにより不協和音の少ない曲を生成することが出来る。
ということで、言いたいことは「コード理論を明示的に組み込まずともデータだけからコード理論を学習させて音楽生成したよ」、だと思います。結果に示すのですが、学習で得られたコードの分散表現がきっちり circle of 5th と同じ並びになっているのはとても興味深いです。
手法
扱うデータ表現:pianoroll
本手法では曲を図4の行列Xのような形式(pianoroll)で表現します。
縦の次元がそれぞれのメロディーノートの id を表し、横の次元が演奏されるタイムステップを表します。
音楽(音声)生成には pianoroll のような記号ベースなものと WaveNet などに見られるように波形ベースなものがあります。記号ベースなものを使った場合は計算量が少ないというメリットがあります。最高。学習に時間がかかるものはやりたくねぇ。
図4. 楽譜と pianoroll の関係モデル
本手法のモデルは chord LSTM と polyphonic LSTM と呼ばれる二つのモデルから構成されています。
手順としてはまず chord LSTM でコードの分散表現を学習します。chord LSTM は与えられたコードの列から次に演奏されるべきコードを予測するように学習します。polyphonic LSTM は現在演奏されているメロディーと chord LSTM で作成されるコード列を元に次に演奏されるべきメロディーを予測します。
これらを用いてコードとメロディーを生成し、それらをまた入力にすることで次々にコードとメロディーと生成し、曲を構成していきます。概観を図5に貼っておきます。
chord LSTM
このモデルの役割は(1)コードの分散表現の学習と(2)現在与えられているコードから次に現れるコードの予測することの二つです。
モデルは自然言語処理に使われているものをベースとし、Embedding、LSTM、全結合層ととてもシンプルな構造をしています。コードは前提知識で述べたように Dm, G7, C と言った記号で表されるので、それにidをふってあげて chord LSTM で分散表現に変換します。
polyphonic LSTM
このモデルの役割は、現在のメロディーノートとコード、そして次の時刻で使用されるコードを入力として受け取り、次の時刻で演奏されるメロディーノートを予測することです。
こちらに関してもモデルはシンプルな LSTM ですが入力ベクトルが少し複雑です。
図6が時刻 t における LSTM への入力です。以下の要素たちを全部繋げたような値となっています。
- Pianoroll:時刻 t における 128 要素をもつベクトル
- chord: 時刻 t におけるコードの分散表現
- next chord: 時刻 t+1 におけるコードの分散表現
- counter: このモデルでは一小節を 8 つに分割しており、時刻 t がそのうちの何番目にあたるか
結果
生成結果
下記のリンクで Jambot により生成された音楽を聞くことができます。良さげ。
Jambot で生成された曲
コードの分散表現
chord LSTM で学習されたコードを PCA を使ってプロットしたものが図7になります。お前本当かよ?と思うくらい circle of 5th に近い関係が学習されていますね。一応 circle of 5th はキーの関係で、この分散表現はコードなので厳密には違うのかもしれませんが驚きです。
図7. 左:chord LSTM によって獲得された各コードの分散表現
感想
発想的には特に変わったこともないのですが、コードの分散表現がきっちり circle of 5th になってるのはちょっと驚きです。コードの分散表現は自分のおもちゃモデルでも使っていたので後で中身確認して見ようかな。
参考文献
[1] Brunner, Gino, et al. "JamBot: Music theory aware chord based generation of polyphonic music with LSTMs." 2017 IEEE 29th International Conference on Tools with Artificial Intelligence (ICTAI). IEEE, 2017.
[2] wikipedia: 五度圏 https://ja.wikipedia.org/wiki/%E4%BA%94%E5%BA%A6%E5%9C%8F