ダークサイドにようこそ!

ダンスしたりアプリ開発したり旅したりしているBBOYのブログ

【音楽】AI(人工知能)に有名DJのミックステープを機械学習させてみた ~CNN編~

タイトルの通りDJのミックステープを機械学習させてみました。正確にはCNN(畳み込みニューラルネットワーク)を用いた深層学習です。

私はBBOY(ブレイクダンサー)なので、いわゆるブレイクビーツのミックステープを使います。ブレイク界でも有名なDJ Lean Rock、DJ Fleg、DJ Nobunagaを今回は学習対象としました。

Dj Lean Rock | Free Listening on SoundCloud
DJ FLEG | Free Listening on SoundCloud
Nobunaga 🎵 | Free Listening on SoundCloud


データの前処理・特徴抽出

音声解析系でよく見かける特徴抽出の手法として周波数解析が挙げられます。スペクトログラムで検索するとカラフルな画像がたくさん出てくると思います。つまり画像を学習させる要領で音楽の学習もできるわけです。今回はメル周波数スペクトログラムを学習に使います。これが何かというと専門外の私にはうまく説明できないのですが、以下URL等が参考になるかと思います(感謝)。

speechresearch.fiw-web.net


ではどうやってメル周波数スペクトログラムを得るのかというと、「LibROSA」という音楽解析用の便利なPython向けライブラリがあるのでそちらを利用させてもらいます、本当に便利。

librosa.github.io


以下のようなコードを書くことでmp3やwavといったオーディオファイルからメル周波数スペクトログラムを得ることができます。ちなみに"sr"がサンプリングレート、"offset"と"duration"で読み込むオーディオの長さを指定できます(何秒地点から何秒間)。durationにNoneを指定すると最後まで読み込みます。

import librosa.display
y, sr = librosa.load(filepath, sr=22050, offset=0.0, duration=None)
S = librosa.feature.melspectrogram(y=y, sr=sr)

librosa.feature.melspectrogramからは2次元のNumPy配列が返ってきます。これを2次元の畳み込みによるCNNに学習させましょう(モデル構造の紹介は省略しますがそんなに複雑ではありません)。
hahaeatora.hateblo.jp


また、今回の学習対象はミックステープとデータ長が長いので(1つにつき約40分程度はあります)、スライディングウィンドウ方式によりデータを分割します。イメージは以下のような感じです(図は適当です)。

f:id:hahaeatora:20190721163859j:plain:w500
切り取り枠をずらしていき、1つのデータから複数のデータを抽出する感じです。スライド幅を短くするとデータ数も増えます。ただし、この手法ではDJのミックステープを学習する上で欠点もあるのでそれは後述します。

ちなみにオーディオファイルの読み込みやデータ抽出にけっこう時間がかかるので、生成したNumPy配列はバイナリファイル(npz)として保存しておきます。以下はその例です(学習&テスト用にデータを分割しているものとする)。

import numpy as np
dataset = (x_train, x_test, y_train, y_test) # すべてNumPy配列にしておく
np.savez("dataset.npz", dataset)



データの学習・モデルの評価

やっとこさ学習データが準備できましたので、3人のDJ名をラベルとしてCNNモデルに学習させます(クラス分類)。その結果、テスト用に分割したデータに対する学習済みモデルの正解率は約50%となりました(ただし時間が取れずパラメーター調整はほとんどしてません)。この数字だけ見ると微妙です。

ただ、テスト用データもスライディングウィンドウ方式で抽出したデータなので一つ一つが短いです。これら各々に対して正解or不正解というのもしっくりこないので、以下のような評価の仕方を考えます。

f:id:hahaeatora:20190721174031j:plain:w500
モデルの出力層からはソフトマックス関数による各クラスの予測確率が算出されます。これらの平均値を求めることで、「このデータはDJ〇〇成分が○%、DJ〇〇が……」といったアウトプットの方法にすることにしました。
せっかくなので、学習に使ったミックステープに含まれない各DJのオリジナル楽曲を学習済みモデルに読み込ませてみましょう。以下にアウトプット例のスクショを載せてみます。


f:id:hahaeatora:20190722002728p:plain:w500
DJ Lean Rockの「Madafaka」ですがLean Rock成分が約57%となりました。


f:id:hahaeatora:20190722003335p:plain:w500
DJ Nobunagaの「Machine Guns」ですがNobunaga成分が約64%となりました。


f:id:hahaeatora:20190722003125p:plain:w500
DJ Flegの「Clive's Chords」ですがFleg成分が約15%となりました。

Lean RockとNobunagaについてはその成分高めということで一応分類もできそうです。ただしFlegの楽曲については逆に一番成分が低めということになってしまいました。ただFlegの楽曲的にLean RockとNobunagaの間に位置しそうな感じもあるような無いような……正直よく分かりません。
とはいえ、この三人以外の楽曲で試して確かにこれはDJ〇〇っぽいみたいなのもありました。例えばDJ Jebelのある楽曲だとNobunaga→Flegの順に成分高めと、個人的にこれはしっくりくる印象です。

Dj Jebel | Free Listening on SoundCloud


課題

今回はスライディングウィンドウ方式によりミックステープを細切れにして学習させましたが、楽曲のつながりにも意味があります。いわゆるストーリー性というのもDJの特色が反映される要素です。その辺りを無視して学習してしまっているので、DJプレイの学習という意味では改善が必要です。DJがかける楽曲の特徴という意味ではある程度学習できているのかなという感じです。他の学習手法も時間あったら試してみようと思います。

参考

ブレインパッドさんの記事にてほとんど同じようなことをされています。導入も非常に丁寧に紹介されているので、この記事より普通に参考になるかと(爆)。
blog.brainpad.co.jp

こういうこともやってます

hahaeatora.hateblo.jp
hahaeatora.hateblo.jp