読者です 読者をやめる 読者になる 読者になる

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 ちなみに、和声の回答集は買ったけど入力する気力が。。。。