post Image
Kerasを使って音楽をジャンル分けしてみた

概要

  • FolkとElectronicのジャンルで各500曲を用意
  • メル周波数ケプストラム係数 (MFCC) を使って学習モデルを作成
  • Kerasを使って学習・判定
  • 交差検証を行い、二値分類で精度は約85%程度

データの準備

フリーで音楽データを利用可能なFMA (Free Music Archive) というサービスがあります。
このFMAからさらに、8ジャンル x 1000曲を抽出したfma_smallというデータセットがあります。

このfma_smallから、違いが分かりやすいと思われる2ジャンル FolkElectronic の楽曲をそれぞれ500曲選択し実験に使いました。

1曲の長さは全て30秒となっています。

モデルの作成

モデルにはメル周波数ケプストラム係数 (MFCC) を用います。
MFCCについてはこちらが詳しく書かれています。

MFCCへの変換にはlibrosaを用いました。
特徴的なFolkとElectronicの曲のMFCCを可視化すると下図のようになります。

スクリーンショット 2018-01-03 23.16.22.png

スクリーンショット 2018-01-03 23.16.42.png

なんとなく違いがあるように思えます。

このままモデルとしても今回の実験ではうまくいかなかったため、縦軸の音の高さ毎に平均を取り1次元の配列にし、それをモデルとしました。
なので、今回のモデルには時間軸の要素はないことになります。

具体的には以下のプログラムでモデルを作成しました。


import os
import librosa
import numpy as np

def load(dir_path, label):
    n_mfcc = 20
    genre_x = np.zeros((0, n_mfcc))
    genre_y = np.zeros((0, 1), dtype='int')

    files = os.listdir(dir_path)
    for i, file in enumerate(files):
        file_path = dir_path + file
        y, sr = librosa.load(file_path)
        mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=n_mfcc)
        mean = np.mean(mfcc, axis = 1)
        genre_x = np.vstack((genre_x, mean))
        genre_y = np.vstack((genre_y, label))

        print(f'{i+1}/{len(files)} loaded: {file_path}')

    return genre_x, genre_y

if __name__ == '__main__':
    folk_x, folk_y = load('Folkのディレクトリパス', 0)
    electronic_x, electronic_y = load('Electronicのディレクトリパス', 1)

    X = np.r_[folk_x, electronic_x]
    Y = np.r_[folk_y, electronic_y]

    np.save('x.npy', X)
    np.save('y.npy', Y)

結果をx.npyy.npyとしてそれぞれファイル保存しています。

学習と評価

前節で作成したモデルを用いて交差検証を行います。


import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
from sklearn.model_selection import train_test_split

x = np.load('x.npy')
y = np.load('y.npy')

x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8)

model = Sequential()
model.add(Dense(256, activation='relu', input_shape=(20,)))
model.add(Dropout(0.25))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.25))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=500, batch_size=128)

score = model.evaluate(x_test, y_test, batch_size=128)
print(f'loss: {score[0]}, accuracy: {score[1]}')

librosaのMFCC変換時の係数の次元がデフォルトで20だったので、入力の次元も20となっています。

結果

学習結果

Epoch 1/500
800/800 [==============================] - 0s 358us/step - loss: 5.3203 - acc: 0.5800
Epoch 2/500
800/800 [==============================] - 0s 35us/step - loss: 3.2174 - acc: 0.6875

...

Epoch 499/500
800/800 [==============================] - 0s 29us/step - loss: 0.0370 - acc: 0.9900
Epoch 500/500
800/800 [==============================] - 0s 30us/step - loss: 0.0067 - acc: 0.9975

学習がうまくいったことが分かります。

評価結果

200/200 [==============================] - 0s 106us/step
loss: 0.8637916135787964, accuracy: 0.8850000071525573

何回か試してみましたが、今回の実験では概ね85%前後となりました。

まとめ

FMAの音楽データを使ってジャンル分類をしました。

結果は二値分類で85%となりましたが、MFCC変換の調整や学習のさせ方次第で、もっと精度が出るような気がします。

今回は2ジャンルでの実験だったので、もっとジャンルを増やしてやってみたいですね。


『 Python 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。