pytorch 联邦学习fedavg梯度平均 放入字典的值的列表 无法平均

先别走!就是个简单的python问题!先停下来看看吧大爹们
就是个简单的列表和字典的问题

代码1和代码2的输出的global_parameters不同,代码1能正确运行,代码2训练不起来

代码1

local_parameters:每一个客户端的梯度
sum_parameters:将客户端的梯度求和
global_parameters:将所有客户端进行fedavg平均之后的梯度

sum_parameters,local_parameters,global_parameters这三个的键都一样,global_parameters的键已经在前面写好
num_in_comm是个非空非零int型

sum_parameters = None # 先赋为none,方便后面写键值对
for client in clients_in_comm:
    local_parameters = 生成的一个新字典,每次的键都相同,值不同(值是tensor类型的)
    if sum_parameters is None:  # 第一次循环
        sum_parameters = {}  # 先赋为none,方便后面写键值对
        for key, var in local_parameters.items():
            sum_parameters[key] = var.clone()  # 第一次运行,之后运行 键就有了,写入了第一个local_parameters的数据
    else:
        for var in sum_parameters:
            sum_parameters[var] = sum_parameters[var] + local_parameters[var] # 将每个梯度相加

for var in global_parameters:
    global_parameters[var] = (sum_parameters[var] / num_in_comm)  # fedavg 

代码2

和代码1不同是sum_parameters的值是字典而不是每个客户端的和,保存了local_parameters每个键的值
在最后进行加和平均,理论上和代码1的工作是相同的,只是保存了每个客户端单独的梯度

sum_parameters = None
for client in clients_in_comm:
    local_parameters = 生成的一个新字典,每次的键都相同,值不同(值是tensor类型的)
    if sum_parameters is None:
        sum_parameters = {}
        for key, var in local_parameters.items():
            sum_parameters[key] = var.clone()  # 到这里和上面的还相同
        for var in sum_parameters:
            sum_parameters[var] = [sum_parameters[var]]  # sum_parameters的每个值都是个list
    else:  # 之后的循环
        for var in sum_parameters:
            sum_parameters[var].append(local_parameters[var]) #  将每个local_parameters的值添加进list中

for var in global_parameters:
    sum_add=None  # 应为tensor类,先定义为none
    for item in sum_parameters[var]:
        if sum_add==None:
            sum_add=item
        else:
            sum_add=sum_add+item  # 后面的梯度相加
    global_parameters[var] = (sum_add / num_in_comm)