import tensorflow as tf

      num_classes: num_classes for training
      vocab_size: a `int`, vocabular size of the problem
      num_power_iteration: a `int`, the number of power iteration
      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)

  d = _mask_by_length(tf.random_normal(shape=tf.shape(embedded)), length)

  for _ in range(num_power_iteration):
    d = _scale_l2(d, small_constant_for_finite_diff)
    d_logits = logits_from_embedding_fn(embedded + d)
    kl = _kl_divergence_with_logits(logits, d_logits, weights, num_classes)
    d, = tf.gradients(kl, d, aggregation_method=tf.AggregationMethod.EXPERIMENTAL_ACCUMULATE_N)
    d = tf.stop_gradient(d)

  perturb = _scale_l2(_mask_by_length(d, length), perturb_norm_length)
  vadv_logits = logits_from_embedding_fn(embedded + perturb)
  return _kl_divergence_with_logits(logits, vadv_logits, weights, num_classes)

