# Path: semi_supervised/vat_utils.py
# def virtual_adversarial_perturbation_direction(
#     x, logits, net, xi=1e-6, num_power_method_iters=1):
# def kl_divergence_from_logits(logits1, logits2):
# def normalize(v):


import functools
import tensorflow as tf
import datasets
import datasets
import semi_supervised.utils as ss_utils
import trainer
import utils
from semi_supervised import vat_utils
        images_unsup, images_sup,
        is_training=(mode == tf.estimator.ModeKeys.TRAIN),
        outputs={'classes': datasets.get_auxiliary_num_classes()})

  # Compute virtual adversarial perturbation
  def classification_net_fn(x):  # pylint: disable=missing-docstring
    with tf.variable_scope('module', reuse=True):
      end_points_x = ss_utils.apply_model_semi(
          x, None,
          is_training=(mode == tf.estimator.ModeKeys.TRAIN),
          outputs={'classes': datasets.get_auxiliary_num_classes()},
          # Don't update batch norm stats as we're running this on perturbed
          # (corrupted) inputs. Setting momentum = 1 is what does the trick.
          normalization_fn=functools.partial(
              tf.layers.batch_normalization, momentum=1.0))
      return end_points_x['classes']

  ## Compute VAT perturbation
  vat_eps = FLAGS.get_flag_value('vat_eps', 1.0)
  vat_num_power_method_iters = FLAGS.get_flag_value('vat_num_power_method_iters', 1)

  if FLAGS.apply_vat_to_labeled:
    images_vat_baseline = tf.concat(
        (images_sup, images_unsup), axis=0)
    predictions_vat_baseline = tf.concat(
        (end_points['classes_sup'], end_points['classes_unsup']), axis=0)
  else:
    images_vat_baseline = images_unsup
    predictions_vat_baseline = end_points['classes_unsup']


# Path: semi_supervised/vat_utils.py
# def virtual_adversarial_perturbation_direction(
#     x, logits, net, xi=1e-6, num_power_method_iters=1):
# def kl_divergence_from_logits(logits1, logits2):
# def normalize(v):


# Path: semi_supervised/vat.py
import functools
import tensorflow as tf
import datasets
import datasets
import semi_supervised.utils as ss_utils
import trainer
import utils
from semi_supervised import vat_utils

        images_unsup, images_sup,
        is_training=(mode == tf.estimator.ModeKeys.TRAIN),
        outputs={'classes': datasets.get_auxiliary_num_classes()})

  # Compute virtual adversarial perturbation
  def classification_net_fn(x):  # pylint: disable=missing-docstring
    with tf.variable_scope('module', reuse=True):
      end_points_x = ss_utils.apply_model_semi(
          x, None,
          is_training=(mode == tf.estimator.ModeKeys.TRAIN),
          outputs={'classes': datasets.get_auxiliary_num_classes()},
          # Don't update batch norm stats as we're running this on perturbed
          # (corrupted) inputs. Setting momentum = 1 is what does the trick.
          normalization_fn=functools.partial(
              tf.layers.batch_normalization, momentum=1.0))
      return end_points_x['classes']

  ## Compute VAT perturbation
  vat_eps = FLAGS.get_flag_value('vat_eps', 1.0)
  vat_num_power_method_iters = FLAGS.get_flag_value('vat_num_power_method_iters', 1)

  if FLAGS.apply_vat_to_labeled:
    images_vat_baseline = tf.concat(
        (images_sup, images_unsup), axis=0)
    predictions_vat_baseline = tf.concat(
        (end_points['classes_sup'], end_points['classes_unsup']), axis=0)
  else:
    images_vat_baseline = images_unsup
    predictions_vat_baseline = end_points['classes_unsup']


  vat_perturbation = vat_utils.virtual_adversarial_perturbation_direction(