本篇文章的阅读论文是《Clustered Federated Learning: Model-Agnostic Distributed Multitask Optimization Under Privacy Constraints》,主要是对论文的作者提供的源码简单的分析一下,留个记录方便之后查看,免得之后重新翻源码。源码地址如下:GitHub源码地址
(源码里是用jupyter,我直接转换成py然后在pycharm里看了,这样看函数方便一些)
1、首先是压缩包解压后的文件,其中包括五个模块,入口在最上面的模块,其中data是我自行修改的,源码中数据集下载的root是“.”,我修改成./data这样更美观一点。

2、 clustered_federated_learning.py
INPUT 1
示例中使用的是经典的EMNIST的byclass数据集,使用只用到了20000 idcs,前10000用作训练,后面用作测试,并且假设的client一共设计有10个,开始时用split_noiid函数打散数据集并且分成十份,所用的函数定义在data_utils中,其实简单来说就是用 np.random.dirichlet 函数使得数据集趋向于noiid分布在十份客户端中。

INPUT 2
第二部分利用绘图将之前打散的数据绘图出来,证明其中的数据分布满足NoIID,因为没有开jupyter就不截图了,大家懂这个意思就行。
INPUT 3
接着作者做了一件事,将前五个client的数据全部旋转180度,经典的人为制造差异,使得后续的计算中将前五个client和后五个client成功分组,然后证明能够更好的效果。

INPUT 4
作者初始化client和server,这部分函数先不说,后续会根据函数代码给大家展示。
初始化时带上了model,这部分很简单,定义在model模块,大家自己看看就行。
INPUT 5
接下来是重点部分,首先作者定义运行80轮,接着定义了eps_1 和 eps_2两个值,至于两个值作用,论文里说的很清楚了,不多赘述,后面也会用到。

开始先做一个判断,第一轮时会初始化client,就是将server端的weight复制到client储存里,相当于初始化同步操作
接着随机选择client进行计算,但是因为本来client就很少,不可能再减少了,所以ftac=1.0,这个就是比例,比例为100%,相当于全选
接着需要每一个client计算weight更新,更新完之后要记得reset,也就是计算完后全部恢复上一次的server端给的weight,因为后续真正的更新需要由server去给。
更新和reset的函数如下,subtract函数是将计算后的weight和weight-old相减计算差值
全部算完就轮到server出场了,server计算会返回一个矩阵,矩阵里就是每个clinet两两之间的余弦值了
矩阵计算,中间省略了一个函数的跳转,source里储存的是每一个client的dw值
接着分割的步骤来了,这里就可以看出eps的作用了,对照论文一目了然,其中作者为了准确度,分割至少需要在20轮之后,较为稳定再去做分割
其中cluster的算法作者直接使用的是AgglomerativeClustering函数,作者现在也在学习各种分类算法,k-means、层次之类的
后面的部分就没什么好说的了,最后附一张图吧。