Skip to content

输入关键词开始搜索

Flower 联邦学习实验:3 个客户端的 FedAvg 复现


前面几周的实验更多关注模型本身,比如迁移学习、主动学习和小样本学习。这一周的重点换成了训练范式:如果数据不能集中到一起,模型还能不能一起训练?

在很多真实场景里,数据天然分散在不同机构中。医疗是最典型的例子。不同医院都有自己的影像、病历和检验数据,但这些数据通常不能直接汇总到一个中心服务器,因为其中包含患者隐私,也受到合规要求限制。

联邦学习要解决的就是这个问题:数据留在本地,模型协同训练。

在联邦学习中,每个客户端只使用自己的本地数据训练模型,然后把模型参数或模型更新发送给服务器。服务器不接触原始数据,只负责聚合不同客户端上传的模型更新,形成新的全局模型。这个过程重复多轮后,全局模型就能逐步吸收多个客户端的数据特征。

这次实验使用 Flower 框架复刻官方 PyTorch Quickstart,在 CIFAR-10 图像分类任务上模拟 3 个客户端进行 FedAvg 训练。


本次实验的目标比较明确:跑通一个标准的联邦学习流程,并观察通信轮次对模型性能的影响。

实验内容如下:

项目设置
框架Flower
深度学习框架PyTorch
数据集CIFAR-10
客户端数量3
联邦算法FedAvg
模型官方 Quickstart 中的 CNN
运行方式本地仿真
训练轮次3 轮
每轮本地训练1 epoch
输出通信轮次-准确率曲线、通信轮次-loss 曲线、医疗场景分析

这里的 3 个客户端可以理解为 3 家医院。每个客户端只访问自己的本地数据,服务器只负责参数聚合。


Flower 官方 PyTorch Quickstart 已经提供了一个完整的联邦学习项目结构。项目中主要包含三个文件:

文件作用
client_app.py定义客户端训练和评估逻辑
server_app.py定义服务器端策略和全局训练流程
task.py定义模型、数据加载、训练函数和测试函数

客户端负责本地训练。服务器端使用 FedAvg 策略聚合多个客户端上传的模型参数。数据集使用 CIFAR-10,任务是 10 类图像分类。

本次实验基本保持官方 Quickstart 的结构,只做了两个改动:

  1. 客户端数量设置为 3;
  2. 使用本地仿真方式运行,避免真实多机器部署带来的额外复杂度。

运行过程中,每一轮通信大致包含四步:

服务器下发全局模型
客户端在本地数据上训练
客户端上传模型更新和训练指标
服务器使用 FedAvg 聚合参数

这个流程正好对应联邦学习的基本思想:客户端之间不共享原始数据,但可以通过模型更新间接协同优化全局模型。


FedAvg 是联邦学习中最经典的参数聚合方法。它的核心思想是:每个客户端在本地训练若干步后,把更新后的模型参数发送给服务器;服务器根据各客户端的数据量,对模型参数做加权平均。

可以把它理解成下面这个过程:

第 t 轮:
1. 服务器保存当前全局模型 W_t
2. 服务器把 W_t 发送给被选中的客户端
3. 每个客户端使用本地数据训练,得到 W_t^k
4. 客户端把 W_t^k 发送回服务器
5. 服务器按样本数加权平均,得到 W_{t+1}

如果第 k 个客户端的数据量更多,它对全局模型的影响也会更大。这样做的好处是简单、稳定,而且很容易扩展到多个客户端。

在这次实验中,日志显示每一轮都采样了 3 个客户端参与训练:

configure_train: Sampled 3 nodes (out of 3)
aggregate_train: Received 3 results and 0 failures

这说明 3 个客户端都成功完成了本地训练,并且服务器端也成功完成了聚合。


这次实验的主要问题不在模型本身,而在环境配置。

一开始直接执行:

Terminal window
pip install -e .

会触发官方项目依赖检查,并尝试下载 torch==2.8.0。这个包接近 900MB,而且当前环境中已经有 PyTorch,所以没有必要重新下载。

最后采用的方式是:

Terminal window
pip install -e . --no-deps

也就是只安装当前 Flower 项目,不自动安装或升级 PyTorch 依赖。这样可以避免大文件下载。

另外,Flower 新版配置方式也和旧版略有不同。旧版可能直接在 pyproject.toml 中配置 options.num-supernodes,新版更推荐通过本地 Flower config 和运行参数指定本地仿真。最终实验使用的命令形式大致如下:

Terminal window
flwr run . local \
--stream \
--federation-config "num-supernodes=3 client-resources-num-cpus=2 client-resources-num-gpus=0.0" \
--run-config "num-server-rounds=3 local-epochs=1 learning-rate=0.01 batch-size=32"

运行过程中还出现了 Ray 的 metrics exporter 报错:

Failed to establish connection to the metrics exporter agent.
Metrics will not be exported.

这个提示只影响 Ray 的监控指标导出,不影响 Flower 的训练流程。最终训练、评估和聚合都正常完成。


实验最终跑了 3 轮通信。初始全局模型准确率接近随机猜测,经过 3 轮 FedAvg 后,全局模型准确率明显提升。

完整结果如下:

RoundTrain LossClient Eval AccClient Eval LossGlobal AccGlobal Loss
0---0.08972.3038
12.05890.36811.75630.37011.7433
21.69800.43941.54530.44281.5308
31.53730.49111.41080.49891.3871

可以看到,随着通信轮次增加,准确率持续上升,loss 持续下降。

其中,全局准确率由初始的 0.0897 提升到第 3 轮的 0.4989,提升了 0.4092。全局 loss 由 2.3038 降到 1.3871,下降了 0.9167

这说明在不集中原始数据的情况下,多个客户端仍然可以通过本地训练和服务器端参数聚合共同提升全局模型性能。


为了更直观地观察 FedAvg 的训练效果,我将每一轮的准确率画成曲线。

FedAvg 在 CIFAR-10 上的准确率曲线

图中可以重点观察两条曲线:

  • Global Accuracy:服务器端全局模型在测试集上的准确率;
  • Client Eval Accuracy:客户端侧聚合评估得到的准确率。

两者整体趋势一致,说明全局模型和客户端侧评估都在随着通信轮次增加而变好。第 0 轮全局模型几乎没有学习能力,准确率只有 0.0897;第 1 轮后准确率迅速提升到 0.3701;第 3 轮达到 0.4989。

这说明 FedAvg 在前几轮就能快速提升模型性能。对于 CIFAR-10 这种 10 类图像分类任务,随机猜测大约是 10%,初始准确率也基本符合这一点。经过几轮联邦训练后,模型已经明显学到了图像类别特征。


除了准确率,loss 的变化也能反映训练是否有效。

FedAvg 在 CIFAR-10 上的 loss 曲线

训练 loss 和评估 loss 都呈下降趋势。客户端训练 loss 由第 1 轮的 2.0589 降到第 3 轮的 1.5373,全局 loss 由初始的 2.3038 降到第 3 轮的 1.3871。

这个趋势说明客户端本地训练有效,服务器端聚合后的全局模型也在逐步收敛。

需要注意的是,联邦学习中的 loss 曲线不一定像单机训练那样平滑。因为每一轮涉及客户端采样、本地数据分布、聚合权重等因素,曲线可能存在波动。在这次实验中,3 个客户端都参与训练,数据划分相对稳定,所以曲线表现比较清晰。


第 0 轮的全局准确率是 0.0897,接近随机猜测。经过第 1 轮 FedAvg 后,全局准确率提升到 0.3701。

这说明即使每个客户端只训练 1 个本地 epoch,只要服务器能够聚合多个客户端的模型更新,全局模型就可以快速获得有效的分类能力。

9.2 loss 持续下降,说明聚合方向有效

Section titled “9.2 loss 持续下降,说明聚合方向有效”

全局 loss 由 2.3038 降到 1.3871,客户端评估 loss 也由 1.7563 降到 1.4108。

这说明 FedAvg 聚合后的模型并不是只在某个客户端上变好,而是在整体评估中也表现更好。对于联邦学习而言,这是很重要的,因为它说明全局模型能够吸收多个客户端的共同信息。

9.3 3 个客户端可以模拟多机构协同

Section titled “9.3 3 个客户端可以模拟多机构协同”

在日志中,每轮训练都显示:

configure_train: Sampled 3 nodes (out of 3)
aggregate_train: Received 3 results and 0 failures

这说明 3 个客户端都参与了训练,且没有客户端失败。对于实验复现来说,这能清楚展示多客户端协同训练的过程。

在真实场景中,这 3 个客户端可以对应 3 家医院、3 个移动设备群体,或者 3 个不同地区的数据中心。

这次实验只跑了 3 轮,主要目的是快速复刻和验证流程。虽然准确率已经达到 0.4989,但距离更高水平仍有提升空间。

如果继续增加通信轮次,例如 10 轮或 20 轮,准确率通常还会继续提升。当然,通信轮次越多,训练时间和通信成本也越高。这正是联邦学习中需要权衡的问题:模型效果、通信成本和客户端资源之间需要平衡。


联邦学习很适合医疗场景。

假设有 3 家医院,每家医院都有自己的医学影像数据,例如胸片、CT、MRI 或病理图像。传统做法可能是把所有数据集中到一个服务器上训练模型,但这会带来隐私、合规和数据安全问题。

联邦学习提供了另一种思路:

医院 A 本地训练模型
医院 B 本地训练模型
医院 C 本地训练模型
服务器聚合三家医院上传的模型更新
全局模型再下发给各医院继续训练

在这个过程中,患者原始影像和病历数据不需要离开医院。服务器只接收模型参数或梯度更新。虽然这并不等于绝对安全,但相比直接传输原始数据,联邦学习显著降低了数据共享风险。

这类方法适合以下任务:

场景说明
医学影像分类多医院联合训练疾病识别模型
疾病风险预测利用多中心电子病历训练预测模型
罕见病识别单家医院样本少,多机构协同更有价值
医疗质控不同机构共享模型能力而非共享原始数据

这次实验虽然用的是 CIFAR-10,而不是医学影像数据,但它复现了联邦学习最核心的流程:数据分布在不同客户端,本地训练,服务器聚合,全局模型提升。


这次实验主要是为了跑通 Flower 联邦学习流程,因此仍然有一些局限。

第一,数据集是 CIFAR-10,不是医学影像数据。它更适合教学和快速验证,不能直接代表真实医疗任务。

第二,本次实验使用的是本地仿真,不是真实多机器部署。所有客户端都在同一台机器上模拟运行,通信延迟、网络中断和客户端掉线等问题没有真正体现。

第三,数据划分相对简单。真实联邦学习中,不同医院的数据分布往往并不一致,比如某些医院某类疾病样本更多,某些医院设备型号不同,图像风格也不同。这种 Non-IID 数据会让联邦训练更困难。

第四,只运行了 3 轮通信。虽然已经能看到明显提升,但如果想得到更充分的实验结论,还需要增加通信轮次,并对比不同客户端数量、不同本地 epoch、不同数据分布方式的影响。


基于这次复现,后续可以做几个扩展:

  1. 增加通信轮次,比如 10 轮、20 轮,观察准确率是否继续提升;
  2. 对比 3、5、10 个客户端数量对训练效果的影响;
  3. 构造 Non-IID 数据划分,模拟不同医院数据分布不一致;
  4. 调整本地训练 epoch,观察本地训练强度对全局模型的影响;
  5. 加入隐私保护机制,比如差分隐私或安全聚合;
  6. 替换成医学图像数据集,让实验更贴近医疗场景。

其中最值得做的是 Non-IID 数据划分。因为真实联邦学习最大的挑战往往不是“能不能把流程跑起来”,而是不同客户端的数据分布差异会让聚合变得不稳定。


这次实验使用 Flower 官方 PyTorch Quickstart,在 CIFAR-10 上模拟了 3 个客户端的 FedAvg 联邦训练流程。

实验结果显示,初始全局准确率为 0.0897,经过 3 轮通信后提升到 0.4989;全局 loss 由 2.3038 降到 1.3871。客户端侧评估准确率也由第 1 轮的 0.3681 提升到第 3 轮的 0.4911。

这个结果说明,即使原始数据不集中共享,多个客户端仍然可以通过本地训练和服务器端参数聚合共同提升全局模型性能。

联邦学习的价值不只是提升模型效果,更重要的是改变了多机构协同建模的方式。对于医疗、金融、移动设备和隐私敏感场景来说,它提供了一种兼顾数据利用和隐私保护的训练范式。