Calculate one step of a dynamic RNN minibatch. Returns an (output, state) pair conditioned on `sequence_length`. When skip_conditionals=False, the pseudocode is something like: if t >= max_sequence_length: return (zero_output, state) if t < min_sequence_length: return call_cell()
(time,
sequence_length,
min_sequence_length,
max_sequence_length,
zero_output,
state,
call_cell,
state_size,
skip_conditionals=False)
| 167 | |
| 168 | # pylint: disable=unused-argument |
| 169 | def _rnn_step(time, |
| 170 | sequence_length, |
| 171 | min_sequence_length, |
| 172 | max_sequence_length, |
| 173 | zero_output, |
| 174 | state, |
| 175 | call_cell, |
| 176 | state_size, |
| 177 | skip_conditionals=False): |
| 178 | """Calculate one step of a dynamic RNN minibatch. |
| 179 | |
| 180 | Returns an (output, state) pair conditioned on `sequence_length`. |
| 181 | When skip_conditionals=False, the pseudocode is something like: |
| 182 | |
| 183 | if t >= max_sequence_length: |
| 184 | return (zero_output, state) |
| 185 | if t < min_sequence_length: |
| 186 | return call_cell() |
| 187 | |
| 188 | # Selectively output zeros or output, old state or new state depending |
| 189 | # on whether we've finished calculating each row. |
| 190 | new_output, new_state = call_cell() |
| 191 | final_output = np.vstack([ |
| 192 | zero_output if time >= sequence_length[r] else new_output_r |
| 193 | for r, new_output_r in enumerate(new_output) |
| 194 | ]) |
| 195 | final_state = np.vstack([ |
| 196 | state[r] if time >= sequence_length[r] else new_state_r |
| 197 | for r, new_state_r in enumerate(new_state) |
| 198 | ]) |
| 199 | return (final_output, final_state) |
| 200 | |
| 201 | Args: |
| 202 | time: int32 `Tensor` scalar. |
| 203 | sequence_length: int32 `Tensor` vector of size [batch_size]. |
| 204 | min_sequence_length: int32 `Tensor` scalar, min of sequence_length. |
| 205 | max_sequence_length: int32 `Tensor` scalar, max of sequence_length. |
| 206 | zero_output: `Tensor` vector of shape [output_size]. |
| 207 | state: Either a single `Tensor` matrix of shape `[batch_size, state_size]`, |
| 208 | or a list/tuple of such tensors. |
| 209 | call_cell: lambda returning tuple of (new_output, new_state) where |
| 210 | new_output is a `Tensor` matrix of shape `[batch_size, output_size]`. |
| 211 | new_state is a `Tensor` matrix of shape `[batch_size, state_size]`. |
| 212 | state_size: The `cell.state_size` associated with the state. |
| 213 | skip_conditionals: Python bool, whether to skip using the conditional |
| 214 | calculations. This is useful for `dynamic_rnn`, where the input tensor |
| 215 | matches `max_sequence_length`, and using conditionals just slows |
| 216 | everything down. |
| 217 | |
| 218 | Returns: |
| 219 | A tuple of (`final_output`, `final_state`) as given by the pseudocode above: |
| 220 | final_output is a `Tensor` matrix of shape [batch_size, output_size] |
| 221 | final_state is either a single `Tensor` matrix, or a tuple of such |
| 222 | matrices (matching length and shapes of input `state`). |
| 223 | |
| 224 | Raises: |
| 225 | ValueError: If the cell returns a state tuple whose length does not match |
| 226 | that returned by `state_size`. |
no test coverage detected