找回密码
 会员注册
查看: 30|回复: 0

联邦学习算法介绍-FedAvg详细案例-Python代码获取

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
64125
发表于 2024-9-13 09:06:23 | 显示全部楼层 |阅读模式
联邦学习算法介绍-FedAvg详细案例-Python代码获取一、联邦学习系统框架二、联邦平均算法(FedAvg)三、联邦随梯度下降算法(FedSGD)四、差分隐私随联邦梯度下降算法(DP-FedSGD)五、差分隐私联邦平均算法(DP-FedAVG)六、FedAVG案例附代码1)案例背景2)参数设置3)结果展示4)代码详解七、完整项目代码获取方式一、联邦学习系统框架图1中心化联邦学习框架  由服务端收集各客户端的梯度信息,通过聚合计算后再分发给各客户端,从而实现多个客户端联合训练模型,且“原始数据不出岛”,从而保护了客户端数据隐私。图2去中心化联邦学习框架  假设中心方是好奇的,那么客户端通过某种规则向其他客户端广播梯度信息,收到梯度信息的客户端聚合参数并训练,将新的梯度信息广播。二、联邦平均算法(FedAvg)图3联邦平均算法框架输入:全局模型参数初始值ω0\omega^0ω0,参与方个数nnn,批样本大小BBB,训练轮数EEE,参与方比例CCC,局部模型学习率η\etaη,各参与方的样本个数mkm_kmk​。输出:最后一次迭代的全局模型参数ωt+1\omega_{t+1}ωt+1​1.中央服务器初始化全局模型参数ω0\omega^0ω0,并传输给所有参与方。2.对t=0,1,2,⋯t=0,1,2,\cdotst=0,1,2,⋯,迭代以下步骤直到全局模型参数ωt+1\omega_{t+1}ωt+1​收敛。  (1)中央服务器根据参与方比例C∈(0,1]C\in(0,1]C∈(0,1],计算参与第ttt轮迭代的参与方个数:M←max⁡(C×n,1)M\leftarrow\max(C\timesn,1)M←max(C×n,1)  (2)中央服务器随机选取MMM个参与方,构成参与方集合StS_tSt​  (3)对∀k∈St\forallk\inS_t∀k∈St​,通过以下步骤更新局部模型参数:    [1]使用接收到的模型参数ωt\omega_tωt​进行模型初始化ωt+1k⟵ωt\omega_{t+1}^k\longleftarrow\omega_tωt+1k​⟵ωt​。    [2]将数据索引集PkP_kPk​按照批样本大小BBB分为若干个批次,记由这些批次构成的集合为BkB_kBk​。对每次训练j=1,⋯ ,Ej=1,\cdots,Ej=1,⋯,E,使用∀b∈Bk\forallb\inB_k∀b∈Bk​,更新局部模型参数:ωt+1k⟵ωt+1k−η∇Fk(ω;b)\omega_{t+1}^k\longleftarrow\omega_{t+1}^k-\eta\nablaF_k(\omega;b)ωt+1k​⟵ωt+1k​−η∇Fk​(ω;b)将更新好的局部模型参数ωl+1k\omega_{l+1}^kωl+1k​传输给中央服务器。  (4)中央服务器聚合所有参数,并传输回所有参与方ωt+1=∑k=1Mmkmωt+1k\omega_{t+1}=\sum_{k=1}^M\frac{m_k}{m}\omega_{t+1}^kωt+1​=k=1∑M​mmk​​ωt+1k​    mkm\frac{m_k}{m}mmk​​为t+1轮聚合中客户端k占参与训练的M个客户端总样本的比例。三、联邦随梯度下降算法(FedSGD)当训练轮数E=1E=1E=1,且批样本大小BBB是对应的参与方的总样本个数时,FedAvg算法退化为FedSGD算法。使用各自的所有样本,对参数ωl+1k\omega_{l+1}^kωl+1k​进行一次梯度下降,计算参数ωt+1k\omega_{t+1}^kωt+1k​的梯度:gk=∇Fk(ωt+1k)g_k=\nablaF_k\left(\omega_{t+1}^k\right)gk​=∇Fk​(ωt+1k​)或者计算参数更新值ωt+1k⟵ωt+1k−ηgk\omega_{t+1}^k\longleftarrow\omega_{t+1}^k-\etag_kωt+1k​⟵ωt+1k​−ηgk​其中η\etaη是学习率。四、差分隐私随联邦梯度下降算法(DP-FedSGD)图4DP-FedSGD算法框架1.参数更新量的裁剪方式ClipFn裁剪方式分2种,即水平裁剪和分层裁剪。(1)水平裁剪。记参数更新量矢量为Δ\DeltaΔ,将其2-范数的上界设为S∈RS\inRS∈R,即:π(Δ,S)= def Δ⋅min⁡(1,S∥Δ∥)\pi(\boldsymbol{\Delta},S)\stackrel{\text{def}}{=}\boldsymbol{\Delta}\cdot\min\left(1,\frac{S}{\|\Delta\|}\right)\quadπ(Δ,S)= def Δ⋅min(1,∥Δ∥S​)(2)分层裁剪。面向神经网络模型,假设网络总共有ccc层,每一层的参数更新量矢量分别为Δ(1),⋯ ,Δ(c)\Delta(1),\cdots,\Delta(c)Δ(1),⋯,Δ(c),对应的2-范数上界分别为S1,⋯S_1,\cdotsS1​,⋯,ScS_cSc​,通过水平裁剪的方法,分别对每一层的矢量进行裁剪:Δ′(j)=π(Δ(j),Sj)\boldsymbol{\Delta}^{\prime}(j)=\pi\left(\boldsymbol{\Delta}(j),S_j\right)Δ′(j)=π(Δ(j),Sj​)总体的参数更新量裁剪上界定义为S=∑j=1cSj2S=\sqrt{\sum_{j=1}^cS_j^2}S=j=1∑c​Sj2​​2.中央服务器通过以下步骤对局部模型参数更新量进行聚合1)计算聚合结果关于加权聚合方式f(C)=∑k∈CdkΔk∑k∈Cdkf(C)=\frac{\sum_{k\inC}d_k\Delta^k}{\sum_{k\inC}d_k}f(C)=∑k∈C​dk​∑k∈C​dk​Δk​(其中Δk\Delta^kΔk是参与方kkk的参数更新量,CCC为一轮中参与迭代的参与方集合)的有界灵敏度(Bounded-sensitivity)的估计量,分为以下2种:    [1]f~f(C)=∑k∈CdkΔkqD\tilde{f}_{\mathrm{f}}(C)=\frac{\sum_{k\inC}d_k\Delta^k}{qD}f~​f​(C)=qD∑k∈C​dk​Δk​其中dk=min⁡(mkm^,1)d_k=\min\left(\frac{m_k}{\hat{m}},1\right)dk​=min(m^mk​​,1),是每个参与方的权重;D=∑k=1ndkD=\sum_{k=1}^nd_kD=∑k=1n​dk​,qqq为每轮通信中参与方的选择概率。    [2]f~c(C)=∑k∈CdkΔkmax⁡(qDmin ,∑k∈Cdk)\tilde{f}_{\mathrm{c}}(C)=\frac{\sum_{k\inC}d_k\Delta^k}{\max\left(qD_{\text{min}},\sum_{k\inC}d_k\right)}f~​c​(C)=max(qDmin ​,∑k∈C​dk​)∑k∈C​dk​Δk​其中Dmin D_{\text{min}}Dmin ​是预先设置的关于权重和的超参数。(2)令S←\leftarrow←裁剪方式ClipFn中的裁剪上界,根据选定的有界灵敏度估计量和噪声规模z,设置高斯噪声的方差:σ←{zSqD for f~f or 2zSqDmin⁡ for f~c}\sigma\leftarrow\left\{\frac{zS}{qD}\text{for}\tilde{f}_{\mathrm{f}}\text{or}\frac{2zS}{qD_{\min}}\text{for}\tilde{f}_{\mathrm{c}}\right\}σ←{qDzS​ for f~​f​ or qDmin​2zS​ for f~​c​}(3)聚合全局模型的参数为ωt+1←ωt+Δt+1+N(0,Iσ2)\omega_{t+1}\leftarrow\omega_t+\Delta_{t+1}+N\left(0,I\sigma^2\right)ωt+1​←ωt​+Δt+1​+N(0,Iσ2)其中,N(0,Iσ2)N\left(0,I\sigma^2\right)N(0,Iσ2)是均值为0、方差为σ2\sigma^2σ2的高斯分布;III是单位方阵,行数和列数都是参数的个数。(4)根据zzz和M\mathcal{M}M计算隐私损失值并输出。五、差分隐私联邦平均算法(DP-FedAVG)  在DP-FedSGD中,被选中的参与方使用全局模型参数对局部模型进行初始化,通过批梯度下降法进行多轮梯度下降,计算梯度更新量。而在DP-FedAVG中,是利用一个批次的数据进行一次梯度下降,计算梯度更新量。六、FedAVG案例附代码1)案例背景  收集2012年某10个城市每天每小时的电力数据。用前24时刻的电力负荷值以及该时刻的4个相关气象数据,来预测该时刻的电力负荷值。  构造四层的深度网络:z1=Iw1,h1=σ(z1)z2=h1w2,h2=σ(z2)z3=h2w3,h3=σ(z3)z4=h3w4,O=σ(z4) loss =12(O−y)2z1=Iw1,h1=σ(z1)z2=h1w2,h2=σ(z2)z3=h2w3,h3=σ(z3)z4=h3w4,O=σ(z4) loss =12(O−y)2z1=Iw1,h1=σ(z1)z2=h1w2,h2=σ(z2)z3=h2w3,h3=σ(z3)z4=h3w4,O=σ(z4) loss =12(O−y)2z1​=Iw1​,h1​=σ(z1​)z2​=h1​w2​,h2​=σ(z2​)z3​=h2​w3​,h3​=σ(z3​)z4​=h3​w4​,O=σ(z4​) loss =21​(O−y)2​  σ\sigmaσ为sigmoid激活函数。2)参数设置表1FedAVG参数参数值聚合轮数5本地训练次数20客户端总数10学习率0.08本地批量样本大小50优化器adam3)结果展示  设置每轮随机抽取参与训练的客户端数量为2、5、8、10。图5FedAVGmae图6FedAVGrmse向梯度中添加随机噪声图7FedAVG+noisemae图8FedAVG+noisermse4)代码详解数据结构,在本地文件夹中,有10个csv文件,这10个文件各自代表一个客户端。在每个csv文件中,均有7个指标,6577条样本,其中第一列表示服务端id。第一步,加载数据。首先需要划分每个客户端的训练集和测试集,本文设置了每个客户端数据结构与样本数量一致(也可以不一致,通过样本对齐方法即可)。#-*-coding:utf-8-*-"""@File:bp_nn.py"""importcopyimportsysimportnumpyasnpimportpandasaspdfromtorchimportnnfromtqdmimporttqdmsys.path.append('../')fromsklearn.metricsimportmean_absolute_error,mean_squared_errorfromitertoolsimportchainfrommodelsimportBP##自定义importosos.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"#避免jupyter崩溃clients_wind=['Task1_W_Zone'+str(i)foriinrange(1,11)]fromargsimportargs_parser##自定义参数defload_data(file_name):#读取某一个文件---横向联邦学习df=pd.read_csv(os.path.dirname(os.getcwd())+'/data/Wind_new/Task1/Task1_W_Zone1_10/'+file_name+'.csv',encoding='gbk')columns=df.columnsdf.fillna(df.mean(),inplace=True)foriinrange(3,7):#3,4,5,6MAX=np.max(df[columns[i]])MIN=np.min(df[columns[i]])df[columns[i]]=(df[columns[i]]-MIN)/(MAX-MIN)#将3,4,5,6列的值,标准化returndf#0-6列,后4列已经标准化defnn_seq_wind(file_name,B):#B实则为本地批量大小print('dataprocessing...')dataset=load_data(file_name)#splittrain=dataset[:int(len(dataset)*0.6)]#前60%为训练集val=dataset[int(len(dataset)*0.6):int(len(dataset)*0.8)]#中间20%为验证集test=dataset[int(len(dataset)*0.8):len(dataset)]#最后20%为测试集defprocess(data):#将特征与标签分开columns=data.columnswind=data[columns[2]]wind=wind.tolist()#转换成列表https://vimsky.com/examples/usage/python-pandas-series-tolist.htmldata=data.values.tolist()X,Y=[],[]foriinrange(len(data)-30):train_seq=[]train_label=[]forjinrange(i,i+24):#24小时train_seq.append(wind[j])forcinrange(3,7):train_seq.append(data[i+24][c])train_label.append(wind[i+24])X.append(train_seq)Y.append(train_label)X,Y=np.array(X),np.array(Y)length=int(len(X)/B)*BX,Y=X[:length],Y[:length]returnX,Ytrain_x,train_y=process(train)val_x,val_y=process(val)test_x,test_y=process(test)return[train_x,train_y],[val_x,val_y],[test_x,test_y]defget_val_loss(args,model,val_x,val_y):#验证集,计算损失,model即为nnbatch_size=args.Bbatch=int(len(val_x)/batch_size)#计算循环次数val_loss=[]foriinrange(batch):start=i*batch_sizeend=start+batch_sizemodel.forward_prop(val_x[start:end],val_y[start:end])model.backward_prop(val_y[start:end])val_loss.append(np.mean(model.loss))returnnp.mean(val_loss)deftrain(args,nn):print('training...')tr,val,te=nn_seq_wind(nn.file_name,args.B)train_x,train_y=tr[0],tr[1]val_x,val_y=val[0],val[1]nn.len=len(train_x)#nn.len训练集的长度batch_size=args.B#每批次大小epochs=args.E#迭代次数batch=int(len(train_x)/batch_size)#每一迭代,需要训练多少次#trainingmin_epochs=10best_model=Nonemin_val_loss=5forepochintqdm(range(epochs)):train_loss=[]foriinrange(batch):start=i*batch_sizeend=start+batch_sizenn.forward_prop(train_x[start:end],train_y[start:end])nn.backward_prop(train_y[start:end])train_loss.append(np.mean(nn.loss))#validationval_loss=get_val_loss(args,nn,val_x,val_y)ifepoch+1>=min_epochsandval_loss
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 13:14 , Processed in 2.406368 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表