"BOKU"のITな日常

還暦越えの文系システムエンジニアの”BOKU”は新しいことが大好きです。

音楽データ(au)をPythonで画像ファイルにしてジャンル分類をする/Neural Network Console応用編

今回は音楽データをNeural Network Consoleで学習・評価させてみます。

f:id:arakan_no_boku:20190326212937j:plain

 

元になる音楽データ

 

音楽データはこれを使います。

http://opihi.cs.uvic.ca/sound/genres.tar.gz

約1.1GBほどある巨大なファイル群です。

解凍すると、以下のようなフォルダ構成になってます。

f:id:arakan_no_boku:20190108010048j:plain

この各フォルダの中にAU形式(UNIX等で利用される音声ファイル形式)の曲データがあります。

f:id:arakan_no_boku:20190108010314j:plain

これらの音源に収められた曲を学習させて、曲を上記の10ジャンルに分類する機械学習の練習用データになっているわけです。 

 

前処理:音楽データを画像データに変換する

 

残念ながら。

AU形式の音声ファイルをそのまま学習・評価用データで利用することはできません。

曲データ毎の音声特性を特徴量としてとらえる方法は「メル周波数ケプストラム係数(Mel-Frequency Cepstrum Coefficients)」を求めて、それをグラフで可視化したものを画像ファイルとして保存して学習・評価に利用できるデータにしてやるというのが、定番っぽいのでそれをやってみます。

とはいえ。

メル周波数ケプストラム係数について、ちゃんと理解しようとすると相当難しいです。

なので、解説はしません(できません・・笑)。

詳しく知りたい場合は「メル周波数ケプストラム係数」で調べてください。

こちらでも説明されてます。

speechresearch.fiw-web.net

 

pythonのlibrosaを使ってメル周波数ケプトストラムを計算

 

有難いことに。

pythonのlibrosaというモジュールを使うと、この難しい「メル周波数ケプストラム係数」を簡単にサクッと求めることができます。

以下がに、曲ファイルを読み込んで「メル周波数ケプストラム係数」を求めて、matplotlibでグラフにしたものをPNG画像で保存するソースです。

librosaは「pip install librosa」でインストールしておく必要があります。

import librosa
import librosa.display
import matplotlib.pyplot as plt
import os

def save_png(filename,soundpath,savepath):
    # オーディオファイル(au)を読み込む
    music, fs = librosa.audio.load(soundpath + filename)
    # メルスペクトラム(MFCC)変換
    mfccs = librosa.feature.mfcc(music, sr=fs)
    # グラフに変換する
    librosa.display.specshow(mfccs, sr=fs, x_axis='time')
    # PNG形式画像で保存する
    plt.savefig(savepath + filename + '.png',dpi=200)
    

soundpath = '.\\03-sound\\au_data\\'
savepath = '.\\03-sound\\img\\'
cnt = 0
for filename in os.listdir(soundpath):
    cnt += 1
    if((cnt % 10) == 0):
        print(cnt,'件を処理しました')
    save_png(filename,soundpath,savepath)

上記 は「.\03-sound\au_data\」フォルダに、au形式データをおいて、「.\03-sound\img\」に生成した画像を置きます。

 

生成した画像のサイズ変更と形式変更

 

でも、生成した画像はそのまま使うのは、少々しんどいです。

ひとつはサイズが約1280×960くらいと大きいこと。

このまま学習させると、下手をするとNeural Network Consoleがメモリアロケーションエラーで実行できなくなります。

あと、これは自分の失敗ですが、PNG画像で保存してます。

そうするとαチャンネルがついて、RGBとあわせて4チャンネルになってしまいます。

なので、Neural Network Consoleのinputでチャンネルを4にしないといけなくなるので、ちょっと気持ちが悪いです。

ということで。

一旦生成した画像はリサイズして、JPEGに変換します。

(当然、最初からJPEGで保存するのが断然スマートですm(__)m)

どんな方法でもいいですが、自分はRalphaをお勧めします。

forest.watch.impress.co.jp

両方一発でできますから。

以後は、横128×縦96のJPEGファイルに変換した前提ですすめます。

 

データセットCSVを作成する

 

データは10分類あるのですが、今回はそのうち3つに絞って3分類でやります。

その3つは、

  • blues 0
  • classical 1
  • metal 2

です。

 

ジャンルを3分類に絞り込む理由

 

3つに絞った理由は単純です。

これ以外のジャンルのデータを加えると、浅いCNNによる短時間の学習では精度がでないからです。

生成された画像を調べてみたのですが、例えば、bluesとreggaeは生成された画像がかなり似通ってます。

同様に、rockとかpopとcountry、discoなどもそうです。

浅いCNNを使って短時間で学習させただけだと、これらの微妙な違い迄きれいに識別できるほどの特徴量をとらえられません。

なので、10分類に挑戦しても、精度は50%から60%でればせいぜい・・という情けない結果になる可能性が高いです。

もちろん、VGG16とかresNetみたいに深いCNNを組んで、GPUとかもある環境で学習させることができればいいんでしょうが、自分みたいに低価格ノートPCしかない環境では深いCNNを組むのは学習に時間がかかりすぎて、現実的ではありません。

今回、やりたいのは、浅いCNNと短時間学習で感触をつかみたいだけです。

だから、手間と時間と精度のトレードオフを考えると、3分類くらいが手頃かな・・。

そういう判断です。

 

CSVファイルの作成

 

さて・・、その前提で。

データセットCSVを作ります。

今回の場合、ファイル名に答えがついているので、コマンドプロンプトで「dir /b > tmp.txt」とでもやって、ファイル名だけのリストをtmp.txtに吐き出して、EXCELにはりつけて、回答のラベルを書いて・・みたいに、完全手作業でも作れます。

f:id:arakan_no_boku:20190110225300j:plain

これをCSVで保存すればよいわけです。

f:id:arakan_no_boku:20190110225130j:plain

こんな感じですね。

こんな感じで、学習用とテスト用の2つのCSVを作ります。

 

学習と評価をやってみる

 

さて、Neural Network Consoleです。

今回も速度重視で浅いCNNでやります。

f:id:arakan_no_boku:20190110233954j:plain

inputがカラーなので、「3,96,128」のように3チャンネルになってます。

もし、JPEGではなくPNGのままでやるときは、「4,96,128」みたいにαチャンネル分を増やしてやる必要があるので、ご注意ください。

Max Epochは「100」で今回はやりました。

validation用データを30個にしたので、バッチサイズはそれより小さくしないと動きませんので、デフォルトの64を16にしてやりました。

ただ、Best validationが85位だったので、若干過学習気味かもしれませんが・・まあ、大丈夫だろうと判断して評価してます。

 

学習・評価を実行した結果

 

評価結果です。

f:id:arakan_no_boku:20190110234651j:plain

まあまあです。

こんな風に音楽データでも、分析ツールを使って波形を画像データにしてしまうと、Neural Network Consoleでも、学習・評価できるようになります。

とりあえず、それが確認できたので、良しとしましょう。

ではでは。