There are a few ways to perform this calculation. We will discuss two options below.
Re-purposing DPSGD analysis tools
You are correct that these tools accept parameters which are named for the DP-SGD setting; however, their arguments can be remapped to the federated setting in a fairly straightforward manner.
Suppose we have the symbol apply_dp_sgd_analysis
from TFP's analysis library. We can write a simple function that essentially modifies the body of compute_dp_sgd_privacy
for the federated setting:
def compute_fl_privacy(num_rounds, noise_multiplier, num_users, users_per_round):
# This actually assumes Poisson subsampling, which may not be *quite*
# right in your setting, but the approximation should be close either way.
q = users_per_round / num_users # q - the sampling ratio.
# These orders are inlined from the body of compute_dp_sgd_privacy
orders = ([1.25, 1.5, 1.75, 2., 2.25, 2.5, 3., 3.5, 4., 4.5] +
list(range(5, 64)) + [128, 256, 512])
# Depending on whether your TFF code by default uses adaptive clipping or not,
# you may need to rescale your noise_multiplier argument.
return apply_dp_sgd_analysis(
q, sigma=noise_multiplier, steps=num_rounds, orders=orders, delta=num_users ** (-1))
Using TFP PrivacyLedger
If you're using the relatively new tff.aggregators.DifferentiallyPrivateFactory
(which I would suggest over the DP process used above), you can pass an already-constructed DPQuery
, which can be decorated with a PrivacyLedger
. This ledger could then be passed directly into a function like compute_rdp_from_ledger
, and it should have tracked the privacy spent from each of the query calls.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…