はじめに
Rajat Hebbarの記事を参考にして、music2vecを用いた音楽ジャンル分類モデルを実装しました。
実装のコードはGithubに公開してあります。
Google Colaboratory上にモデルの実装、学習、評価を簡単に実行できるようにまとめてあります(Githubのmusic2vec.ipynbと同じもの)。
-
追記(2021/04/25)
関連記事
DANet(Deep Attractor Network)の実装と解説
DANetとmusic2vecによるノイズ除去と音楽ジャンル分類
概要
1. 実行したPythonのバージョンと使用したパッケージ
- Python 3.7.10
- TensorFlow 2.4.1
モデルの構築に利用 - numpy 1.19.5
各種計算、配列処理等に利用 - librosa 0.8.0
音声のファイルからのロード、リサンプリングといった音声処理に利用
2. 使用したデータ
GTZANをデータとして使用しました。
1000個の音楽データの内950個を訓練データとして学習させ、50個をテストデータとして用いました。
SoundNetの論文3ページ目の"2 Large Unlabeled Video Dataset"に従い、入力音源はサンプリングレート22050Hzにし、-256から256までの範囲の数値にしました。
3. モデルの構成
Rajat Hebbarの記事で紹介されている上の写真のモデルをもとに、下のモデルを作成した。
SoundNetベースのCNNを実際のSoundNetに変えたのが主な変更点です。
それによりCNNの層が増えて入力を長くする必要が出てきたため、入力サイズが大きくなりました。
4. 結果と評価
学習の10epochs後と20epochs後に50個のテストデータで推論させて混同行列の作成とAccuracy・Precision・Recall・F1の求値を行いました。
ここで、Precision・Recall・F1の値は各ラベルごとの値をデータ数に応じて重み付けをして平均したものです。例えば、下のような混同行列であれば下の計算式によりPrecisionはおよそ0.58になります。
\frac{10}{19}\times\frac{15}{50}+\frac{12}{18}\times\frac{25}{50}+\frac{6}{13}\times\frac{10}{50}\fallingdotseq0.58
また、学習前と学習後でモデル中のSoundNetの部分の出力を平坦化したものをPCAやt-SNEで可視化しました。
学習後ではt-SNEでジャンルごとにある程度分離されていることがわかります。特にclassicalやmetalはよく分離されています。
5. パッケージとしての利用
Githubに載せた実装をパッケージとして利用することで、GTZANに含まれる音楽のジャンル分類を学習させることが簡単にできます。
また、データ処理に関する関数をすべてそのまま使うことはできなくなりますが、パッケージを利用することで他のデータを用いてこのモデルに音声分類させることも簡単にできます。
-
パッケージのインストール、インポート
$pip install git+https://github.com/KMASAHIRO/music2vec
import music2vec
-
GTZANデータセットの用意
# (注意!)以下のリンクは切れているので、新しいリンク(https://www.kaggle.com/datasets/andradaolteanu/gtzan-dataset-music-genre-classification?resource=download)にしてダウンロードしてください。パスも少し変わります。 $wget http://opihi.cs.uvic.ca/sound/genres.tar.gz $tar -zxvf genres.tar.gz
-
データの前処理
# データをシャッフルして訓練データとそのラベル、テストデータとそのラベルを用意する # genres_pathはGTZANデータが含まれるgenresディレクトリのパス、testdata_numはテストデータの数 train_filenames, test_filenames, train_labels, test_labels = music2vec.data_preparation.gtzan_preparation(genres_path="genres/", testdata_num=50)
-
モデルを構築
model = music2vec.music2vec.create_model()
-
モデルの学習
# 訓練後のモデルを返す model = music2vec.music2vec.train(model=model, train_filenames=train_filenames, train_labels=train_labels, batch_size=25, epochs=20)
-
テストデータによる推論
# テストデータとなる音楽をロードして前処理する test_inputs = list() for file in test_filenames: test_inputs.append(music2vec.data_preparation.load_audiofile(file)) test_inputs = np.asarray(test_inputs) # 推論 result = model.predict(test_inputs, batch_size=25) # Accuracyを求める m = tf.keras.metrics.CategoricalAccuracy() m.update_state(test_labels, result) print(m.result().numpy())
おわりに
Rajat Hebbarの記事を参考にして、music2vecを用いた音楽ジャンル分類モデルを実装しました。
記事ではテストデータでの精度は66.32%となっており、今回の結果はおよそ62%であるので少し低い結果となりました。
しかし、データセットの違いにより
・分類ジャンル数が記事では8つなのに対して今回は10個で分類をしている
・記事のモデルでは入力が小さいこともありおよそ158,200個のデータを使用しているのに対し、今回は1,000個のデータを使用している
という違いがあるので、今回の結果は悪くないと考えられます。
今回作成したパッケージを使い、ぜひ様々な音声分類をしてみてください。
不明な点、実装コードに関するアドバイス、パッケージとして利用する際の問題などありましたらコメントお願いします。
(この記事は研究室インターンで取り組みました:https://kojima-r.github.io/kojima/)