LSTMの可変長系列入力について

2,029 views
Skip to first unread message

吴益明

unread,
Aug 31, 2016, 12:07:45 AM8/31/16
to Chainer Japanese User Group
今回のリリースで、LSTM functionが可変長系列入力をサポートしたとありますが、どう使えるようになったのかいまひとつ解りません。

functionではなくLSTM Linkを使う場合の話ですが、例えば標準のRNNを書く場合、
従来のLSTM層では、shape=(バッチ数,入力次元数)のVariableを(ループを回しながら)一つずつ入力し、
系列の長さと同じ数のshape=(バッチ数,出力次元数)のVariableが得られる、という流れになると思うのですが、
これが一つずつ入力せずに済んで、shape=(バッチ数,系列長,入力次元数)のVariableがLSTM Linkに入力されれば、
RNNの要領で時間方向に沿って計算され、
出力系列も一つのVariableにまとめられた形になる、という風になったのでしょうか。
こうなればいいなと強く希望していたので・・・誤解でしたらすみません。

あと、従来のLSTM層の使い方についてですが、
出力系列が複数のVariableという形になるのですが、
この出力に対してaverage_poolingをしたい場合などに、これまでの勾配情報を保持したまま、
一つのVariableに結合(?)することは可能なのでしょうか?

お詳しい方がいれば、ご教授お願いしたいです。

Yuya Unno

unread,
Sep 2, 2016, 1:14:56 AM9/2/16
to 吴益明, Chainer Japanese User Group
サンプルがないのでちょっとわかりにくいかと思いますが、簡単に説明します(今、不具合で最新のドキュメントが公開されていないことに気づきました)。
今までLSTMは同じバッチサイズの入力ベクトル(xとします)を入れていましたが、可変長の入力を扱うときは単調減少する入力を扱えます。
短いバッチサイズの入力があった場合、LSTMの内部状態のhやcは、その分だけ更新されます。
例えばlen(x1) = 3, len(x2) = 2のとき、lstm(x1)でミニバッチ数3の内部状態ができ、そのあとlstm(x2)を呼ぶとh[0:2]とc[0:2]の領域だけ更新されます。

以下のissueを参考にしてください。

これを利用するには、まず入力シーケンスを長さの長い順に並べ替えてください。
そのあと転置をとって、ミニバッチの単語シーケンスにしてください。
転置のための関数として、functions.transpose_sequenceを利用してください。
hやcの次元の順番を変えるために、functions.permutate関数を利用してください。

ちゃんと動作確認をとってませんが、以下の様な感じで使えます。

sequences = [
  [w1, w2, w3, w4],  # "w1w2w3w4" という系列、以下同じ
  [w5, w6, w7],
  [w8, w9]
]
words = transpose_sequnce(sequences)  # wordsは[[w1, w5, w8], [w2, w6, w9], [w3, w7], [w4]]になる
for w in words:
    lstm(w)
h = lstm.h    # h.data.shape == (3,)


出力系列も一つのVariableにまとめられた形になる、という風になったのでしょうか。
こちらは別PRで進行中で、近々マージされると思います。
特にcuDNNのRNNを利用するので、速度が今までのChainerの数倍になると思います。



2016年8月31日 13:07 吴益明 <wuyim...@hotmail.com>:

--
このメールは Google グループのグループ「Chainer Japanese User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには chainer-jp+unsubscribe@googlegroups.com にメールを送信してください。
このグループに投稿するには chain...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/chainer-jp/7e62d033-c0db-42ce-9cde-9d0dc47b7251%40googlegroups.com にアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

Message has been deleted

Yuya Unno

unread,
Sep 9, 2016, 12:02:01 PM9/9/16
to 吴益明, Chainer Japanese User Group
はい、そうです。
今まではwhereでマスクするなど以外の方法はありませんでしたが、この方法ですと無駄な計算が発生します(-1の部分も一度計算してから消されるため)。
新しい方法ですと、必要な部分だけ計算するようになります。

2016年9月4日 14:34 吴益明 <wuyim...@hotmail.com>:
返信遅れて申し訳ありません。

ご返答ありがとうございました!
自分はこのケースを処理する場合、まず入力の末尾に適当な値を入れて同じ長さに揃えてから転置し、
ターゲット値はignore_label=-1を入れて走らせていました。
たしか、where関数で不要な状態更新を避ける手法もありましたね。
今のところは、そのあたりの手間が省けるようになったということですね?

在 2016年9月2日星期五 UTC+8下午1:14:56,Yuya Unno写道:
このグループから退会し、グループからのメールの配信を停止するには chainer-jp+...@googlegroups.com にメールを送信してください。

このグループに投稿するには chain...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/chainer-jp/7e62d033-c0db-42ce-9cde-9d0dc47b7251%40googlegroups.com にアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

--
このメールは Google グループのグループ「Chainer Japanese User Group」に登録しているユーザーに送られています。
このグループから退会し、グループからのメールの配信を停止するには chainer-jp+unsubscribe@googlegroups.com にメールを送信してください。
このグループに投稿するには chain...@googlegroups.com にメールを送信してください。
このディスカッションをウェブ上で閲覧するには https://groups.google.com/d/msgid/chainer-jp/2183601f-2e72-414a-adbf-408d23e0c711%40googlegroups.com にアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。

Reply all
Reply to author
Forward
0 new messages