【FL论文阅读】Communication-Efficient Learning of Deep Networks from Decentralized Data

一、Intro

  1. 对于Federated Optimization来说,其同传统Distributed optimization问题有下面几点区别
    a. 数据非独立同分布Non-IID,对于任意特定节点的本地数据来说,其分布不能代表总体分布;
    b. 数据不均衡Unbalanced,不同的节点所拥有的本地数据量不同;
    c. 大量分布Massively Distributed,每轮参与优化的节点数目远远大于每个节点所拥有的平均数据量;
    d. 通信受限,例如移动设备经常处于掉线或者连接不稳定的状态。
  2. 这篇论文的重点放在探讨联邦学习中优化问题的数据Non-IID、Unbalanced特性,以及通信的限制。据此,论文中实验的设置假设每一轮通信的过程中,模型的更新是同步的(We assume a synchronous update scheme that proceeds in rounds of communication)
  3. 假设数据被划分到K个Clients之上,P_k用来标记每个Client所拥有的data points的indexes的集合(set),n_k用来标记|P_k|,即每个Client拥有的data points的数目。据此,可以将优化的目标f(w)重写为如下形式:
    在这里插入图片描述
    f_i(w)表示对于给定参数w的条件下,对于第i个data point计算出的loss值。F_k(w)表示对于第k个Client中每个data point的loss平均值。
    对于non-IID设定下的数据来说,不满足:
    在这里插入图片描述
  4. 论文指出通信设备算力增加的现状,并提出了通过增加节点本地计算以减少通信次数的方法:
    a. 增加并行increased parallelism:在每一轮通信之间使用更多的Client独立运行。
    b. 增加每个Client的计算increased computation on each client:每轮通信之间,每个Client完成更多次数的计算。

二、Federated-Averaging Algorithm

  1. 使用large-batch synchronous SGD作为baseline,同时考虑到联邦学习的setting,每轮中将选择C个Client参加学习,故而C控制global batch size(C=1表示一个full-batch的GD),作者将这个baseline称为FedSGD。
  2. 作者提出的Federated-Averaging算法,计算的总量由三个key参数控制:
    a. C:每轮参与计算的Clients数目
    b. E:每轮中每个Client在本地数据集上迭代的次数
    c. B:Client本地的minibatch size,当B=无穷表示一次本地迭代中,使用本地全部的数据;当B=无穷且E=1时,表示算法退化到前面提到的FedSGD算法。
    对于拥有n_k个本地数据的Client,每轮本地update的数目如下计算:
    在这里插入图片描述
  3. 算法的伪代码如下:
    在这里插入图片描述

三、Experimental Results

  1. 作者选择了图像分类任务和语言模型任务进行实验。对于每个任务,首先选择一个合适大小的proxy数据集,因此可以更好的探索FedAvg算法中超参数设置对结果的影响。
  2. 对于MNIST数据集,作者研究了两种在Clients上划分数据集的方法
    a. IID,先对数据进行shuffle操作,然后将数据平分给各个Client
    b. Non-IID,首先利用digit label对数据完成sort操作,将其划分为200份大小为300的shards,而后给每个Client2个shards。这也叫做pathological non-IID partition of the data
    对于pathological non-IID划分的函数设计如下:
def pathological_non_iid_split(
	dataset,  # torch.utils.Dataset类型的数据集
	n_classes, # 数据集中样本类别数
	n_clients, # 节点的数量
	n_classes_per_client, # 每个client拥有的类别数
	frac=1, # 使用数据集的比例
	seed=1234 # 传入随机数的种子
):

函数功能:先将样本按照标签进行排序,再将样本划分为n_clients * n_classes_per_clientshards(每个shard大小相等),对每个client分配n_classes_per_clientshards
函数返回:一个由n_clientsubgroup组成的列表client_indices,每个subgroup对应某个client所需样本索引组成的列表

# 根据frac获取数据集的子集
  rng_seed = (seed if (seed is not None and seed >= 0) else int(time.time())) 
  rng = random.Random(rng_seed)
  np.random.seed(rng_seed)

  # get subset
  n_samples = int(len(dataset) * frac)
  selected_indices = rng.sample(list(range(len(dataset))), n_samples)


# 从选出的数据集索引建立一个key为类别,value为对应样本集索引列表的字典,相当于按照label对样本进行排序

  label2index = {k: [] for k in range(n_classes)}
  for idx in selected_indices:
      _, label = dataset[idx]
      label2index[label].append(idx)

  sorted_indices = []
  for label in label2index:
      sorted_indices += label2index[label]

# 将数据划分为n_clients * n_classes_per_client 个独立同分布的shards
# 然后给n_clients中的每一个client分配n_classes_per_client个shards

  def iid_divide(l, g):
      """
      将列表`l`分为`g`个独立同分布的group(其实就是直接划分)
      每个group都有 `int(len(l)/g)` 或者 `int(len(l)/g)+1` 个元素
      返回由不同的groups组成的列表
      """
      num_elems = len(l)
      group_size = int(len(l) / g)
      num_big_groups = num_elems - g * group_size
      num_small_groups = g - num_big_groups
      glist = []
      for i in range(num_small_groups):
          glist.append(l[group_size * i: group_size * (i + 1)])
      bi = group_size * num_small_groups
      group_size += 1
      for i in range(num_big_groups):
          glist.append(l[bi + group_size * i:bi + group_size * (i + 1)])
      return glist


  n_shards = n_clients * n_classes_per_client
  # 一共分成n_shards个独立同分布的shards
  shards = iid_divide(sorted_indices, n_shards)
  random.shuffle(shards)
  # 然后再将n_shards拆分为n_client份
  tasks_shards = iid_divide(shards, n_clients)

  clients_indices = [[] for _ in range(n_clients)]
  for client_id in range(n_clients):
      for shard in tasks_shards[client_id]:
          # 这里shard是一个shard的数据索引(一个列表)
          # += shard 实质上是在列表里并入列表
          clients_indices[client_id] += shard 

# 返回clients_indices
 return clients_indices

  1. 对于语言建模,使用shakespear数据集:
    a. 对于每个Client,将数据划分为training lines和test lines
    b. 数据非常Unbalanced,有些角色只有寥寥几句台词,有些角色台词却非常多
    c. 进一步观察到,test set不是随机lines的sample,而是根据每个play的年表来进行temporally separate
    d. 同样的也有一个IID版本的数据划分。

四、Conclusions and Future Work

  1. Federated Learning实用
  2. FedAvg可以在减少通信次数的基础上,训练高质量的模型
  3. Privacy、secure multi-party computation或是二者的组合会是未来的研究方向,而这两个类型的技巧亦可以和FedAvg狠好的结合。

五、References

多任务学习中的数据分布问题(二)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值