Merge branch 'tensorflow:master' into master
This commit is contained in:
commit
6301f3ffef
3 changed files with 39 additions and 1 deletions
|
@ -84,6 +84,7 @@ py_library(
|
||||||
name = "tree_aggregation_accountant",
|
name = "tree_aggregation_accountant",
|
||||||
srcs = ["tree_aggregation_accountant.py"],
|
srcs = ["tree_aggregation_accountant.py"],
|
||||||
srcs_version = "PY3",
|
srcs_version = "PY3",
|
||||||
|
deps = ["@com_google_differential_py//dp_accounting:accounting"],
|
||||||
)
|
)
|
||||||
|
|
||||||
py_test(
|
py_test(
|
||||||
|
|
|
@ -69,8 +69,9 @@ appearance of a same sample. For `target_delta`, the estimated epsilon is:
|
||||||
|
|
||||||
import functools
|
import functools
|
||||||
import math
|
import math
|
||||||
from typing import Collection, Union
|
from typing import Collection, Optional, Union
|
||||||
|
|
||||||
|
import dp_accounting
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,3 +377,26 @@ def compute_zcdp_single_tree(
|
||||||
sum_sensitivity_square = _max_tree_sensitivity_square_sum(
|
sum_sensitivity_square = _max_tree_sensitivity_square_sum(
|
||||||
max_participation, min_separation, total_steps)
|
max_participation, min_separation, total_steps)
|
||||||
return _compute_gaussian_zcdp(noise_multiplier, sum_sensitivity_square)
|
return _compute_gaussian_zcdp(noise_multiplier, sum_sensitivity_square)
|
||||||
|
|
||||||
|
|
||||||
|
def _gaussian_zcdp_to_epsilon(
|
||||||
|
zcdp: float,
|
||||||
|
target_delta: float = 1e-10,
|
||||||
|
accountant: Optional[dp_accounting.PrivacyAccountant] = None,
|
||||||
|
) -> float:
|
||||||
|
"""Transforms zCDP of Gaussian Mechanism to (epsilon, delta)-DP.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
zcdp: Input zCDP value.
|
||||||
|
target_delta: Specified target delta for (epsilon, delta)-DP.
|
||||||
|
accountant: Defaults to PLD accounting. Other options including RDP, i.e.,
|
||||||
|
dp_accounting.rdp.RdpAccountant()
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Epsilon under given delata for (epsilon, delta)-DP.
|
||||||
|
"""
|
||||||
|
if accountant is None:
|
||||||
|
accountant = dp_accounting.pld.PLDAccountant()
|
||||||
|
noise_multiplier = 1.0 / (zcdp * 2) ** 0.5
|
||||||
|
accountant.compose(dp_accounting.GaussianDpEvent(noise_multiplier), 1)
|
||||||
|
return accountant.get_epsilon(target_delta)
|
||||||
|
|
|
@ -187,6 +187,19 @@ class TreeAggregationTest(tf.test.TestCase, parameterized.TestCase):
|
||||||
tree_aggregation_accountant._compute_gaussian_zcdp(
|
tree_aggregation_accountant._compute_gaussian_zcdp(
|
||||||
sigma, sum_sensitivity_square))
|
sigma, sum_sensitivity_square))
|
||||||
|
|
||||||
|
def test_gaussian_zcdp_to_epsilon(self):
|
||||||
|
# The example below is reported in
|
||||||
|
# https://ai.googleblog.com/2022/02/federated-learning-with-formal.html
|
||||||
|
# Uses updated default RDP order (i.e., orders=None) can achieve better
|
||||||
|
# guarantees. Uses PLD accounting (dp_accounting.pld.PLDAccountant) can
|
||||||
|
# usually be tigher than RDP.
|
||||||
|
zcdp = 0.81
|
||||||
|
orders = [1 + x / 10.0 for x in range(1, 100)] + list(range(12, 64))
|
||||||
|
eps = tree_aggregation_accountant._gaussian_zcdp_to_epsilon(
|
||||||
|
zcdp, accountant=dp_accounting.rdp.RdpAccountant(orders)
|
||||||
|
)
|
||||||
|
self.assertNear(eps, 8.92, err=0.01)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
tf.test.main()
|
tf.test.main()
|
||||||
|
|
Loading…
Reference in a new issue