yuxiangw / autodp

autodp: A flexible and easy-to-use package for differential privacy
Apache License 2.0
260 stars 52 forks source link

AFA of composition of subsampled Laplace Mechanism breaks down #34

Open zhuyizheng opened 2 years ago

zhuyizheng commented 2 years ago

Following the tutorial here, I tried to compute optimal accounting of composition of subsampled Gaussian and Laplace Mechanisms:

from autodp.mechanism_zoo import GaussianMechanism, LaplaceMechanism
from autodp.transformer_zoo import ComposeAFA
from autodp.transformer_zoo import AmplificationBySampling_pld

sigma = 1.0
b = 1.0
delta = 1e-5
prob=.1

gm1 = GaussianMechanism(sigma, phi_off=False, name='phi_GM1')
lm1 = LaplaceMechanism(b, phi_off=False, name='phi_LM1')

transformer_remove_only = AmplificationBySampling_pld(PoissonSampling=True, neighboring='remove_only')
transformer_add_only = AmplificationBySampling_pld(PoissonSampling=True, neighboring='add_only')
sample_gau_remove_only =transformer_remove_only(gm1, prob)
sample_lap_remove_only =transformer_remove_only(lm1, prob)
compose_gm = ComposeAFA()
compose_lm = ComposeAFA()
composed_gm_afa = compose_gm([sample_gau_remove_only], [10])
composed_lm_afa = compose_lm([sample_lap_remove_only], [10])

eps_gm_afa = composed_gm_afa.get_approxDP(delta)
eps_lm_afa = composed_lm_afa.get_approxDP(delta)

The Gaussian proceeds normally. The Laplace breaks down with the following error:

  File "AUTODPHOME/gmvslm.py", line 25, in <module>
    eps_lm_afa = composed_lm_afa.get_approxDP(delta)
  File "AUTODPHOME/autodp/autodp_core.py", line 113, in get_approxDP
    return self.approxDP(delta)
  File "AUTODPHOME/autodp/converter.py", line 1118, in min_f1_f2
    return np.minimum(f1(x), f2(x))
  File "AUTODPHOME/autodp/converter.py", line 824, in approxdp
    t = exp_eps(1 - delta)
  File "AUTODPHOME/autodp/converter.py", line 1080, in inv_f
    results = minimize_scalar(normal_equation, bounds=bounds, bracket=[1,2], tol=tol)
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/optimize/_minimize.py", line 879, in minimize_scalar
    return _minimize_scalar_brent(fun, bracket, args, **options)
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/optimize/_optimize.py", line 2511, in _minimize_scalar_brent
    brent.optimize()
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/optimize/_optimize.py", line 2281, in optimize
    xa, xb, xc, fa, fb, fc, funcalls = self.get_bracket_info()
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/optimize/_optimize.py", line 2257, in get_bracket_info
    xa, xb, xc, fa, fb, fc, funcalls = bracket(func, xa=brack[0],
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/optimize/_optimize.py", line 2765, in bracket
    fa = func(*(xa,) + args)
  File "AUTODPHOME/autodp/converter.py", line 1077, in normal_equation
    return abs(fun(x))
  File "AUTODPHOME/autodp/converter.py", line 1073, in fun
    return f(x) - y
  File "AUTODPHOME/autodp/converter.py", line 818, in trade_off
    result = cdf_p(log_e) + x*cdf_q(-log_e)
  File "AUTODPHOME/autodp/autodp_core.py", line 324, in <lambda>
    cdf_p2q = lambda x: converter.phi_to_cdf(log_phi_p2q, x, n_quad = n_quad)
  File "AUTODPHOME/autodp/converter.py", line 924, in phi_to_cdf
    res = integrate.fixed_quad(inte_f, -1.0, 1.0, n =n_quad)
  File "AUTODPHOME/venv/lib/python3.8/site-packages/scipy/integrate/_quadrature.py", line 151, in fixed_quad
    return (b-a)/2.0 * np.sum(w*func(y, *args), axis=-1), None
  File "AUTODPHOME/autodp/converter.py", line 923, in <lambda>
    inte_f = lambda t: qua(t) * (1 + t ** 2) / ((1 - t ** 2) ** 2)
  File "AUTODPHOME/autodp/converter.py", line 919, in qua
    phi_result = [log_phi(x) for x in new_t]
  File "AUTODPHOME/autodp/converter.py", line 919, in <listcomp>
    phi_result = [log_phi(x) for x in new_t]
  File "AUTODPHOME/autodp/transformer_zoo.py", line 111, in new_log_phi_p2q
    return sum([c * mech.log_phi_p2q(x) for (mech, c) in zip(mechanism_list, coeff_list)])
  File "AUTODPHOME/autodp/transformer_zoo.py", line 111, in <listcomp>
    return sum([c * mech.log_phi_p2q(x) for (mech, c) in zip(mechanism_list, coeff_list)])
TypeError: unsupported operand type(s) for *: 'int' and 'NoneType'
yuxiangw commented 1 year ago

Thanks for submitting the issue! @jeremy43 is this tutorial example working reliably now?