def __init__(self, params, name='SubsampleGaussian'): Mechanism.__init__(self) self.name = name self.params = { 'prob': params['prob'], 'sigma': params['sigma'], 'coeff': params['coeff'] } # create such a mechanism as in previously subsample = transformer_zoo.AmplificationBySampling( ) # by default this is using poisson sampling mech = GaussianMechanism(sigma=params['sigma']) # Create subsampled Gaussian mechanism SubsampledGaussian_mech = subsample(mech, params['prob'], improved_bound_flag=True) # Now run this for niter iterations compose = transformer_zoo.Composition() mech = compose([SubsampledGaussian_mech], [params['coeff']]) # Now we get it and let's extract the RDP function and assign it to the current mech being constructed rdp_total = mech.RenyiDP self.propagate_updates(rdp_total, type_of_update='RDP')
def __init__(self, sigma, name='Gaussian', RDP_off=False, approxDP_off=False, fdp_off=True, use_basic_RDP_to_approxDP_conversion=False, use_fDP_based_RDP_to_approxDP_conversion=False): # the sigma parameter is the std of the noise divide by the l2 sensitivity Mechanism.__init__(self) self.name = name # When composing self.params = {'sigma': sigma} # This will be useful for the Calibrator # TODO: should a generic unspecified mechanism have a name and a param dictionary? self.delta0 = 0 if not RDP_off: new_rdp = lambda x: rdp_bank.RDP_gaussian({'sigma': sigma}, x) if use_fDP_based_RDP_to_approxDP_conversion: # This setting is slightly more complex, which involves converting RDP to fDP, # then to eps-delta-DP via the duality self.propagate_updates(new_rdp, 'RDP', fDP_based_conversion=True) elif use_basic_RDP_to_approxDP_conversion: self.propagate_updates(new_rdp, 'RDP', BBGHS_conversion=False) else: # This is the default setting with fast computation of RDP to approx-DP self.propagate_updates(new_rdp, 'RDP') if not approxDP_off: # Direct implementation of approxDP new_approxdp = lambda x: dp_bank.get_eps_ana_gaussian(sigma, x) self.propagate_updates(new_approxdp,'approxDP_func') if not fdp_off: # Direct implementation of fDP fun1 = lambda x: fdp_bank.log_one_minus_fdp_gaussian({'sigma': sigma}, x) fun2 = lambda x: fdp_bank.log_neg_fdp_grad_gaussian({'sigma': sigma}, x) self.propagate_updates([fun1,fun2],'fDP_and_grad_log') # overwrite the fdp computation with the direct computation self.fdp = lambda x: fdp_bank.fDP_gaussian({'sigma': sigma}, x)
def __init__(self, sigma, gamma, name='Subsample_Gaussian_phi', lower_bound = False, upper_bound=False): """ sigma: the std of the noise divide by the l2 sensitivity. gamma: the sampling probability. lower_bound: if the lower_bound is True, the privacy cost (delta(epsilon) or delta(epsilon)) is a valid lower bound of the true privacy guarantee besides negligible errors induced by trunction. upper_bound: if the upper_bound is True, the privacy cost (delta(epsilon) or delta(epsilon)) is a valid upper bound of the true privacy guarantee besides negligible errors induced by trunction. """ Mechanism.__init__(self) self.name = name # When composing self.params = {'sigma': sigma,'gamma':gamma} self.delta0 = 0 if lower_bound: # log_phi_p denotes the approximated phi-function of the privacy loss R.V. log(p/q). # log_phi_q denotes the approximated phi-function of the privacy loss R.V. log(q/p). self.log_phi_p = lambda x: phi_bank.phi_subsample_gaussian_p(self.params, x, phi_min = True) self.log_phi_q = lambda x: phi_bank.phi_subsample_gaussian_q(self.params, x, phi_min = True) elif upper_bound: self.log_phi_p = lambda x: phi_bank.phi_subsample_gaussian_p(self.params, x, phi_max=True) self.log_phi_q = lambda x: phi_bank.phi_subsample_gaussian_q(self.params, x, phi_max=True) else: # The following phi_p and phi_q is for Double quadrature method. # Double quadrature method approximates phi-function using Gaussian quadrature directly. self.log_phi_p = lambda x: phi_bank.phi_subsample_gaussian_p(self.params, x) self.log_phi_q = lambda x: phi_bank.phi_subsample_gaussian_q(self.params, x) self.propagate_updates((self.log_phi_p, self.log_phi_q), 'log_phi')
def __init__(self, params, name='GaussianSVT'): Mechanism.__init__(self) self.name = name self.params = {'b': params['b'], 'k': params['k'], 'c': params['c']} new_rdp = lambda x: rdp_bank.RDP_svt_laplace(self.params, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self, b=None, name='Laplace', RDP_off=False, phi_off=True): """ b: the ratio of the scale parameter and L1 sensitivity. RDP_off: if False, then we characterize the mechanism using RDP. fdp_off: if False, then we characterize the mechanism using fdp. phi_off: if False, then we characterize the mechanism using phi-function. """ Mechanism.__init__(self) self.name = name self.params = {'b': b} # This will be useful for the Calibrator self.delta0 = 0 if not phi_off: log_phi_p = lambda x: phi_bank.phi_laplace(self.params, x) log_phi_q = lambda x: phi_bank.phi_laplace(self.params, x) self.log_phi_p = log_phi_p self.log_phi_q = log_phi_q self.propagate_updates((log_phi_p, log_phi_q), 'log_phi') if not RDP_off: new_rdp = lambda x: rdp_bank.RDP_laplace({'b': b}, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self, eps, name='PureDP'): # the eps parameter is the pure DP parameter of this mechanism Mechanism.__init__(self) self.name = name # Used for generating new names when composing self.params = {'eps': eps} # self.propagate_updates(eps, 'pureDP')
def __init__(self,params,name='NoisyScreen'): Mechanism.__init__(self) self.name=name self.params={'logp':params['logp'],'logq':params['logq']} # create such a mechanism as in previously new_rdp = lambda x: rdp_bank.RDP_noisy_screen({'logp': params['logp'], 'logq': params['logq']}, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self,rho,xi=0,name='zCDP_mech'): Mechanism.__init__(self) self.name = name self.params = {'rho':rho,'xi':xi} new_rdp = lambda x: rdp_bank.RDP_zCDP(self.params, x) self.propagate_updates(new_rdp,'RDP')
def __init__(self, p=None, name='Randresponse'): Mechanism.__init__(self) self.name = name self.params = {'p': p} # This will be useful for the Calibrator self.delta0 = 0 if p is not None: new_rdp = lambda x: rdp_bank.RDP_randresponse({'p': p}, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self, b=None, name='Laplace'): Mechanism.__init__(self) self.name = name self.params = {'b': b} # This will be useful for the Calibrator self.delta0 = 0 if b is not None: new_rdp = lambda x: rdp_bank.RDP_laplace({'b': b}, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self, params=None,approxDP_off=False, name='StageWiseMechanism'): # the sigma parameter is the std of the noise divide by the l2 sensitivity Mechanism.__init__(self) self.name = name # When composing self.params = {'sigma': params['sigma'], 'k':params['k'], 'c':params['c']} self.delta0 = 0 if not approxDP_off: # Direct implementation of approxDP new_approxdp = lambda x: dp_bank.eps_generalized_gaussian(x, **params) self.propagate_updates(new_approxdp, 'approxDP_func')
def __init__(self,params,name='GaussianSVT', rdp_c_1=True): Mechanism.__init__(self) self.name=name if rdp_c_1 == True: self.name = name + 'c_1' self.params = {'sigma': params['sigma'], 'k': params['k'], 'margin':params['margin']} new_rdp = lambda x: rdp_bank.RDP_gaussian_svt_c1(self.params, x) else: self.name = name + 'c>1' self.params = {'sigma':params['sigma'],'k':params['k'], 'c':params['c']} new_rdp = lambda x: rdp_bank.RDP_gaussian_svt_cgreater1(self.params, x) self.propagate_updates(new_rdp, 'RDP')
def __init__(self, sigma=None, name='Gaussian'): # the sigma parameter is the std of the noise divide by the l2 sensitivity Mechanism.__init__(self) self.name = name # When composing self.params = {'sigma': sigma} # This will be useful for the Calibrator self.delta0 = 0 if sigma is not None: new_rdp = lambda x: rdp_bank.RDP_gaussian({'sigma': sigma}, x) self.propagate_updates(new_rdp, 'RDP') # Overwrite the approxDP and fDP with their direct computation self.approxDP = lambda x: dp_bank.get_eps_ana_gaussian(sigma, x) self.fDP = lambda x: fdp_bank.fDP_gaussian({'sigma': sigma}, x)
def __init__(self, params, name='SubsampleGaussian'): Mechanism.__init__(self) self.name = name self.params = {'sigma': params['sigma'], 'coeff': params['coeff']} # create such a mechanism as in previously mech = GaussianMechanism(sigma=params['sigma']) # Now run this for coeff iterations compose = transformer_zoo.Composition() mech = compose([mech], [params['coeff']]) # Now we get it and let's extract the RDP function and assign it to the current mech being constructed rdp_total = mech.RenyiDP self.propagate_updates(rdp_total, type_of_update='RDP')
def __init__(self, p=None, RDP_off=False, phi_off=True, name='Randresponse'): """ p: the Bernoulli probability p of outputting the truth. """ Mechanism.__init__(self) self.name = name self.params = {'p': p} self.delta0 = 0 if not RDP_off: new_rdp = lambda x: rdp_bank.RDP_randresponse({'p': p}, x) self.propagate_updates(new_rdp, 'RDP') approxDP = lambda x: dp_bank.get_eps_randresp_optimal(p, x) self.propagate_updates(approxDP, 'approxDP_func') if not phi_off: log_phi = lambda x: phi_bank.phi_rr_p({'p': p, 'q':1-p}, x) self.log_phi_p = self.log_phi_q = log_phi self.propagate_updates((self.log_phi_p, self.log_phi_q), 'log_phi')
def __init__(self, prob, sigma, niter, PoissonSampling=True, name='NoisySGD'): Mechanism.__init__(self) self.name = name self.params = {'prob': prob, 'sigma': sigma, 'niter': niter, 'PoissonSampling': PoissonSampling} # create such a mechanism as in previously subsample = transformer_zoo.AmplificationBySampling(PoissonSampling=PoissonSampling) # by default this is using poisson sampling mech = ExactGaussianMechanism(sigma=sigma) prob = 0.01 # Create subsampled Gaussian mechanism SubsampledGaussian_mech = subsample(mech, prob, improved_bound_flag=True) # for Gaussian mechanism the improved bound always applies # Now run this for niter iterations compose = transformer_zoo.Composition() mech = compose([SubsampledGaussian_mech], [niter]) # Now we get it and let's extract the RDP function and assign it to the current mech being constructed rdp_total = mech.RenyiDP self.propagate_updates(rdp_total, type_of_update='RDP')
def __init__(self, sigma, name='Gaussian', RDP_off=False, approxDP_off=False, fdp_off=True, use_basic_RDP_to_approxDP_conversion=False, use_fDP_based_RDP_to_approxDP_conversion=False, phi_off=True): """ sigma: the std of the noise divide by the l2 sensitivity. coeff: the number of composition RDP_off: if False, then we characterize the mechanism using RDP. fdp_off: if False, then we characterize the mechanism using fdp. phi_off: if False, then we characterize the mechanism using phi-function. """ Mechanism.__init__(self) self.name = name # When composing self.params = {'sigma': sigma} # This will be useful for the Calibrator # TODO: should a generic unspecified mechanism have a name and a param dictionary? self.delta0 = 0 if not phi_off: """ Apply phi function to analyze Gaussian mechanism. the CDF of privacy loss R.V. is computed using an integration (see details in cdf_bank) through Levy Theorem. If self.exactPhi = True, the algorithm provides an exact characterization. """ self.exactPhi = True log_phi = lambda x: phi_bank.phi_gaussian({'sigma': sigma}, x) self.log_phi_p = self.log_phi_q = log_phi # self.cdf tracks the cdf of log(p/q) and the cdf of log(q/p). self.propagate_updates((log_phi, log_phi), 'log_phi') """ Moreover, we know the closed-form expression of the CDF of the privacy loss RV privacy loss RV distribution l=log(p/q) ~ N(1/2\sigma^2, 1/sigma^2) We can also use the following closed-form cdf directly. """ #sigma = sigma*1.0/np.sqrt(coeff) #mean = 1.0 / (2.0 * sigma ** 2) #std = 1.0 / (sigma) #cdf = lambda x: norm.cdf((x - mean) / std) #self.propagate_updates(cdf, 'cdf', take_log=True) if not RDP_off: new_rdp = lambda x: rdp_bank.RDP_gaussian({'sigma': sigma}, x) if use_fDP_based_RDP_to_approxDP_conversion: # This setting is slightly more complex, which involves converting RDP to fDP, # then to eps-delta-DP via the duality self.propagate_updates(new_rdp, 'RDP', fDP_based_conversion=True) elif use_basic_RDP_to_approxDP_conversion: self.propagate_updates(new_rdp, 'RDP', BBGHS_conversion=False) else: # This is the default setting with fast computation of RDP to approx-DP self.propagate_updates(new_rdp, 'RDP') if not approxDP_off: # Direct implementation of approxDP new_approxdp = lambda x: dp_bank.get_eps_ana_gaussian(sigma, x) self.propagate_updates(new_approxdp,'approxDP_func') if not fdp_off: # Direct implementation of fDP fun1 = lambda x: fdp_bank.log_one_minus_fdp_gaussian({'sigma': sigma}, x) fun2 = lambda x: fdp_bank.log_neg_fdp_grad_gaussian({'sigma': sigma}, x) self.propagate_updates([fun1,fun2],'fDP_and_grad_log') # overwrite the fdp computation with the direct computation self.fdp = lambda x: fdp_bank.fDP_gaussian({'sigma': sigma}, x)