kerasでLSTM(RNN)

盛大にハマってしまったので、メモ。

映画の感情分析のサンプルは最初にembedding層があったりしてわかりにくかった。

入力(X_train)はこの場合(データ番号、時間、特徴量の次元)の3階テンソルで、1つのデータとは1つの系列の事かと勘違いしていた。 実際は下のように1つの時系列でも重複させて入力するのが正解らしい。

参考: qiita.com

import keras

def vec_to_df(vec,seqlen=5):
    a=vec
    df=[]

    for i in range(len(a)-seqlen):
        tmp=a[i:i+seqlen]
        df.append(tmp)

    return np.array(df)


import pandas as pd
import numpy as np
import math

# 乱数の係数
random_factor = 0.05
# サイクルあたりのステップ数
steps_per_cycle = 80
# 生成するサイクル数
number_of_cycles = 50

df = pd.DataFrame(np.arange(steps_per_cycle * number_of_cycles + 1), columns=["t"])
df["sin_t"] = df.t.apply(lambda x: math.sin(x * (2 * math.pi / steps_per_cycle)+ random.uniform(-1.0, +1.0) * random_factor))

length_of_sequences = 10
a=np.array(df.t)[:200]
xx=vec_to_df(a,length_of_sequences )
xx=np.reshape(xx,[xx.shape[0],10,1])
X_train=xx

y_train=np.array(df.sin_t)[:X_train.shape[0]]
y_train=np.reshape(y_train,[len(y_train),1])

from keras.models import Sequential  
from keras.layers.core import Dense, Activation  
from keras.layers.recurrent import LSTM


in_out_neurons = 1
hidden_neurons = 300

model = Sequential()  
model.add(LSTM(hidden_neurons, batch_input_shape=(None, 10,1),return_sequences=False))
model.add(Dense(in_out_neurons))  
model.add(Activation("linear"))  

model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, batch_size=1, nb_epoch=10, validation_split=0.05) 

ちなみに手を付けたキッカケは前にも書いたけど、和音の評価で、X_tとして和音の適当な表現の入力を与えて、オートエンコーダーの特徴量と比較することで評価できないかとおもうけど、手持ちのサンプルを連結を考えず縦のみ(280和音程度)で、ただのNN+AEで低次元にしてみてもあまり良くない様子。ちなみにtsneで2次元に射影すると良く似た和音がまとまっている。 今のところ一番マトモな音を生成しているのが、randomforestの旋律予測と、内声予測(和音の評価)(全てcategorical変数)を手動で重み付けしたもので、前に台形型の特徴量を作ってたのが何って感じですよorz ちなみに、和声の回答集は買ったけど入力する気力が。。。。

作曲家総選挙2016

というものをtwitterでやっていて

twitter.com

言語処理のお勉強のために、作曲家名の情報を知らないとして抽出できないか試してみた。

word2vecとクラスタリングとかもやってみたけどあまりうまく行かず、良かったのはtf-idfで重み付けして、ソートした最上位の単語を抽出。 前処理は ・Mecab分かち書きストップワード除去 ・1文字の単語除去 ・記号,URLを除去

くらい。 変な文字が多いからか、python文字コード関係でちょっと虐められました。 あと、最後の結果からひらがな・漢字を含む単語は除去。作曲家名はカタカナなので卑怯だが、なくてもまずまずの結果だった。

選挙なので、抽出した単語集計した結果(n>=3) f:id:biones:20160819192225p:plain

敬愛するモーリス・ラヴェル先生が一位!(主催者らしいが!) クヴァンツとか私も知らない作曲家も抽出できてるし、まずまずなのかなと。 フォロワ作曲弦楽四重奏 D-mollとか・・・無いですね。

LiNGAMモデル(因果推論)

因果推論周辺について調べた。

構造方程式モデルによる因果推論: 因果構造探索に関する最近の発展 http://www.ar.sanken.osaka-u.ac.jp/~sshimizu/papers/BSJ2012_Tutorial_final_web.pdf

ガウス性を用いた線形非巡回なデータ生成過程部分の発見と同定 https://kaigi.org/jsai/webprogram/2012/pdf/258.pdf

ざっくり書くと、xを確率変数を縦にならべたベクトルとして,非巡回かつ潜在変数なしで、xを並び替えてBを下三角行列、eを非正規分布の確率ノイズとして x=Bx+e  とかけるようなモデル。 結局、correlation-faithfulness の仮定がいるのか、チェックはどうするのか、eが非ガウスならOKなのかよく分からなかった。 とりあえず、Rのpcalgというパッケージの中のLINGAMで試してみた。

#1から2
x1=runif(N)-0.5
x2=x1*0.7+runif(N)-0.5
LINGAM(cbind(x1,x2))

$B
         [,1] [,2]
[1,] 0.000000    0
[2,] 1.582669    0

$Adj
      [,1]  [,2]
[1,] FALSE  TRUE
[2,] FALSE FALSE
#2から1
x2=runif(N)-0.5
x1=2*x2+runif(N)-0.5
LINGAM(cbind(x1,x2))

LINGAM(cbind(x1,x2))
$B
     [,1]     [,2]
[1,]    0 1.738995
[2,]    0 0.000000

$Adj
      [,1]  [,2]
[1,] FALSE FALSE
[2,]  TRUE FALSE
#1から2へガウスノイズ
x1=runif(N)-0.5
x2=x1*1.5+rnorm(N)
LINGAM(cbind(x1,x2))

$B
         [,1] [,2]
[1,] 0.000000    0
[2,] 1.845528    0

$Adj
      [,1]  [,2]
[1,] FALSE  TRUE
[2,] FALSE FALSE

ガウスでも多少は当たる!? (上の例で160/200回くらいの正解率)

モデル妥当性のチェックも機械学習のcross-validationみたいなのが無いので、良く分からない。

• ブートストラップ法によるアプローチ: – サンプルサイズが小さいか非ガウス性が小さいかすれば、ブートスト ラップ標本についてのLiNGAMの結果は大きくばらつくはず

ふーむ。。。。

2声の自動生成

4声は悲惨だが2声の対旋律付けなら酷いレベルではない・・・とおもう。 ドフェミファソファミレの繰り返しのバスに対してソプラノの対旋律を生成した(両方生成する事もできる)。

www.youtube.com

G7でファ→ミの限定進行など和声っぽい音の動きが見られた。

ハ長調ではなくて旋法(ドリアとか)だと面白いのだけど、印刷物含めデータが多くないので、いずれ。

f:id:biones:20160307215903j:plain

上の画像の台形の音の音程について、(前の和音のMIDI距離,ソプラノの増分,テノールの増分)を特徴量としている。 この例だと(17,1,2)というベクトル。 探索方法はとりあえずで、焼きなまし法。 ドレミファソラシドという旋律とドの初期音からこのスケールを導くためにはひとつ前の和音も考慮すればいい(未実装)。

4声にしたときに、縦の響きについては流石に(台形の特徴量で)線形だとダメで(この特徴量だとG7の時は2度がOKみたいな状況からXORパターンがでてくると思われるから)、

(1)台形を一つふやす(4C3通り)
(2)カーネル法を使う

もっそり実験しようと思います。

3/23追記 1classSVM(と各種カーネル)でも4声は微妙。特徴量の次元が台形だけでも510次元,手持ちの課題を全部入力しても500和音程度にしかならないので(6000円の解答集を買えば3000和音くらいにはなる?)、実際の楽譜を使えるような方法に切り替えたほうがいいのだろうか。 転移音(和声外の音)や、4声(+旋律)→5声→3声みたいに特徴量の次元が不定で、そういうデータを上手く扱う方法はないのだろうか(ノンパラメトリックベイズとか、RNN?)。

kernelPCA(500→10〜200次元くらいまで落とす)→kmeans でも微妙。教師なし学習の検討はできないので、相変わらず生成して私の耳で検証(楽で良いのだが)。異常検知の本とか買うと良いのだろーか。。。 いや、多分和声の解答集を買う事ですね。。。。

音楽データ分析(2)

島岡氏の和声の本のサンプルやら,図書館で借りてきた本の解答を手動でノーテーションソフトに入力して,music21等を使い、4声になっていない部分を補完。

和音の声部の横の流れはとりあえず考えないで、入力した音の基準で和音の縦の響きの「良さ」を計算してみる。 最大エントロピー法で、Xを和音,x_i∈Xを音程と(鍵盤の距離で0-34して
{p(X)=\frac{e^{\sum_{k} \omega * f_k(x) }}{Z} }
というモデルを考える。 素性fは音程があれば1そうでなければ0。重みωは35次元で、L2ノルムの制約つき(ω2=1)。 和音に出てくる2音の音程(つまり4音なら4C2=6パターン)のXω/(2度のパターン数)をスコアとしました。 入力した和音は4音350くらい。全部C-major。

f:id:biones:20160219174009p:plain 音程のスコアの分布。x軸はMIDIの距離(オクターブ→12)

無事オクターブ(12),5度(7),3度(3,4)あたりが高くなった。

本当は音程ではなく音そのものでやりたかったのだけど(低いド-ミと高いド-ミの意味はだいぶ違うと思うから)、思っていたよりかなりデータが手に入りにくいので、低次元な方向でやりたいと思う。 次は隣り合った2和音について、「台形」の(前の和音の2声部の縦の音程、下の声部が変化分,上の声部の変化分)を素性としてやりたいと思う。これだと連続・平達5度等が考慮される・・・ハズ。

XTを教師データの音,x0∈XTを探索を開始する和音,Xを探索パラメータωに基づいて生成された音, scoreωをXに対するωで評価したスコアとして scoreω(X(x0,ω))とscore_ω(XT)の差をlossとしてωを最適化する、探索を組み込んだ将棋のボナンザメソッドみたいな事できないだろーか。。。

転調は調を隠れ変数、転移音は転移音用の素性を用意すれば、大分実際の曲のデータを使えるようになる・・・と思う。

pandas,numpy.matrix,listの行き来はまだまだ慣れないですorz