LSTMを使って音楽データのジャンル分けをする

Pocket

深層学習を用いて音楽データのジャンル分けをする

はじめに

時系列データを扱った深層学習をしてみたかったので馴染みのある音楽データを使ったものをやってみることにした。
今回は以下のサイトのデータセットを使って音楽のジャンル分けを行う。
The MagnaTagATune Dataset

データの中身は30秒ほどの音楽データとそれぞれに対応するタグとなっている。
タグは男性か女性が歌っているのか、どんな楽器で演奏されているかなど、様々な特徴が188個用意されている。

実行環境は以下の通り。

Windows 10  
Python 3.6.6
keras 2.2.2
Tensorflow 1.10.0

GPUつきで学習を行う。
使用したのはNVIDIA GeForce 1080 Ti。

前準備関連は以下のサイトを参考にした。
DeepLearningで楽曲特徴量を抽出し、タグを予測する – Qiita

前処理編

データセットの用意

wgetを入れていたので以下の4つのコマンドで主要ファイルを取得できる。

$ wget http://mi.soi.city.ac.uk/datasets/magnatagatune/mp3.zip.001
$ wget http://mi.soi.city.ac.uk/datasets/magnatagatune/mp3.zip.002
$ wget http://mi.soi.city.ac.uk/datasets/magnatagatune/mp3.zip.003  
$ copy /b mp3.zip.001+mp3.zip.002+mp3.zip.003 input.zip

$ wget http://mi.soi.city.ac.uk/datasets/magnatagatune/annotations_final.csv
$wget http://mi.soi.city.ac.uk/datasets/magnatagatune/clip_info_final.csv

あとはまとまったzipファイルを解凍するだけ。
ファイル構造はこんな感じ。

└─input
    ├─0
    ├─1
    ├─2
    ├─3
    ├─4
    ├─5
    ├─6
    ├─7
    ├─8
    ├─9
    ├─a
    ├─b
    ├─c
    ├─d
    ├─e
    └─f
  annotation_final.csv

0~fのところにそれぞれ音楽ファイルが格納されている。
それぞれの音楽ファイルをのぞいてみると、すごく長い名称になっていた。annotation_finalの最後の列でファイル名は書かれていたのでそれで合致させられるようだ。

mp3データをNumPyのndarrayに読み込ませる。

ここではpydubを使うことにした。
あとコンバートにffmpegを使うのでそれもインストールした。
waveデータやmp3データを読み込むときにはよく使われるらしい。

import pydub
import numpy as np

def read_mp3(fname):
    sound = pydub.AudioSegment.from_mp3(fname)
    data = np.array(sound.get_array_of_samples())
    # ステレオ音声から片方だけ
    x = data[::sound.channels]
    return x

csvファイルの読み込み

csvファイルを読み込んでいく。

import pandas as pd
def preprocess():
    # csvファイルから読み込んだデータを受け渡せるようにする
    df = pd.read_csv('annotations_final.csv',delim_whitespace=True)
    df = df.set_index('clip_id')
    paths = df['mp3_path']
    df = df.drop('mp3_path',axis='columns')
    data = df.values
    path_list = np.array(paths)
    return data, path_list

訓練データの準備

次に受けとったpath_listからデータを格納していく部分。
今回、全体のデータを12等分して取得していくつもりなのでその部分も含めた。

def load_data(path_list, num_data):
    # 渡されたファイルのリストから1つずつmp3ファイルを読み込んでいく
    # 465984/12 = 38832
    X = np.empty((num_data, 12, 38832),dtype='int16') # 音声ファイルの長さが分かっているのであらかじめ受け皿を用意しておく
    i = 0
    for path in path_list:
        if i == num_data:
            break
        # 読み込めないデータが存在していたみたいなのでtryを使っておく。
        try:
            raw_data = read_mp3('./input/'+path)
            for k in range(12):
                X[i][k] = raw_data[38832*k:38832*(k+1)]
            i += 1
        except:
            continue
    return X # かなりのサイズになる。

として保存する。
今回はメモリの制約から8000曲を学習することにした。
この8000曲は無作為抽出されたものとする。
手元のRAMが24GBでも全部乗り切らなかったのでおそるべし・・・・

def make_data(num_data=8000, random_state=42): # 訓練データを作成する
    data, path_list = preprocess()
    np.random.seed(random_state)
    rand_idx = np.random.choice(len(path_list),len(path_list), replace=False) # 被りなし
    X = load_data(path_list, num_data=num_data)
    X = X.astype('float16', copy=False)
    X -= X.mean()
    X /= X.std() # 正規化
    y = data[rand_idx[:num_data]]
    return X, y

f1_scoreの実装

評価関数としてf1_scoreを実装しておく。(クラスではなくてタグ付けのようなものなので若干の例外処理をしておく必要があるため)

def f1_score(true_y, pred_y):
    pred_label = np.where(pred_y>=0.5, 1.0, 0.0).astype('float32')
    true_y = true_y.astype('float32')
    TP = np.where(true_y+pred_label==2.0,1.0,0.0).sum()
    TN = np.where(true_y+pred_label==0.0,1.0,0.0).sum()
    FP = np.where(true_y- pred_label==1.0,1.0,0.0).sum()
    FN = np.where(true_y- pred_label==-1.0,1.0,0.0).sum()
    # エラーを起こさないようにするため
    if TP == 0.0:
        TP = 0.1
    if FN == 0.0:
        FN = 0.1
    if FP == 0.0:
        FP = 0.1
    recall = TP / (TP + FN)
    precision = TP / (TP + FP)
    return (2*recall * precision)/(recall+precision)

ここまでを

utils.py

として保存しておく。

モデルの作成

これで入力データの用意まではできたので次はモデル作成。
今回はRNNを使ってみたかったのでLSTMを使うことにする。

既存のモデルとかあまり調べられていなかったので、かなり適当にモデルを組んでいる。
このあたりは今後の課題。

LSTMで出力する特徴量の数を減らすことで学習させるパラメータの数を減らし、その分、途中の出力を次の層へ伝えることにした。
損失は以下の形
loss = \frac{1}{N}\sum^{N}_{i=0}(y\cdot ln(sigmoid(logits))+(1-y)\cdot ln(1-sigmoid(logits))) \\
を試してみたが、うまく学習が進まなかったので却下。

import keras
from keras.layers import Dense,  Flatten

from keras.models import Sequential
from keras.layers.core import Activation
from keras.layers.recurrent import LSTM
from keras.optimizers import Adam

from keras import backend as K

def generator_loss(y_true, y_pred):
    return -K.mean(y_true*K.log(y_pred + 1e-7) + (1-y_true)*K.log(1 - y_pred + 1e-7), axis=1)

def model(input_shape=(12,38832),
          output_dim=188,
          eta=1e-3,
          lstm_activation = 'tanh',
          dense_activation = 'sigmoid'):
    model = Sequential()
    model.add(LSTM(output_dim,input_shape=input_shape,name='LSTM',return_sequences=True,
                   activation=lstm_activation))
    model.add(LSTM(512, name='LSTM_2', activation=lstm_activation))
    model.add(Flatten())
    model.add(Dense(188))
    model.add(Activation(dense_activation))

    opt = Adam(lr=eta)
    model.compile(loss="binary_crossentropy",
                  optimizer=opt,
                  metrics=['accuracy'])
    return model

これを

model.py

として保存しておく。

パラメータチューニング

せっかくなのでsklearnのGridSearchCVを使ってハイパーパラメータのチューニングを行うことにした。
データの規模をかなり小規模にして行った。
使える評価基準がどうやら’accuracy’のみっぽかったので今回のケースにこれが適切に作動したかどうかは自信がない。

ちなみに現在のディレクトリ構造はこんな感じ。

  utils.py
  model.py
  main.py
├─input
│  ├─0
│  ├─1
│  ├─2
│  ├─3
│  ├─4
│  ├─5
│  ├─6
│  ├─7
│  ├─8
│  ├─9
│  ├─a
│  ├─b
│  ├─c
│  ├─d
│  ├─e
│  └─f
├─models

main.pyは以下の感じ。

import utils
import model
import numpy as np
import gc

from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import roc_auc_score, f1_score

from keras.wrappers.scikit_learn import KerasClassifier



import matplotlib.pyplot as plt
import keras
import tensorflow as tf

X, y = utils.make_data(num_data=1000)
train_X, test_X, train_y, test_y = train_test_split(X, y,
                                                    test_size=0.1,
                                                    random_state=42)
model_tune = KerasClassifier(build_fn=model.model, verbose=0)
param_grid = dict(input_shape=[(train_X.shape[1],train_X.shape[2])],
                  output_dim=[16,32],
                  eta = [1e-4, 1e-5,1e-6],
                  lstm_activation=["tanh","relu"])
grid = GridSearchCV(estimator=model_tune,param_grid=param_grid)
grid_result = grid.fit(train_X, train_y,batch_size=50,epochs=2)
print("==============================================")
print("parameter optimize finished")
print("Best practices are")
print(grid_result.best_params_)
print("Best score is ")
print(grid_result.best_score_)

これの出力結果は以下のようになった。

==============================================
parameter optimize finished
Best practices are
{'dense_activation': 'relu', 'eta': 0.01, 'input_shape': (12, 38832), 'lstm_activation': 'tanh', 'output_dim': 16}
Best score is
0.174074076336843

学習

チューニングを行った値で学習させていく。
5000個のファイルを10エポックほど学習させる。
先ほどのmain.pyの続きで、

best_params = grid_result.best_params_.copy()
del grid_result, grid, model_tune, train_X, test_X, train_y, test_y,X,y
gc.collect();
print("Main training started")
# 毎回mp3ファイルを変換するのが非効率だったので配列として保存する。
try:
    X = np.load('X.npy')
    y = np.load('y.npy')
except:
    X, y = utils.make_data(num_data=8000, random_state=42)
    np.save('X.npy', X)
    np.save('y.npy', y)
train_X, test_X, train_y, test_y = train_test_split(X, y,
                                                    test_size=0.1,
                                                    random_state=42)

model_train = model.model(input_shape=(train_X.shape[1],train_X.shape[2]),
                    output_dim=best_params['output_dim'],
                    eta = best_params['eta'],
                    lstm_activation= best_params['lstm_activation'],
                    dense_activation='relu'
                    )
print(model_train.summary())
# 100エポック学習させる  
for i in range(10):
    model_train.fit(train_X, train_y, batch_size=50,
              epochs=5)
    pred = model_train.predict(test_X, batch_size=100)
    try:
        print("score is :\t", utils.f1_score(test_y, pred))
    except:
        pass


    model_train.save_weights('./models/model_weight_{}.h5'.format(i))
# ノイズが混じったデータでも検証してみる  
x_with_noise = test_X + np.random.randn(test_X.shape[0],test_X.shape[1],test_X.shape[2])/3.0
pred_noise = model_train.predict(x_with_noise, batch_size=100)
# ノイズが混じった時にスコアがどれだけ変動するかを調べる
print("score with noise is  :\t", utils.f1_score(test_y, pred_noise))

あまりうまくパラメータチューニングがうまくいかなかったので、以下のモデルで再定義して学習させた。

model_train = model.model(input_shape=(train_X.shape[1],train_X.shape[2]),
                          output_dim=16,
                          eta = 1e-3,
                          lstm_activation='relu')

出力結果

パラメータチューニングの部分。

==============================================
parameter optimize finished
Best practices are
{'eta': 0.01, 'input_shape': (12, 38832), 'lstm_activation': 'tanh', 'output_dim': 16}
Best score is
0.9812411183781095

学習部分。

In [1]: %run main.py
Using TensorFlow backend.
Main training started
_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
LSTM (LSTM)                  (None, 12, 16)            2486336
_________________________________________________________________
LSTM_2 (LSTM)                (None, 512)               1083392
_________________________________________________________________
dense_1 (Dense)              (None, 188)               96444
_________________________________________________________________
activation_1 (Activation)    (None, 188)               0
=================================================================
Total params: 3,666,172
Trainable params: 3,666,172
Non-trainable params: 0
_________________________________________________________________
None
Epoch 1/10
2018-12-06 03:27:54.704086: I T:\src\github\tensorflow\tensorflow\core\platform\cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2
2018-12-06 03:27:56.541613: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1405] Found device 0 with properties:
name: GeForce GTX 1080 Ti major: 6 minor: 1 memoryClockRate(GHz): 1.62
pciBusID: 0000:01:00.0
totalMemory: 11.00GiB freeMemory: 9.10GiB
2018-12-06 03:27:56.549536: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1484] Adding visible gpu devices: 0
2018-12-06 03:28:12.320406: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:965] Device interconnect StreamExecutor with strength 1 edge matrix:
2018-12-06 03:28:12.325689: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:971]      0
2018-12-06 03:28:12.328773: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:984] 0:   N
2018-12-06 03:28:12.360223: I T:\src\github\tensorflow\tensorflow\core\common_runtime\gpu\gpu_device.cc:1097] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 8793 MB memory) -> physical GPU (device: 0, name: GeForce GTX 1080 Ti, pci bus id: 0000:01:00.0, compute capability: 6.1)
7200/7200 [==============================] - 42s 6ms/step - loss: 0.6850 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.6680 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.6514 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.6353 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.6197 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.6046 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5899 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5757 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5618 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5484 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5353 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5227 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.5104 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4985 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4869 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4757 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4648 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4543 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4440 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4341 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4244 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4151 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.4060 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 17s 2ms/step - loss: 0.3972 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3887 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3804 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3723 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3645 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3570 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 17s 2ms/step - loss: 0.3496 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3425 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3356 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3288 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3223 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3160 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3098 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.3039 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2981 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2924 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2870 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2817 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2765 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2715 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2666 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2619 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2573 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2528 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2485 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2442 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2401 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2361 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2322 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2284 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2248 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2212 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2177 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2143 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2110 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2078 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2047 - acc: 0.9817
score is :       0.03683541734514799
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.2017 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1987 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1958 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1930 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1903 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1876 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1850 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1825 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1800 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1776 - acc: 0.9817
score is :       0.17022550389143884
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1753 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1730 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1708 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1686 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1665 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1644 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1624 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1605 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1586 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1567 - acc: 0.9817
score is :       0.14898506319417848
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1549 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1531 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1514 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1497 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1480 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1464 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1449 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1433 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1418 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1404 - acc: 0.9817
score is :       0.13025780189959293
Epoch 1/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1389 - acc: 0.9817
Epoch 2/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1376 - acc: 0.9817
Epoch 3/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1362 - acc: 0.9817
Epoch 4/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1349 - acc: 0.9817
Epoch 5/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1336 - acc: 0.9817
Epoch 6/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1323 - acc: 0.9817
Epoch 7/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1311 - acc: 0.9817
Epoch 8/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1299 - acc: 0.9817
Epoch 9/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1287 - acc: 0.9817
Epoch 10/10
7200/7200 [==============================] - 18s 2ms/step - loss: 0.1275 - acc: 0.9817
score is :       0.13025780189959293
score with noise is  :   0.13025780189959293

あまりうまく学習しなかった。

まとめ

やったこと

  • 音楽データからラベル付けするモデルを学習させた
  • mp3からデータを読み取った
  • gridsearchを使ってハイパーパラメータの調整した
  • LSTMを使ってみた

考察および感想

かなりシンプルにやってみようと意識してみたつもりだが結局丸一日溶かす結果になってしまった。まだまだkerasには慣れきれてない部分があるようなのでもう少し触れている時間を伸ばしていきたい。
ネットで調べても複数の特徴量を一度に入力するLSTMの実装があまり見当たらなかったり、複数ラベルを求める問題を解いているものがあまりなく、素直に参考にできるコードが少なかったのが意外だった。その分予想外のエラーとかでかなりデバッグに時間を取られてしまった。
とりあえず今回は波形データを12分割するだけのものだったが、LSTMへ入力する際に特徴量の次元を減らしてもよかったかなとは後になって思ったのでこのあたりは余裕あったらやりたい。

学習結果としては設定した損失は減少したものの、出力した値が0に近づいたというだけだった。
設定したモデルがシンプルすぎて正しく特徴量を表現できなかったか、そもそも入力の段階でもう少し工夫したほうがよかったかもしれない。
波形をそのまま入力したほうがもしかしたらうまく行ったかもしれないが時間の制約上そこまで検証できなかった。

Pocket