Propagates through all the cells in dim_indices dimensions.
(dim_indices, conf, cells, c_prev, m_prev, new_output, new_state,
first_call)
| 609 | |
| 610 | |
| 611 | def _propagate(dim_indices, conf, cells, c_prev, m_prev, new_output, new_state, |
| 612 | first_call): |
| 613 | """Propagates through all the cells in dim_indices dimensions. |
| 614 | """ |
| 615 | if len(dim_indices) == 0: |
| 616 | return |
| 617 | |
| 618 | # Because of the way RNNCells are implemented, we take the last dimension |
| 619 | # (H_{N-1}) out and feed it as the state of the RNN cell |
| 620 | # (in `last_dim_output`). |
| 621 | # The input of the cell (H_0 to H_{N-2}) are concatenated into `cell_inputs` |
| 622 | if conf.num_dims > 1: |
| 623 | ls_cell_inputs = [None] * (conf.num_dims - 1) |
| 624 | for d in conf.dims[:-1]: |
| 625 | if new_output[d.idx] is None: |
| 626 | ls_cell_inputs[d.idx] = m_prev[d.idx] |
| 627 | else: |
| 628 | ls_cell_inputs[d.idx] = new_output[d.idx] |
| 629 | cell_inputs = array_ops.concat(ls_cell_inputs, 1) |
| 630 | else: |
| 631 | cell_inputs = array_ops.zeros([m_prev[0].get_shape().as_list()[0], 0], |
| 632 | m_prev[0].dtype) |
| 633 | |
| 634 | last_dim_output = (new_output[-1] |
| 635 | if new_output[-1] is not None else m_prev[-1]) |
| 636 | |
| 637 | for i in dim_indices: |
| 638 | d = conf.dims[i] |
| 639 | if d.non_recurrent_fn: |
| 640 | if conf.num_dims > 1: |
| 641 | linear_args = array_ops.concat([cell_inputs, last_dim_output], 1) |
| 642 | else: |
| 643 | linear_args = last_dim_output |
| 644 | with vs.variable_scope('non_recurrent' if conf.tied else |
| 645 | 'non_recurrent/cell_{}'.format(i)): |
| 646 | if conf.tied and not (first_call and i == dim_indices[0]): |
| 647 | vs.get_variable_scope().reuse_variables() |
| 648 | |
| 649 | new_output[d.idx] = layers.fully_connected( |
| 650 | linear_args, |
| 651 | num_outputs=conf.num_units, |
| 652 | activation_fn=d.non_recurrent_fn, |
| 653 | weights_initializer=(vs.get_variable_scope().initializer or |
| 654 | layers.initializers.xavier_initializer), |
| 655 | weights_regularizer=vs.get_variable_scope().regularizer) |
| 656 | else: |
| 657 | if c_prev[i] is not None: |
| 658 | cell_state = (c_prev[i], last_dim_output) |
| 659 | else: |
| 660 | # for GRU/RNN, the state is just the previous output |
| 661 | cell_state = last_dim_output |
| 662 | |
| 663 | with vs.variable_scope('recurrent' if conf.tied else |
| 664 | 'recurrent/cell_{}'.format(i)): |
| 665 | if conf.tied and not (first_call and i == dim_indices[0]): |
| 666 | vs.get_variable_scope().reuse_variables() |
| 667 | cell = cells[i] |
| 668 | new_output[d.idx], new_state[d.idx] = cell(cell_inputs, cell_state) |
no test coverage detected