客户端数据集
AD: AbstructDataset {
shape: class
raw_data: Opt\[Tuple\[any\]\]
user_id: Opt\[str\]
metadata: Opt\[Dict\[str, Any\]\]
train_kwargs: Opt\[Dict\[str, Any\]\]
eval_kwargs: Opt\[Dict\[str, Any\]\]
-split(\.\.\.)`划分数据集`: \[AbstractDataset, AbstractDataset\]
-get_worker_partition()`给出分配给当前用户的数据集,所有用户的数据集构成一整个数据集`: AbstractDataset
}
DS: Dataset {
shape: class
+get_worker_partition()`依赖DistributedContext返回raw_data的size`: AbstractDataset
+split(\.\.\.)`实现了按照比例划分train和val数据集`
}
AD -> DS
TD: TabularDataset {
shape: class
+ features: ndarray
+ labels: ndarray
\# `features 连同 labels 一起构造成raw_data,其余的行为和Dataset一致`
}
DS->TD
DSpt: DatasetSplit {
shape: class
\# 这个类型是用于本地数据集已经预先划分成train和val的情况,例如元学习
+ train_dataset: AbstractDataset
+ val_dataset: AbstractDataset
\# ! 这个数据集不能迭代,需要调用split先
}
AD->DSpt
PTD: PyTorchTensorDataset {
shape: class
\# In\-meory的PyTorch tensor数据集
+ raw_data: Tuple\[torch.Tensor\]
}
DS->PTD
PDD: PytorchDataDataset {
shape: class
# 当(用户)数据集过大不能完全读进内存的时候使用,例如一个大的集中eval数据集
+ raw_data: torch.utils.data.Dataset
+ **dataloader_kargs`至少得包含batch_size`: Dict
+ split`NotImplement`: DO NOT USE
}
AD -> PDD
联邦数据集
用户的数据集构造是由 FederatedDatasetBase
的继承类定义的。每次当 __next__
被调用的时候,会返回一个 (user_data, seed)
的元祖,其中 user_data
是一个 pfl.data.dataset.Dataset
,seed
是一个随机的整数,每个 worker 的每次调用生成一个随机的整数是为了让 DP 不要生成相等的噪声
FDB: FederatedDatasetBase {
shape: class
_random_state: np.uint32
- __next__(): Tuple\[AbstractDataset, int\]
- get_cohort(cohort_size)`获取整批用户,在多worker的语境中,被指派给这个worker的所有用户数据集会被返回`: Iterable\[Tuple\[AbstractDataset, int\]\]
}
AFD: ArtificialFederatedDataset {
shape: class
\# `通过自动将数据组合进用户来模拟一个联邦数据集`
\# `这个class是当数据集没有一个特定的用户标识符的时候用的,当然如果提供用户标识符也一样work`
\# `一个用户的数据集如何生成取决于提供的采样方法`
+ make_dataset_fn`一个函数,输入样本下标,返回生成的用户数据集`: callabel(dataset_indices) -> user_dataset
+ data_sampler`采样策略,采样数据样本下标,用来后续构造一个新的用户数据集`: callable(dataset_length) -> dataset_indices
\# 注意采样方式会受到distributed的影响,具体可以看代码中的sel\.sampler = iter(_distributed_sampler(\.\.\.))
+ sample_dataset_len`一个函数,需要采样出来一个用户的样本量`: callable() -> dataset_length
+ `classmethod`from_slices(data, data_sampler,sampler_data_len): ArtificialFederatedDataset
}
FDB -> AFD
FD: FederatedDataset {
shape: class
\# `federated dataset是一些对应特定用户的数据集的集合,在这个类上迭代每次会返回一个属于特定用户的数据集`
+ make_dataset_fn`一个函数,输入一个用户标识符,返回一个用户数据集`
+ user_sampler`对用户id进行采样的方法`: callable() -> user_id
+ user_id_to_weight`将用户 ID 映射到权重的字典,用作代理的计算时间。如果传递了这个参数,会使用_SortedCohortSampler来构造采样函数,暂时还不清楚有什么用`: dict\[Any, int\]
}
FDB -> FD
PFD: PyTorchFederatedDataset {
shape: class
\# 这个实现地非常fusion,最好不要用
+ dataset`一个PyTorch dataset实例,__getitem__应该实现为接收一个用户id,返回分配给这个用户的所有样本,而不是一个样本`: torch.utils.data.Dataset
+ dataset_cls: Type\[PyTorchTensorDataset\]
+ dataloader_kwargs`opt,注意如果batch_size在这个字典里则一定要为None或1`: Opt\[Dict\]
}
FD->PFD
Partition .py
- Partition_by_dirichlet_class_distribution: 可以用来生成 non-iid 的数据
sampling.py
- CrossSiloUserSampler: 一种用户采样方法,假设用户被分成了属于不同 silos 的不同子集。
- 每一轮,所有的 silos 都会为群体作出贡献,并且每个 silo 会采样出一个或者多个用户
- 在分布式的语境下,silos 会被划分给不同的节点,每次采样调用时,按照固定的顺序选取一个 silos 然后对子集进行采样
- 构造时可以提供一个字典表示预先分配的 silos 子集,如果没有提供,所有用户会被平均分配给 n 个 silos