<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def maybe_scheduled_sampling(self, features, logits, losses):
 """Scheduled sampling. Performs forward inference again with "targets" feature replaced with values sampled from the model. This is the identity unless self.hparams.scheduled_sampling_prob > 0 (default). **WARNING**: This is not a faithful implementation of scheduled sampling. This implementation samples tokens for timestep t condtioned on gold tokens sampled tokens. Doing so is not efficient for models such like Transformer. Args: features: {str: Tensor}. Features sharded along batch dimension. logits: Tensor. Logits for each shard of data. losses: 0-D Tensor or (num: 0-D Tensor, denom: 0-D Tensor). Loss Tensor Returns: new_logits: Tensor. new_losses: {str: loss} where loss is one of (i) a 0-D Tensor or (ii) a (num: 0-D Tensor, denom: 0-D Tensor) pair to be used in a weighted average. """

    hparams = self.hparams
    problem_hparams = self._problem_hparams

    # Only do scheduled sampling if requested.
    if hparams.scheduled_sampling_prob == 0.0:
      return (logits, losses)

    # Only do scheduled sampling on language tasks.
    modality = problem_hparams.modality["targets"]
    if modality != modalities.ModalityType.SYMBOL:
      assert hparams.scheduled_sampling_prob == 0, (
          "Scheduled sampling only applies to ModalityType.SYMBOL. Set "
          "hparams.scheduled_sampling_prob == 0.0.")
      return (logits, losses)

    # Only do scheduled sampling when training.
    is_training = (hparams.mode == tf.estimator.ModeKeys.TRAIN)
    if not is_training:
      tf.logging.info("Running in %s mode. Not using scheduled sampling.",
                      hparams.mode)
      return (logits, losses)

    # Pad vocabulary if vocab size must be evenly divisible by vocab_divisor.
    vocab_size = problem_hparams.vocab_size["targets"]
    assert vocab_size is not None
    assert hparams.vocab_divisor == 1

    def sample(x):
      """Multinomial sampling from a n-dimensional tensor."""
      samples = tf.multinomial(tf.reshape(x, [-1, vocab_size]), 1)
      reshaped_samples = tf.reshape(samples, common_layers.shape_list(x)[:-1])
      return tf.to_int32(reshaped_samples)

    def mix_gold_sampled(gold_targets, sampled_targets, mixin_prob):
      """Interleave sampled and gold tokens randomly."""
      return tf.where(
          tf.less(
              tf.random_uniform(common_layers.shape_list(sampled_targets)),
              mixin_prob),
          sampled_targets,
          gold_targets)

    def sampled_results(features, logits, mixin_prob):
      """Generate scheduled sampling results."""
      sampled_targets = sample(logits)
      new_targets = mix_gold_sampled(features["targets"],
                                     sampled_targets,
                                     mixin_prob)
      new_targets = tf.stop_gradient(new_targets)  # Treat new_targets as given.
      new_features = copy.copy(features)
      new_features["targets"] = new_targets
      with tf.variable_scope(tf.get_variable_scope(), reuse=True):
        # Compute bottom() for new_targets.
        #
        # TODO(duckworthd): Only apply bottom to 'new_targets'.
        new_transformed_features = self.bottom(new_features)

        # Compute body.
        with tf.variable_scope("body"):
          new_body_outputs, new_losses = self._normalize_body_output(
              self.body(new_transformed_features))
        assert "training" not in new_losses

        # Compute top.
        new_logits = self.top(new_body_outputs, new_features)

        # Compute loss. Use original features (== labels).
        if (hparams.mode != tf.estimator.ModeKeys.PREDICT and
            hparams.mode != "attack"):
          new_losses["training"] = self.loss(new_logits, features)
        else:
          new_losses["training"] = 0.0

      return new_logits, new_losses

    tf.logging.info("Using scheduled sampling.")
    assert hparams.scheduled_sampling_prob == 1.0, (
        "hparams.scheduled_sampling_prob must be 0 or 1.")
    # Gradually increase over a warmup period. Lower numbers mean more gold
    # tokens.
    mixin_prob = (
        hparams.scheduled_sampling_gold_mixin_prob *
        common_layers.inverse_exp_decay(
            hparams.scheduled_sampling_warmup_steps,
            min_value=0.001)
    )

    # Apply scheduled sampling over N passes. The logits from the (n-1)-th pass
    # will be mixed with gold tokens for conditioning in the n-th pass.
    scheduled_sampling_num_passes = getattr(
        hparams, "scheduled_sampling_num_passes", 1)
    assert scheduled_sampling_num_passes > 0, (
        "hparams.scheduled_sampling_num_passes must be > 0 if "
        "hparams.scheduled_sampling_prob > 0.0")
    new_logits = logits
    new_losses = losses
    for _ in range(scheduled_sampling_num_passes):
      new_logits, new_losses = sampled_results(features, new_logits, mixin_prob)
    return new_logits, new_losses