音楽自動生成Magentaを使ってみて

非力なintel製Macbook Pro(13inch 2017 メモリ8GB ストレージ256GB)を使ってMagentaをローカル環境で動かしています。

独自の学習済みデータを作成して、音楽を制作してみて気付いた点について、まとめてみたいと思います。

目次

参考書

まず、Magentaをどう使うかで途方に暮れると思います。「Magentaで開発 AI作曲」が大変参考になりますので、まずはこれを一読されることをおすすめします。

インストール方法から、コマンドの使い方まで、大変親切に書かれています。

ただし、すべてが本の通り、というわけでもありませんので、MagentaのGithubにも目を通された方が良いと思います。コマンドもコピペできますし、学習済みデータもダウンロード可能です。

独自学習済みデータの作成について

Magentaには、いくつかのモデルがありますが、わたしはクラシック曲のオルゴールを制作しているので、主に以下のモデルを使っています。

  • Polyphony_RNN(和音を生成。学習済みデータでは、バッハ風の合唱曲を生成できます。)
  • Performance_RNN(音楽性豊かなかなり高度なピアノ曲が生成できます。)

Pianoroll_RNNというモデルもありますが、これは、かなり現代風(前衛的?)な曲に仕上がるので、ちょっと使いづらいし、イメージには合わないので使っていません。

絵の自動生成Stable Diffusionに比べると、音楽の自動生成Magentaの話題はほとんど上がらないように感じます。ネットで検索しても、古い情報が多く、情報も少ないように感じます。

情報が少ない理由としては、

学習させるためには、膨大なmidiデータが必要になるということがあると思います。わたしも自分でデータを収集しましたが、かなり骨が折れました。著作権の問題がありますが、わたしの場合は、もともとがパブリックドメインのクラシック曲を対象としているので、著作権の問題自体はあまり問題になりません。(まったく問題にならないわけではありませんが)

AI音楽生成のネットサービスがありますが、ほんとが有料です。無料となると、いくつかありますが機能的に限定されてしまいます。満足のいく結果を得て、自由に使うためには、自分で環境を構築する必要があります。そうなると、Pythonの知識が必要になります。しかし、その環境構築が簡単ではありません。

さらに、midiデータを扱うため、LogicXなどのDAWソフトも必要になってきます。プログラミングの知識と音楽の知識の両方が必要になってきますので、非常にハードルが高くなってしまうのだと思います。

絵の場合、ボタン一つで画像が出てきて、そのまま使うことも可能です。しかし、Magentaの場合は、生成されるのはmidiデータなので、DAWソフトで仕上げる必要があります。また、生成された曲が綺麗に終わっているとは限らないので、若干の修正が必要になります。これもコードなどの音楽の知識が必要になりますので、ハードルが高くなる一因ではないかと思います。

今回、クラシック曲のmidiを1400曲ほどMagenta用に作成しました(だいたい150時間分。全部聞くのに、寝ないで丸1週間弱はかかると思います)。

MagentaのGithubには参考となる元データがあるのですが、それを見ると、バッハの合唱曲は400曲ほどしか学習させていないようです。バッハの合唱曲は約2500曲(バッハ曲全体だと約4000曲)あるので、思ったより少なく感じます。しかし、400曲であの精度が出るのであれば、もう少し増やせばかなり良い結果が出せそうです。

ちなみに、Performance_RNNでは、ヤマハのmidiコンテストで集めたデータが使われており、調べてみると、およそ2400曲ほどありました。(重複曲もかなりあります)

絵の自動生成Stable Diffusionなどでは、数百万もの絵を学習させていますが、それに比べると恐ろしいほど少ないです。世の中の曲がどのくらいあるのかわかりませんが、絵に比べれば圧倒的に少ないと思います。

絵は簡単に画像データとして収集できますが、音楽データはそうはいきません。楽譜をそのまま読ませることはできず、音符をデータに変換しなければなりません。やってみるとわかりますが、これは大変な労力を要します。絵と音楽では、ここの差が大きいと思います。

また、著作権の問題があります。絵の自動生成でも著作権は問題になりますが、音楽に比べると緩いと思います。著作権の問題を回避するためには、パブリックドメインに限られてしまう、という制約もあると思います。

Polyphony_RNN

Magenta開発チームから提供されている学習済みデータから、バッハ風の和音曲が生成されます。実際に生成してみると、結構使えます。オルゴールの雰囲気にもぴったりなので、もう少しブラッシュアップしたいと思い、独自の学習済みデータを生成することにしました。

元データとなる、midi音楽データを1400曲を同じフォルダに放り込み、Magentaで読み込むためのデータ(NoteSequence。TensorFlowのレコードファイル)に変換します。

python magenta/scripts/convert_dir_to_note_sequences.py \
--input_dir=/Users/ユーザー名/フォルダ名 \
--output_file=/Users/ユーザー名/フォルダ名/notesequences.tfrecord  \
--recursive

変換したら、学習データと評価データを作成します。わたしの場合、学習データを9割、評価データを1割に分けました。

python magenta/models/polyphony_rnn/polyphony_rnn_create_dataset.py \
--input=/Users/ユーザー名/フォルダ名/notesequences.tfrecord  \
--output_dir=/Users/ユーザー名/フォルダ名 \
--eval_ratio=0.1

この学習データ・評価データの作成時間が結構かかります。Polyphony_RNNの場合、1時間ほどかかりました。データ量は学習データが10.5GB、評価データが1.1GB。

python magenta/models/polyphony_rnn/polyphony_rnn_train.py \
--run_dir=/Users/ユーザー名/フォルダ名 \
--sequence_example_file=/Users/ユーザー名/フォルダ名/training_poly_tracks.tfrecord \
--hparams="batch_size=128,rnn_layer_sizes=[128,128]" \
--num_training_steps=20000

学習データができれば、あとは学習させるだけです。これが一番時間がかかります。バッチサイズ128、レイヤーサイズ128×128、ステップ数20000回で、丸9日かかりました。時々ファンが回りながら、9日間フル稼働でした。intel製MacではCPUしか使えないため、時間がかかりますが、できないことはありません。時間はかかるのですが、収束は早く、損失関数はステップ数10000あたりからほぼ横ばいになります。

本当は、M1 Proの強力なGPUを使いたいのですが、Magentaを動かすことができません。NVIDIAを使うべき、というのはわかっていますが、あの大きな躯体ははっきり言って邪魔です。しかも、GPUのためだけに結構な投資が必要です。電気代もかかります。代わりに無料版GPUを使うという方法もあり、Google Colabが使えそうですが、残念ながら制限時間内には終わらないと思いますので(12時間でリセットされてしまう。CPUで9日かかるものを強力なGPUを使うとはいえ、12時間以内にはさすがに終わらないでしょう)、とりあえず費用をかけずに試してみるという点では、今の方法が最善ではないかと思います。学習させている間、他のPCで作業をしていればよいだけなので。(今も学習中です。)

Performance_RNN

NoteSequenceファイルはPolyphony_RNNの場合と同じです。

このファイルから、学習データと評価データを作成します。同じように、データの9割を学習データ、1割を評価データに当てます。

python magenta/models/performance_rnn/performance_rnn_create_dataset.py \
--config=multiconditioned_performance_with_dynamics \
--input=/Users/ユーザー名/フォルダ名/notesequences.tfrecord  \
--output_dir=/Volumes/HDDD/フォルダ名/original_performance_data \
--eval_ratio=0.10

Polyphony_RNNとは異なり、この学習データ・評価データの作成時間、データ量がともにとんでもないことになりました。

当初、3500曲ほどのmidiデータで作成させようとしましたが、いつまで経っても終わりません。Polyphonyの要領でいけば半日で終わるかな、と予想していたのですが、想定を超えてしまい、焦りました。2日目に突入したところで100GBを超え、MacBook Proの内蔵SSDの容量がみるみるなくなっていきます(256GBしかありません)。このままいくと容量オーバーになりそうだったので、いったん停止し、外部HDDに保存するよう設定を変更してからもう一度試してみました。すると、今度はSSDではないので、転送速度が遅く、3日後に200GBを超えてもまだ終わる気配がないため、どこまでいくのか怖くなったので、途中で停止しました。

学習データ量がどのくらいになるのかの目安が知りたかったので、midiファイルを1000曲に減らして再度試してみました。すると、1日半かかって、学習データが123GB、評価データが480MBに収まり、とりあえず安堵。これならMacBook Proの内蔵SSDで作業できるので、高速で学習させることができます。

Performance_RNNは学習データ自体の生成に時間がかかり、データ量も非常に大きくなるので、注意が必要だということを学びました。

学習データができれば、あとは学習させるだけです。

python magenta/models/performance_rnn/performance_rnn_train.py \
--config=multiconditioned_performance_with_dynamics \
--run_dir=/Users/ユーザー名/フォルダ名 \
--sequence_example_file=/Users/ユーザー名/フォルダ名/training_performances.tfrecord \
--hparams="batch_size=128,rnn_layer_sizes=[128,128]" \
--num_training_steps=20000

Polyphony_RNNからステップ数は10000程度で収束しそうなので、10000くらいでよいかなと思ったのですが、10000では足りないです。10000でも損失関数は思ったより小さくなりません。Polyphony_RNNでは、損失関数が1.1を割り込むくらいまでいくのですが、Performance_RNNでは1.5前後をうろうろします。しかも結構ブレが大きく、たまに2.0を超えることもあるので、10000程度では学習不足と感じます。

Polyphony_RNNとは違って、学習時間はとても短いです。これは意外でした。ステップ数10000だと1日で終わりました。ステップ数20000でも2日ほどで終わります。

モデルによって、データの作成、学習に大きな違いがあるということが分かりました。

なお、Performance_RNNでは、学習データが巨大になるとわかりましたので、外付けSSDを購入しました。

目次