tensorflow_probability/python/mcmc/nuts.py
def loop_tree_doubling(self, step_size, momentum_state_memory,
                         current_step_meta_info, iter_, initial_step_state,
                         initial_step_metastate):
    """Main loop for tree doubling."""
    with tf.name_scope('loop_tree_doubling'):
      batch_shape = prefer_static.shape(current_step_meta_info.init_energy)
      direction = tf.cast(
          tf.random.uniform(
              shape=batch_shape,
              minval=0,
              maxval=2,
              dtype=tf.int32,
              seed=self._seed_stream()),
          dtype=tf.bool)

      tree_start_states = tf.nest.map_structure(
          lambda v: tf.where(  # pylint: disable=g-long-lambda
              _rightmost_expand_to_rank(direction, prefer_static.rank(v[1])),
              v[1], v[0]),
          initial_step_state)

      directions_expanded = [
          _rightmost_expand_to_rank(
              direction, prefer_static.rank(state))
          for state in tree_start_states.state
      ]

      integrator = leapfrog_impl.SimpleLeapfrogIntegrator(
          self.target_log_prob_fn,
          step_sizes=[
              tf.where(d, ss, -ss)
              for d, ss in zip(directions_expanded, step_size)
          ],
          num_steps=self.unrolled_leapfrog_steps)

      [
          candidate_tree_state,
          tree_final_states,
          final_not_divergence,
          continue_tree_final,
          energy_diff_tree_sum,
          momentum_tree_cumsum,
          leapfrogs_taken
      ] = self._build_sub_tree(
          directions_expanded,
          integrator,
          current_step_meta_info,
          # num_steps_at_this_depth = 2**iter_ = 1 << iter_
          tf.bitwise.left_shift(1, iter_),
          tree_start_states,
          initial_step_metastate.continue_tree,
          initial_step_metastate.not_divergence,
          momentum_state_memory)

      last_candidate_state = initial_step_metastate.candidate_state
      tree_weight = candidate_tree_state.weight
      if MULTINOMIAL_SAMPLE:
        weight_sum = log_add_exp(tree_weight, last_candidate_state.weight)
        log_accept_thresh = tree_weight - last_candidate_state.weight
      else:
        weight_sum = tree_weight + last_candidate_state.weight
        log_accept_thresh = tf.math.log(
            tf.cast(tree_weight, tf.float32) /
            tf.cast(last_candidate_state.weight, tf.float32))
      log_accept_thresh = tf.where(
          tf.math.is_nan(log_accept_thresh),
          tf.zeros([], log_accept_thresh.dtype),
          log_accept_thresh)
      u = tf.math.log1p(-tf.random.uniform(
          shape=batch_shape,
          dtype=log_accept_thresh.dtype,
          seed=self._seed_stream()))
      is_sample_accepted = u <= log_accept_thresh

      choose_new_state = is_sample_accepted & continue_tree_final

      new_candidate_state = TreeDoublingStateCandidate(
          state=[
              tf.where(  # pylint: disable=g-complex-comprehension
                  _rightmost_expand_to_rank(
                      choose_new_state, prefer_static.rank(s0)), s0, s1)
              for s0, s1 in zip(candidate_tree_state.state,
                                last_candidate_state.state)
          ],
          target=tf.where(
              _rightmost_expand_to_rank(
                  choose_new_state,
                  prefer_static.rank(candidate_tree_state.target)),
              candidate_tree_state.target, last_candidate_state.target),
          target_grad_parts=[
              tf.where(  # pylint: disable=g-complex-comprehension
                  _rightmost_expand_to_rank(
                      choose_new_state, prefer_static.rank(grad0)),
                  grad0, grad1)
              for grad0, grad1 in zip(candidate_tree_state.target_grad_parts,
                                      last_candidate_state.target_grad_parts)
          ],
          energy=tf.where(
              _rightmost_expand_to_rank(
                  choose_new_state,
                  prefer_static.rank(candidate_tree_state.target)),
              candidate_tree_state.energy, last_candidate_state.energy),
          weight=weight_sum)

      # Update left right information of the trajectory, and check trajectory
      # level U turn
      tree_otherend_states = tf.nest.map_structure(
          lambda v: tf.where(  # pylint: disable=g-long-lambda
              _rightmost_expand_to_rank(direction, prefer_static.rank(v[1])),
              v[0], v[1]), initial_step_state)

      new_step_state = tf.nest.pack_sequence_as(initial_step_state, [
          tf.stack([  # pylint: disable=g-complex-comprehension
              tf.where(
                  _rightmost_expand_to_rank(direction, prefer_static.rank(l)),
                  r, l),
              tf.where(
                  _rightmost_expand_to_rank(direction, prefer_static.rank(l)),
                  l, r),
          ], axis=0)
          for l, r in zip(tf.nest.flatten(tree_final_states),
                          tf.nest.flatten(tree_otherend_states))
      ])

      if GENERALIZED_UTURN:
        state_diff = momentum_tree_cumsum
      else:
        state_diff = [s[1] - s[0] for s in new_step_state.state]

      no_u_turns_trajectory = has_not_u_turn(
          state_diff,
          [m[0] for m in new_step_state.momentum],
          [m[1] for m in new_step_state.momentum],
          log_prob_rank=prefer_static.rank_from_shape(batch_shape))

      new_step_metastate = TreeDoublingMetaState(
          candidate_state=new_candidate_state,
          is_accepted=choose_new_state | initial_step_metastate.is_accepted,
          energy_diff_sum=(
              energy_diff_tree_sum + initial_step_metastate.energy_diff_sum),
          continue_tree=continue_tree_final & no_u_turns_trajectory,
          not_divergence=final_not_divergence,
          leapfrog_count=(initial_step_metastate.leapfrog_count +
                          leapfrogs_taken))

      return iter_ + 1, new_step_state, new_step_metastate
Main loop for tree doubling.
Main loop for tree doubling.
Main loop for tree doubling .
def loop_tree_doubling(self, step_size, momentum_state_memory,
                         current_step_meta_info, iter_, initial_step_state,
                         initial_step_metastate):
    with tf.name_scope('loop_tree_doubling'):
      batch_shape = prefer_static.shape(current_step_meta_info.init_energy)
      direction = tf.cast(
          tf.random.uniform(
              shape=batch_shape,
              minval=0,
              maxval=2,
              dtype=tf.int32,
              seed=self._seed_stream()),
          dtype=tf.bool)
      tree_start_states = tf.nest.map_structure(
          lambda v: tf.where(  
              _rightmost_expand_to_rank(direction, prefer_static.rank(v[1])),
              v[1], v[0]),
          initial_step_state)
      directions_expanded = [
          _rightmost_expand_to_rank(
              direction, prefer_static.rank(state))
          for state in tree_start_states.state
      ]
      integrator = leapfrog_impl.SimpleLeapfrogIntegrator(
          self.target_log_prob_fn,
          step_sizes=[
              tf.where(d, ss, -ss)
              for d, ss in zip(directions_expanded, step_size)
          ],
          num_steps=self.unrolled_leapfrog_steps)
      [
          candidate_tree_state,
          tree_final_states,
          final_not_divergence,
          continue_tree_final,
          energy_diff_tree_sum,
          momentum_tree_cumsum,
          leapfrogs_taken
      ] = self._build_sub_tree(
          directions_expanded,
          integrator,
          current_step_meta_info,
          tf.bitwise.left_shift(1, iter_),
          tree_start_states,
          initial_step_metastate.continue_tree,
          initial_step_metastate.not_divergence,
          momentum_state_memory)
      last_candidate_state = initial_step_metastate.candidate_state
      tree_weight = candidate_tree_state.weight
      if MULTINOMIAL_SAMPLE:
        weight_sum = log_add_exp(tree_weight, last_candidate_state.weight)
        log_accept_thresh = tree_weight - last_candidate_state.weight
      else:
        weight_sum = tree_weight + last_candidate_state.weight
        log_accept_thresh = tf.math.log(
            tf.cast(tree_weight, tf.float32) /
            tf.cast(last_candidate_state.weight, tf.float32))
      log_accept_thresh = tf.where(
          tf.math.is_nan(log_accept_thresh),
          tf.zeros([], log_accept_thresh.dtype),
          log_accept_thresh)
      u = tf.math.log1p(-tf.random.uniform(
          shape=batch_shape,
          dtype=log_accept_thresh.dtype,
          seed=self._seed_stream()))
      is_sample_accepted = u <= log_accept_thresh
      choose_new_state = is_sample_accepted & continue_tree_final
      new_candidate_state = TreeDoublingStateCandidate(
          state=[
              tf.where(  
                  _rightmost_expand_to_rank(
                      choose_new_state, prefer_static.rank(s0)), s0, s1)
              for s0, s1 in zip(candidate_tree_state.state,
                                last_candidate_state.state)
          ],
          target=tf.where(
              _rightmost_expand_to_rank(
                  choose_new_state,
                  prefer_static.rank(candidate_tree_state.target)),
              candidate_tree_state.target, last_candidate_state.target),
          target_grad_parts=[
              tf.where(  
                  _rightmost_expand_to_rank(
                      choose_new_state, prefer_static.rank(grad0)),
                  grad0, grad1)
              for grad0, grad1 in zip(candidate_tree_state.target_grad_parts,
                                      last_candidate_state.target_grad_parts)
          ],
          energy=tf.where(
              _rightmost_expand_to_rank(
                  choose_new_state,
                  prefer_static.rank(candidate_tree_state.target)),
              candidate_tree_state.energy, last_candidate_state.energy),
          weight=weight_sum)
      tree_otherend_states = tf.nest.map_structure(
          lambda v: tf.where(  
              _rightmost_expand_to_rank(direction, prefer_static.rank(v[1])),
              v[0], v[1]), initial_step_state)
      new_step_state = tf.nest.pack_sequence_as(initial_step_state, [
          tf.stack([  
              tf.where(
                  _rightmost_expand_to_rank(direction, prefer_static.rank(l)),
                  r, l),
              tf.where(
                  _rightmost_expand_to_rank(direction, prefer_static.rank(l)),
                  l, r),
          ], axis=0)
          for l, r in zip(tf.nest.flatten(tree_final_states),
                          tf.nest.flatten(tree_otherend_states))
      ])
      if GENERALIZED_UTURN:
        state_diff = momentum_tree_cumsum
      else:
        state_diff = [s[1] - s[0] for s in new_step_state.state]
      no_u_turns_trajectory = has_not_u_turn(
          state_diff,
          [m[0] for m in new_step_state.momentum],
          [m[1] for m in new_step_state.momentum],
          log_prob_rank=prefer_static.rank_from_shape(batch_shape))
      new_step_metastate = TreeDoublingMetaState(
          candidate_state=new_candidate_state,
          is_accepted=choose_new_state | initial_step_metastate.is_accepted,
          energy_diff_sum=(
              energy_diff_tree_sum + initial_step_metastate.energy_diff_sum),
          continue_tree=continue_tree_final & no_u_turns_trajectory,
          not_divergence=final_not_divergence,
          leapfrog_count=(initial_step_metastate.leapfrog_count +
                          leapfrogs_taken))
      return iter_ + 1, new_step_state, new_step_metastate
def loop_tree_doubling ( self , step_size , momentum_state_memory , current_step_meta_info , iter_ , initial_step_state , initial_step_metastate ) : with tf . name_scope ( 'loop_tree_doubling' ) : batch_shape = prefer_static . shape ( current_step_meta_info . init_energy ) direction = tf . cast ( tf . random . uniform ( shape = batch_shape , minval = 0 , maxval = 2 , dtype = tf . int32 , seed = self . _seed_stream ( ) ) , dtype = tf . bool ) tree_start_states = tf . nest . map_structure ( lambda v : tf . where ( _rightmost_expand_to_rank ( direction , prefer_static . rank ( v [ 1 ] ) ) , v [ 1 ] , v [ 0 ] ) , initial_step_state ) directions_expanded = [ _rightmost_expand_to_rank ( direction , prefer_static . rank ( state ) ) for state in tree_start_states . state ] integrator = leapfrog_impl . SimpleLeapfrogIntegrator ( self . target_log_prob_fn , step_sizes = [ tf . where ( d , ss , - ss ) for d , ss in zip ( directions_expanded , step_size ) ] , num_steps = self . unrolled_leapfrog_steps ) [ candidate_tree_state , tree_final_states , final_not_divergence , continue_tree_final , energy_diff_tree_sum , momentum_tree_cumsum , leapfrogs_taken ] = self . _build_sub_tree ( directions_expanded , integrator , current_step_meta_info , tf . bitwise . left_shift ( 1 , iter_ ) , tree_start_states , initial_step_metastate . continue_tree , initial_step_metastate . not_divergence , momentum_state_memory ) last_candidate_state = initial_step_metastate . candidate_state tree_weight = candidate_tree_state . weight if MULTINOMIAL_SAMPLE : weight_sum = log_add_exp ( tree_weight , last_candidate_state . weight ) log_accept_thresh = tree_weight - last_candidate_state . weight else : weight_sum = tree_weight + last_candidate_state . weight log_accept_thresh = tf . math . log ( tf . cast ( tree_weight , tf . float32 ) / tf . cast ( last_candidate_state . weight , tf . float32 ) ) log_accept_thresh = tf . where ( tf . math . is_nan ( log_accept_thresh ) , tf . zeros ( [ ] , log_accept_thresh . dtype ) , log_accept_thresh ) u = tf . math . log1p ( - tf . random . uniform ( shape = batch_shape , dtype = log_accept_thresh . dtype , seed = self . _seed_stream ( ) ) ) is_sample_accepted = u <= log_accept_thresh choose_new_state = is_sample_accepted & continue_tree_final new_candidate_state = TreeDoublingStateCandidate ( state = [ tf . where ( _rightmost_expand_to_rank ( choose_new_state , prefer_static . rank ( s0 ) ) , s0 , s1 ) for s0 , s1 in zip ( candidate_tree_state . state , last_candidate_state . state ) ] , target = tf . where ( _rightmost_expand_to_rank ( choose_new_state , prefer_static . rank ( candidate_tree_state . target ) ) , candidate_tree_state . target , last_candidate_state . target ) , target_grad_parts = [ tf . where ( _rightmost_expand_to_rank ( choose_new_state , prefer_static . rank ( grad0 ) ) , grad0 , grad1 ) for grad0 , grad1 in zip ( candidate_tree_state . target_grad_parts , last_candidate_state . target_grad_parts ) ] , energy = tf . where ( _rightmost_expand_to_rank ( choose_new_state , prefer_static . rank ( candidate_tree_state . target ) ) , candidate_tree_state . energy , last_candidate_state . energy ) , weight = weight_sum ) tree_otherend_states = tf . nest . map_structure ( lambda v : tf . where ( _rightmost_expand_to_rank ( direction , prefer_static . rank ( v [ 1 ] ) ) , v [ 0 ] , v [ 1 ] ) , initial_step_state ) new_step_state = tf . nest . pack_sequence_as ( initial_step_state , [ tf . stack ( [ tf . where ( _rightmost_expand_to_rank ( direction , prefer_static . rank ( l ) ) , r , l ) , tf . where ( _rightmost_expand_to_rank ( direction , prefer_static . rank ( l ) ) , l , r ) , ] , axis = 0 ) for l , r in zip ( tf . nest . flatten ( tree_final_states ) , tf . nest . flatten ( tree_otherend_states ) ) ] ) if GENERALIZED_UTURN : state_diff = momentum_tree_cumsum else : state_diff = [ s [ 1 ] - s [ 0 ] for s in new_step_state . state ] no_u_turns_trajectory = has_not_u_turn ( state_diff , [ m [ 0 ] for m in new_step_state . momentum ] , [ m [ 1 ] for m in new_step_state . momentum ] , log_prob_rank = prefer_static . rank_from_shape ( batch_shape ) ) new_step_metastate = TreeDoublingMetaState ( candidate_state = new_candidate_state , is_accepted = choose_new_state | initial_step_metastate . is_accepted , energy_diff_sum = ( energy_diff_tree_sum + initial_step_metastate . energy_diff_sum ) , continue_tree = continue_tree_final & no_u_turns_trajectory , not_divergence = final_not_divergence , leapfrog_count = ( initial_step_metastate . leapfrog_count + leapfrogs_taken ) ) return iter_ + 1 , new_step_state , new_step_metastate
Main loop for tree doubling.
Main loop for tree doubling .
"""Main loop for tree doubling.""" # pylint: disable=g-long-lambda # num_steps_at_this_depth = 2**iter_ = 1 << iter_ # pylint: disable=g-complex-comprehension # pylint: disable=g-complex-comprehension # Update left right information of the trajectory, and check trajectory # level U turn # pylint: disable=g-long-lambda # pylint: disable=g-complex-comprehension
self
step_size
momentum_state_memory
current_step_meta_info
iter_
initial_step_state
initial_step_metastate