我跟随本教程创建了一个图像分类实验(7个班),目的是用TFF框架对3个数据仓进行分类器的训练。
在开始培训之前,我使用tff.learning.assign_weights_to_keras_model(model,state.model)将模型转换为tf keras模型,以便对验证集进行评估。不管标签是什么,模型只预测一个类。这是预期的,因为还没有进行培训的模式。然而,在每个联邦平均轮之后,我重复这个步骤,并且问题仍然存在。所有验证图像都被预测为一个类。我还保存了tf角模型的权重后,每一轮,并作出预测的测试集-没有变化。
我为检查问题的根源而采取的一些步骤如下:
模型详细信息:
该模型使用XceptionNet作为基本模型,其中权重未冻结。当将所有培训图像汇集到全局数据集中时,这在分类任务上执行得很好。我们的目标是希望取得与FL相当的表现。
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 )这是我的训练代码:
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发布于 2020-05-08 15:16:21
只运行几轮联邦学习听起来还不够。一个最早的联邦平均论文(McMahan 2016)要求运行数百轮时,MNIST数据有非iid分裂。最近,(雷迪2020)需要数千轮的CIFAR-100。需要注意的一点是,每一个“回合”都是全球模式的一个“步骤”。随着客户时代的增加,这个步骤可能会更大,但是这些都是平均的,发散的客户端可能会减少全局步骤的规模。
我还保存了tf角模型的权重后,每一轮,并作出预测的测试集-没有变化。
这是值得关注的。如果您能够共享FL培训循环中使用的代码,那么调试将更加容易。
发布于 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)似乎只给出了一个数据点,我如何才能获得每个测试示例验证的单个测试精度?
感谢你对这件事的任何想法,科林。。。
https://stackoverflow.com/questions/61677696
复制相似问题