Path: blob/master/site/zh-cn/federated/tutorials/random_noise_generation.ipynb
25118 views
Copyright 2021 The TensorFlow Federated Authors.
TFF 中的随机噪声生成
本教程将讨论 TFF 中随机噪声生成的推荐最佳做法。随机噪声生成是联合学习算法中许多隐私保护技术(如差分隐私)的重要组成部分。
准备工作
首先,让我们确保笔记本连接到已编译相关组件的后端。
请运行以下“Hello World”示例以确保正确设置 TFF 环境。如果无效,请参阅安装指南查看说明。
客户端上的随机噪声
客户端对噪声的需求一般分为两种情况:相同噪声和独立同分布噪声。
对于相同噪声,推荐模式是在服务器上维护一个种子,将其广播给客户端,并使用
tf.random.stateless
函数来生成噪声。对于独立同分布噪声,请使用在客户端上通过 from_non_deterministic_state 初始化的 tf.random.Generator 以符合 TF 的建议,从而避免使用 tf.random.<distribution> 函数。
客户端行为与服务器不同(不受后面讨论的陷阱影响),因为每个客户端都将构建自己的计算图并初始化自己的默认种子。
客户端上的相同噪声
客户端上的独立噪声
客户端上的模型初始化器
服务器上的随机噪声
不鼓励使用:直接使用 tf.random.normal
根据 TF 中的随机噪声生成教程,强烈建议不要在 TF2 中使用 TF1.x 之类的 API tf.random.normal
来生成随机噪声。当这些 API 与 tf.function
和 tf.random.set_seed
一起使用时,可能会发生出人意料的行为。例如,以下代码将在每次调用时生成相同的值。TF 会出现这种出人意料的行为,可以在 tf.random.set_seed
的文档中找到解释。
在 TFF 中,情况略有不同。如果我们将噪声生成包装为 tff.tf_computation
而不是 tf.function
,则会生成非确定性随机噪声。但是,如果我们多次运行此代码段,每次都会生成不同的 (n1, n2)
集。为 TFF 设置全局随机种子没有捷径。
此外,可以在 TFF 中生成确定性噪声,而无需显式设置种子。以下代码段中的函数 return_two_noise
返回两个相同的噪声值。这是预期的行为,因为 TFF 将在执行之前提前构建计算图。但是,这暗示用户必须注意 tf.random.normal
在 TFF 中的用法。
小心使用:tf.random.Generator
我们可以按照 TF 教程中的建议使用 tf.random.Generator
。
但是,用户可能必须小心谨慎地使用它
tf.random.Generator
使用tf.Variable
来维护 RNG 算法的状态。在 TFF 中,建议在tff.tf_computation
中构建生成器;很难在tff.tf_computation
函数之间传递生成器及其状态。前面的代码段还依赖于在生成器中仔细设置种子。如果我们改用
tf.random.Generator.from_non_deterministic_state()
,则可能得到预期但出人意料的结果(确定性的n1==n2
)。
一般而言,TFF 更倾向于函数式运算,我们将在以下部分中展示 tf.random.stateless_*
函数的用法。
在联合学习的 TFF 中,我们经常使用嵌套结构而不是标量,并且前面的代码段可以自然地扩展为嵌套结构。
推荐使用:带辅助函数的 tf.random.stateless_*
TFF 中的一般建议是使用函数式 tf.random.stateless_*
函数生成随机噪声。这些函数将 seed
(形状为 [2]
的张量或两个标量张量的 tuple
)作为显式输入参数来生成随机噪声。我们首先定义一个辅助函数类来将种子保持为伪状态。辅助函数 RandomSeedGenerator
具有状态输入状态输出形式的函数算子。使用计数器作为 tf.random.stateless_*
的伪状态是合理的,因为这些函数在使用种子之前会对其进行加扰,从而使相关联种子产生的噪声在统计上不相关。
现在,让我们使用辅助函数类和 tf.random.stateless_normal
在 TFF 中生成随机噪声(的嵌套结构)。以下代码段看起来很像 TFF 迭代过程,请参阅 simple_fedavg 作为将联合学习算法表达为 TFF 迭代过程的示例。此处用于随机噪声生成的伪种子状态是 tf.Tensor
,可以在 TFF 和 TF 函数中轻松传输。