最近のトラックバック

« 2019年3月 | トップページ | 2019年6月 »

2019.05.27

伴奏リズムパターンの評価(主観ですが)を学習させてみた

2月に、クジラ飛行机さんのソフト"テキスト音楽「サクラ」(https://sakuramml.com/)"で

「いつもちがう波」という曲を作りました。Randomselectという関数によって、オルガンパートのリズムが演奏ごとにランダムに変化します。
例えば 

とかいった感じになります。よい部分も悪い部分もありますね。

さて一方、この10連休を使って「Pythonで動かして学ぶ!あたらしい深層学習の教科書(石川聡彦著・翔泳社)」を、ちょうど機械学習の基本のところまで読みました。この章では機械学習のデータサンプルは自動生成されたものでしたが、

「では何かデータを自分で作ってみよう」→「そういえばあの曲で、良い(と思う)部分を学習させたらどうなるか」と思い、以下のことを試しました。

  • 「いつもちがう波」のオルガン伴奏パターンを良し悪し(主観・〇×二択)を機械学習させてみる(教師あり学習)
  • まずは「そんなことが本当にできるか」見たい。次いで私「×」機械「〇」としたもので面白いものを発見したい。
  • サンプルデータが増え、判定者が増えれば、客観的な「良い」ものに近づく可能性もある(が、まだそこまではできない)。
  • 判定対象は、曲中の0.5拍+2小節(8分音符17個分)。ちょうど真ん中14~17秒あたり。
  • 曲を100回聴いて、それぞれ上記判定対象につき「良い」「悪い」判定。独断と偏見。
  • そのうち80曲分のパターンと判定を学習させる→残り20曲分をテストデータとして判定を予測させ、自分の判定と比較する。

最初の80曲を学習データ、残りの20曲をテストデータとした結果は下図の通りです。「当たり」が12曲=正解率60%でした。

例えば図にある最初の行は、|♩ ♩ -♩ |♩ ♩ ♩ ♩ | みたいなリズムで、私は「×」を出し、機械もそれまでの学習から私が「×」を出すだろうと予測しました。一方最後の行は裏拍を使っていてなかなかよいので、私は「〇」を出し、機械もそれまでの学習から私が「〇」を出すだろうと判定しました。そのように一致したのが12曲あったという意味です。

Photo_3

ランダムに学習データとテストデータを分けても正解率はだいたい55~70%です。機械はわかってくれたのか、まあ微妙です。

あと、いろいろこまごまと、ご参考までに。

  • 判定対象のオルガンパートのリズムを「休符=0,音符の始まり=2,前の音符を伸ばす=3」とし、8分音符17個分表示させるよう、「テキスト音楽サクラ」データを修正した。
  • 下図のように音符データが表示されるので、100曲分コピーして、明細100行のcsvデータを作成(→xとする)Photo_4  Photo_5
  • 評価は「0=悪い,1=良い」として1曲ごとに横に並べ、明細1行100列のcsvを作成(→yとする)
  • Colaboratoryにて、
    Python scikit-learnでSVMを利用した。正常終了時のソースコードは以下の通り。

-----------------------------------------------------

import pandas as pd
import numpy as np
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split

list_y = pd.read_csv("20190520_aaw_y.csv").values.tolist()
list_x = pd.read_csv("20190520_aaw_x.csv").values.tolist()

yy = np.array(list_y)
y = yy[0]
x = np.array(list_x)

model = SVC()

train_x = x[:80]
train_y = y[:80]
test_x = x[80:]
test_y = y[80:]

model.fit(train_x, train_y)

pred_y = model.predict(test_x)

print("正答:")
print(test_y)
print("予測:")
print(pred_y)

--------------------------------------------------

  • →結果は以下の通り。「正答」は私の評価で、「予測」は機械が私がこう思うだろうと予想したもの。
    正答:
    [0 0 0 1 1 0 1 0 1 1 0 0 1 0 0 1 1 0 1 1]
    予測:
    [0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 1 0 1]
  • yをnumpyのarrayに変換した時、何故か角カッコが2重についたので、「y = yy[0]」という変換を追加した。
  • 「TypeError: fit() missing 1 required positional argument: 'y'」というエラーの対処にかなり手間取ったが、結局原因は「model = SVC()」の最後のカッコを忘れたことであった。

    以上です。

9日後、続きを書きました。

 

« 2019年3月 | トップページ | 2019年6月 »