import tensorflow as tf

      small_constant_for_finite_diff: a `float`, Small constant for finite difference method
      perturb_norm_length: a `float`, Norm length of adversarial perturbation
          to be optimized with validatio

  Returns:
      a `float` `scalar`, KL divergence.
  """
  logits = tf.stop_gradient(logits)
  weights = _end_of_seq_mask(labels, vocab_size)

  perturbs = [_mask_by_length(tf.random_normal(shape=tf.shape(emb)), length) for emb in embedded]
  for _ in range(num_power_iteration):
    perturbs = [_scale_l2(d, small_constant_for_finite_diff) for d in perturbs]
    d_logits = logits_from_embedding_fn([emb + d for (emb, d) in zip(embedded, perturbs)])
    kl = _kl_divergence_with_logits(logits, d_logits, weights, num_classes)
  perturbs = tf.gradients(
      kl, perturbs, aggregation_method=tf.AggregationMethod.EXPERIMENTAL_ACCUMULATE_N)
  perturbs = [tf.stop_gradient(d) for d in perturbs]

  perturbs = [_scale_l2(_mask_by_length(d, length), perturb_norm_length) for d in perturbs]
  vadv_logits = logits_from_embedding_fn([emb + d for (emb, d) in zip(embedded, perturbs)])
  return _kl_divergence_with_logits(logits, vadv_logits, weights, num_classes)


def _mask_by_length(t, length):
  maxlen = t.get_shape().as_list()[1]
  mask = tf.sequence_mask(length, maxlen=maxlen)
  mask = tf.expand_dims(tf.cast(mask, tf.float32), -1)
  return t * mask

