def run_membership_probability_analysis(
        attack_input: AttackInputData,
        slicing_spec: SlicingSpec = None) -> MembershipProbabilityResults:
    """Perform membership probability analysis on all given slice types.

  Args:
    attack_input: input data for compute membership probabilities
    slicing_spec: specifies attack_input slices

  Returns:
    the membership probability results.
  """
    attack_input.validate()
    membership_prob_results = []

    if slicing_spec is None:
        slicing_spec = SlicingSpec(entire_dataset=True)
    num_classes = None
    if slicing_spec.by_class:
        num_classes = attack_input.num_classes
    input_slice_specs = get_single_slice_specs(slicing_spec, num_classes)
    for single_slice_spec in input_slice_specs:
        attack_input_slice = get_slice(attack_input, single_slice_spec)
        membership_prob_results.append(
            _compute_membership_probability(attack_input_slice))

    return MembershipProbabilityResults(
        membership_prob_results=membership_prob_results)
예제 #2
0
 def test_slice_by_correcness(self):
     input_data = SlicingSpec(entire_dataset=False,
                              by_classification_correctness=True)
     expected = SingleSliceSpec(SlicingFeature.CORRECTLY_CLASSIFIED, True)
     output = get_single_slice_specs(input_data)
     self.assertLen(output, 2)
     self.assertTrue(_are_all_fields_equal(output[0], expected))
예제 #3
0
 def test_slice_by_percentiles(self):
     input_data = SlicingSpec(entire_dataset=False, by_percentiles=True)
     expected0 = SingleSliceSpec(SlicingFeature.PERCENTILE, (0, 10))
     expected5 = SingleSliceSpec(SlicingFeature.PERCENTILE, (50, 60))
     output = get_single_slice_specs(input_data)
     self.assertLen(output, 10)
     self.assertTrue(_are_all_fields_equal(output[0], expected0))
     self.assertTrue(_are_all_fields_equal(output[5], expected5))
예제 #4
0
 def test_slice_by_classes(self):
     input_data = SlicingSpec(by_class=True)
     n_classes = 5
     expected = [self.ENTIRE_DATASET_SLICE] + [
         SingleSliceSpec(SlicingFeature.CLASS, c) for c in range(n_classes)
     ]
     output = get_single_slice_specs(input_data, n_classes)
     self.assertTrue(_are_lists_equal(output, expected))
예제 #5
0
 def test_slicing_by_multiple_features(self):
     input_data = SlicingSpec(entire_dataset=True,
                              by_class=True,
                              by_percentiles=True,
                              by_classification_correctness=True)
     n_classes = 10
     expected_slices = n_classes
     expected_slices += 1  # entire dataset slice
     expected_slices += 10  # percentiles slices
     expected_slices += 2  # correcness classification slices
     output = get_single_slice_specs(input_data, n_classes)
     self.assertLen(output, expected_slices)
def run_attacks(attack_input: AttackInputData,
                slicing_spec: SlicingSpec = None,
                attack_types: Iterable[AttackType] = (
                    AttackType.THRESHOLD_ATTACK, ),
                privacy_report_metadata: PrivacyReportMetadata = None,
                balance_attacker_training: bool = True,
                min_num_samples: int = 1) -> AttackResults:
    """Runs membership inference attacks on a classification model.

  It runs attacks specified by attack_types on each attack_input slice which is
   specified by slicing_spec.

  Args:
    attack_input: input data for running an attack
    slicing_spec: specifies attack_input slices to run attack on
    attack_types: attacks to run
    privacy_report_metadata: the metadata of the model under attack.
    balance_attacker_training: Whether the training and test sets for the
          membership inference attacker should have a balanced (roughly equal)
          number of samples from the training and test sets used to develop
          the model under attack.
    min_num_samples: minimum number of examples in either training or test data.

  Returns:
    the attack result.
  """
    attack_input.validate()
    attack_results = []

    if slicing_spec is None:
        slicing_spec = SlicingSpec(entire_dataset=True)
    num_classes = None
    if slicing_spec.by_class:
        num_classes = attack_input.num_classes
    input_slice_specs = get_single_slice_specs(slicing_spec, num_classes)
    for single_slice_spec in input_slice_specs:
        attack_input_slice = get_slice(attack_input, single_slice_spec)
        for attack_type in attack_types:
            attack_result = _run_attack(attack_input_slice, attack_type,
                                        balance_attacker_training,
                                        min_num_samples)
            if attack_result is not None:
                attack_results.append(attack_result)

    privacy_report_metadata = _compute_missing_privacy_report_metadata(
        privacy_report_metadata, attack_input)

    return AttackResults(single_attack_results=attack_results,
                         privacy_report_metadata=privacy_report_metadata)
예제 #7
0
def run_attacks(
    attack_input: AttackInputData,
    slicing_spec: SlicingSpec = None,
    attack_types: Iterable[AttackType] = (AttackType.THRESHOLD_ATTACK, )
) -> AttackResults:
    """Run all attacks."""
    attack_input.validate()
    attack_results = []

    if slicing_spec is None:
        slicing_spec = SlicingSpec(entire_dataset=True)
    input_slice_specs = get_single_slice_specs(slicing_spec,
                                               attack_input.num_classes)
    for single_slice_spec in input_slice_specs:
        attack_input_slice = get_slice(attack_input, single_slice_spec)
        for attack_type in attack_types:
            attack_results.append(run_attack(attack_input_slice, attack_type))

    return AttackResults(single_attack_results=attack_results)
예제 #8
0
def run_attacks(
        attack_input: AttackInputData,
        slicing_spec: SlicingSpec = None,
        attack_types: Iterable[AttackType] = (AttackType.THRESHOLD_ATTACK, ),
        privacy_report_metadata: PrivacyReportMetadata = None
) -> AttackResults:
    """Runs membership inference attacks on a classification model.

  It runs attacks specified by attack_types on each attack_input slice which is
   specified by slicing_spec.

  Args:
    attack_input: input data for running an attack
    slicing_spec: specifies attack_input slices to run attack on
    attack_types: attacks to run
    privacy_report_metadata: the metadata of the model under attack.

  Returns:
    the attack result.
  """
    attack_input.validate()
    attack_results = []

    if slicing_spec is None:
        slicing_spec = SlicingSpec(entire_dataset=True)
    input_slice_specs = get_single_slice_specs(slicing_spec,
                                               attack_input.num_classes)
    for single_slice_spec in input_slice_specs:
        attack_input_slice = get_slice(attack_input, single_slice_spec)
        for attack_type in attack_types:
            attack_results.append(_run_attack(attack_input_slice, attack_type))

    privacy_report_metadata = _compute_missing_privacy_report_metadata(
        privacy_report_metadata, attack_input)

    return AttackResults(single_attack_results=attack_results,
                         privacy_report_metadata=privacy_report_metadata)
예제 #9
0
 def test_entire_dataset(self):
     input_data = SlicingSpec()
     expected = [self.ENTIRE_DATASET_SLICE]
     output = get_single_slice_specs(input_data)
     self.assertTrue(_are_lists_equal(output, expected))
예제 #10
0
 def test_no_slices(self):
     input_data = SlicingSpec(entire_dataset=False)
     expected = []
     output = get_single_slice_specs(input_data)
     self.assertTrue(_are_lists_equal(output, expected))