首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >联邦学习训练中的模型性能没有提高

联邦学习训练中的模型性能没有提高
EN

Stack Overflow用户
提问于 2020-05-08 11:05:19
回答 2查看 748关注 0票数 3

我跟随本教程创建了一个图像分类实验(7个班),目的是用TFF框架对3个数据仓进行分类器的训练。

在开始培训之前,我使用tff.learning.assign_weights_to_keras_model(model,state.model)将模型转换为tf keras模型,以便对验证集进行评估。不管标签是什么,模型只预测一个类。这是预期的,因为还没有进行培训的模式。然而,在每个联邦平均轮之后,我重复这个步骤,并且问题仍然存在。所有验证图像都被预测为一个类。我还保存了tf角模型的权重后,每一轮,并作出预测的测试集-没有变化。

我为检查问题的根源而采取的一些步骤如下:

  1. 检查tf角模型的权重是否在每一轮后转换为FL模型时更新--它们正在更新。
  2. 确保缓冲区大小大于每个客户端的培训数据集大小。
  3. 将预测结果与训练数据集中的类分布进行比较。虽然存在阶级不平衡,但模型预测的一类不一定是多数类。而且,它并不总是同一个类。在大多数情况下,它只预测0级。
  4. 将轮数增加到5次,每轮增加10次。这在计算上非常密集,因为它是一个相当大的模型,每个客户端大约有1500张图像。
  5. 对每次培训尝试中的TensorBoard日志进行调查。随着训练质量的提高,训练损失逐渐减少。
  6. 尝试了一个简单得多的模型-基本的CNN与2层。这使我大大增加了划时代和轮回的数量。当在测试集上对该模型进行评估时,它预测了4个不同的类,但性能仍然很差。这意味着我只需要增加原始模型的圆圈数和周期数,就可以增加预测的变化。这是困难的,因为大量的训练时间将是一个结果。

模型详细信息:

该模型使用XceptionNet作为基本模型,其中权重未冻结。当将所有培训图像汇集到全局数据集中时,这在分类任务上执行得很好。我们的目标是希望取得与FL相当的表现。

代码语言:javascript
复制
base_model = Xception(include_top=False,
                      weights=weights,
                      pooling='max',
                      input_shape=input_shape)
x = GlobalAveragePooling2D()( x )
predictions = Dense( num_classes, activation='softmax' )( x )
model = Model( base_model.input, outputs=predictions )

这是我的训练代码:

代码语言:javascript
复制
def fit(self):
    """Train FL model"""
    # self.load_data()
    summary_writer = tf.summary.create_file_writer(
        self.logs_dir
    )
    federated_averaging = self._construct_iterative_process()
    state = federated_averaging.initialize()
    tfkeras_model = self._convert_to_tfkeras_model( state )
    print( np.argmax( tfkeras_model.predict( self.val_data ), axis=-1 ) )
    val_loss, val_acc = tfkeras_model.evaluate( self.val_data, steps=100 )

    with summary_writer.as_default():
        for round_num in tqdm( range( 1, self.num_rounds ), ascii=True, desc="FedAvg Rounds" ):

            print( "Beginning fed avg round..." )
            # Round of federated averaging
            state, metrics = federated_averaging.next(
                state,
                self.training_data
            )
            print( "Fed avg round complete" )
            # Saving logs
            for name, value in metrics._asdict().items():
                tf.summary.scalar(
                    name,
                    value,
                    step=round_num
                )
            print( "round {:2d}, metrics={}".format( round_num, metrics ) )
            tff.learning.assign_weights_to_keras_model(
                tfkeras_model,
                state.model
            )
            # tfkeras_model = self._convert_to_tfkeras_model(
            #     state
            # )
            val_metrics = {}
            val_metrics["val_loss"], val_metrics["val_acc"] = tfkeras_model.evaluate(
                self.val_data,
                steps=100
            )
            for name, metric in val_metrics.items():
                tf.summary.scalar(
                    name=name,
                    data=metric,
                    step=round_num
                )
            self._checkpoint_tfkeras_model(
                tfkeras_model,
                round_num,
                self.checkpoint_dir
            )
def _checkpoint_tfkeras_model(self,
                              model,
                              round_number,
                              checkpoint_dir):
    # Obtaining model dir path
    model_dir = os.path.join(
        checkpoint_dir,
        f'round_{round_number}',
    )
    # Creating directory
    pathlib.Path(
        model_dir
    ).mkdir(
        parents=True
    )
    model_path = os.path.join(
        model_dir,
        f'model_file_round{round_number}.h5'
    )
    # Saving model
    model.save(
        model_path
    )

def _convert_to_tfkeras_model(self, state):
    """Converts global TFF modle of TF keras model

    Takes the weights of the global model
    and pushes them back into a standard
    Keras model

    Args:
        state: The state of the FL server
            containing the model and
            optimization state

    Returns:
        (model); TF Keras model

    """
    model = self._load_tf_keras_model()
    model.compile(
        loss=self.loss,
        metrics=self.metrics
    )
    tff.learning.assign_weights_to_keras_model(
        model,
        state.model
    )
    return model

def _load_tf_keras_model(self):
    """Loads tf keras models

    Raises:
        KeyError: A model name was not defined
            correctly

    Returns:
        (model): TF keras model object

    """
    model = create_models(
        model_type=self.model_type,
        input_shape=[self.img_h, self.img_w, 3],
        freeze_base_weights=self.freeze_weights,
        num_classes=self.num_classes,
        compile_model=False
    )

    return model

def _define_model(self):
    """Model creation function"""
    model = self._load_tf_keras_model()

    tff_model = tff.learning.from_keras_model(
        model,
        dummy_batch=self.sample_batch,
        loss=self.loss,
        # Using self.metrics throws an error
        metrics=[tf.keras.metrics.CategoricalAccuracy()] )

    return tff_model

def _construct_iterative_process(self):
    """Constructing federated averaging process"""
    iterative_process = tff.learning.build_federated_averaging_process(
        self._define_model,
        client_optimizer_fn=lambda: tf.keras.optimizers.SGD( learning_rate=0.02 ),
        server_optimizer_fn=lambda: tf.keras.optimizers.SGD( learning_rate=1.0 ) )
    return iterative_process
EN

回答 2

Stack Overflow用户

发布于 2020-05-08 15:16:21

  1. 把子弹数量增加到5枚..。

只运行几轮联邦学习听起来还不够。一个最早的联邦平均论文(McMahan 2016)要求运行数百轮时,MNIST数据有非iid分裂。最近,(雷迪2020)需要数千轮的CIFAR-100。需要注意的一点是,每一个“回合”都是全球模式的一个“步骤”。随着客户时代的增加,这个步骤可能会更大,但是这些都是平均的,发散的客户端可能会减少全局步骤的规模。

我还保存了tf角模型的权重后,每一轮,并作出预测的测试集-没有变化。

这是值得关注的。如果您能够共享FL培训循环中使用的代码,那么调试将更加容易。

票数 0
EN

Stack Overflow用户

发布于 2020-05-28 11:29:27

注:肯定这是一个答案,但更多的是一个受欢迎的观察。

我一直试图描述的学习过程(准确性和损失)的联邦学习图像分类笔记本教程与TFF。

通过修改时代超参数,我看到收敛速度有了很大的提高。改变时代从5,10,20等,但我也看到了大幅度提高训练的准确性。我怀疑过度拟合正在发生,虽然那时我评估的测试集的准确性仍然很高。

想知道发生了什么事。?

我的理解是,每一轮培训中,划时代的param控制每个客户的前/后支柱#。这是对的吗?因此,对10个客户进行10轮培训,10轮培训将是10轮,10轮,10轮,10轮。意识到需要更大范围的客户,等等,但我期待看到更低的准确性在测试集。

我能做些什么来看看发生了什么。我可以使用评估检查与学习曲线之类的东西,看看是否发生过度拟合?

test_metrics =评估(state.model,federated_test_data)似乎只给出了一个数据点,我如何才能获得每个测试示例验证的单个测试精度?

感谢你对这件事的任何想法,科林。。。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61677696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档