Merge branch 'tensorflow:master' into better-mi

This commit is contained in:
Nicholas Carlini 2021-12-14 12:59:50 -08:00 committed by GitHub
commit afe6ea7699
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 0 deletions

View file

@ -48,6 +48,7 @@ else:
from tensorflow_privacy.privacy.analysis.rdp_accountant import get_privacy_spent
from tensorflow_privacy.privacy.analysis.tree_aggregation_accountant import compute_rdp_tree_restart
from tensorflow_privacy.privacy.analysis.tree_aggregation_accountant import compute_rdp_single_tree
from tensorflow_privacy.privacy.analysis.tree_aggregation_accountant import compute_zcdp_single_tree
# DPQuery classes
from tensorflow_privacy.privacy.dp_query.dp_query import DPQuery

View file

@ -313,3 +313,54 @@ def compute_rdp_single_tree(
for alpha in orders
])
return rdp
def _compute_gaussian_zcdp(sigma: float,
sum_sensitivity_square: float) -> float:
"""Computes zCDP of Gaussian mechanism."""
return sum_sensitivity_square / (2 * sigma**2)
def compute_zcdp_single_tree(
noise_multiplier: float, total_steps: int, max_participation: int,
min_separation: int) -> Union[float, Collection[float]]:
"""Computes zCDP of the Tree Aggregation Protocol for a single tree.
The accounting assume a single tree is constructed for `total_steps` leaf
nodes, where the same sample will appear at most `max_participation` times,
and there are at least `min_separation` nodes between two appearance. The key
idea is to (recurrently) count the worst-case occurence of a sample
in all the nodes in a tree, which implements a dynamic programming algorithm
that exhausts the possible `num_participation` appearance of a sample in
`steps` leaf nodes.
See Appendix D of
"Practical and Private (Deep) Learning without Sampling or Shuffling"
https://arxiv.org/abs/2103.00039.
The Zero-Concentrated Differential Privacy (zCDP) definition is described in
"Concentrated Differential Privacy: Simplifications, Extensions,
and Lower Bounds" https://arxiv.org/abs/1605.02065
Args:
noise_multiplier: A non-negative float representing the ratio of the
standard deviation of the Gaussian noise to the l2-sensitivity of the
function to which it is added.
total_steps: Total number of steps (leaf nodes in tree aggregation).
max_participation: The maximum number of times a sample can appear.
min_separation: The minimum number of nodes between two appearance of a
sample. If a sample appears in consecutive x, y steps in a streaming
setting, then `min_separation=y-x-1`.
Returns:
The zCDP.
"""
_check_nonnegative(noise_multiplier, "noise_multiplier")
if noise_multiplier == 0:
return np.inf
_check_nonnegative(total_steps, "total_steps")
_check_nonnegative(max_participation, "max_participation")
_check_nonnegative(min_separation, "min_separation")
sum_sensitivity_square = _max_tree_sensitivity_square_sum(
max_participation, min_separation, total_steps)
return _compute_gaussian_zcdp(noise_multiplier, sum_sensitivity_square)

View file

@ -180,6 +180,16 @@ class TreeAggregationTest(tf.test.TestCase, parameterized.TestCase):
tree_aggregation_accountant._max_tree_sensitivity_square_sum(
max_participation, min_separation, steps))
def test_compute_gaussian_zcdp(self):
for sigma in tf.random.uniform([5], minval=0.01, maxval=100).numpy():
for sum_sensitivity_square in tf.random.uniform([5],
minval=0.01,
maxval=1000).numpy():
self.assertEqual(
tree_aggregation_accountant._compute_gaussian_rdp(
sigma, sum_sensitivity_square, alpha=1),
tree_aggregation_accountant._compute_gaussian_zcdp(
sigma, sum_sensitivity_square))
if __name__ == '__main__':
tf.test.main()