加载多个 CSV 文件(孤岛)以组成 Tensorflow Federated 数据集

Loading multiple CSV files (silos) to compose Tensorflow Federated dataset

我正在处理预处理数据,这些数据已经被隔离到单独的 csv 文件中,以表示用于联邦学习的单独本地数据。

为了在 TensorFlow Federated 上使用这些多个 CSV 正确实施联合学习,我只是试图在 iris 数据集中用一个玩具示例重现相同的方法。但是,当尝试使用 tff.simulation.datasets.TestClientData 方法时,出现错误:

TypeError: can't pickle _thread.RLock objects

当前代码如下,首先将三个鸢尾花数据集CSV文件(每个50个样本)从文件名iris1.csv、iris2.csv、[=41=中加载到字典中]:

    silos = {}
    for silo in silos_files:
        silo_name = silo.replace(".csv", "")
        silos[silo_name] = pd.read_csv(silos_path + silo)
        silos[silo_name]["variety"].replace({"Setosa" : 0, "Versicolor" : 1, "Virginica" : 2}, inplace=True)

正在创建一个带有张量的新字典:

    silos_tf = collections.OrderedDict()
    for key, silo in silos.items():
        silos_tf[key] = tf.data.Dataset.from_tensor_slices((silo.drop(columns=["variety"]).values, silo["variety"].values))

最后,尝试将 Tensorflow 数据集转换为 Tensorflow 联合数据集:

tff_dataset = tff.simulation.datasets.TestClientData(
    silos_tf
)

引发错误:

TypeError                                 Traceback (most recent call last)
<ipython-input-58-a4b5686509ce> in <module>()
      1 tff_dataset = tff.simulation.datasets.TestClientData(
----> 2     silos_tf
      3 )

/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/simulation/datasets/from_tensor_slices_client_data.py in __init__(self, tensor_slices_dict)
     59     """
     60     py_typecheck.check_type(tensor_slices_dict, dict)
---> 61     tensor_slices_dict = copy.deepcopy(tensor_slices_dict)
     62     structures = list(tensor_slices_dict.values())
     63     example_structure = structures[0]

...

/usr/lib/python3.7/copy.py in deepcopy(x, memo, _nil)
    167                     reductor = getattr(x, "__reduce_ex__", None)
    168                     if reductor:
--> 169                         rv = reductor(4)
    170                     else:
    171                         reductor = getattr(x, "__reduce__", None)

TypeError: can't pickle _thread.RLock objects

我也尝试使用 Python 字典而不是 OrderedDict,但错误是一样的。对于此实验,我使用 Google Colab 和 this notebook 作为参考 运行 TensorFlow 2.8.0 和 TensorFlow Federated 版本 0.20.0。我也参考了之前的这些问题:

Is there a reasonable way to create tff clients datat sets?

我不确定这是否是适用于玩具示例之外的案例的好方法,如果有任何关于如何为 TFF 测试引入已经孤立的数据的建议,我将不胜感激。

我使用 class tff.simulation.datasets.TestClientData 在 github 中搜索了 public 代码,然后我找到了以下实现 (source here):

def to_ClientData(clientsData: np.ndarray, clientsDataLabels: np.ndarray,
    ds_info, is_train=True) -> tff.simulation.datasets.TestClientData:

    """Transform dataset to be fed to fedjax
    :param clientsData: dataset for each client
    :param clientsDataLabels:
    :param ds_info: dataset information
    :param train: True if processing train split
    :return: dataset for each client cast into TestClientData
    """
    num_clients = ds_info['num_clients']

    client_data = collections.OrderedDict()

    for i in range(num_clients if is_train else 1):
        client_data[str(i)] = collections.OrderedDict(
            x=clientsData[i],
            y=clientsDataLabels[i])

    return tff.simulation.datasets.TestClientData(client_data)

我从这个片段中了解到 tff.simulation.datasets.TestClientData class 需要一个由 numpy 数组组成的 OrderedDict 作为参数,而不是张量字典 (因为我的以前的实现),现在我更改了以下代码:

silos_tf = collections.OrderedDict()
for key, silo in silos.items():
    silos_tf[key] = collections.OrderedDict(
            x=silo.drop(columns=["variety"]).values,
            y=silo["variety"].values)
    

其次是:

tff_dataset = tff.simulation.datasets.TestClientData(
    silos_tf
)

正确运行为以下输出:

>>> tff_dataset.client_ids
['iris3', 'iris1', 'iris2']