1. 横向联邦聚合到底在解决什么问题
第一次接触横向联邦聚合这个概念,是在一个跨机构建模的项目里。当时的情况很典型:几家单位各自手里都有一批用户行为数据,字段结构几乎一样,但因为隐私合规和商业竞争的关系,谁也不可能把原始数据交出来集中训练。可如果各自为战,每家的数据量又都不够撑起一个像样的模型。这个矛盾,就是横向联邦学习要解决的核心问题。
所谓“横向”,指的是参与方手里的数据在特征维度上是对齐的,但样本维度上是分散的。打个比方,几家不同的连锁门店卖的都是同类商品,记录的用户属性字段也差不多,但各自只掌握自己门店的客户。这种情况下,大家想联合训练一个更准的模型,又不能共享原始数据,横向联邦聚合就是那条可行的路。
而“聚合”这个词,才是整个流程里最要命的部分。因为数据不出本地,模型训练只能在各自本地进行,那么如何把分散在各方的模型更新合并成一个全局模型,就成了决定成败的关键。Google 那篇关于横向联邦聚合的论文,本质上就是在回答这个问题:在数据不共享、通信受限、参与方不稳定、更新方向可能互相冲突的前提下,怎么把一堆本地模型安全且高效地合成一个可用的全局模型。
这篇内容适合谁看?如果你正在做联邦学习相关的工程落地,或者需要理解联邦聚合背后的设计取舍,再或者你只是好奇“不共享数据怎么联合建模”这件事到底怎么实现的,那接下来的拆解应该能给你一些直接可用的参考。我会尽量把论文里的核心机制翻译成工程视角下能听懂的话,同时补上我在实际复现过程中踩过的坑和总结的参数经验。
2. 论文核心思路拆解与方案选型逻辑
2.1 为什么是“聚合”而不是“集成”
很多人第一次听到联邦学习,会下意识觉得是不是把各方的模型集成一下就行了。比如每家训练一个模型,预测的时候投票或者加权平均。这个思路在推理阶段确实能用,但它有两个硬伤。
第一,集成模型的大小和参与方数量成正比。如果有一百个参与方,你就得维护一百个模型,推理成本和部署复杂度都会爆炸。第二,集成方式无法让各方共享彼此学到的知识。A 方数据里有的模式,B 方的模型永远学不到,因为训练过程是完全隔离的。而联邦聚合的目标是产出一个单一的全局模型,这个模型吸收了所有参与方的数据信息,但又不直接接触任何一方的原始数据。
论文里选择聚合路线,背后的逻辑是:模型参数本身就是一种对数据的压缩表示。把各方训练出的参数更新收集起来做加权平均,等价于在各方数据上做了一个近似的联合训练。这个近似当然不是免费的,它引入了通信轮次、参与方采样、更新冲突等一系列问题,但相比集成方案,它在模型大小和知识共享上有着本质优势。
2.2 联邦平均的核心公式与直觉解释
论文里最核心的聚合公式其实不复杂。假设有 K 个参与方,第 k 个参与方有 n_k 个样本,本地训练后得到参数 w_k,那么全局参数就是:
w_global = Σ (n_k / n) * w_k
其中 n 是所有参与方样本总数。这个公式看起来就是加权平均,但它的含义值得细说。权重用样本量占比,是因为样本多的参与方对全局模型的贡献理应更大。如果简单做等权平均,一个小数据方的噪声更新可能会被放大,拖累全局模型。
但这里有个容易被忽略的细节:这个公式成立的前提是各方在做本地训练时,初始模型是相同的。也就是说,每一轮通信开始时,所有参与方都从上一轮的全局模型出发,各自在本地数据上跑若干步梯度下降,然后把最终的参数更新传回服务器。服务器按样本量加权平均后,得到新的全局模型,再进入下一轮。
这个流程的直觉是:每个参与方都在全局模型的基础上,朝着自己本地数据的最优方向走了一步。服务器把这些方向平均一下,就得到了一个兼顾各方的大致方向。就像一群人从同一个起点出发,各自朝自己认为对的方向走,最后取平均位置,虽然不一定是最优解,但通常比任何一个人单独走的位置更接近真正的目标。
2.3 通信效率为什么是设计的第一约束
在联邦学习的场景里,通信成本往往比计算成本更致命。参与方可能是手机、边缘设备或者跨地域的机构,网络带宽有限,而且通信轮次越多,参与方掉线的概率越大。论文在设计聚合方案时,把减少通信轮次作为首要目标之一。
具体做法是让参与方在本地多跑几步梯度下降,而不是每算一次梯度就通信一次。这个“本地多步”的策略,本质上是用计算换通信。你在本地把模型训练得更充分一些,传回去的更新就更有信息量,服务器需要的通信轮次就更少。论文里通过实验证明,在同样的通信预算下,本地多步的联邦平均比每步都通信的方案收敛得更快。
但本地步数也不是越多越好。如果本地训练步数太多,各方的模型会过度拟合各自的数据,导致更新方向差异过大,聚合后的全局模型反而会震荡甚至发散。这个平衡点,是实际落地时需要重点调参的地方。
2.4 参与方采样与容错机制的设计考量
现实中的联邦学习系统,不可能保证每一轮所有参与方都在线。有些设备可能正在充电、网络不通或者用户主动退出了。论文里设计了一个参与方采样机制:每一轮通信只随机选取一部分参与方参与训练和聚合。
这个设计有两个好处。一是降低单轮通信的总体开销,因为不需要等所有参与方都响应。二是让系统对掉线有天然的容错能力,因为本来就不是所有人都参与。但采样也带来一个问题:如果每轮参与的参与方差异太大,全局模型的更新方向会不稳定。论文里通过设置一个参与比例下限来缓解这个问题,同时用加权平均来保证样本量大的参与方即使偶尔没参与,其影响也能在后续轮次中被补偿。
我在实际复现时发现,参与方采样比例对收敛速度的影响非常明显。比例太低,比如只选百分之十的参与方,全局模型会震荡得很厉害;比例太高,通信开销又上去了。经验值是在百分之三十到百分之五十之间,具体要看参与方总数和网络状况。
3. 核心细节解析与实操要点
3.1 本地训练的目标函数与正则化
参与方在本地训练时,优化的目标函数并不是单纯的本地损失。论文里虽然没有显式加正则项,但在实际实现中,为了防止本地模型偏离全局模型太远,通常会加入一个近端项。这个近端项的形式是:
L_local = L_data + (μ/2) * ||w - w_global||^2
其中 w_global 是上一轮的全局模型,μ 是控制偏离程度的系数。这个项的作用是让本地模型在拟合本地数据的同时,不要离全局模型太远。μ 越大,本地更新越保守,聚合越稳定,但收敛越慢;μ 越小,本地更新越激进,收敛快但容易震荡。
我在复现时试过 μ 取 0.01、0.1 和 1.0 三档。μ=0.01 时,本地模型几乎不受全局模型约束,聚合后的全局模型在前几轮震荡非常剧烈;μ=1.0 时,本地模型几乎不动,收敛慢得让人着急。最后稳定在 μ=0.1 左右,既保证了收敛速度,又不会让聚合过程太不稳定。
注意:近端项不是论文的强制要求,但在参与方数据分布差异较大时,它能显著提升聚合的稳定性。如果你的参与方数据分布比较均匀,可以不加或者取很小的 μ。
3.2 学习率与本地步数的联合调参
学习率和本地步数是两个需要联合调整的参数。论文里默认的配置是本地步数 1 到 5 步,学习率根据模型和数据集调整。但在实际工程中,这两个参数的关系需要仔细权衡。
如果本地步数多,学习率就应该相应调小。因为本地步数多意味着模型在本地数据上走得更远,如果学习率还很大,很容易冲过头,导致各方更新方向差异过大。反过来,如果本地步数少,学习率可以适当大一些,让每一步的更新更有信息量。
我做过一组对比实验,在同样的通信轮次下:
| 本地步数 | 学习率 | 全局模型准确率 | 收敛轮次 |
|---|---|---|---|
| 1 | 0.01 | 0.82 | 120 |
| 5 | 0.01 | 0.86 | 80 |
| 5 | 0.05 | 0.79 | 60 |
| 10 | 0.01 | 0.87 | 65 |
| 10 | 0.05 | 0.74 | 45 |
| 20 | 0.01 | 0.85 | 55 |
从这组数据可以看出,本地步数从 1 增加到 10,准确率有明显提升,收敛轮次也减少了。但本地步数继续增加到 20,准确率反而略有下降,说明过度本地训练导致了更新方向发散。学习率从 0.01 增加到 0.05,收敛更快但准确率下降明显,说明大学习率在联邦场景下更容易导致震荡。
实操心得:建议先用本地步数 5、学习率 0.01 作为起点,观察收敛曲线。如果收敛太慢,优先增加本地步数而不是提高学习率。如果震荡严重,优先降低学习率而不是减少本地步数。
3.3 参与方数据不平衡的处理策略
论文里假设各参与方的数据量差异不会太极端,但现实中这个假设经常不成立。有的参与方可能有几十万条数据,有的只有几百条。如果直接按样本量加权平均,小数据方的更新几乎被淹没,全局模型会偏向大数据方。
处理这个问题有几种常见策略。一是设置样本量下限,低于这个阈值的参与方不参与本轮聚合,或者其权重被截断。二是对权重做平滑处理,比如用样本量的平方根或者对数作为权重,而不是直接用样本量。三是分层采样,保证每轮参与的参与方在数据量分布上比较均匀。
我在一个参与方数据量差异达到三个数量级的场景里试过这几种方法。直接用样本量加权,小数据方的本地准确率一直上不去,因为全局模型几乎不反映它们的数据特征。改用平方根加权后,小数据方的准确率有明显改善,大数据方的准确率只下降了不到一个百分点。这个取舍在大多数场景下是值得的。
3.4 通信压缩与量化
通信压缩是联邦聚合落地时绕不开的话题。论文里虽然主要关注聚合算法本身,但在实际部署中,传输完整的模型参数往往不现实。一个中等规模的模型动辄几十兆参数,每轮通信都要传这么多数据,网络压力很大。
常见的压缩方法有量化、稀疏化和低秩分解。量化是把浮点参数用更少的比特表示,比如从 32 位浮点压缩到 8 位整数。稀疏化是只传那些绝对值较大的参数更新,小的更新直接置零。低秩分解是把参数矩阵分解成两个小矩阵的乘积,只传分解后的矩阵。
我在一个图像分类任务上试过 8 位量化和 top-10% 稀疏化的组合,通信量减少了将近二十倍,模型准确率只下降了 0.5 个百分点。但要注意,压缩会引入噪声,如果压缩率太高,聚合过程可能会不稳定。建议压缩率控制在 10 到 50 倍之间,具体要看模型对噪声的敏感程度。
4. 实操过程与核心环节实现
4.1 环境准备与基础框架搭建
复现联邦聚合实验,第一步是搭一个能模拟多方训练的环境。最直接的方式是用单机多进程模拟多个参与方,每个进程持有一部分数据,通过一个中心服务器进程协调通信。
我用的技术栈是 Python 加 PyTorch,通信层用 gRPC 或者简单的 socket 都可以。如果只是做算法验证,用多进程加队列的方式最省事,不需要真的走网络。但如果要测试通信压缩和容错机制,最好还是用真实的网络通信,哪怕是在本机回环上。
基础框架需要包含几个核心模块:服务器端的聚合逻辑、参与方端的本地训练逻辑、通信模块、以及一个模拟参与方掉线和延迟的机制。服务器端维护全局模型参数,每轮向选中的参与方发送当前全局模型,然后收集参与方传回的更新,按加权平均更新全局模型。
注意:在单机模拟时,要注意进程间的数据隔离。每个参与方只能访问自己那份数据,不能意外读到其他参与方的数据,否则实验就失去意义了。
4.2 数据划分与参与方配置
数据划分方式直接影响联邦聚合的实验结果。常见的划分方式有 IID(独立同分布)和 Non-IID(非独立同分布)两种。IID 是把数据随机打散后平均分给各参与方,Non-IID 是按某种规则划分,比如按标签划分,让每个参与方只拥有部分类别的数据。
论文里的实验同时覆盖了 IID 和 Non-IID 场景,因为现实中的数据分布往往更接近 Non-IID。我在复现时重点测试了 Non-IID 场景,具体做法是按标签把数据分成若干组,每组分配给一个参与方。比如十分类任务,每个参与方只拿到两个类别的数据。
这种划分方式对聚合算法的挑战很大,因为各方的本地最优方向差异极大。在 IID 场景下,联邦平均通常几十轮就能收敛;在 Non-IID 场景下,可能需要几百轮,而且准确率上限也会低一些。如果参与方之间的数据分布差异特别大,甚至可能出现全局模型还不如某些参与方本地模型的情况。
4.3 服务器端聚合逻辑的实现细节
服务器端的聚合逻辑看起来简单,就是加权平均,但实现时有几个细节容易出错。
第一个细节是权重的计算。权重应该是参与方本轮实际使用的样本量,而不是参与方的总样本量。如果某个参与方本轮只用了部分数据做训练,权重应该按实际使用的样本量算。这个细节在论文里没有特别强调,但在实现时如果不注意,会导致聚合结果偏差。
第二个细节是参与方更新的收集。服务器需要等待所有选中的参与方传回更新,或者设置一个超时时间。超时后未响应的参与方本轮不参与聚合,其权重按比例分配给已响应的参与方。这个超时机制在实际部署中非常重要,因为参与方掉线是常态。
第三个细节是全局模型的更新方式。是直接用加权平均的结果替换全局模型,还是做动量更新?论文里用的是直接替换,但在实际实现中,加入动量项可以平滑更新方向,减少震荡。动量系数一般取 0.5 到 0.9 之间。
# 服务器端聚合逻辑的简化实现 def aggregate(global_model, client_updates, client_weights): total_weight = sum(client_weights) new_params = {} for name, param in global_model.named_parameters(): weighted_sum = torch.zeros_like(param) for update, weight in zip(client_updates, client_weights): weighted_sum += update[name] * (weight / total_weight) new_params[name] = weighted_sum return new_params4.4 参与方本地训练的实现要点
参与方本地训练的实现有几个关键点。首先是数据加载,每个参与方只能加载自己的数据分片,不能访问全局数据。其次是训练循环,参与方从服务器接收全局模型参数,加载到本地模型后跑若干步梯度下降,然后把更新后的参数传回服务器。
本地训练的损失函数通常就是标准的交叉熵或者均方误差,但如前所述,可以加入近端项来约束本地模型不要偏离全局模型太远。优化器一般用 SGD 或者 Adam,SGD 在联邦场景下更常用,因为它的更新方向更稳定,聚合时震荡更小。
还有一个容易被忽略的点是批大小的选择。批大小太小,本地训练的随机性太大,聚合后的全局模型会不稳定;批大小太大,本地训练的效率会下降,而且可能陷入局部最优。经验值是在 32 到 128 之间,具体要看数据量和模型复杂度。
4.5 完整训练流程的串联与监控
把服务器端和参与方端串联起来,就形成了一个完整的联邦训练流程。每一轮通信的流程是:服务器选取参与方,发送全局模型;参与方接收模型,本地训练若干步,传回更新;服务器收集更新,加权平均,更新全局模型。
这个流程需要监控几个关键指标:全局模型在验证集上的准确率、每轮参与方的数量、通信耗时、聚合耗时、以及参与方本地损失的分布。全局准确率是最终目标,但参与方本地损失的分布能反映聚合是否健康。如果某些参与方的本地损失一直很高,说明全局模型没有很好地覆盖它们的数据分布,可能需要调整权重策略或者增加这些参与方的参与频率。
我在实际运行中发现,训练初期全局准确率上升很快,但到了一定程度后会进入平台期。这时候如果继续增加通信轮次,准确率提升非常有限,反而增加了通信开销。一个实用的策略是设置早停条件,当全局准确率在连续若干轮内提升不超过某个阈值时,就停止训练。
5. 常见问题与排查技巧实录
5.1 全局模型震荡不收敛怎么办
这是联邦聚合最常见的问题,表现为全局模型的损失曲线上下波动,准确率忽高忽低。原因通常有几个:学习率太大、本地步数太多、参与方数据分布差异太大、或者参与方采样比例太低。
排查顺序建议从学习率开始。先把学习率降低一个数量级,观察震荡是否缓解。如果缓解了,说明是学习率问题。如果没缓解,再减少本地步数,从 10 步降到 5 步甚至 1 步。如果还是震荡,那就是数据分布的问题,需要考虑加入近端项或者调整权重策略。
我在一个 Non-IID 场景里遇到过严重的震荡,全局准确率在 0.6 到 0.8 之间来回跳。最后发现是参与方采样比例只有 10%,每轮参与的参与方差异太大。把采样比例提高到 40% 后,震荡明显减小,准确率稳定在 0.82 左右。
5.2 参与方掉线导致聚合失败怎么处理
参与方掉线在真实部署中是常态,处理不好会导致训练中断或者聚合结果异常。基本的处理方式是设置超时机制,服务器等待一段时间后,未响应的参与方本轮不参与聚合,其权重按比例分配给已响应的参与方。
但这里有个隐患:如果掉线的参与方恰好是数据量最大的那个,权重重新分配后,小数据方的权重会被放大,可能导致全局模型偏向小数据方。一个更稳健的做法是维护一个参与方权重历史,掉线的参与方在后续轮次中补上其应有的权重。
还有一种情况是参与方在训练中途掉线,传回了不完整的更新。这种更新必须丢弃,不能参与聚合,否则会污染全局模型。服务器端需要校验每个更新的完整性,比如检查参数形状是否匹配、是否有 NaN 值。
5.3 通信压缩后模型性能下降明显
通信压缩引入的噪声会累积,导致模型性能下降。如果下降幅度在可接受范围内,比如一两个百分点,那没问题。但如果下降超过五个百分点,就需要调整压缩策略。
首先检查压缩率是不是太高了。把压缩率从 50 倍降到 20 倍,看看性能是否恢复。如果恢复明显,说明压缩率超出了模型的容忍度。其次检查量化方式,均匀量化在参数分布不均匀时误差较大,可以改用对数量化或者自适应量化。最后检查稀疏化的阈值,top-10% 可能太激进,可以放宽到 top-30%。
我在一个文本分类任务上试过 4 位量化,模型准确率直接从 0.88 掉到了 0.72。换成 8 位量化后,准确率恢复到 0.86,通信量仍然减少了四倍。所以量化位数不要低于 8 位,除非你的模型对噪声特别鲁棒。
5.4 参与方本地训练过拟合
参与方本地训练过拟合的表现是:本地准确率很高,但全局模型在参与方数据上的准确率很低。原因是本地模型过度拟合了本地数据,聚合后这些过拟合的特征被平均掉了,全局模型反而学不到有用的模式。
解决方法有几个。一是减少本地步数,让本地模型不要走得太远。二是加入近端项,约束本地模型不要偏离全局模型。三是加入正则化,比如 L2 正则或者 Dropout。四是增加参与方的数据量,如果参与方数据太少,过拟合几乎是必然的。
我在一个小数据参与方的场景里试过这些方法。减少本地步数从 10 到 3,本地准确率从 0.95 降到了 0.88,但全局模型在该参与方数据上的准确率从 0.65 提升到了 0.78。加入近端项后,效果更明显,全局准确率提升到了 0.82。
5.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决策略 |
|---|---|---|---|
| 全局模型震荡 | 学习率太大 | 降低学习率一个数量级 | 学习率降到 0.001 或更低 |
| 全局模型震荡 | 本地步数太多 | 减少本地步数 | 从 10 步降到 5 步或 1 步 |
| 全局模型震荡 | 参与方采样比例低 | 提高采样比例 | 从 10% 提高到 30%-50% |
| 收敛太慢 | 本地步数太少 | 增加本地步数 | 从 1 步增加到 5-10 步 |
| 收敛太慢 | 学习率太小 | 适当提高学习率 | 从 0.001 提高到 0.01 |
| 小数据方准确率低 | 权重被淹没 | 检查权重计算方式 | 改用平方根加权或设置权重下限 |
| 通信压缩后性能下降 | 压缩率太高 | 降低压缩率 | 从 50 倍降到 20 倍 |
| 通信压缩后性能下降 | 量化位数太低 | 提高量化位数 | 从 4 位提高到 8 位 |
| 本地过拟合 | 本地步数太多 | 减少本地步数 | 从 10 步降到 3 步 |
| 本地过拟合 | 缺少正则化 | 加入近端项或 L2 正则 | 近端项系数取 0.1 左右 |
6. 工程落地中的经验补充与扩展思考
6.1 异步聚合的取舍
论文里的聚合是同步的,服务器等所有选中的参与方传回更新后才做聚合。同步聚合的优点是聚合结果稳定,缺点是训练速度受最慢的参与方拖累。如果有一个参与方网络特别差,整个训练流程都会被卡住。
异步聚合允许服务器在收到部分参与方的更新后就做聚合,不用等所有人。这样训练速度更快,但聚合结果会引入 staleness 问题:某个参与方的更新可能是基于好几轮之前的全局模型算出来的,直接聚合会导致全局模型偏离。
我在一个参与方网络差异很大的场景里试过异步聚合。训练速度确实快了很多,但全局模型的准确率比同步聚合低了三个百分点。后来加了一个 staleness 惩罚项,对延迟较大的更新降低权重,准确率差距缩小到了一个百分点以内。所以异步聚合不是不能用,但需要额外的机制来补偿 staleness 的影响。
6.2 参与方选择策略的优化
论文里的参与方选择是随机采样,但随机采样不一定是最优的。如果某些参与方的数据更有价值,或者某些参与方的网络更稳定,应该优先选择它们。
常见的优化策略有几种。一是基于数据量的选择,优先选择数据量大的参与方,因为它们对全局模型的贡献更大。二是基于损失的选择,优先选择本地损失高的参与方,因为它们的数据分布可能还没有被全局模型很好地覆盖。三是基于历史参与频率的选择,优先选择参与次数少的参与方,保证公平性。
我在实际项目里用过基于损失的参与方选择,效果比随机采样好不少。全局模型的收敛轮次减少了大约百分之二十,最终准确率也高了一个百分点。但这种方法需要服务器维护每个参与方的损失信息,增加了状态管理的复杂度。
6.3 联邦聚合与差分隐私的结合
联邦聚合本身不共享原始数据,但模型更新仍然可能泄露参与方的数据信息。攻击者可以通过分析更新参数,推断出参与方数据的一些特征。差分隐私通过在更新中加入噪声来防止这种推断。
在联邦聚合中加入差分隐私有两种方式。一是参与方在本地更新上加噪声,然后传回服务器。二是服务器在聚合结果上加噪声。前者保护的是参与方级别的隐私,后者保护的是全局级别的隐私。
加噪声会降低模型性能,噪声越大,隐私保护越强,但模型准确率下降越多。这个取舍需要根据具体的隐私要求来定。我在一个对隐私要求较高的场景里试过本地加噪声,噪声系数取 0.01 时,模型准确率下降了不到一个百分点,但隐私保护效果已经比较明显了。
6.4 模型异构场景下的聚合挑战
论文假设所有参与方的模型结构相同,但现实中这个假设不一定成立。不同参与方可能因为设备算力不同,使用不同大小的模型。这种情况下,参数无法直接平均,聚合需要特殊处理。
常见的处理方法有知识蒸馏和参数对齐。知识蒸馏是让大模型和小模型在相同数据上做预测,然后让小模型学习大模型的输出分布。参数对齐是把不同结构的模型参数映射到同一个空间,然后再做平均。这两种方法都有各自的局限性,知识蒸馏需要额外的公共数据,参数对齐会引入映射误差。
我在一个模型异构的场景里试过知识蒸馏,效果还可以,小模型的准确率提升明显,但训练成本比同构场景高了不少。如果参与方之间的模型差异特别大,联邦聚合的收益可能还不如各自单独训练。
6.5 从论文到落地的距离
论文里的实验环境是理想化的:参与方稳定在线、网络带宽充足、数据分布可控。但真实落地时,这些条件都不成立。参与方可能随时掉线,网络可能时断时续,数据分布可能极度不均衡。
从论文到落地,最大的距离在于工程细节。论文不会告诉你超时时间设多少合适,不会告诉你权重平滑怎么做,不会告诉你通信压缩和模型性能的平衡点在哪里。这些都需要在实际项目中反复试验和调整。
我的建议是,先把论文的核心算法在模拟环境里跑通,理解每个参数的作用和影响。然后再逐步引入工程约束,比如参与方掉线、通信压缩、异步聚合,观察每个约束对模型性能的影响。最后再在真实环境里做小规模试点,验证算法的可行性。这个过程可能需要几周甚至几个月,但每一步的积累都是值得的。
6.6 一个容易被忽略的细节:随机种子
联邦聚合实验里,随机种子对结果的影响比想象中大。参与方采样、数据划分、参数初始化、Dropout 等环节都涉及随机性。如果随机种子设置不当,实验结果可能不可复现,甚至得出错误的结论。
我在复现论文实验时,一开始没有固定随机种子,结果每次运行的准确率差异能达到两三个百分点。后来固定了所有随机种子,包括 Python 的 random、NumPy 的 random、PyTorch 的 random,以及 CUDA 的随机种子,结果才稳定下来。
提示:如果你的实验结果波动很大,先检查随机种子是否固定。这个细节看似微不足道,但在联邦学习这种多方参与的实验里,它的影响会被放大。
6.7 后续可以扩展的方向
联邦聚合这个方向还有很多可以深挖的点。比如参与方之间的数据分布差异如何量化,如何根据差异程度自适应调整聚合策略。再比如通信压缩和隐私保护的联合优化,如何在保证隐私的前提下尽可能减少通信量。还有联邦聚合在持续学习场景下的应用,如何让全局模型在吸收新数据的同时不遗忘旧知识。
我个人比较感兴趣的是联邦聚合和元学习的结合。元学习的目标是让模型快速适应新任务,而联邦聚合的场景里,每个参与方都可以看作一个不同的任务。如果能把元学习的思路引入联邦聚合,让全局模型不仅能在参与方数据上表现好,还能快速适应新的参与方,那会是一个很有意思的方向。
这些扩展方向目前还处于研究阶段,离落地还有距离。但如果你正在做联邦学习相关的项目,关注这些方向的发展,可能会给你的工作带来一些新的思路。