RNNこれくしょんでLSTM使おうと思って失敗した話をMLCTでした
RNNこれくしょんを早速人柱になろうじゃないかと使ってみた
本来であれば結果や内部でどんな表現を獲得してるのかを話したかったが、 動くまでがものすごくツラく、しかもまだ間違ってるっぽい
しかし、後世の人たちの為にセグフォで落ちないところまでどうやったかをまとめておく
ただし、全てのデータが必ずこのやり方で落ちないとはかぎらない
公式のwikiに書かれているMLPのレイヤー数を変更したりしても落ちるので注意
入力データについて
※LSTMは自然言語処理なところで流行っているのでfeatureの日本語は「素性」とします
サンプルにあるrecall.jsonで動かす場合入力データはpythonのstructでpackされている(gen_recall.pyのwrite_binay参照)
素性が01の二値である場合(jsonの設定のdata/typeにserise_int_binaryを指定した)これでいいようだ
今回は文中の単語や文字をword2vecを用いて分散表現にしたのち、各次元を一つの素性として与えている
このときはどうやらserise_asciiを選択するよう(任意の実数値を読み込めるのがこれだけだった)で
おそらくこれでいい
正解ラベルも二値分類なら0-1でいいがn値なら正解だけを1、他を0にしたベクトル行×データセット分の列とすれば読み込めた
次に読み込ませるにはこれを各値ごとに1行割り当てる必要がある
実際に読み込んでいるscr/core/io.hppではfscanf("%f", &data[i])として読み込んだあと各値を
node->x_all[0][i][j]に入れていた(nodeはsrc/core/node.hppで定義されいるmsadow/tensorのTensorContainer。余談だが、3重ループのコメントアウトやインデントのされ方的に3つ目の次元も使おうとしていたっぽい。ひょっとするとこれをシーケンスの長さに利用する予定だったのかも)
jsonの設定について
こいつもまた厄介
data/n_{train, test}で学習、テストのデータ件数を指定するが、こいつはΣn_i * l_iとなる
n_iはi番目のデータ、l_iはn_iのシーケンスの長さ
これはもちろん人力計算
learning/n_timeは公式でBPTTの逆伝播ステップ数となっている
ん?固定長なのかまさか?
というわけで再び入力データ
n_timeが固定っぽいので、短いデータはどうすんだ?となった
確かに公式wikiのサンプルはいずれも固定長だ(なんでRNNのサンプルにMNISTのデータとか使ったんだろ?)
本当はその辺の処理もどうしてるかソース読まないかんのだけど、今回はとりあえず よろしくやってくれるだろうと信じて、0のベクトルを埋めてみた
そしてその結果うまく行かなかったのでおそらくここの扱いが間違ってる
平均取る時に確実にこのゼロの部分も計算に入れられてるね。。
その他
データ件数、素性数、BPTTのステップ数など、間違えて入力データと整合性がとれないと確実にセグフォになります
人力計算が含まれているのでかなりツラいです
データと設定の整合性がとれていないと動かないのは下手に中途半端な動作をしてマズい結果を出すよりはいいと思うのですが、何処と何処の整合性がとれていないかは出して欲しいですw
さて、その後の飲み会でも話題になったDevDataですが、このRNNこれくしょんはいい感じにそれを体現してるな、と思いました
最終更新が1ヶ月前と不穏ですが、せっかくOSSとしてGithubに上がっているのだから積極的な参加でよくしていくことが求められます
研究レベルで新しいこと(LSTMは97年。忘却ゲート入れたのも00年ですが)は、優れたライブラリの登場によって応用研究やビジネス利用にも繋がっていきます
是非、数年後に「このRNNこれくしょんはワシが育てた」とか言えるにはもってこいのOSSだとおもいますよ!
実装への貢献だけじゃなく、ドキュメントの充実でも、英語化でも何でもいいと思います