The actual implementation of the evaluation.
  :param sess: tf.Session
  :param model: cleverhans.model.Model
  :param dataset: cleverhans.dataset.Dataset
  :param factory: the dataset factory corresponding to `dataset`
  :param x_data: numpy array of input examples
  :param y_data: numpy array of class labels
  :param base_eps_iter: step size for PGD if data were in [0, 1]
  :param nb_iter: number of PGD iterations
  :returns: dict mapping string adversarial example names to accuracies

def impl(sess, model, dataset, factory, x_data, y_data,
         base_eps_iter=BASE_EPS_ITER, nb_iter=NB_ITER,
         batch_size=BATCH_SIZE):
  """
  The actual implementation of the evaluation.
  :param sess: tf.Session
  :param model: cleverhans.model.Model
  :param dataset: cleverhans.dataset.Dataset
  :param factory: the dataset factory corresponding to `dataset`
  :param x_data: numpy array of input examples
  :param y_data: numpy array of class labels
  :param base_eps_iter: step size for PGD if data were in [0, 1]
  :param nb_iter: number of PGD iterations
  :returns: dict mapping string adversarial example names to accuracies
  """

  center = dataset.kwargs['center']
  max_val = dataset.kwargs['max_val']
  value_range = max_val * (1. + center)
  min_value = 0. - center * max_val

  if 'CIFAR' in str(factory.cls):
    base_eps = 8. / 255.
    if base_eps_iter is None:
      base_eps_iter = 2. / 255.
  elif 'MNIST' in str(factory.cls):
    base_eps = .3
    if base_eps_iter is None:
      base_eps_iter = .1
  else:
    raise NotImplementedError(str(factory.cls))

  pgd_params = {'eps': base_eps * value_range,
                'eps_iter': base_eps_iter * value_range,
                'nb_iter': nb_iter,
                'clip_min': min_value,
                'clip_max': max_val}

  semantic = Semantic(model, center, max_val, sess)
  pgd = ProjectedGradientDescent(model, sess=sess)

  jobs = [('clean', None, None, None),
          ('Semantic', semantic, None, None),
          ('pgd', pgd, pgd_params, None)]

  out = {}

  for job in jobs:
    name, attack, attack_params, job_batch_size = job
    if job_batch_size is None:
      job_batch_size = batch_size
    t1 = time.time()
    acc = accuracy(sess, model, x_data, y_data, batch_size=job_batch_size,
                   devices=devices, attack=attack, attack_params=attack_params)
    t2 = time.time()
    out[name] = acc
    print("Accuracy on " + name + " examples: ", acc)
    print("Evaluation took", t2 - t1, "seconds")

  return out