LoginSignup
40
42

More than 5 years have passed since last update.

TensorFlow製音楽生成プロジェクト「Magenta」でMIDIファイルを学習させ、曲を生成する。

Posted at

はじめに

この記事では、Magentaの開発環境を準備した上で、手元のMIDIファイルを学習し、曲を作成するということを行います。
magentaのBasic RNNのREADMEの通りですので、そちらを読んでいただいてもよろしいかと思います。

用語等、不明な点もあるため、ご了承いただければと思います。
開発環境の準備はこちらの記事もご参考ください。

TensorFlow製音楽生成プロジェクト「Magenta」を開発環境の設定から曲生成までやってみる。

データセットを作る

手持ちにMIDIファイルを学習する前に、まずはTensorFlowで扱えるように、NoteSequencesという形式に変換する必要があります。

下記のスクリプトを実行します。
不正な形式のMIDIファイルを読み込んだ際にエラーを吐くことがあります。
解析できないMIDIファイルはスキップされるので安心して大丈夫なようです。


MIDI_DIRECTORY=<folder containing MIDI files. can have child folders.>

# TFRecord file that will contain NoteSequence protocol buffers.
SEQUENCES_TFRECORD=/tmp/notesequences.tfrecord

bazel run //magenta/scripts:convert_midi_dir_to_note_sequences -- \
--midi_dir=$MIDI_DIRECTORY \
--output_file=$SEQUENCES_TFRECORD \
--recursive


convert_midi_dir_to_note_sequences.pyと言うのを実行しているようですね。

下記のようなメッセージが表示されれば完了です。

..............
INFO: Found 1 target...
Target //magenta/scripts:convert_midi_dir_to_note_sequences up-to-date:
  bazel-bin/magenta/scripts/convert_midi_dir_to_note_sequences
INFO: Elapsed time: 7.312s, Critical Path: 0.63s

(中略)

INFO:tensorflow:Could not parse 0 MIDI files.
INFO:tensorflow:Wrote 6 NoteSequence protos to '/tmp/notesequences.tfrecord'

学習する

メロディーを抽出する

basic_rnn_create_dataset.pyを実行します。

これは上記でMIDIファイルを元に作成したNoteSequence dataからメロディーを抽出するスクリプトです。
アウトプットはSequenceExampleprotosを含んだtfrecordファイルとして書き出されます。

basic_rnnモデルのTensorFlowの読み込みは、SequenceExample protosを直接モデルに読み込むことができます。

この例では、評価データセットを2つ目のtfrecordファイルとして作ります。
ですが、evaloutputevalratioフラグを削除することで省くことができます。

下記のようなメッセージが出ればOKです。

INFO: Found 1 target...
Target //magenta/models/basic_rnn:basic_rnn_create_dataset up-to-date:
  bazel-bin/magenta/models/basic_rnn/basic_rnn_create_dataset
INFO: Elapsed time: 0.573s, Critical Path: 0.01s

INFO: Running command line: bazel-bin/magenta/models/basic_rnn/basic_rnn_create_dataset '--input=/tmp/notesequences.tfrecord' '--output_dir=/tmp/basic_rnn/sequence_examples' '--eval_ratio=0.10'
INFO:tensorflow:

Completed.

INFO:tensorflow:Processed 6 inputs total. Produced 31 outputs.
INFO:tensorflow:DAGPipeline_RandomPartition_training_melodies_count: 29
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_melodies_discarded_too_long: 0
INFO:tensorflow:DAGPipeline_RandomPartition_eval_melodies_count: 2
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_melody_lengths_in_bars:
  [0,1): 10
  [1,3): 6
  [3,6): 17
  [6,7): 2
  [7,8): 1
  [8,10): 4
  [10,20): 21
  [20,30): 5
  [30,40): 6
  [50,100): 4
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_melodies_discarded_too_short: 35
INFO:tensorflow:DAGPipeline_Quantizer_sequences_discarded_because_multiple_time_signatures: 5
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_melodies_truncated: 0
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_polyphonic_tracks_discarded: 43
INFO:tensorflow:DAGPipeline_MonophonicMelodyExtractor_melodies_discarded_too_few_pitches: 10

完了すると
/tmp/basic_rnn/sequence_examples/
training_melodies.tfrecordeval_melodies.tfrecordの2つのファイルができます。
training_melodies.tfrecordは訓練用、eval_melodies.tfrecordは評価用のようです。

トレーニングのスクリプトを実行する

Magentaの開発者の方がスクリプトを作ってくださっています。

$EXPERIMENT_DIR=/tmp/basic_rnn/logdir

作業フォルダを指定します。

$HYPERPARAMETER_STRING=`{"rnn_layer_sizes":[50]}’

ハイパーパラメータの指定をします。
このように指定することで、LSTMモデルのサイズを指定することができるようです。
LSTMについては下記が参考になると思います(大作)。

わかるLSTM ~ 最近の動向と共に

LSTM(Long short-term memory)は、RNN(Recurrent Neural Network)の拡張として1995年に登場した、時系列データ(sequential data)に対するモデル、あるいは構造(architecture)の1種です。

 (中略)

LSTMのその最も大きな特長は、従来のRNNでは学習できなかった長期依存(long-term dependencies)を学習可能であるところにあります。

$NUM_TRAINING_STEPS=20000

訓練回数を指定します。Macだととても時間がかかるので、数百とかに減らすといいと思います。

$TRAIN_DATA=/tmp/basic_rnn/sequence_examples/training_melodies.tfrecord

上記で生成した訓練データのパスを記載します。

$EVAL_DATA=/tmp/basic_rnn/sequence_examples/eval_melodies.tfrecord

オプションとして、訓練データと並行して検証データも並行してはしらせることができるようです。

設定ができたら、スクリプトを実行します。

./run_basic_rnn_train.sh $EXPERIMENT_DIR $HYPERPARAMETER_STRING $NUM_TRAINING_STEPS $TRAIN_DATA [$EVAL_DATA]

下記のメッセージが出ます。

INFO: Found 1 target...
Target //magenta/models/basic_rnn:basic_rnn_train up-to-date:
  bazel-bin/magenta/models/basic_rnn/basic_rnn_train
INFO: Elapsed time: 0.544s, Critical Path: 0.00s
INFO:tensorflow:hparams = {'rnn_layer_sizes': [50], 'decay_rate': 0.85, 'dropout_keep_prob': 0.5, 'batch_size': 128, 'decay_steps': 1000, 'clip_norm': 5, 'initial_learning_rate': 0.01, 'skip_first_n_losses': 0}
Starting TensorBoard 28 on port 6006
(You can navigate to http://10.200.3.144:6006)
INFO:tensorflow:Train dir: /tmp/melody_rnn/logdir/run1/train
INFO:tensorflow:Starting training loop...
INFO:tensorflow:global_step/sec: 0

(中略)

INFO:tensorflow:Global Step: 100 - Learning Rate: 0.01000 - Loss: 1.680 - Perplexity: 13.678 - Accuracy: 85.811
INFO:tensorflow:Training complete.

曲を生成する。

上記の訓練が完了すると、作業ディレクトリ/tmp/basic_rnn/logdir/run1/train/ の配下に、下記のようなファイルができると思います。

checkpoint                  model.ckpt-31
events.out.tfevents.1475664203.HTMac.local  model.ckpt-31.meta
graph.pbtxt                 model.ckpt-39
model.ckpt-15                   model.ckpt-39.meta
model.ckpt-15.meta              model.ckpt-47
model.ckpt-23                   model.ckpt-47.meta
model.ckpt-23.meta

checkpointというのはTensorFlowにおけるファイルの保存やロードに用いるもののようです。
Basic_RNNではこのうち、最後のcheckpoint(上記だとmodel.ckpt-47)を用いて曲を生成してくれるようです。

また、曲を生成するには、モデルにはじまりのメロディを与える必要があります。
曲生成はそのメロディを元に、次の音をどんどん予測して行って曲を延長していく、ということをするからです。準備するメロディはモノラルの(同タイミングに複数の音が鳴らない)メロディである必要があります。

任意に作成してもいいですし、サンプルとして
/magenta/models/shared/primer.midも準備されています。

ここではこのサンプルを用います。

PRIMER_PATH=<absolute path of your primer MIDI file>

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

最小の3小節はprimer.midを元に固定されています。

サンプル1
サンプル2

サカナクションさんを学習させましたが、雰囲気を感じることができました。

最後に

DeepLearningの知識、TensorFlowの知識、英語読解力の不足が原因で、ちょっと読み解けてない部分があります。
引き続き勉強します。。。

ありがとうございました。

40
42
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
40
42