问题描述
我正在关注this tutorial,以开始使用tensorflow联合。我的目标是在将客户端梯度值发送到服务器之前对其进行一些操作来运行联邦sgd(而非联邦avg)。
在继续操作之前,为简要地重申联邦sgd流程,客户端每转一圈,客户端会将其计算出的梯度(未更新的权重)发送到服务器,服务器将其汇总并向客户端广播更新的模型。
现在,到目前为止,我可以使用上述教程中的函数build_federated_sgd_process
代替build_federated_averaging_process
来以上述方式执行联合sgd。
我迷路的地方是,在将渐变发送到服务器之前,我需要裁剪客户端渐变并为其添加一些噪音(针对每个渐变值独立生成),我不确定该怎么做。生成噪声足够简单,但是我应该修改/实现哪个函数才能将噪声应用于梯度?
解决方法
build_federated_sgd_process
已完全罐装;它实际上是设计为参考实现,而不是可扩展性。
我相信您正在寻找的是build_federated_sgd_process
在“ tff.learning.framework.build_model_delta_optimizer_process
”下调用的函数。此函数使您可以提供自己的从模型函数(即,一个可返回tff.learning.Model
的零参数可调用对象,返回tff.learning.framework.ClientDeltaFn
)的映射。
您的ClientDeltaFn
类似于:
@tf.function
def _clip_and_noise(grads):
return ...
class ClippedGradClientDeltaFn(tff.learning.framework.ClientDeltaFn)
def __init__(self,model,...):
self._model = model
...
@tf.function
def __call__(dataset,weights):
# Compute gradients grads
return _clip_and_noise(grads)
您将可以通过调用以下命令来构建tff.templates.IterativeProcess
:
def clipped_sgd(model_fn: Callable[[],model_lib.Model]) -> ClippedGradClientDeltaFn:
return ClippedGradClientDeltaFn(
model_fn(),...)
iterproc = optimizer_utils.build_model_delta_optimizer_process(
model_fn,model_to_client_delta_fn=clipped_sgd,...)
在build_federated_sgd_process
的正文中或多或少。
在我看来,您对差异化隐私感兴趣;实际上,TFF的设计通常是通过聚合过程而不是编写不同的客户端更新来实现差异性隐私,尽管这当然是一种方法。请参见TFF for research documentation的指针,以了解将差异隐私连接到TFF的惯用方法。