Creates an `RNN` specified by RNNCell `cell` and loop function `loop_fn`. **NOTE: This method is still in testing, and the API may change.** This function is a more primitive version of `dynamic_rnn` that provides more direct access to the inputs each iteration. It also provides more cont
(cell,
loop_fn,
parallel_iterations=None,
swap_memory=False,
scope=None)
| 938 | |
| 939 | @tf_export(v1=["nn.raw_rnn"]) |
| 940 | def raw_rnn(cell, |
| 941 | loop_fn, |
| 942 | parallel_iterations=None, |
| 943 | swap_memory=False, |
| 944 | scope=None): |
| 945 | """Creates an `RNN` specified by RNNCell `cell` and loop function `loop_fn`. |
| 946 | |
| 947 | **NOTE: This method is still in testing, and the API may change.** |
| 948 | |
| 949 | This function is a more primitive version of `dynamic_rnn` that provides |
| 950 | more direct access to the inputs each iteration. It also provides more |
| 951 | control over when to start and finish reading the sequence, and |
| 952 | what to emit for the output. |
| 953 | |
| 954 | For example, it can be used to implement the dynamic decoder of a seq2seq |
| 955 | model. |
| 956 | |
| 957 | Instead of working with `Tensor` objects, most operations work with |
| 958 | `TensorArray` objects directly. |
| 959 | |
| 960 | The operation of `raw_rnn`, in pseudo-code, is basically the following: |
| 961 | |
| 962 | ```python |
| 963 | time = tf.constant(0, dtype=tf.int32) |
| 964 | (finished, next_input, initial_state, emit_structure, loop_state) = loop_fn( |
| 965 | time=time, cell_output=None, cell_state=None, loop_state=None) |
| 966 | emit_ta = TensorArray(dynamic_size=True, dtype=initial_state.dtype) |
| 967 | state = initial_state |
| 968 | while not all(finished): |
| 969 | (output, cell_state) = cell(next_input, state) |
| 970 | (next_finished, next_input, next_state, emit, loop_state) = loop_fn( |
| 971 | time=time + 1, cell_output=output, cell_state=cell_state, |
| 972 | loop_state=loop_state) |
| 973 | # Emit zeros and copy forward state for minibatch entries that are finished. |
| 974 | state = tf.where(finished, state, next_state) |
| 975 | emit = tf.where(finished, tf.zeros_like(emit_structure), emit) |
| 976 | emit_ta = emit_ta.write(time, emit) |
| 977 | # If any new minibatch entries are marked as finished, mark these. |
| 978 | finished = tf.logical_or(finished, next_finished) |
| 979 | time += 1 |
| 980 | return (emit_ta, state, loop_state) |
| 981 | ``` |
| 982 | |
| 983 | with the additional properties that output and state may be (possibly nested) |
| 984 | tuples, as determined by `cell.output_size` and `cell.state_size`, and |
| 985 | as a result the final `state` and `emit_ta` may themselves be tuples. |
| 986 | |
| 987 | A simple implementation of `dynamic_rnn` via `raw_rnn` looks like this: |
| 988 | |
| 989 | ```python |
| 990 | inputs = tf.compat.v1.placeholder(shape=(max_time, batch_size, input_depth), |
| 991 | dtype=tf.float32) |
| 992 | sequence_length = tf.compat.v1.placeholder(shape=(batch_size,), |
| 993 | dtype=tf.int32) |
| 994 | inputs_ta = tf.TensorArray(dtype=tf.float32, size=max_time) |
| 995 | inputs_ta = inputs_ta.unstack(inputs) |
| 996 | |
| 997 | cell = tf.compat.v1.nn.rnn_cell.LSTMCell(num_units) |
nothing calls this directly
no test coverage detected