書いたこと
ニューラルネットワークを使ってこんなのを作るのに必要な基礎知識
はじめに
この記事は、AWS builders.flashのブログ記事、「Deep Learningで音楽を作成するにはどうしたらいいの?」の補足版にあたります。記事の性質上、ニューラルネットワークの細かい動作などには触れなかったため、興味がある方向けに編集でカットした部分を含めて一部改訂したものをこのQiita記事に載せています。ライトに記事をサクッと読みたい方や、生成される音楽自体に興味があるかたは上記のbuilders.flashの記事もお楽しみください。
概要
- ニューラルネットワークを使った音楽(楽譜)の生成手法の一例を解説
- 音楽を生成する際の入力(モチーフ)と出力の関係
- 音楽生成におけるニューラルネットワークの特徴
- 音楽データのencoding
- ニューラルネットワークを用いた音楽生成の実例
- MiniBach
- DeepBach
ブログを書く上で参考にした資料・Webサイト
ニューラルネットワークによる音楽生成に関して下記の素晴らしい総論があります。ほぼ毎年改定されており、技術革新の目覚ましい深層学習のトレンドが音楽生成にも貪欲に取り入れられる様を目の当たりにできます。ただし基本的な部分は不変で、今回のブログの記事もこの総論の基本的な内容をベースにしています。
[Deep Learning Techniques for Music Generation — A Survey] (https://arxiv.org/abs/1709.01620)
また、上記の総論を日本語でまとめたウェブサイトもあり、こちらも非常にわかりやすいです。データの記号化や事例の詳細やリンクが豊富です。
[Deep Learninhgを用いた音楽生成手法のまとめ [サーベイ]] (https://naotokui.medium.com/deep-learning%E3%82%92%E7%94%A8%E3%81%84%E3%81%9F%E9%9F%B3%E6%A5%BD%E7%94%9F%E6%88%90%E6%89%8B%E6%B3%95%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81-%E3%82%B5%E3%83%BC%E3%83%99%E3%82%A4-1298d29f8101)
1. 音楽生成をする際の入力(モチーフ)と出力
“音楽”を生成すると一口に言っても、具体的に何を作り出すかで適切なデータの表現方法やニューラルネットワークの構造が変わってきます。「何から何をつくるか?」つまり入力(モチーフ)と出力の対応関係を考えながら説明していきます。
1.1. メロディ→メロディ
まず、上図の点線枠のように一つのメロディがモチーフとして与えられたとします。例えば頭の中にメロディが突然ひらめいたと考えてください。この1小節の美しいメロディをなんとか曲として完成させるためにメロディの続き、つまり上図の1のように楽譜でいうと水平方向に音楽を生成します。これを“メロディ→メロディ”と表現することにします。
1.2. メロディ→ハーモニー(伴奏)
次に、思いついたメロディに対して別のパートを作りだすということもありそうです。メロディに対して伴奏をつけたり、もしくはメロディに対して対になるようなメロディ(典型的にはハモりのパートですね)をつけたりすることが考えられますね。これらを総称してメロディ→ハーモニーとグループ分けしておきます。
1.3. ハーモニー(伴奏)→メロディ
上述のメロディ→ハーモニーの反対でハーモニー→メロディの音楽生成もあります。こちらは、伴奏がすでに楽譜として与えられているときにメロディを作るというケースですね。
1.4.コード(和音)→メロディ
また、伴奏を楽譜レベルできっちり決める前に、メロディを作りたいというケースもあるかもしれません。下図に示したアルファベットと数字で表された記号は、コードネームといわる和音記号で、ギターなどを弾いたことがある方は目にしたことがあるかもしれません。例えばFというコードは{ファ、ラ、ド}を構成音とする和音です。コードを指定することで曲の雰囲気をひとまず決めておいて、伴奏より先にメロディを付けるという方式ですね。この場合Fというコードを{ファ、ラ、ド}という3音と表現しても良いですし、“F”という文字列として表現しても良いです(他にも表現方法があるかもしれません)。扱いたい情報をどのような表現方法にするかで、学習した機械学習モデルの性能は変わってきます。例えば、明るい響きのするコード(メジャーコード)か、暗い響きのするコードか(マイナーコード)に着目したい(と開発者側が思っている)場合は、それを入力データに明示的に表した方が期待する動作をするでしょう。これはデータサイエンスにおける特徴量抽出と全く同じですね。
1.5. コード&メロディ→コード
これは既存の楽曲(メロディ&コード)に対して新しいコード進行をつける作業に相当します。いわゆるリハーモナイゼーションですね。
1.6. 無→メロディ and/or 伴奏
これまでのケースは、音楽を生成するときにメロディやハーモニーなど、特定のモチーフ(入力データ)を必要としてきました。しかし、場合によってはモチーフを一切提示することなく「自律的に」音楽を生成することが求められることもあります。プロデューサーに「明日までにいい感じの5曲頼むよ」と言われたシンガーソングライターのケースですね。コンピュータが音楽を自動生成する、という響きには多分にこの自律性が反映されている気もします。論文では、このように入力データ(モチーフ)の提示なしに音楽を生成することを“ex nihilo” (ラテン語で「無から」を意味する)と表現しています。
2. 音楽の記号化と表現方法
3. 音楽生成におけるニューラルネットワークの特徴
自律的な音楽生成とニューラルネットワークの関係
最初に言ってしまうと身も蓋もないのですが、ニューラルネットワークは、1.6で示したような自律性の高い音楽生成(つまり音楽的なモチーフの提示なしに音楽を生成すること)には向いていません。なぜなら、ニューラルネットワークは(その複雑さはどうあれ)入力データを受け取って出力データを吐き出す関数なので、何かしらのデータを必ず入力として必要とします。
すると、「じゃあ一般的なニューラルネットワークではモチーフの提示なしには音楽を作れないんじゃ?」と思われたかもしれません。そんなことはなく、AutoencoderやVAEなど、下記に示したように機械学習で使われる技術を音楽生成に巧妙に取り込んで、自律的に音楽を生成する研究・開発が行われてきました。このブログでは基本的なモデルであるMLP、LSTMを使った音楽生成の事例について紹介します。記事を読んでその他の手法も気になった方はぜひ、上であげた参考論文・ウェブサイトをみてください。
- Multi Layer Perceptron
- Convolutional Neural Network (CNN)
- Recurrent Network (例 LSTM)
- Autoencoder (AE)
- Restricted Boltzmann Machine (RBM)
- Variational Autoencoder (VAE)
- Generative Adversarial Network (GAN)
- Reinforcement Learning
音楽生成と再現性
音楽生成における再現性の問題とニューラルネットワークの関係についても触れておきます。機械学習モデルの運用において再現性の担保は重要な問題です。幸い、ニューラルネットワークは決定的(deterministic)な機械学習モデルであるため同じ入力から常に同じ出力を得ることができます。
しかし、音楽生成においては再現性が常に重要視されるかというとそうではありません。常に同じタイミングで同じフレーズが演奏されると聞き手は飽きてしますよね。リズム微妙な揺れがその人の個性やグルーブとなったり、セッションでは(ミスを含む)偶発的な演奏から盛り上がったりします。ニューラルネットワークを用いてランダム性を交えた音楽を生成するためには、入力データに小さなノイズを付加したり、場合によっては完全な乱数を入力データとして使うこともあります。
前置きが長くなりましたが、いよいよニューラルネットワークにデータを流し込む方法について見ていきます。
4.音楽データの入力のためのdata encoding
音楽データをニューラルネットワークで扱うためのデータのエンコーディング方法について説明します。
総論 (https://arxiv.org/abs/1709.01620)のP.37より引用 一部追記
単一の値(スカラー)としてエンコーディング
まず、標準的な88鍵のピアノで、真ん中より少し右の位置にある鍵盤のラの音(“A4”と表記されます)をニューラルネットワークで扱う方法を考えます。このラは周波数440Hzに調律されている(ことが多い)ので、“440.0”という小数値で表すことができます。単純に音程を周波数として表すということですね。
一方で、音程を厳密に周波数で表さなければいけないケースはあまりないと思います。音程に関する離散的な情報だけを用いたい場合は、例えば“69”という数値を使って表すことができます。この69という数字がどこから来たかと言いますと、MIDIという規格があって(細かい話は省略します)、その中で音程(すなわちピアノの鍵盤)それぞれに“[ノートナンバー] (https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%BC%E3%83%88%E3%83%8A%E3%83%B3%E3%83%90%E3%83%BC)”という値を割り振っています。A4(440Hz)の音程はノートナンバー69に対応しています。それぞれの音程を離散的なクラスとみなして、クラス番号を直接ニューラルネットワークに渡してあげようという話です。
One-hotベクトルによるエンコーディング
データサイエンスでは離散的なクラスをそのクラス番号を用いる他に、One-hot encodingとい言われるやり方で表すことも多いです。音楽生成におけるニューラルネットワークでも、各音程をOne-hot encodingを用いて表すやり方はよく見られます。音程(クラス)の数を要素とするOne-hotベクトルを用意して実際に発音する音程を1、他を0とする表現方法です。
複数の発音を表現するエンコーディング
スカラー値やOne-hot encodingでは一つの発音しか表すことができませんでした。複数の発音を表すには、複数のクラスのフラグ(“1”の値)を許すMany-hot encodingや、One-hot encodingを複数用いるMulti-one-hot encodingを用います。Many-hot encodingとMulti-one-hot encodingの使い分けですが、実際の発音原理と対応させるのがシンプルで良いと思います。例えばピアノのように一つの楽器で複数の発音が可能であるのならばMany-hot encoding、トランペットとサキソフォンのように単音の楽器が複数ある場合はMulti-one-hot encodingが自然でしょう。もちろん、場合によってはMany-hot encodingを複数並べたMulti-many-hot encodingもあります。
ここまで、ニューラルネットワークのノードに音楽情報を入力させるためのエンコーディング手法について説明しました。注意してほしい点として、「ここで述べたエンコーディング手法では、ある瞬間における発音に関する音程の情報だけが含まれており、音の長さや順序、すなわち時系列的な情報は含まれていない」ことに注意してください。さらには、音の強さや音色のような情報も含まれていません。
ここで述べた手法の他にも様々なエンコーディング手法があります。例えば、後述する畳み込みニューラルネットワーク(CNN)を用いる場合は、[ピアノロール] (https://ja.wikipedia.org/wiki/%E3%83%94%E3%82%A2%E3%83%8E%E3%83%AD%E3%83%BC%E3%83%AB)と呼ばれるデータ形式を用いることが多いです。画像の横軸が時間、縦軸が音程、各ピクセルが実際の発音に相当します。画像と似ているのでCNNとの相性の良さがイメージできると思います。
5.ニューラルネットワークを用いた音楽生成の実例
さぁ、それでは実際にニューラルネットワークを用いた音楽生成を見て(聴いて)いきましょう!
5-1. MiniBach (G. Hadjeres et al.)
まず最初に示すのは最も基本的なニューラルネットワーク構造、隠れ層を1層含む3層型のパーセプトロンを用いたMiniBachです。Bachというのは18世紀のドイとツで活躍したあのバッハ(ヨハン・セバスチャン・バッハ)のことです。MiniBachはニューラルネットワークの学習で用いるmini batch(ミニバッチ)にかけているんでしょうね。
用いたデータセット
MiniBachではJSB Chorales datasetと呼ばれるデータセットを用いています。コラール(choral)とはもともとドイツのルター派協会で用いられた賛美歌のことで、グレゴリオ聖歌など各種の聖歌や教会歌の総称の意味でも使われます。JSB Chorales Datasetはバッハ(ヨハン・セバスチャン・バッハ)が作曲した382曲の4声のコラールをデータ化したものになります(データセットのフォーマットなどの詳細はここでは詳しく触れません)。
MiniBachのネットワーク構造と入出力
総論 (https://arxiv.org/abs/1709.01620)のP.93より引用
前述したとおり、MiniBachでは入力層→隠れ層→出力層の3層のネットワーク構造を持ちます。入力データは4声のパートのうちソプラノ(最も高いパート)のデータを入力データとして、残りの3パート(バス、テノール、アルト)を出力する構造となってます。JSB Chorales Datasetを教師データとして、ソプラノパートから他のパートを予測するタスクとみなすことができます。既存のデータセットの曲を再現するように学習させたあとに、新しいメロディのソプラノパートを入力して残りのパートを生成し、全体として4声の楽曲を生成することができます。
それでは入力層の各ノードにソプラノパートのデータをどのように入力するかを見ていきます。
総論 (https://arxiv.org/abs/1709.01620)のP.94より引用
一番左のノードが入力層でここにソプラノパートのデータが入ります。楽譜が縦に表記されているのに注意してください。音符の最小分解能(この場合16音符)に対して21半音の音域を表すOne-hot encodingの21個のノードが対応します。次のグリッド(16音符)の音符に対応する21個のノードは先ほどのノードの下(隣)に配置します。非常にシンプルというか力技な構造です。入力層のノードの数は21音域×16部音符×4小節=1344個になります。(後に触れるように、この方式は一見、音符を時系列に並べて入力しているように見えますが、ニューラルネットワークでは並列しているノードの順序に意味はないため、楽譜の前後関係を捉えられていません)
入力層に入力されたデータ200個ノードの隠れ層を経て、出力層に渡ります。出力層は3声のパートに対して(21+21+28)音域×16小節×4小節=4480個のノードになります。出力層のノード結果をデコードして楽曲データ(簡単に言えば譜面)に変換します。
MiniBachでの音楽生成例
それでは生成された楽曲を見てみましょう。ソプラノのフレーズを入力データと、出力された3声のデータを 合わせて示します。
総論 (https://arxiv.org/abs/1709.01620)のP.95より引用
再生してみましょう。
どうでしょうか。感想はおそらく人それぞれだと思いますが個人的にはそれっぽい曲ができているように聞こえます。不自然な音の跳躍や不協和音がなく、曲として調性がとれているように聴こえます。一方で単調な曲にも聞こえますね。以下、私の主観を述べます(素人のウンチクが必要なければ飛ばしてください)
入力データであるソプラノパートではラの音が出てきませんが、出力の3声パートではラの音が出てきます。つまり入力データに使われている音のみを単純に使って出力しているわけではなさそうです。加えて、入力データの音列とバッティングするような音も使っていません。入力メロディから全体としての調性を掴んで(複数の解釈がありますがその中の一つを選択して)いるように思えます。もちろんこれは著者の後付けの解釈であって、MiniBachのモデルの中に明示的に調性を判断するようなルールがあるわけではありません(少なくとも人間が解釈できる形ではありません)。しかし、このような単純なネットワーク構造を用いるだけでも曲として成り立つものが生成できることは素直に驚きです。
一方で、曲としては単調で面白みがないようにも感じられます。例えば曲としての盛り上がりや展開を出すための和音の展開が感じられません。特にバッハのコラール音楽で見られるようなわかりやすい解決感、[主調] (https://ja.wikipedia.org/wiki/%E9%96%A2%E4%BF%82%E8%AA%BF)への(完全)[終止] (https://ja.wikipedia.org/wiki/%E7%B5%82%E6%AD%A2)感が感じられません。終止感というのは、超ざっくりいうと小学校の音楽の授業の最初にピアノで弾く”起立(ジャーン)・礼(ジャーン)・着席(ジャーン)”ってやったときの「決まった!!!」って感じのことです。
また、出力された各パートのメロディは全て四分音符で、フレーズとしての複雑さや展開がありません。学習に用いたデータセットであるバッハのコラールがこういった単調な曲ばかりであるということはもちろんありません。また、バッハの音楽に特徴的な、あるパートで出てきたフレーズがしばらくすると別のパートで形を変えて出てくる、つまりモチーフの展開がみられません。そういったバッハのコラールの特徴をMiniBachでは学習によって獲得できていないと考えられます。そしてそれは(著者が思うに)MiniBachのネットワーク構造に由来しています。
MiniBachの構造に起因する問題
上で述べたように、MiniBachで生成した例では楽曲の進行にともなう和声的・フレーズ的な展開が感じられません。なぜMiniBachが時間方向に対する表現力が乏しいかネットワーク構造をもう一度見てみましょう(忘れた方は、一度戻って確認してみてください)。
入力データのソプラノパートはいかにも発音(発生)の順番で入力層のノードに入力しているように見えますが、よく考えてください。ニューラルネットワークのノードの順序に意味があるでしょうか?いえ、ありません(反語)。例えば1番目のノードと3番目のノードの入力順序を入れ替えたとしても、対応する重みを全て入れ替えてしまえば全体としては全く同じ出力を作ることができます。結局のところ、楽譜通りの順番でノードに入力したとしても、MiniBachのネットワーク構造はフレーズの時間順序を全く考慮できないんですね。つまり、フレーズを逆再生したものであっても、フレーズをランダムにシャッフルしたものであっても、(学習の再現性が担保されるのであれば)どんなものでも本質的に同じモデルが学習によって生成されます。これではデータセットに含まれる和音やフレーズの展開をパターンとして獲得することは難しいでしょう。
他にも、音楽生成に対するMiniBachの問題(制限)が総説では言及されています。以下に、簡単にまとめます。
- 固定された長さの楽曲しか生成できない(それより短くても長くてもダメ)
- 同じ入力からは常に同じ出力(音楽)が生成される
- 音楽生成のプロセスを細分化できない(single atomic step)ため、人間とのインタラクティブな音楽生成が不可能
次章では、これらの課題を解決するために、再帰的なニューラルネットワークを用いた例を紹介します。
5-2. DeepBach (G. Hadjeres et al., 2017)
前述したMiniBachはシンプルすぎて、時系列の情報を扱えない、可変長の音楽性ができない、常に同じ結果しか得られない、人間の意向を組み込めない、という課題がありました。この課題に対応する新しい音楽生成モデルがMiniBachの著者より発表されています。その名もDeepBach。そう、MiniBachの改良版ですね。MiniBachと同様にバッハのコラールデータセットを用いて、コラール形式の音楽を生成するシステムです。このシステムでは、LSTMモデルを使って可変長を含む時系列データの生成を可能にしました。また、あとで紹介するような擬似(pseudo)ギブスサンプリングとよばれるアルゴリズムを使って、演奏にランダム性を取り入れたり、人間の意向を反映させることが可能になっています。以下、順次説明していきます。
DeepBachのネットワーク構造
総論 (https://arxiv.org/abs/1709.01620)のP.170, 171を元に一部追記
MiniBachのように一つのパートを入力として他の3つのパートを予測するのではなく、現在・未来・過去の演奏データから現在の自分のパートの発音を予測するタスクになります。上図を使ってもう少し詳細に説明します。
DeepBachでは、4声の各パートに一つのニューラルネットワークモデルが対応しています(つまり全体で4つのネットワークがある)。ネットワークは、双方向性(bi-directional)のLSTMアーキテクチャが用いられています。一つ目のLSTMは過去から現在(の1時点前)を辿るLSTMネットワーク、もう一つは未来から現在(の1時点後)までを逆向きに辿るLSTMネットワークです。加えて、現時点のみの演奏情報を入力として用いるネットワークがあり、その3つの出力をマージしたのちにさらに後段のニューラルネットワークにに通して最終的な出力を得ます。出力情報は自分のパートの現時点の音程(ノートナンバー)です。正確には扱っている音域全てのノードに対するsoftmax出力です。
図のように、Voice 1(例えばソプラノ)を例にとると、自分の現在の発音(すなわち予測したい答え)以外の周辺データを用いて現在の自分の発音を予測する、という問題設定になります。未来の発音データを使うことに違和感を覚えるかもしれません。しかし、例えば人間がジャズセッションをする場合など、楽譜やコード譜の形で曲の構成、すなわち未来的な展開を予め知っています。その際に、演奏を着地させたい時点を決めてそこから逆算しながらフレーズを開始するということを自然にやっています。ですので、逆方向に辿るLSTMネットワークも同じようなことをしていると解釈できます。
擬似ギブスサンプリング(pseudo-Gibbs sampling)
LSTMを用いることで、MiniBachの抱える問題のうち、時系列データ(音符)の関係性や可変長のデータを扱えるようになります。しかし、このままでは決定的なニューラルネットワークの性質はそのまま、つまり同じ入力から常に同じ出力を得ることになり、予想外の結果は起き得ません。また、部分的に人間が考えたフレーズを埋め込むというのも難しいです。例えば、「ここはブレイクだから止まってほしい」「ここは決めフレーズを入れたい」といった願望です。楽曲生成後に、部分的に人間の考えたフレーズに書き換えるる方法では、周りのフレーズとの関連性が考慮されません。
DeepBachでは擬似ギブスサンプリングと名付けられた手法を使うことで、これらの問題に対処しています。擬似ギブスサンプリングのアルゴリズムを図を使って説明します。
図に示した、表の中に数値が書いてあるのが生成される音楽データです。横軸は時間に対するグリッド(例えば16分音符)、中の“78”のような値は発音されるMIDIナンバーを示しています(これはあくまで説明のための表記です)。この発音情報がVoice1から4までの4つ、それに加えて拍の位置とフェルマータの有無の情報もあります。
擬似ギブスサンプリングのアルゴリズム
初期状態(図の左上)では全ての数値を乱数によって初期化します。当然生成される音楽(楽譜)はデタラメな演奏です。この初期状態からサンプリングを一音ずつ繰り返すことによって少しずつ意味のある音楽へと収束させていきます。
図左下の1回目のサンプリングでは、まずサンプリング対象のデータ(図の緑色の領域)を決定します。この場合はVoice 1の左から7番目のデータになります。そして、Voice 1に対応するネットワークを用いて、対象領域の周辺の演奏データ(図の薄い水色、青、濃い青色)から、現時点でのVoice1の発音を予測します。前述したように、ネットワークの最終出力はsoftmaxになっており、その出力値に基づいて出力される音程をサンプリングします。例えばsoftmaxの出力がC4(ド)が60%、D4(レ)が30%、E4(ミ)が10%の場合、その確率に基づいてサンプリングを行います(実際はもっと広い音域を扱います)。通常のニューラルネットワークでは、例えば猫が60%、ウサギが30%、リスが10%のような場合は最も確度の高い猫を採用しますが(すなわちargmaxをおこなう)、DeepBachの場合softmaxの出力値をもとにサンプリングすることでランダム性を取り入れていることになります。
このサンプリングを行うことで緑の領域はサンプリング前(左上)の“41”から“60”(左下の赤字)へと変化しました。1音の変化ですが、サンプリング前よりは周辺の音列を考慮した音程に修正されました。このサンプリングを10回、100回、1000回と繰り返すことでランダム性を持たせつつ、全体として前後、パート間の関係を考慮した音楽生成が可能になります。
また、人間の意向を簡単に反映できるのも大きなメリットです。例えば特定のフレーズを埋め込みたい場合は、初期化時にそのフレーズを直接入力し、以降そのフレーズの領域はサンプリングの対象から外せばその部分は意図した通りの演奏ができますし、その前後に関しては埋め込んだフレーズとの関連性を考慮しつつサンプリングすることが可能です。
擬似ギブスサンプリングの逐次生成例
このサンプリングを行ったアニメーション(GIF)を示します。反復の回数が増えるに伴い、音符が収束していく様子が確認できます。
それでは、サンプリングによって徐々に生成(収束)していく様子を音で聴いてみましょう。
DeepBachの生成例を聴いてみる
i=0 (初期状態)
まずは、サンプリング前の完全な初期値です。4小節分生成していますが、最初の3小節のみを表示しています。
譜面をみてもわかるように、16部音符で見るからにデタラメです。臨時記号(シャープやダブルフラットなど)もたくさん付いておりで調性もなにもあったもんじゃないですね。まぁ、これはこれでカッコよく聞こえます。
(ちなみにフラットやシャープの表記方法は、楽譜に起こす時の譜面エディタの影響です。DeepBachが「これはラ♯ではなくてシ♭」とか指定しているわけではありません。MIDIノートナンバーでは同じ音です)
i=10(240回のサンプリングによる修正)
なんとなく曲っぽくなってきた感があります。各パート、4小節(=64個の16分音符)に対して60回の修正を行っています。初期のカオス状態から、徐々にリズム(譜割り)や音使いが曲のようなものへと変化していっているように聞こえます。
i=298 (7152回のサンプリング)
ここまでくると一つの曲として聞こえてきます。音符もランダムな16分音符から、4分音符や8分音符を使ったフレーズへと収束しています。特に前半部分など、ここまでくると人間が作った曲と間違える人もいるのではないかと感じます。ただ、最終小節のソプラノパート(最上段)、一番最後の音(ソのシャープ)が調子っぱずれに聞こえますね。逆にいうと、最後の音が奇妙に感じるくらい他は全体としてまとまっている、とも言えます。最終小節が単調(同じ音を繰り返している)な理由はよくわかりませんが、曲の切れ目(最初と最後)であるために、(画像におけるCNNと同じく)データのパディングの影響を受けている可能性もあります。
i=1998 (47952回のサンプリング)
はい、サンプリングの最終回(2000回まで切り上げました)の生成結果です。ここまでくると立派に曲ですね。調性として破綻していない、というだけでなく曲の展開が(私には感じられます)。最初は悲しい感じで始まっていて(主調の平行調のEmのコード)、3小節目で2分音符を使ってクライマックス感を出しています。起承転結感があるように感じられます。また、音列の上行・下行がパート内で繰り返されたり、パートからパートへと引き渡されたり、モチーフの展開も感じられます。私だけの主観だと自信がないのでTwitter上で感想を聞いてみました。
- 出だしのハーモニックマイナーっぽいフレーズがクラシカルな雰囲気を出している
- 最後(4小節目の3拍目)不協和音が残念(4拍目への解決感もない)
といったご意見をいただきました。また、バッハっぽい、逆にバッハっぽくない、という意見もシンプルな意見もいただきました(ご意見いただいた方、ありがとうございました。)
〇〇っぽい(いまの場合、バッハっぽい)を評価するのはなかなか難しいですね。ちなみにDeepBachでは、音楽版チューリングテストとも呼ぶべきテストをおこなっています。曲を聴かせて本物のバッハの曲かそれとも機械学習モデル(DeepBach)が生成した曲かを当てるテストを行っています。それによると、音楽の習熟度の異なる3グループに対してDeepBachを(それとは知らせず)聴かせたところグループの差異はありますがどのグループも概ね50%がバッハの曲、残りの50%がDeepBachの生成曲と答えました。(ちなみに本物のバッハの曲は約80%がバッハの曲と答えています)
[DeepBach] (https://arxiv.org/abs/1612.01010) (G.Hadjeres, et al, 2017)より引用
おわりに
ニューラルネットワークを用いた音楽生成手法について、基本的な構造(多層パーセプトロン、LSTM)を用いた事例についてお話ししました。音楽データをどうやってニューラルネットワークに入力するか、モデルからどのように最終的な出力を得るか、なるべく具体的に説明しました。DeepBachについては著者が実装を[github] (https://github.com/Ghadjeres/DeepBach)で公開しているので、興味のあるかたは実際に音楽を生成させたり、ご自身のデータセットで学習させてDeep〇〇(←あなたのお名前)を作ってみるのも良いかもしれません。(このブログの擬似ギブスサンプリングによる生成例も著者実装をもとに私がコードを一部改変して生成しました)
生成モデルの花形、GANやVAEなどを用いた音楽生成については今回は分量の関係で全く触れませんでしたが、機会があればまた取り上げてみたいと思います。このブログを読まれた皆様もぜひ、論文を読んで実装にチャレンジしてみてください。