Skip to content

Commit 622a37c

Browse files
committed
Add standard deviation to PDTP output
Signed-off-by: abigailt <[email protected]>
1 parent 59b2f99 commit 622a37c

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

art/metrics/privacy/membership_leakage.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def PDTP( # pylint: disable=C0103
3737
y: np.ndarray,
3838
indexes: Optional[np.ndarray] = None,
3939
num_iter: Optional[int] = 10,
40-
) -> Tuple[np.ndarray, np.ndarray]:
40+
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
4141
"""
4242
Compute the pointwise differential training privacy metric for the given classifier and training set.
4343
@@ -52,8 +52,8 @@ def PDTP( # pylint: disable=C0103
5252
computed for all samples in `x`.
5353
:param num_iter: the number of iterations of PDTP computation to run for each sample. If not supplied,
5454
defaults to 10. The result is the average across iterations.
55-
:return: A tuple of two arrays, containing the average (worse) PDTP value for each sample in the training set
56-
respectively. The higher the value, the higher the privacy leakage for that sample.
55+
:return: A tuple of three arrays, containing the average (worse, standard deviation) PDTP value for each sample in
56+
the training set respectively. The higher the value, the higher the privacy leakage for that sample.
5757
"""
5858
from art.estimators.classification.pytorch import PyTorchClassifier
5959
from art.estimators.classification.tensorflow import TensorFlowV2Classifier
@@ -121,6 +121,7 @@ def PDTP( # pylint: disable=C0103
121121
per_sample = list(map(list, zip(*results)))
122122
avg_per_sample = np.array([sum(val) / len(val) for val in per_sample])
123123
worse_per_sample = np.max(per_sample, axis=1)
124+
std_dev_per_sample = np.std(per_sample, axis=1)
124125

125-
# return avg+worse leakage per sample
126-
return avg_per_sample, worse_per_sample
126+
# return avg+worse leakage + standard deviation per sample
127+
return avg_per_sample, worse_per_sample, std_dev_per_sample

tests/metrics/privacy/test_membership_leakage.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,15 @@ def test_membership_leakage_decision_tree(art_warning, decision_tree_estimator,
3535
extra_classifier = decision_tree_estimator()
3636
(x_train, y_train), _ = get_iris_dataset
3737
prev = classifier.model.tree_
38-
avg_leakage, worse_leakage = PDTP(classifier, extra_classifier, x_train, y_train)
38+
avg_leakage, worse_leakage, std_dev = PDTP(classifier, extra_classifier, x_train, y_train)
3939
logger.info("Average PDTP leakage: %.2f", (np.average(avg_leakage)))
4040
logger.info("Max PDTP leakage: %.2f", (np.max(avg_leakage)))
4141
assert classifier.model.tree_ == prev
4242
assert np.all(avg_leakage >= 1.0)
4343
assert np.all(worse_leakage >= avg_leakage)
4444
assert avg_leakage.shape[0] == x_train.shape[0]
4545
assert worse_leakage.shape[0] == x_train.shape[0]
46+
assert std_dev.shape[0] == x_train.shape[0]
4647
except ARTTestException as e:
4748
art_warning(e)
4849

@@ -53,13 +54,14 @@ def test_membership_leakage_tabular(art_warning, tabular_dl_estimator, get_iris_
5354
classifier = tabular_dl_estimator()
5455
extra_classifier = tabular_dl_estimator()
5556
(x_train, y_train), _ = get_iris_dataset
56-
avg_leakage, worse_leakage = PDTP(classifier, extra_classifier, x_train, y_train)
57+
avg_leakage, worse_leakage, std_dev = PDTP(classifier, extra_classifier, x_train, y_train)
5758
logger.info("Average PDTP leakage: %.2f", (np.average(avg_leakage)))
5859
logger.info("Max PDTP leakage: %.2f", (np.max(avg_leakage)))
5960
assert np.all(avg_leakage >= 1.0)
6061
assert np.all(worse_leakage >= avg_leakage)
6162
assert avg_leakage.shape[0] == x_train.shape[0]
6263
assert worse_leakage.shape[0] == x_train.shape[0]
64+
assert std_dev.shape[0] == x_train.shape[0]
6365
except ARTTestException as e:
6466
art_warning(e)
6567

@@ -71,13 +73,16 @@ def test_membership_leakage_image(art_warning, image_dl_estimator, get_default_m
7173
extra_classifier, _ = image_dl_estimator()
7274
(x_train, y_train), _ = get_default_mnist_subset
7375
indexes = random.sample(range(x_train.shape[0]), 100)
74-
avg_leakage, worse_leakage = PDTP(classifier, extra_classifier, x_train, y_train, indexes=indexes, num_iter=1)
76+
avg_leakage, worse_leakage, std_dev = PDTP(
77+
classifier, extra_classifier, x_train, y_train, indexes=indexes, num_iter=1
78+
)
7579
logger.info("Average PDTP leakage: %.2f", (np.average(avg_leakage)))
7680
logger.info("Max PDTP leakage: %.2f", (np.max(avg_leakage)))
7781
assert np.all(avg_leakage >= 1.0)
7882
assert np.all(worse_leakage >= avg_leakage)
7983
assert avg_leakage.shape[0] == x_train.shape[0]
8084
assert worse_leakage.shape[0] == x_train.shape[0]
85+
assert std_dev.shape[0] == x_train.shape[0]
8186
except ARTTestException as e:
8287
art_warning(e)
8388

0 commit comments

Comments
 (0)