先别走!就是个简单的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)