TensorFlow Federated中federated_computation内Call对象不可下标访问问题
问题原因
你的猜测完全正确,报错核心原因是run_one_round被tff.federated_computation装饰器修饰,TFF的联邦计算函数执行分为两个完全独立的阶段:
- 编译阶段:定义
federated_computation函数时,TFF并不会真实执行函数内的代码,而是将所有逻辑转换为TFF内部的抽象计算图节点。你在函数内拿到的value.comp不是实际运行时的张量/数组数据,而是TFF内部表示计算节点的Call类型对象,本身不支持下标访问、长度计算等Python原生操作,因此会抛出'Call' object is not subscriptable报错。 - 运行阶段:你在主函数调用
iterative_process.next时,才会真实执行编译好的联邦计算逻辑,返回的value_comp是计算完成后得到的真实数值(tf张量或numpy数组),所以可以正常使用Python循环和下标操作。
实现方案
你要在tff.federated_mean调用前处理客户端返回的test变量,不能直接用原生Python逻辑,需要按照TFF的编程规范实现:
- 如果是每个客户端处理自己的
test数据:将你的解压处理逻辑封装为tf.function修饰的TensorFlow兼容函数,再通过tff.federated_map映射到所有客户端的client_outputs.test上执行即可。 - 如果需要收集所有客户端的
test数据到服务器侧统一处理:先调用tff.federated_collect将客户端侧的test数据聚合到服务器placement,再用tff.federated_map在服务器侧执行你的处理逻辑。
示例代码如下:
# 首先将解压逻辑改造为TF兼容的函数 import tensorflow as tf import sparse_ternary_compression @tf.function def decompress_test(test_item): res = [] # 用tf.range替代Python range保证可以被编译为TF图 for index in tf.range(len(test_item)): res.append(sparse_ternary_compression.stc_decompression( test_item[index][0], test_item[index][1], test_item[index][2], test_item[index][3], test_item[index][4] )) return res def run_one_round(server_state, federated_dataset): # 原有逻辑不变... client_outputs = tff.federated_map( client_update_fn, (federated_dataset, server_message_at_client)) # 新增:处理客户端test数据 processed_test = tff.federated_map(decompress_test, client_outputs.test) # 后续你可以用processed_test做后续操作,比如继续聚合等 # 原有逻辑不变...
内容的提问来源于stack exchange,提问作者Fanto
相关产品推荐
相关产品推荐

