def _make_test_accountants(self): return [ rdp_privacy_accountant.RdpAccountant( [2.0], privacy_accountant.NeighboringRelation.ADD_OR_REMOVE_ONE), rdp_privacy_accountant.RdpAccountant( [2.0], privacy_accountant.NeighboringRelation.REPLACE_ONE), rdp_privacy_accountant.RdpAccountant( [2.0], privacy_accountant.NeighboringRelation.REPLACE_SPECIAL) ]
def test_compute_rdp_gaussian(self): alpha = 3.14159 sigma = 2.71828 event = dp_event.GaussianDpEvent(sigma) accountant = rdp_privacy_accountant.RdpAccountant(orders=[alpha]) accountant.compose(event) self.assertAlmostEqual(accountant._rdp[0], alpha / (2 * sigma**2))
def test_zero_fixed_batch_sample(self): accountant = rdp_privacy_accountant.RdpAccountant( [3.14159], privacy_accountant.NeighboringRelation.REPLACE_ONE) accountant.compose( dp_event.SampledWithoutReplacementDpEvent( 1000, 0, dp_event.GaussianDpEvent(1.0))) self.assertEqual(accountant.get_epsilon(1e-10), 0) self.assertEqual(accountant.get_delta(1e-10), 0)
def test_supports(self): aor_accountant = rdp_privacy_accountant.RdpAccountant( [2.0], privacy_accountant.NeighboringRelation.ADD_OR_REMOVE_ONE) ro_accountant = rdp_privacy_accountant.RdpAccountant( [2.0], privacy_accountant.NeighboringRelation.REPLACE_ONE) event = dp_event.GaussianDpEvent(1.0) self.assertTrue(aor_accountant.supports(event)) self.assertTrue(ro_accountant.supports(event)) event = dp_event.SelfComposedDpEvent(dp_event.GaussianDpEvent(1.0), 6) self.assertTrue(aor_accountant.supports(event)) self.assertTrue(ro_accountant.supports(event)) event = dp_event.ComposedDpEvent( [dp_event.GaussianDpEvent(1.0), dp_event.GaussianDpEvent(2.0)]) self.assertTrue(aor_accountant.supports(event)) self.assertTrue(ro_accountant.supports(event)) event = dp_event.PoissonSampledDpEvent(0.1, dp_event.GaussianDpEvent(1.0)) self.assertTrue(aor_accountant.supports(event)) self.assertFalse(ro_accountant.supports(event)) composed_gaussian = dp_event.ComposedDpEvent( [dp_event.GaussianDpEvent(1.0), dp_event.GaussianDpEvent(2.0)]) event = dp_event.PoissonSampledDpEvent(0.1, composed_gaussian) self.assertTrue(aor_accountant.supports(event)) self.assertFalse(ro_accountant.supports(event)) event = dp_event.SampledWithoutReplacementDpEvent( 1000, 10, dp_event.GaussianDpEvent(1.0)) self.assertFalse(aor_accountant.supports(event)) self.assertTrue(ro_accountant.supports(event)) event = dp_event.SampledWithoutReplacementDpEvent(1000, 10, composed_gaussian) self.assertFalse(aor_accountant.supports(event)) self.assertTrue(ro_accountant.supports(event)) event = dp_event.SampledWithReplacementDpEvent( 1000, 10, dp_event.GaussianDpEvent(1.0)) self.assertFalse(aor_accountant.supports(event)) self.assertFalse(ro_accountant.supports(event))
def test_no_tree_no_sampling(self, total_steps, noise_multiplier): orders = [1 + x / 10 for x in range(1, 100)] + list(range(12, 64)) tree_rdp = _compose_trees(noise_multiplier, [1] * total_steps, orders)._rdp accountant = rdp_privacy_accountant.RdpAccountant(orders) event = dp_event.SelfComposedDpEvent( dp_event.GaussianDpEvent(noise_multiplier), total_steps) accountant.compose(event) base_rdp = accountant._rdp self.assertTrue(np.allclose(tree_rdp, base_rdp, rtol=1e-12))
def _compose_trees(noise_multiplier, step_counts, orders): accountant = rdp_privacy_accountant.RdpAccountant( orders, privacy_accountant.NeighboringRelation.REPLACE_SPECIAL) accountant.compose( dp_event.ComposedDpEvent([ dp_event.SingleEpochTreeAggregationDpEvent(noise_multiplier, step_count) for step_count in step_counts ])) return accountant
def test_epsilon_delta_consistency(self): orders = range(2, 50) # Large range of orders (helps test for overflows). for q in [0, 0.01, 0.1, 0.8, 1.]: for multiplier in [0.0, 0.1, 1., 10., 100.]: event = dp_event.PoissonSampledDpEvent( q, dp_event.GaussianDpEvent(multiplier)) accountant = rdp_privacy_accountant.RdpAccountant(orders) accountant.compose(event) for delta in [.99, .9, .1, .01, 1e-3, 1e-5, 1e-9, 1e-12]: epsilon = accountant.get_epsilon(delta) delta2 = accountant.get_delta(epsilon) if np.isposinf(epsilon): self.assertEqual(delta2, 1.0) elif epsilon == 0: self.assertLessEqual(delta2, delta) else: self.assertAlmostEqual(delta, delta2)
def test_compute_rdp_multi_gaussian(self): alpha = 3.14159 sigma1, sigma2 = 2.71828, 6.28319 rdp1 = alpha / (2 * sigma1**2) rdp2 = alpha / (2 * sigma2**2) rdp = rdp1 + rdp2 accountant = rdp_privacy_accountant.RdpAccountant(orders=[alpha]) accountant.compose( dp_event.PoissonSampledDpEvent( 1.0, dp_event.ComposedDpEvent([ dp_event.GaussianDpEvent(sigma1), dp_event.GaussianDpEvent(sigma2) ]))) self.assertAlmostEqual(accountant._rdp[0], rdp)
def test_compute_rdp_poisson_sampled_gaussian(self): orders = [1.5, 2.5, 5, 50, 100, np.inf] noise_multiplier = 2.5 sampling_probability = 0.01 count = 50 event = dp_event.SelfComposedDpEvent( dp_event.PoissonSampledDpEvent( sampling_probability, dp_event.GaussianDpEvent(noise_multiplier)), count) accountant = rdp_privacy_accountant.RdpAccountant(orders=orders) accountant.compose(event) self.assertTrue( np.allclose( accountant._rdp, [ 6.5007e-04, 1.0854e-03, 2.1808e-03, 2.3846e-02, 1.6742e+02, np.inf ], rtol=1e-4))
def test_tree_wrong_neighbor_rel(self, neighboring_relation): event = dp_event.SingleEpochTreeAggregationDpEvent(1.0, 1) accountant = rdp_privacy_accountant.RdpAccountant( neighboring_relation=neighboring_relation) self.assertFalse(accountant.supports(event))
def _get_test_rdp(event, count=1): accountant = rdp_privacy_accountant.RdpAccountant(orders=[2.71828]) accountant.compose(event, count) return accountant._rdp[0]
def test_epsilon_non_private_gaussian(self): accountant = rdp_privacy_accountant.RdpAccountant([3.14159]) accountant.compose(dp_event.GaussianDpEvent(0)) self.assertEqual(accountant.get_epsilon(1e-1), np.inf)
def test_zero_poisson_sample(self): accountant = rdp_privacy_accountant.RdpAccountant([3.14159]) accountant.compose( dp_event.PoissonSampledDpEvent(0, dp_event.GaussianDpEvent(1.0))) self.assertEqual(accountant.get_epsilon(1e-10), 0) self.assertEqual(accountant.get_delta(1e-10), 0)