RecurrentShop について調べる
RecurrentShop: Keras 上で RNN をうまく使うためのフレームワーク。
Decoder や Readout を簡単に実装できるようにしたよというやつ。
誤りなどありましたらご指摘いただけますと幸いです。
RNNCell
RecurrentShop での RNN は下図のような構成になっているようです。
参考: https://github.com/datalogai/recurrentshop/blob/master/recurrentshop/basic_cells.py
(正確には、入力:[x, h_tm] 出力:[h, h] となっているのですが、入出力の各 index:1 の要素(隠れ層入出力)は RecurrentSequential 内でよしなにぐるぐる回されるので外から見えるのは、入力:x, 出力:h となるようです。)
私が見慣れた RNN だと、出力が次の入力に再入力される、つまり出力と入力は次元数が同じネットワークとなるのですが、そのようなネットワークを作る場合後述する readout を使う必要がありそうです。
LSTM や GRU の場合もちゃんと読んでいないですがおそらく同様です。
RecurrentSequential
rnn = RecurrentSequential(unroll=False, return_sequences=False)
rnn.add(SimpleRNNCell(10, input_dim=5))
rnn.add(LSTMCell(12))
rnn.add(Dense(5))
rnn.add(GRU(8))
# rnn can now be used as regular Keras Recurrent layer.
rnn = RecurrentSequential(unroll=False, return_sequences=False)
rnn.add(SimpleRNNCell(10, input_dim=5))
rnn.add(LSTMCell(12))
rnn.add(Dense(5))
rnn.add(GRU(8))
# rnn can now be used as regular Keras Recurrent layer.
RNN の Cell もしくは通常の Cell をつなぎ合わせて RNN を作れます。
https://github.com/datalogai/recurrentshop/blob/master/recurrentshop/engine.py#L987 あたりのコードを読むと、下図のようにつながるようです。
(各セルの中のベクトルの流れは不正確です。http://qiita.com/KojiOhki/items/89cd7b69a8a6239d67ca あたりを読んで下さい。)
計算はある時刻tの中で下から上まですべて計算されます。
(各 RNN のセルは、下から渡ってきた入力と、時刻t-1の隠れ層の状態から出力を決定し上のノードにそれを伝えます)
つまり、破線で囲われた多層 RNN が一つの RNN セルのように振る舞います。
ネストした RNN
ちなみに上の「」は実はその通りのことができて、 RecurrentSequential を一つのセルに変換できます。
それによってネストした RNN を作ることができます。
rnn1 = RecurrentSequential()
rnn1.add(....)
rnn1.add(....)
rnn1_cell = rnn1.get_cell() ## ここ!
rnn2 = RecurrentSequential()
rnn2.add(rnn1_cell)
rnn2.add(...)
Decoder
https://github.com/datalogai/recurrentshop/blob/master/docs/decoder.md
単一のベクトルから時系列を生成する RecurrentNetwork のことです。
RecurrentShop では Attention などに対応するため時系列を入力する方法もあるそうですがちゃんと見てません。
RecurrentSequential に decode=True
を与えることで Decoder にできます。この場合出力する時系列は無限につづいてしまうので output_length を指定する必要があります。
rnn = RecurrentSequential(decode=True, output_length=10)
rnn.add(SimpleRNNCell(25, input_dim=20))
x = Input((20,))
y = rnn(x)
print(K.int_shape(y)) # >> (None, 10, 25)
上の例では、(20次元) でバッチサイズは任意の入力を受け取って、 (バッチサイズ任意, 長さ10, 25次元) の時系列を出力します。
Decoder への入力
コードを読んだ感じ、状態だけをぐるぐる回しているようにみえるけどいまいちわからない。要調査
preprocessed_input = self.preprocess_input(inputs, training=None)
constants = self.get_constants(inputs, training=None)
if self.decode:
initial_states.insert(0, inputs)
preprocessed_input = K.zeros((1, self.output_length, 1))
input_length = self.output_length
else:
input_length = input_shape[1]
if self.decode:
model_input = states
else:
model_input = [inputs] + states
Readout
https://github.com/datalogai/recurrentshop/blob/master/docs/readout.md
RNN の出力を次時刻の入力に入れます。
rnn = RecurrentSequential(readout='add')
rnn.add(LSTMCell(10, input_dim=10))
rnn.add(GRUCell(10))
rnn.add(SimpleRNNCell(10))
時刻tの LSTM への入力は、外から与えられた入力と時刻t-1のRNNの出力の和になるということです。
(readout の Input と本来の Input の計算(add, mull, avg..)は element-wise に行われます。 add([1,2,3], [1,1,1])
は [2,3,4]
となります)
ちなみに https://github.com/farizrahman4u/seq2seq の seq2seq は readout を使っていないのでいわゆる巷でいう seq2seq とやや違う構造になっている気がします。
teacher_force
https://github.com/datalogai/recurrentshop/blob/master/docs/teacher_force.md
学習時に readout の入力を ground_truth に差し替えることができるようです。
rnn = RecurrentSequential(readout='add', teacher_force=True, return_sequences=True)
rnn.add(LSTMCell(10, input_dim=10))
rnn.add(LSTMCell(10))
rnn.add(LSTMCell(10))
rnn.add(Activation('softmax'))
x = Input((7, 10))
y_true = Input((7, 10)) # This is where you feed the ground truth values
y = rnn(x, ground_truth=y_true)
model = Model([x, y_true], y)
model.compile(loss='categorical_crossentropy', optimizer='sgd')
# Training
X_true = np.random.random((32, 7, 10))
Y_true = np.random.random((32, 7, 10))
model.fit([X_true, Y_true], Y_true) # Note that Y_true is part of both input and output
# Prediction
X = np.random.random((32, 7, 10))
model.predict(X) # >> Error! the graph still has an input for ground truth..
zeros = np.zeros((32, 7, 10)) # Need not be zeros.. any array of same shape would do
model.predict([X, zeros])
生成時に適当な行列を与えます。
生成時は下記のコードの通り ground_truth は使われないようなっているようです。
readout = K.in_train_phase(K.switch(counter[0], ground_truth_slice, readout), readout)
unroll
https://keras.io/ja/layers/recurrent/
Keras に標準である機能なようです。
unroll: 真理値(デフォルトはFalse).Trueなら,ネットワークは展開され, そうでなければシンボリックループが使われます. 展開はよりメモリ集中傾向になりますが,RNNをスピードアップできます. 展開は短い系列にのみ適しています.
Author And Source
この問題について(RecurrentShop について調べる), 我々は、より多くの情報をここで見つけました https://qiita.com/halhorn/items/27ed5c0aac7adf7941e7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .