福岡人データサイエンティストの部屋

データサイエンスを極めるため、日々の学習を綴っています。

MusicVAEで作曲してみた!【図解速習DeepLearning】#020



こんにちは!こーたろーです。


久々の投稿です。


一週間ほどお休みいただきました。


結構ブログって大変ですね。


毎日書くのは大変!


ということで、今回も【図解速習DEEP LEARNING】やっていきます!


今回はMusicVAEで作曲していきます!


環境の準備



今回もPython2系を使用していきます。


下記のURLから2系のGoogle Colabを開きます。


https://colab.research.google.com/notebook#create=true&language=python2


環境設定を行っていきます。


Music VAEなどをインストールします。

import glob

print 'Copying checkpoints and example MIDI from GCS. This will take a few minutes...'
!gsutil -q -m cp -R gs://download.magenta.tensorflow.org/models/music_vae/colab2/* /content/

print 'Installing dependencies...'
!apt-get update -qq && apt-get install -qq libfluidsynth1 fluid-soundfont-gm build-essential libasound2-dev libjack-dev
!pip install -q pyfluidsynth
!pip install -q magenta==0.5

import ctypes.util
orig_ctypes_util_find_library = ctypes.util.find_library
def proxy_find_library(lib):
  if lib == 'fluidsynth':
    return 'libfluidsynth.so.1'
  else:
    return orig_ctypes_util_find_library(lib)
ctypes.util.find_library = proxy_find_library

print 'Importing libraries and defining some helper functions...'
from google.colab import files
import magenta.music as mm
from magenta.models.music_vae import configs
from magenta.models.music_vae.trained_model import TrainedModel
import numpy as np
import os
import tensorflow as tf

import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)

def play(note_sequence):
  mm.play_sequence(note_sequence, synth=mm.fluidsynth)

def interpolate(model, start_seq, end_seq, num_steps, max_length=32,
                assert_same_length=True, temperature=0.5,
                individual_duration=4.0):

  note_sequences = model.interpolate(
      start_seq, end_seq,num_steps=num_steps, length=max_length,
      temperature=temperature,
      assert_same_length=assert_same_length)

  print 'Start Seq Reconstruction'
  play(note_sequences[0])
  print 'End Seq Reconstruction'
  play(note_sequences[-1])
  print 'Mean Sequence'
  play(note_sequences[num_steps // 2])
  print 'Start -> End Interpolation'
  interp_seq = mm.sequences_lib.concatenate_sequences(
      note_sequences, [individual_duration] * len(note_sequences))
  play(interp_seq)
  mm.plot_sequence(interp_seq)
  return interp_seq if num_steps > 3 else note_sequences[num_steps // 2]

def download(note_sequence, filename):
  mm.sequence_proto_to_midi_file(note_sequence, filename)
  files.download(filename)

print 'Done'

データセットについて

今回は学習済みのモデルを使用します。


事前学習済みのモデルは以下の4つを使用していきます。

  • 2小節ドラムモデル
  • 2小節メロディモデル
  • 16小節メロディモデル
  • 16小節「トリオ」モデル(リード、ベース、ドラム)



それでは作曲始めます!

2小節ドラムモデル

学習済みモデルの取得



4種の学習済みモデルを取得します。

drums_models = {}

drums_config = configs.CONFIG_MAP['cat-drums_2bar_small']
drums_models['drums_2bar_oh_lokl'] = TrainedModel(drums_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/drums_2bar_small.lokl.ckpt')
drums_models['drums_2bar_oh_hikl'] = TrainedModel(drums_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/drums_2bar_small.hikl.ckpt')

drums_nade_reduced_config = configs.CONFIG_MAP['nade-drums_2bar_reduced']
drums_models['drums_2bar_nade_reduced'] = TrainedModel(drums_nade_reduced_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/drums_2bar_nade.reduced.ckpt')
drums_nade_full_config = configs.CONFIG_MAP['nade-drums_2bar_full']
drums_models['drums_2bar_nade_full'] = TrainedModel(drums_nade_full_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/drums_2bar_nade.full.ckpt')


サンプルを生成



評価済みのモデルを選んで、サンプルを作成します。

#@title Generate 4 samples from the prior of one of the models listed above.
drums_sample_model = "drums_2bar_oh_hikl" #@param ["drums_2bar_oh_lokl", "drums_2bar_oh_hikl", "drums_2bar_nade_reduced", "drums_2bar_nade_full"]
temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
drums_samples = drums_models[drums_sample_model].sample(n=4, length=32, temperature=temperature)
for ns in drums_samples:
  play(ns)



f:id:dsf-kotaro:20210226132207p:plain
f:id:dsf-kotaro:20210226132223p:plain

サンプルをダウンロード



生成したサンプルをダウンロードしておきます。


この後、サンプルのアップロードを行います。


Google Colabのファイルから開いてもいいかもしれません。

for i, ns in enumerate(drums_samples):
  download(ns, '%s_sample_%d.mid' % (drums_sample_model, i))


ファイルのアップロード



先ほど生成したファイル4つを、一度に選択してアップロードしてください。

input_drums_midi_data = [
    tf.gfile.Open(fn).read()
    for fn in sorted(tf.gfile.Glob('/content/midi/drums_2bar*.mid'))]

input_drums_midi_data = files.upload().values() or input_drums_midi_data



f:id:dsf-kotaro:20210226132259p:plain

補間を生成
drums_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_drums_midi_data]
extracted_beats = []
for ns in drums_input_seqs:
  extracted_beats.extend(drums_nade_full_config.data_converter.to_notesequences(
      drums_nade_full_config.data_converter.to_tensors(ns)[1]))
for i, ns in enumerate(extracted_beats):
  print "Beat", i
  play(ns)

f:id:dsf-kotaro:20210226132325p:plain

補間を生成(詳細チューニング)


#@title Interpolate between 2 beats, selected from those in the previous cell.
drums_interp_model = "drums_2bar_nade_reduced" #@param ["drums_2bar_oh_lokl", "drums_2bar_oh_hikl", "drums_2bar_nade_reduced", "drums_2bar_nade_full"]
start_beat =  0#@param {type:"integer"}
end_beat =  1#@param {type:"integer"}
start_beat = extracted_beats[start_beat]
end_beat = extracted_beats[end_beat]

temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
num_steps = 6 #@param {type:"integer"}

drums_interp = interpolate(drums_models[drums_interp_model], start_beat, end_beat, num_steps=num_steps, temperature=temperature)



f:id:dsf-kotaro:20210226132350p:plain


f:id:dsf-kotaro:20210226132406p:plain

download(drums_interp, '%s_interp.mid' % drums_interp_model)

mel_2bar_config = configs.CONFIG_MAP['cat-mel_2bar_big']
mel_2bar = TrainedModel(mel_2bar_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/mel_2bar_big.ckpt')



これにて 2小節ドラムモデルが完成です。


以降、同様の手順で進めていきます。

2小節メロディモデル


学習済みモデルを取得


#@title Generate 4 samples from the prior.
temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
mel_2_samples = mel_2bar.sample(n=4, length=32, temperature=temperature)
for ns in mel_2_samples:
  play(ns)



f:id:dsf-kotaro:20210226132447p:plain


f:id:dsf-kotaro:20210226132502p:plain

サンプルを生成


サンプルをダウンロード


for i, ns in enumerate(mel_2_samples):
  download(ns, 'mel_2bar_sample_%d.mid' % i)

input_mel_midi_data = [
    tf.gfile.Open(fn).read()
    for fn in sorted(tf.gfile.Glob('/content/midi/mel_2bar*.mid'))]


ファイルのアップロード


input_mel_midi_data = files.upload().values() or input_mel_midi_data



f:id:dsf-kotaro:20210226132535p:plain

補間を生成


mel_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_mel_midi_data]
extracted_mels = []
for ns in mel_input_seqs:
  extracted_mels.extend(
      mel_2bar_config.data_converter.to_notesequences(
          mel_2bar_config.data_converter.to_tensors(ns)[1]))
for i, ns in enumerate(extracted_mels):
  print "Melody", i
  play(ns)



f:id:dsf-kotaro:20210226132601p:plain

補間を生成(詳細チューニング)
#@title Interpolate between 2 melodies, selected from those in the previous cell.
start_melody = 0 #@param {type:"integer"}
end_melody = 1 #@param {type:"integer"}
start_mel = extracted_mels[start_melody]
end_mel = extracted_mels[end_melody]

temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
num_steps = 13 #@param {type:"integer"}

mel_2bar_interp = interpolate(mel_2bar, start_mel, end_mel, num_steps=num_steps, temperature=temperature)



f:id:dsf-kotaro:20210226132625p:plain


f:id:dsf-kotaro:20210226132642p:plain

download(mel_2bar_interp, 'mel_2bar_interp.mid')


16小節メロディモデル


学習済みモデルを取得


mel_16bar_models = {}
hierdec_mel_16bar_config = configs.CONFIG_MAP['hierdec-mel_16bar']
mel_16bar_models['hierdec_mel_16bar'] = TrainedModel(hierdec_mel_16bar_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/mel_16bar_hierdec.ckpt')

flat_mel_16bar_config = configs.CONFIG_MAP['flat-mel_16bar']
mel_16bar_models['baseline_flat_mel_16bar'] = TrainedModel(flat_mel_16bar_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/mel_16bar_flat.ckpt')


サンプルを生成


#@title Generate 4 samples from the selected model prior.
mel_sample_model = "baseline_flat_mel_16bar" #@param ["hierdec_mel_16bar", "baseline_flat_mel_16bar"]
temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
mel_16_samples = mel_16bar_models[mel_sample_model].sample(n=4, length=256, temperature=temperature)
for ns in mel_16_samples:
  play(ns)



f:id:dsf-kotaro:20210226132716p:plain


f:id:dsf-kotaro:20210226132730p:plain

サンプルをダウンロード


for i, ns in enumerate(mel_16_samples):
  download(ns, '%s_sample_%d.mid' % (mel_sample_model, i))
input_mel_16_midi_data = [
    tf.gfile.Open(fn).read()
    for fn in sorted(tf.gfile.Glob('/content/midi/mel_16bar*.mid'))]


ファイルのアップロード


input_mel_16_midi_data = files.upload().values() or input_mel_16_midi_data



f:id:dsf-kotaro:20210226132807p:plain

補間を生成


mel_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_mel_16_midi_data]
extracted_16_mels = []
for ns in mel_input_seqs:
  extracted_16_mels.extend(
      hierdec_mel_16bar_config.data_converter.to_notesequences(
          hierdec_mel_16bar_config.data_converter.to_tensors(ns)[1]))
for i, ns in enumerate(extracted_16_mels):
  print "Melody", i
  play(ns)

f:id:dsf-kotaro:20210226132829p:plain

補間を生成(詳細チューニング)


#@title Compute the reconstructions and mean of the two melodies, selected from the previous cell.
mel_interp_model = "hierdec_mel_16bar" #@param ["hierdec_mel_16bar", "baseline_flat_mel_16bar"]

start_melody = 0 #@param {type:"integer"}
end_melody = 1 #@param {type:"integer"}
start_mel = extracted_16_mels[start_melody]
end_mel = extracted_16_mels[end_melody]

temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}

mel_16bar_mean = interpolate(mel_16bar_models[mel_interp_model], start_mel, end_mel, num_steps=3, max_length=256, individual_duration=32, temperature=temperature)



f:id:dsf-kotaro:20210226132858p:plain


f:id:dsf-kotaro:20210226132914p:plain

download(mel_16bar_mean, '%s_mean.mid' % mel_interp_model)


16小節「トリオ」モデル(リード、ベース、ドラム)


学習済みモデルを取得


trio_models = {}
hierdec_trio_16bar_config = configs.CONFIG_MAP['hierdec-trio_16bar']
trio_models['hierdec_trio_16bar'] = TrainedModel(hierdec_trio_16bar_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/trio_16bar_hierdec.ckpt')

flat_trio_16bar_config = configs.CONFIG_MAP['flat-trio_16bar']
trio_models['baseline_flat_trio_16bar'] = TrainedModel(flat_trio_16bar_config, batch_size=4, checkpoint_dir_or_path='/content/checkpoints/trio_16bar_flat.ckpt')


サンプルを生成


#@title Generate 4 samples from the selected model prior.
trio_sample_model = "hierdec_trio_16bar" #@param ["hierdec_trio_16bar", "baseline_flat_trio_16bar"]
temperature = 0.7 #@param {type:"slider", min:0.1, max:1.5, step:0.1}

trio_16_samples = trio_models[trio_sample_model].sample(n=4, length=256, temperature=temperature)
for ns in trio_16_samples:
  play(ns)



f:id:dsf-kotaro:20210226132950p:plain


f:id:dsf-kotaro:20210226133006p:plain

サンプルをダウンロード


for i, ns in enumerate(trio_16_samples):
  download(ns, '%s_sample_%d.mid' % (trio_sample_model, i))


ファイルのアップロード


input_trio_midi_data = [
    tf.gfile.Open(fn).read()
    for fn in sorted(tf.gfile.Glob('/content/midi/trio_16bar*.mid'))]

input_trio_midi_data = files.upload().values() or input_trio_midi_data



f:id:dsf-kotaro:20210226133105p:plain

補間を生成


trio_input_seqs = [mm.midi_to_sequence_proto(m) for m in input_trio_midi_data]
extracted_trios = []
for ns in trio_input_seqs:
  extracted_trios.extend(
      hierdec_trio_16bar_config.data_converter.to_notesequences(
          hierdec_trio_16bar_config.data_converter.to_tensors(ns)[1]))
for i, ns in enumerate(extracted_trios):
  print "Trio", i
  play(ns)



f:id:dsf-kotaro:20210226133129p:plain

補間を生成(詳細チューニング)


#@title Compute the reconstructions and mean of the two trios, selected from the previous cell.
trio_interp_model = "hierdec_trio_16bar" #@param ["hierdec_trio_16bar", "baseline_flat_trio_16bar"]

start_trio = 0 #@param {type:"integer"}
end_trio = 1 #@param {type:"integer"}
start_trio = extracted_trios[start_trio]
end_trio = extracted_trios[end_trio]

temperature = 0.5 #@param {type:"slider", min:0.1, max:1.5, step:0.1}
trio_16bar_mean = interpolate(trio_models[trio_interp_model], start_trio, end_trio, num_steps=3, max_length=256, individual_duration=32, temperature=temperature)



f:id:dsf-kotaro:20210226133159p:plain


f:id:dsf-kotaro:20210226133216p:plain

download(trio_16bar_mean, '%s_mean.mid' % trio_interp_model)



今回は、MusicVAEでMidiデータを使用して、曲をDeepLearningで作成してみました!


久々の投稿でしたが、1週間分の内容が詰まっている気がします(笑


忙しい中ではありますが、技術ブログは続けていけたらと思います!


ではでは。


Pythonコードレシピ集

Pythonコードレシピ集