如何使用TensorFlow的联合学习

344 阅读6分钟

使用TensorFlow的联邦学习法

集中式机器学习涉及到模型和数据集在同一设备上的问题。谷歌等公司将数据上传到云端以训练他们的机器学习模型。

联合学习翻转了这种模式。我们不是将数据传输到云端,而是将基于云的模型发送到我们的设备上。然后这些模型在我们的设备上进行本地训练。

一旦我们在本地训练了这些模型,更新的模型就会被发送到服务器上,而不是数据。服务器检查这些模型,然后更新云上的全球模型。这个过程被称为Federated Learning

TensorFlow Federated是谷歌的一个开源框架,用于实现联合学习。

目标

在这篇文章中,我们将学习研究人员和机器学习专家如何利用TensorFlow Federated来实现数据集的联合学习。

前提条件

为了理解本文的内容,你需要熟悉。

  • Python编程语言。
  • TensorFlow机器学习框架。
  • 联合学习。
  • [NIST数据集]

TensorFlow Federated (TFF)简介

TFF是一个开源的框架,用于在分散的数据上进行联合学习。它由谷歌带头,并在最近几年得到了普及。

TFF有三个主要特点。

  1. TFF是架构无关的。

这意味着它可以将所有的代码编译成一个抽象的表示。因此,它可以被部署在不同的环境中。

  1. TFF节省了精力。

它的设计是为了减轻我们开发人员在开发联合学习系统时所面临的痛点。

其中的一些挑战包括不同类型的逻辑交错,全局与局部的沟通角度,以及构建与执行顺序之间的矛盾。

  1. TFF有很多扩展。

一些可用的扩展包括差分隐私、压缩和量化。

TensorFlow的联合层

TFF提供两个主要层。

  1. 联合学习(FL)API FL API是一个实现联合训练和评估的高级API。它可以应用于现有的TensorFlow模型或数据。

  2. 联合核心(FC)API FC是在联合学习API下面的一个低层次框架。这个API提供了通用表达式来运行和模拟自定义类型的计算,以及控制你自己的协调。它也有一个支持模拟的本地运行时间。

在本教程中,我们将重点介绍FL API和它背后的代码。

联合学习的应用

根据你的兴趣,你可以有不同的方式参与进来。

  1. 一个机器学习开发者可以将联合学习API应用到现有的TensorFlow模型中。

  2. 一个联合学习研究者可以帮助设计新的使用FC API的联合学习算法。

  3. 一个系统研究人员可以协助优化生成的计算结构。

  4. 一个系统开发人员可以帮助将TFF与不同的开发环境集成。

TensorFlow联盟(TFF)背后的代码

首先,让我们简单看一下Keras模型的样子。

    def create_compiled_keras_model():
        model = tf.keras.models.Sequential([
            tf.keras.layers.Dense(
                10, activation=tf.nn.softmax, kernel_initializer = 'zeros', input_shape = (784, 
                )
            )
        ])

        model.compile(
            loss=tf.keras.losses.SparseCategoricalCrossentropy(),
            optimizer=tf.keras.optimizers.SGD(learning_rate=0.02),
            metrics=[tf.keras.metrics.SparseCategoricalAccuracy()] 

        )
    return model

Keras 模型使用的是Sequential() API,因为它允许我们逐层创建模型。这对于解决简单的神经网络问题是很理想的。

然而,对于共享层或有许多输入/输出的复杂网络,如残差和连体网络,它并不理想。

在这种情况下,要使用functional APIs。功能性API有更大的灵活性,因为人们可以很容易地定义各层连接到不止是上一层和下一层的模型。

请参考下面的视频,深入了解这些差异。

我们将使用create_compiled_keras_model() 方法将其导入到我们的主函数model_fn

    def model_fn():

        keras_model = create_compiled_keras_model()

        return tff.learning.from_compiled_keras_model(keras_model, sample_batch)

上面的代码显示了你将添加Keras模型的地方。

     state = train.initialize() 

    for _ in range (5):
        state, metrics = train.next(state, train_data)
        print (metrics.loss) 

在上面的代码中,initialize() 方法检索了初始服务器状态。然后它调用train.next ,该方法将运行我们的联合训练。这包括向每个客户端发送初始服务器状态。

每个客户端将运行自己的本地训练轮次,然后向服务器发送一个更新。服务器存储从分散的数据中产生的新的聚合的全球模型。

    eval = tff.learning.build_federated_evaluation(model_fn)
    metrics = eval(state.model, test_data)

最后,我们可以进行联合评估,以了解我们训练的模型的状态。build_federated_evaluation() 方法有助于执行这种联合评估。

下面是TFF的整个代码的样子。


    train_data, test_data = 
    tff.simulation.datasets.emnist.load_data()

    def model_fn():

        keras_model = create_keras_model()

        return tff.learning.from_keras_model(keras_model, sample_batch)
    
    train = tff.learning.build_federated_averaging_process(model_fn)

    state = train.initialize() 

    for _ in range (5):
        state, metrics = train.next(state, train_data)
        print (metrics.loss) 

    eval = tff.learning.build_federated_evaluation(model_fn)
    metrics = eval(state.model, test_data)

综上所述,FL API的一般组件包括。

  1. 模型
  • tff.learning.Model

  • create_keras_model()

  1. 联合计算构建器 TFF提供了两个构建器函数。
  • tff.learning.build_federated_averaging_process 生成联合训练的联合计算。

  • tff.learning.build_federated_evaluation 生成用于联合评估的联合计算。

让我们用MNIST训练的例子来介绍TFF的联合学习(FL)API层。

第1步:安装TensorFlow联合计算

在将TensorFlow Federated导入你的笔记本之前,请确保安装它。如果不这样做,可能会导致一个错误。

我们使用以下命令来安装TensorFlow Federated。

pip install tensorflow-federated --upgrade

第2步:将依赖项导入我们的笔记本中

import tensorflow as tf
import tensorflow_federated as tff

我们已经将tensorflowtensorflow federated 导入到我们的项目中。

第3步:模拟数据集

emnist_train, emnist_test = tff.simulation.datasets.emnist.load_data()
def client_data(n):
  return emnist_train.create_tf_dataset_for_client(source.client_ids[n]).map(
      lambda e: (tf.reshape(e['pixels'], [-1]), e['label'])
  ).repeat(10).batch(20)
  

使用的模拟数据集是MNIST数据集的联合版本,称为NIST,由Leaf项目提供。Leaf为联合学习提供了一个基准框架。

为什么是联盟版的数据集?

这是因为FL中的数据集是从多个用户那里获得的。这带来了一系列独特的挑战,而普通版本的数据集并没有表现出来。

我们使用load_data() 功能将联合数据导入项目中。

第4步:使用联合数据进行训练

train_data = [client_data(n) for n in range(3)]

trainer = tff.learning.build_federated_averaging_process(
  model_fn,
  client_optimizer_fn=lambda: tf.keras.optimizers.SGD(0.1))
state = trainer.initialize()
for _ in range(50):
  state, metrics = trainer.next(state, train_data)
  print(metrics['train']['loss'])

在训练部分,你会注意到只有一个客户端设备的子集被选择来接受训练模型。这是因为不是所有的设备都有资格。在任何时候,只有少数设备可能有相关数据来解决你的问题。

12.931682
13.094639
12.765134
11.813275
11.521152
10.681865
10.033001
......
......
......
0.038877
0.03537092
0.032601092
0.030380366
0.028545696
0.02700758

在TFF中,在选定的设备上训练完模型后,会得到结果并计算损失。

在上面的实验中,每一轮联合训练后,训练损失都在减少,表明模型正在收敛。

我们将训练设定为50轮。训练结束时的训练损失是0.02700758 ,比训练开始时记录的12.931682

在现实情况下,用户可以自由加入和退出实验。这意味着,人们会在每一轮中随机选择一个用户样本。然而,为了使事情变得简单,并使系统迅速收敛,我们将重复使用相同的用户。

实施总结

请随意修改参数,如批次大小、用户数量、epochs和学习率,以模拟随机用户的训练。

总结

这是对TensorFlow Federated和FC API的一个简单介绍。我们使用MNIST训练实例来介绍TFF的Federated Learning(FL)API层。

我上面展示的代码是开源的,可以在Github上找到。你可以通过这个链接访问它。