通常,TFF 将数据的馈送视为“Python 驱动程序循环”的一部分,这在编写 TFF 代码时有助于区分。
其实在写TFF的时候,一般可以写三个层次:
- TensorFlow 定义本地处理(IE,将发生在客户端、服务器、聚合器或任何其他可能需要的位置的处理,但只有一个位置。
- 本机 TFF 定义了跨展示位置的数据通信方式。例如,在装饰器
tff.federated_sum
内部编写;tff.federated_computation
编写此行声明“此数据从客户端移动到服务器,并通过 sum 运算符聚合”。
- Python “驱动” TFF 循环,例如运行单轮。最后一层的工作是做一个“真正的”联邦学习运行时会做的事情;这里的一个例子是为给定的一轮选择客户。
如果牢记这一细分,使用生成器或其他一些惰性评估风格的构造将数据输入到联合计算中会变得相对简单;它只是在 Python 级别完成的。
可以做到这一点的一种方法是通过对象create_tf_dataset_for_client
上的方法ClientData
;当您循环循环时,您的 Python 代码可以从 列表中进行选择client_ids
,然后您可以实例化一个新列表tf.data.Datasets
并将它们作为您的新客户端数据集传递。这种相对简单的用法示例在这里,一个更高级的用法(包括定义一个作为参数的自定义client_datasets_fn
,client_id
并将其传递给单独定义的训练循环将在这里,在与本文相关的代码中。
最后一点:实例化 atf.data.Dataset
并不实际将数据集加载到内存中;数据集仅在迭代时加载。我从第一作者那里收到的一个有用的提示tf.data.Dataset
是将tf.data.Dataset
更多地视为“数据集配方”,而不是数据集本身的文字实例化。有人建议,DataSource
这个构造可能有一个更好的名称;希望这可能有助于心理模型了解实际发生的情况。类似地,使用该tff.simulation.ClientData
对象通常不应该真正将任何东西加载到内存中,直到它在客户端的训练中被迭代;这应该使管理数据集内存的一些细微差别更简单。