Path: blob/master/site/en-snapshot/federated/tutorials/random_noise_generation.ipynb
25118 views
Copyright 2021 The TensorFlow Federated Authors.
Random noise generation in TFF
This tutorial will discuss the recommended best practices for random noise generation in TFF. Random noise generation is an important component of many privacy protection techniques in federated learning algorithms, e.g., differential privacy.
Before we begin
First, let us make sure the notebook is connected to a backend that has the relevant components compiled.
Run the following "Hello World" example to make sure the TFF environment is correctly setup. If it doesn't work, please refer to the Installation guide for instructions.
Random noise on clients
The need for noise on clients generally falls into two cases: identical noise and i.i.d. noise.
For identical noise, the recommended pattern is to maintain a seed on the server, broadcast it to clients, and use the
tf.random.stateless
functions to generate noise.For i.i.d. noise, use a tf.random.Generator initialized on the client with from_non_deterministic_state, in keeping with TF's recommendation to avoid the tf.random.<distribution> functions.
Client behavior is different from server (doesn't suffer from the pitfalls discussed later) because each client will build their own computation graph and initialize their own default seed.
Identical noise on clients
Independent noise on clients
Model initializer on clients
Random noise on the server
Discouraged usage: directly using tf.random.normal
TF1.x like APIs tf.random.normal
for random noise generation are strongly discouraged in TF2 according to the random noise generation tutorial in TF. Surprising behavior may happen when these APIs are used together with tf.function
and tf.random.set_seed
. For example, the following code will generate the same value with each call. This surprising behavior is expected for TF, and explanation can be found in the documentation of tf.random.set_seed
.
In TFF, things are slightly different. If we wrap the noise generation as tff.tf_computation
instead of tf.function
, non-deterministic random noise will be generated. However, if we run this code snippet multiple times, different set of (n1, n2)
will be generated each time. There is no easy way to set a global random seed for TFF.
Moreover, deterministic noise can be generated in TFF without explicitly setting a seed. The function return_two_noise
in the following code snippet returns two identical noise values. This is expected behavior because TFF will build computation graph in advance before execution. However, this suggests users have to pay attention on the usage of tf.random.normal
in TFF.
Usage with care: tf.random.Generator
We can use tf.random.Generator
as suggested in the TF tutorial.
However, users may have to be careful on its usage
tf.random.Generator
usestf.Variable
to maintain the states for RNG algorithms. In TFF, it is recommended to contruct the generator inside atff.tf_computation
; and it is difficult to pass the generator and its state betweentff.tf_computation
functions.the previous code snippet also relies on carefully setting seeds in generators. We may get expected but surprising results (deterministic
n1==n2
) if we usetf.random.Generator.from_non_deterministic_state()
instead.
In general, TFF prefers functional operations and we will showcase the usage of tf.random.stateless_*
functions in the following sections.
In TFF for federated learning, we often work with nested structures instead of scalars and the previous code snippet can be naturally extended to nested structures.
Recommended usage: tf.random.stateless_*
with a helper
A general recommendation in TFF is to use the functional tf.random.stateless_*
functions for random noise generation. These functions take seed
(a Tensor with shape [2]
or a tuple
of two scalar tensors) as an explicit input argument to generate random noise. We first define a helper class to maintain the seed as pseudo state. The helper RandomSeedGenerator
has functional operators in a state-in-state-out fashion. It is reasonable to use a counter as pseudo state for tf.random.stateless_*
as these functions scramble the seed before using it to make noises generated by correlated seeds statistically uncorrelated.
Now let us use the helper class and tf.random.stateless_normal
to generate (nested structure of) random noise in TFF. The following code snippet looks a lot like a TFF iterative process, see simple_fedavg as an example of expressing federated learning algorithm as TFF iterative process. The pseudo seed state here for random noise generation is tf.Tensor
that can be easily transported in TFF and TF functions.