2016年11月16日水曜日

人工知能で作曲してみた


というわけで聴いてください。





Google社の人工知能ライブラリ TensorFlow、それを音楽に使おうというプロジェクトの magneta が発表されていたので試してみました。

手順は以下の通りです。
  1. 学習データの準備
  2. 特徴量抽出
  3. メロディ生成 
(あらかじめ、python,tensorflow,magenta,bazelのインストールが必要です。、
OSX El capitanの環境で行いました。)

[学習データの準備]


まず学習用のMIDIファイルを用意します。(MIDIとは、メロディなどを記録したデータファイルです)

MIDIはこのmidiworld.comなどから色々ダウンロード可能ですが、実際に「メロディだけ」のMIDIファイルってあまりないです。 

ということで、ここはこまめに手動で編集しました。 

MIDIファイルを音楽編集ソフトで開き、ドラムやベースなどのメロディ楽器以外を削除、さらに繰り返しのある楽曲は、ワンコーラスのみに区切って、 トリルやフェイクなどの、細かい部分は削って、正規化(という言い方がいいのかどうか?)しました。 

使用したデータはOasisの楽曲20曲ほどです。
選んだ理由は、メロディやコード進行が素直なのとデータ量が豊富なこと、ブリットポップへの愛着を込めて。 


まずは、作り上げるデータファイルの名前、と参考にするMIDIデータを入れるディレクトリを設定し、 

SEQUENCES_TFRECORD=/tmp/notesequences.tfrecord
MIDI_DIRECTORY=midi

以下のようにデータファイルを作ります。

bazel build //magenta/scripts:convert_midi_dir_to_note_sequences
./bazel-bin/magenta/scripts/convert_midi_dir_to_note_sequences \
--midi_dir=$MIDI_DIRECTORY \
--output_file=$SEQUENCES_TFRECORD \
--recursive




こんな感じの表記が出れば成功です。 

INFO: Elapsed time: 0.444s, Critical Path: 0.00s 
INFO:tensorflow:Converting MIDI files in 'midi/'.
INFO:tensorflow:Converted 20 MIDI files in 'midi/'.
INFO:tensorflow:Could not parse 0 MIDI files.
INFO:tensorflow:Wrote 20 NoteSequence protos to '/tmp/notesequences.tfrecord'



これで、/tmp/notesequences.tfrecord


というdatasetが作成されます。


[特徴量抽出] 


「特徴量抽出」とは本来機械によって把握しずらい情報を 分類しやすくするために、「特徴ベクトル」に分ける作業のことを言います。 

この後の行程の特徴量抽出と、メロディ生成には

  • basic_rnnn
  • lookback_rnn
  • attention_rnn

の三種類の方法が、提案されているのですが、 ここでは一番基本のbasic runnを使うことにします。 

いくつかの環境変数を決めて、以下を実行。

SEQUENCES_TFRECORD=/tmp/notesequences.tfrecord
DATASET_DIR=/tmp/basic_rnn/sequence_examples
TRAIN_DATA=$DATASET_DIR/training_melodies.tfrecord
EVAL_DATA=$DATASET_DIR/eval_melodies.tfrecord
EVAL_RATIO=0.10


bazel run //magenta/models/basic_rnn:basic_rnn_create_dataset -- \
--input=$SEQUENCES_TFRECORD \
--output_dir=$DATASET_DIR \
--eval_ratio=$EVAL_RATIO

bazel build //magenta/models/basic_rnn:basic_rnn_train


./bazel-bin/magenta/models/basic_rnn/basic_rnn_train \
--run_dir=/tmp/basic_rnn/logdir/run1 \
--sequence_example_file=$TRAIN_DATA \
--hparams='{"rnn_layer_sizes":[50]}' \
--num_training_steps=20000


実際、この学習にはとても時間がかかります。途中途中で、/tmp/basic_runn/logdirに記録されていくので、そのデータを使っても大丈夫です。

[Midi作成] 


さて、これでメロディ作成の準備が整いました。実際のメロディ作成の前に、最初の音を提示してやる必要があります。

どうやら、このmagentaは、最初の音を与えないと、どこからスタートしたらいいか自分では決められないようです。

この場合、primer.midiとシンプルな1小節のメロディを自分で作り、データとして与えてやることにしました。

そして、そのファイルを、以下において、

PRIMER_PATH=/Users/myname/magenta/primer/primer.midi


メロディ作成!!

bazel run //magenta/models/basic_rnn:basic_rnn_generate -- \
--run_dir=/tmp/basic_rnn/logdir/run1 \
--hparams='{"rnn_layer_sizes":[50]}' \
--output_dir=/Users/myname/magenta/resultMidi \
--num_outputs=10 \
--num_steps=128 \
--primer_midi=$PRIMER_PATH


この例だと、128ステップ(16ビートで8小節分のメロディ)10パターンを作成します。 


で、実際できた音源が冒頭にもあげましたが、こんな感じです。 
(TensorFlowの作ったメロディに伴奏をつけています) 




どうでしょう、ちょっと音楽的に感じられるでしょうか? 


通常音符をランダムに並べただけだと、メロディっぽくは聞こえません。 


その中に「調性」を感じられると途端メロディっぽくなってきます。 


Oasisの楽曲が学習データですので、途中これ、絶対Roll with it の影響だろ、と言いたくなるメロディとかが入って、 


じわじわくるかんじで、 絶妙に面白いんだけど、はたして、伝わるでしょうか。

[気づいた点。とまとめ。]


良い点

  • 調性が感じられる 
  • 跳躍が自然 

ダメな点

  • フレーズをまとまりで捉えることができてない
  • コード進行の概念がないため、起承転結が発生しない 
  • データ用意が大変 

正直、現時点では、人間の能力には、およびもつかないというのが実際の感想。
もちろん数年後はわかりませんけれど。

いや、3年後だって、はたまた来年だって。。。


それに、人間がやる場合は早いフレーズと遅いフレーズを交互に入れるとか、シンコペーションを規則的にするとか、意識するしないに関わらずそういった工夫をかなりしているってことにも改めて気付かされます。

しかし何と言ってもパワフルなのが、いのが10でも20でも、100でも1000でも一瞬で作れちゃうっていうこと、気に入らないものや失敗作はどんどん捨てていけばいいわけで、精度が上がって、100%は無理でも、10に一つは使い物になるメロディができるようになれば、有用な作曲ツールとして、存在感を現してきそうです。





0 件のコメント:

コメントを投稿