如下:parameters是一个列表,其中,列表中的每个元素都是以字典的形式存在。
如果想要把parameters中的字典的键中包含weight的内容复制到另一个列表中,列表中的元素仍然以字典的形式存在,可以这样写:
parameters = [{"1.0weight":[1,1,1],"1.0bias":2,"1.1weight":[11,11,11],"1.0bias":4,"2.1weight":[111,111,111],"2.1bias":6},
{"1.0weight":[2,2,2],"1.0bias":22,"1.1weight":[22,22,22],"1.0bias":44,"2.1weight":[222,222,222],"2.1bias":66},
{"1.0weight":[3,3,3],"1.0bias":222,"1.1weight":[33,33,33],"1.0bias":444,"2.1weight":[333,333,333],"2.1bias":666}]
client_list = []#定义空列表
for param in parameters:#每个param是字典的形式
client = {} # 定义空字典
#print("param",param)
for key in param.keys():#每个key是1.0weight、1.0bias等这样的形式
if 'weight' in key:
client[str(key)] = param[str(key)] # 将clients中包含weight的键对应的键值对取出来复制到client中
#print("client", client)
client_list.append(client)#将字典param的包含weight键对应的所有的键值对组成的字典client存在列表client_list中
#现在client_list中存储的就是每个客户端包含weight的参数
print("client_list",client_list)
输出结果:
client_list [{'1.0weight': [1, 1, 1], '1.1weight': [11, 11, 11], '2.1weight': [111, 111, 111]}, {'1.0weight': [2, 2, 2], '1.1weight': [22, 22, 22], '2.1weight': [222, 222, 222]}, {'1.0weight': [3, 3, 3], '1.1weight': [33, 33, 33], '2.1weight': [333, 333, 333]}]
假设
client_list=[{'1.0weight': [11, 21, 11], '1.1weight': [101, 121, 131], '2.1weight': [111, 161, 111]},
{'1.0weight': [22, 122, 112], '1.1weight': [242, 262, 222], '2.1weight': [222, 222, 222]},
{'1.0weight': [33, 311, 123], '1.1weight': [33, 33, 33], '2.1weight': [333, 343, 313]},
{'1.0weight': [44, 411, 23], '1.1weight': [43, 342, 45], '2.1weight': [444, 343, 290]}]
代表的是四个客户端在神经网络训练过程中的参数,这里我们只取了权重,因为如果参数中有偏置等参数的时候我们可以利用上面的方法只取出权重。
下面我们要实现的是:每个客户端计算与其他客户端之间的欧氏距离,根据欧氏距离找到离它最近的k个客户端作为邻居。
random_workers = 4
client_list=[{'1.0weight': [11, 21, 11], '1.1weight': [101, 121, 131], '2.1weight': [111, 161, 111]},
{'1.0weight': [22, 122, 112], '1.1weight': [242, 262, 222], '2.1weight': [222, 222, 222]},
{'1.0weight': [33, 311, 123], '1.1weight': [33, 33, 33], '2.1weight': [333, 343, 313]},
{'1.0weight': [44, 411, 23], '1.1weight': [43, 342, 45], '2.1weight': [444, 343, 290]}]
k_num = 2#邻居的数量
neighbor=np.zeros((random_workers,k_num))##########用来存储每个客户端的邻居的索引
for k_main in range(len(client_list)):
dist_sum = []
dist_neighbor = []
for k_sec in range(len(client_list)):
dist_mid = []
for keys in client_list[0].keys():
dist_mid.append(np.linalg.norm(np.array(client_list[k_main][str(keys)]) - np.array(client_list[k_sec][str(keys)]))) #计算欧氏距离
dist_sum.append(np.sum(dist_mid))##dist_sum是一个列表,存储的是客户端k_main与其他客户端的欧氏距离值的列表
dist_new = np.argpartition(dist_sum, k_num + 1)[:k_num + 1] # 选出最小的k_num+1个欧氏距离并将其对应的索引存储在dist_new中,因为我们计算了客户端跟自己之间的距离,所以这里筛选出的邻居数是k_num+1
for j in range(k_num + 1): # SeLo_index
if dist_new[j] == k_main:
continue # 在客户端k_main的邻居中,把客户端k_main的索引去掉
else:
dist_neighbor.append(dist_new[j]) # dist_neighbor存储的是客户端k的邻居的索引
neighbor[k_main, :] = dist_neighbor[:] # 将索引赋值给neighbor,neighbor就是一个矩阵,包含每个客户端的邻居,第i行是第i个客户端的k_num个邻居的索引
print("neighbor",neighbor)
输出结果:
neighbor [[1. 2.]
[0. 2.]
[3. 1.]
[1. 2.]]



