示例#1
0
def run_batch_with_goal(sess, model, x, y, adv_x_val, criteria, attack_configs,
                        run_counts, goal, report, report_path,
                        attack_batch_size=BATCH_SIZE):
  """
  Runs attack bundling on one batch of data.
  This function is mostly intended to be called by
  `bundle_attacks_with_goal`.

  :param sess: tf.session.Session
  :param model: cleverhans.model.Model
  :param x: numpy array containing clean example inputs to attack
  :param y: numpy array containing true labels
  :param adv_x_val: numpy array containing the adversarial examples made so far
    by earlier work in the bundling process
  :param criteria: dict mapping string names of criteria to numpy arrays with
    their values for each example
    (Different AttackGoals track different criteria)
  :param run_counts: dict mapping AttackConfigs to numpy arrays reporting how
    many times they have been run on each example
  :param goal: the AttackGoal to work on
  :param report: dict, see `bundle_attacks_with_goal`
  :param report_path: str, path to save the report to
  """
  attack_config = goal.get_attack_config(attack_configs, run_counts, criteria)
  idxs = goal.request_examples(attack_config, criteria, run_counts,
                               attack_batch_size)
  x_batch = x[idxs]
  assert x_batch.shape[0] == attack_batch_size
  y_batch = y[idxs]
  assert y_batch.shape[0] == attack_batch_size
  adv_x_batch = run_attack(sess, model, x_batch, y_batch,
                           attack_config.attack, attack_config.params,
                           attack_batch_size, devices, pass_y=attack_config.pass_y)
  criteria_batch = goal.get_criteria(sess, model, adv_x_batch, y_batch,
                                     batch_size=min(attack_batch_size,
                                                    BATCH_SIZE))
  # This can't be parallelized because some orig examples are copied more
  # than once into the batch
  cur_run_counts = run_counts[attack_config]
  for batch_idx, orig_idx in enumerate(idxs):
    cur_run_counts[orig_idx] += 1
    should_copy = goal.new_wins(criteria, orig_idx, criteria_batch, batch_idx)
    if should_copy:
      adv_x_val[orig_idx] = adv_x_batch[batch_idx]
      for key in criteria:
        criteria[key][orig_idx] = criteria_batch[key][batch_idx]
      assert np.allclose(y[orig_idx], y_batch[batch_idx])
  report['bundled'] = ConfidenceReportEntry(criteria['correctness'], criteria['confidence'])

  should_save = False
  new_time = time.time()
  if hasattr(report, 'time'):
    if new_time - report.time > REPORT_TIME_INTERVAL:
      should_save = True
  else:
    should_save = True
  if should_save:
    report.time = new_time
    goal.print_progress(criteria, run_counts)
    save(criteria, report, report_path, adv_x_val)
def test_save_load_confidence_report():
  """
  Test that a confidence report can be loaded and saved.
  """
  report = ConfidenceReport()
  num_examples = 2
  clean_correctness = np.zeros((num_examples,), dtype=np.bool)
  clean_confidence = np.zeros((num_examples,), dtype=np.float32)
  adv_correctness = clean_correctness.copy()
  adv_confidence = clean_confidence.copy()
  report['clean'] = ConfidenceReportEntry(clean_correctness, clean_confidence)
  report['adv'] = ConfidenceReportEntry(adv_correctness, adv_confidence)
  report.completed = True
  filepath = ".test_confidence_report.joblib"
  serial.save(filepath, report)
  report = serial.load(filepath)
def test_confidence_report():
    # Test that we can make a confidence report, put an entry in it, and get
    # that entry back out
    report = ConfidenceReport()
    entry = ConfidenceReportEntry(correctness=np.array([True, False]),
                                  confidence=np.array([0.9, 0.1]))
    report['clean'] = entry
    assert report['clean'] is entry
示例#4
0
def bundle_attacks(sess, model, x, y, attack_configs, goals, report_path,
                   attack_batch_size=BATCH_SIZE, eval_batch_size=BATCH_SIZE):
  """
  Runs attack bundling.
  Users of cleverhans may call this function but are more likely to call
  one of the recipes above.

  Reference: https://openreview.net/forum?id=H1g0piA9tQ

  :param sess: tf.session.Session
  :param model: cleverhans.model.Model
  :param x: numpy array containing clean example inputs to attack
  :param y: numpy array containing true labels
  :param attack_configs: list of AttackConfigs to run
  :param goals: list of AttackGoals to run
    The bundler works through the goals in order, until each is satisfied.
    Some goals may never be satisfied, in which case the bundler will run
    forever, updating the report on disk as it goes.
  :param report_path: str, the path the report will be saved to
  :param attack_batch_size: int, batch size for generating adversarial examples
  :param eval_batch_size: int, batch size for evaluating the model on clean / adversarial examples
  :returns:
    adv_x: The adversarial examples, in the same format as `x`
    run_counts: dict mapping each AttackConfig to a numpy array reporting
      how many times that AttackConfig was run on each example
  """
  assert isinstance(sess, tf.Session)
  assert isinstance(model, Model)
  assert all(isinstance(attack_config, AttackConfig) for attack_config
             in attack_configs)
  assert all(isinstance(goal, AttackGoal) for goal in goals)
  assert isinstance(report_path, six.string_types)
  if x.shape[0] != y.shape[0]:
    raise ValueError("Number of input examples does not match number of labels")

  # Note: no need to precompile attacks, correctness_and_confidence
  # caches them

  run_counts = {}
  for attack_config in attack_configs:
    run_counts[attack_config] = np.zeros(x.shape[0], dtype=np.int64)

  # TODO: make an interface to pass this in if it has already been computed
  # elsewhere
  _logger.info("Running on clean data to initialize the report...")
  packed = correctness_and_confidence(sess, model, x, y, batch_size=eval_batch_size,
                                      devices=devices)
  _logger.info("...done")
  correctness, confidence = packed
  _logger.info("Accuracy: " + str(correctness.mean()))
  report = ConfidenceReport()
  report['clean'] = ConfidenceReportEntry(correctness, confidence)

  adv_x = x.copy()

  for goal in goals:
    bundle_attacks_with_goal(sess, model, x, y, adv_x, attack_configs,
                             run_counts,
                             goal, report, report_path,
                             attack_batch_size=attack_batch_size, eval_batch_size=eval_batch_size)

  # Many users will set `goals` to make this run forever, so the return
  # statement is not the primary way to get information out.
  return adv_x, run_counts
示例#5
0
def bundle_examples_with_goal(sess, model, adv_x_list, y, goal,
                              report_path):
  """
  A post-processor version of attack bundling, that chooses the strongest
  example from the output of multiple earlier bundling strategies.

  :param sess: tf.session.Session
  :param model: cleverhans.model.Model
  :param adv_x_list: list of numpy arrays
    Each entry in the list is the output of a previous bundler; it is an
      adversarial version of the whole dataset.
  :param y: numpy array containing true labels
  :param goal: AttackGoal to use to choose the best version of each adversarial
    example
  :param report_path: str, the path the report will be saved to
  """

  # Check the input
  num_attacks = len(adv_x_list)
  assert num_attacks > 0
  adv_x_0 = adv_x_list[0]
  assert isinstance(adv_x_0, np.ndarray)
  assert all(adv_x.shape == adv_x_0.shape for adv_x in adv_x_list)

  # Allocate the output
  out = np.zeros_like(adv_x_0)
  m = adv_x_0.shape[0]
  # Initialize with negative sentinel values to make sure everything is
  # written to
  correctness = -np.ones(m, dtype='int32')
  confidence = -np.ones(m, dtype='float32')

  # Gather criteria
  criteria = [goal.get_criteria(sess, model, adv_x, y) for adv_x in adv_x_list]
  assert all('correctness' in c for c in criteria)
  assert all('confidence' in c for c in criteria)
  _logger.info("Accuracy on each advx dataset: ")
  for c in criteria:
    _logger.info("\t" + str(c['correctness'].mean()))

  for example_idx in range(m):
    # Index of the best attack for this example
    attack_idx = 0
    # Find the winner
    for candidate_idx in range(1, num_attacks):
      if goal.new_wins(criteria[attack_idx], example_idx,
                       criteria[candidate_idx], example_idx):
        attack_idx = candidate_idx
    # Copy the winner into the output
    out[example_idx] = adv_x_list[attack_idx][example_idx]
    correctness[example_idx] = criteria[attack_idx]['correctness'][example_idx]
    confidence[example_idx] = criteria[attack_idx]['confidence'][example_idx]

  assert correctness.min() >= 0
  assert correctness.max() <= 1
  assert confidence.min() >= 0.
  assert confidence.max() <= 1.

  report = ConfidenceReport()
  report['bundled'] = ConfidenceReportEntry(correctness, confidence)
  serial.save(report_path, report)
  assert report_path.endswith('.joblib')
  adv_x_path = report_path[:-len('.joblib')] + "_adv_x.npy"
  np.save(adv_x_path, out)