はい、セル出力は非表示状態と同じです。LSTMの場合、次の図に示すように、これはタプル(の2番目の要素LSTMStateTuple
)の短期間の部分です。
ただしtf.nn.dynamic_rnn
、の場合、シーケンスが短い(引数)と、返される状態が異なる場合がありますsequence_length
。この例を見てください:
n_steps = 2
n_inputs = 3
n_neurons = 5
X = tf.placeholder(dtype=tf.float32, shape=[None, n_steps, n_inputs])
seq_length = tf.placeholder(tf.int32, [None])
basic_cell = tf.nn.rnn_cell.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, sequence_length=seq_length, dtype=tf.float32)
X_batch = np.array([
# t = 0 t = 1
[[0, 1, 2], [9, 8, 7]], # instance 0
[[3, 4, 5], [0, 0, 0]], # instance 1
[[6, 7, 8], [6, 5, 4]], # instance 2
[[9, 0, 1], [3, 2, 1]], # instance 3
])
seq_length_batch = np.array([2, 1, 2, 2])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
outputs_val, states_val = sess.run([outputs, states],
feed_dict={X: X_batch, seq_length: seq_length_batch})
print(outputs_val)
print()
print(states_val)
ここで、入力バッチには4つのシーケンスが含まれており、そのうちの1つは短く、ゼロが埋め込まれています。実行すると、次のようになります。
[[[ 0.2315362 -0.37939444 -0.625332 -0.80235624 0.2288385 ]
[ 0.9999524 0.99987394 0.33580178 -0.9981791 0.99975705]]
[[ 0.97374666 0.8373545 -0.7455188 -0.98751736 0.9658986 ]
[ 0. 0. 0. 0. 0. ]]
[[ 0.9994331 0.9929737 -0.8311569 -0.99928087 0.9990415 ]
[ 0.9984355 0.9936006 0.3662448 -0.87244385 0.993848 ]]
[[ 0.9962312 0.99659646 0.98880637 0.99548346 0.9997809 ]
[ 0.9915743 0.9936939 0.4348318 0.8798458 0.95265496]]]
[[ 0.9999524 0.99987394 0.33580178 -0.9981791 0.99975705]
[ 0.97374666 0.8373545 -0.7455188 -0.98751736 0.9658986 ]
[ 0.9984355 0.9936006 0.3662448 -0.87244385 0.993848 ]
[ 0.9915743 0.9936939 0.4348318 0.8798458 0.95265496]]
...確かにstate == output[1]
、完全なシーケンスとstate == output[0]
短いシーケンスの両方を示しています。またoutput[1]
、このシーケンスのゼロベクトルです。LSTMおよびGRUセルについても同様です。
したがって、これはゼロを無視しstate
て、最後の実際の RNN状態を保持する便利なテンソルです。output
テンソルは、出力の保持している全ての細胞を、それがゼロを無視しません。それが両方を返す理由です。