def posterior_marginals(self, observations, name=None):
with tf.name_scope(name or "<STR_LIT>"):<EOL><INDENT>with tf.control_dependencies(self._runtime_assertions):<EOL><INDENT>observation_tensor_shape = tf.shape(input=observations)<EOL>with self._observation_shape_preconditions(observation_tensor_shape):<EOL><INDENT>observation_batch_shape = observation_tensor_shape[<EOL>:-<NUM_LIT:1> - self._underlying_event_rank]<EOL>observation_event_shape = observation_tensor_shape[<EOL>-<NUM_LIT:1> - self._underlying_event_rank:]<EOL>batch_shape = tf.broadcast_dynamic_shape(observation_batch_shape,<EOL>self.batch_shape_tensor())<EOL>log_init = tf.broadcast_to(self._log_init,<EOL>tf.concat([batch_shape,<EOL>[self._num_states]],<EOL>axis=<NUM_LIT:0>))<EOL>log_transition = self._log_trans<EOL>observations = tf.broadcast_to(observations,<EOL>tf.concat([batch_shape,<EOL>observation_event_shape],<EOL>axis=<NUM_LIT:0>))<EOL>observation_rank = tf.rank(observations)<EOL>underlying_event_rank = self._underlying_event_rank<EOL>observations = distribution_util.move_dimension(<EOL>observations, observation_rank - underlying_event_rank - <NUM_LIT:1>, <NUM_LIT:0>)<EOL>observations = tf.expand_dims(<EOL>observations,<EOL>observation_rank - underlying_event_rank)<EOL>observation_log_probs = self._observation_distribution.log_prob(<EOL>observations)<EOL>log_adjoint_prob = tf.zeros_like(log_init)<EOL>def forward_step(log_previous_step, log_prob_observation):<EOL><INDENT>return _log_vector_matrix(log_previous_step,<EOL>log_transition) + log_prob_observation<EOL><DEDENT>log_prob = log_init + observation_log_probs[<NUM_LIT:0>]<EOL>forward_log_probs = tf.scan(forward_step, observation_log_probs[<NUM_LIT:1>:],<EOL>initializer=log_prob,<EOL>name="<STR_LIT>")<EOL>forward_log_probs = tf.concat([[log_prob], forward_log_probs], axis=<NUM_LIT:0>)<EOL>def backward_step(log_previous_step, log_prob_observation):<EOL><INDENT>return _log_matrix_vector(log_transition,<EOL>log_prob_observation + log_previous_step)<EOL><DEDENT>backward_log_adjoint_probs = tf.scan(<EOL>backward_step,<EOL>observation_log_probs[<NUM_LIT:1>:],<EOL>initializer=log_adjoint_prob,<EOL>reverse=True,<EOL>name="<STR_LIT>")<EOL>total_log_prob = tf.reduce_logsumexp(<EOL>input_tensor=forward_log_probs[-<NUM_LIT:1>], axis=-<NUM_LIT:1>)<EOL>backward_log_adjoint_probs = tf.concat([backward_log_adjoint_probs,<EOL>[log_adjoint_prob]], axis=<NUM_LIT:0>)<EOL>log_likelihoods = forward_log_probs + backward_log_adjoint_probs<EOL>marginal_log_probs = distribution_util.move_dimension(<EOL>log_likelihoods - total_log_prob[..., tf.newaxis], <NUM_LIT:0>, -<NUM_LIT:2>)<EOL>return categorical.Categorical(logits=marginal_log_probs)<EOL><DEDENT><DEDENT><DEDENT>
Compute marginal posterior distribution for each state.

        This function computes, for each time step, the marginal
        conditional probability that the hidden Markov model was in
        each possible state given the observations that were made
        at each time step.
        So if the hidden states are `z[0],...,z[num_steps - 1]` and
        the observations are `x[0], ..., x[num_steps - 1]`, then
        this function computes `P(z[i] | x[0], ..., x[num_steps - 1])`
        for all `i` from `0` to `num_steps - 1`.

        This operation is sometimes called smoothing. It uses a form
        of the forward-backward algorithm.

        Note: the behavior of this function is undefined if the
        `observations` argument represents impossible observations
        from the model.

        Args:
          observations: A tensor representing a batch of observations
            made on the hidden Markov model.  The rightmost dimension of this tensor
            gives the steps in a sequence of observations from a single sample from
            the hidden Markov model. The size of this dimension should match the
            `num_steps` parameter of the hidden Markov model object. The other
            dimensions are the dimensions of the batch and these are broadcast with
            the hidden Markov model's parameters.
          name: Python `str` name prefixed to Ops created by this class.
            Default value: "HiddenMarkovModel".

        Returns:
          posterior_marginal: A `Categorical` distribution object representing the
            marginal probability of the hidden Markov model being in each state at
            each step. The rightmost dimension of the `Categorical` distributions
            batch will equal the `num_steps` parameter providing one marginal
            distribution for each step. The other dimensions are the dimensions
            corresponding to the batch of observations.

        Raises:
          ValueError: if rightmost dimension of `observations` does not
          have size `num_steps`.