📣 分析实验过程
Last updated on 2023-10-13 20:22
1.联邦学习过程
从main出发——> fl_run(联邦学习总的训练过程)——> run_fl_round(联邦学习的一轮训练)——>test(每轮进行测试–测试正常样本和后门样本)——>save_model(保存模型)
2.联邦学习一轮训练
1.helper里能干的事情
初始化任务
- 给params赋值
make_task
找到运行联邦任务的py文件make_synthesizer
找到后门攻击对应的py文件,并初始化攻击- 1.初始化全局模型resnet18
在联邦学习中初始化 ResNet-18 模型的过程与常规深度学习中的初始化过程类似。初始化 ResNet-18 模型的方法通常是随机初始化,以确保模型在各个参与方的本地训练中具有足够的随机性,以便更好地学习各自的数据。实现如下:
1
2
3# 初始化 ResNet-18 模型
resnet18 = models.resnet18(pretrained=False) # 随机初始化
# 这些参数会根据某个分布(如均匀分布或正态分布)中的随机值进行初始化保存模型
保存断点
2.run_fl_round
中干的事情
- 加载全局模型和局部模型
- 随机选择参与者(可能包括恶意参与者):fl_task文件中
- 创建一个新的权重累积字典
- 接着每个参与者在本地训练全局模型,得到上传更新
- 然后更新全局模型
3.全局模型参数和本地模型参数
1.初始化全局模型参数
2.全局模型参数
3.本地模型参数
3.对参与者进行中毒和随机选择参与者
1.随机选择10个客户端
实现:fl_task
文件中sample_users_for_round
里面的实现思路:
- 在100个参与者中随机选择10个参与者,是从100个id中选择10个id
- 新建一个参与者样本列表
- 对于这10个用户,来查看其是否是恶意的,并对每个用户打标记(恶意和非恶意)
- 将打了标记的10个参与者加入参与者样本列表
2.给参与者打标记
实现:fl_task
文件中check_user_compromised
里面的实现思路:
- 先让参与者为正常参与者
- 根据单轮攻击还是多轮攻击中的攻击者列表来给当前参与者打标记
- 返回标记
3.中毒比例设置
这里需要设置2个:
- 对于单次攻击,在选中的轮次中进行攻击的时候,有10个参与者,从10个参与者里选择攻击者,这是一次中毒比例选择,参数为:fl_number_of_adversaries,取值为1-10
- 对于多次攻击,在完整轮次中所有100个参与者选择攻击者,也是一次中毒比例选择,参数为:fl_number_of_adversaries,取值为1-100
- 对于恶意参与者内部,有个样本中毒比例,参数为:poisoning_proportion。代码默认写的是0.5
4.参与者本地的训练过程
实现:training
文件里
实现思路如下:
0.在之前对数据集进行处理的过程中,如何需要设置非IID条件,可以直接设置狄利克雷分布为true即可。
- 将全局模型复制到本地模型中,实现:
fl_task
文件中copy_params
- 选择优化器SGD-随机梯度下降算法,用于优化损失函数,实现:
task
文件中的make_optimizer
- 开始本地轮次的训练:
- 如果是恶意参与者,就怎么训练
- 如果是正常参与者,就怎么训练
- 计算本地更新,
- 正常参与者,实现:
fl_task
文件中get_fl_update
。思路:本地模型—上轮全局模型 - 恶意参与者,在正常参与者计算过程上还会乘上一个数(fl_weight_scale),从而增大该更新的权重。实现:
attack
文件中的fl_scale_update
。
- 正常参与者,实现:
- 可以给上传更新用同态加密技术进行加密,实现:
fl_task
文件中get_fl_update
- 积累权重然后记录到权重累积字典,实现:
fl_task
文件中accumulate_weights
- 更新全局模型,实现:
fl_task
文件中update_global_model
5.本地模型训练的过程
实现:training.py文件中
实现的思路如下:
- 确定损失函数:交叉熵,实现:
task
文件中的make_criterion
- 开启训练模式
- 开始本地轮次的批次训练:
- 获得当前的batch,把数据加载到设备上
- 梯度为0
- 计算损失,实现:
attack.py
中的compute_blind_loss
- 将损失loss 向输入侧进行反向传播
- SGD优化器对值进行更新
- 打印训练时期的精度和损失等info信息,实现:
helper.py
中的report_training_losses_scales
6.本地模型计算损失的过程
实现:attack.py
中的compute_blind_loss
实现的思路如下:
- 记录训练的任务是什么,是后门任务和正常任务
- 获得后门训练批次,这里是加后门攻击的过程,实现:
synthesizer
中make_backdoor_batch
- 利用多梯度下降算法来计算损失和梯度,实现:
losses.loss_functions
中的compute_all_losses_and_grads
1.多梯度下降算法MGDA
前置知识:
多梯度下降算法(Multi-Gradient Descent Algorithm,简称MGDA)是一种优化算法,旨在解决多目标优化问题,也就是在一个优化问题中存在多个目标函数需要最小化或最大化的情况。MGDA 的思路是通过协调多个目标函数的优化过程,以在不同目标之间取得平衡。
下面是 MGDA 算法的基本思路:
- 多目标问题设定: 首先,确定一个多目标优化问题,其中有多个待优化的目标函数。这里是正常任务和后门任务
- 权衡策略: 在 MGDA 中,需要定义一个权衡策略,该策略决定了如何将多个目标函数结合起来形成一个综合目标,以便进行单一的优化。这个权衡策略通常包括权重或权衡参数,用于调整不同目标函数的相对重要性。这里的权衡策略是什么?
- 梯度计算: 对于每个目标函数,计算其相对于优化变量的梯度。这意味着对每个目标函数进行单独的梯度计算。
- 合并梯度: 使用权衡策略将不同目标函数的梯度合并为一个综合梯度。这通常涉及将不同目标函数的梯度按照其权重进行加权求和。
- 参数更新: 使用合并的综合梯度来更新优化变量,通常使用标准的梯度下降或其他优化方法来实现。
- 迭代优化: 重复步骤 3 到步骤 5,直到满足停止条件(例如达到最大迭代次数或梯度阈值)。
- 结果分析: 最终的优化结果是一个在多个目标函数下达到权衡的解决方案。
MGDA 的主要挑战在于权衡策略的选择,因为不同的权衡策略可能会导致不同的最终解决方案。因此,需要根据具体问题的性质和需求来选择适当的权衡策略。
总的来说,MGDA 旨在处理多目标优化问题,通过协调不同目标函数的优化过程,寻找一个在多个目标之间取得平衡的解决方案。它在多领域的优化问题中都有应用,包括机器学习、控制系统、工程优化等领域。
以下是一个简单的例子,说明如何使用MGDA来解决一个多目标优化问题:
假设你是一家制造公司的经理,你需要决定生产两种不同的产品A和B。你有两个关键的目标:最大化产品A的利润和最大化产品B的销售量。然而,这两个目标之间存在权衡,因为提高产品A的利润可能会导致产品B的销售量下降,反之亦然。
问题设定如下:
- 目标1:最大化产品A的利润(表示为Profit_A)
- 目标2:最大化产品B的销售量(表示为Sales_B)
你可以使用MGDA来解决这个问题的优化过程:
- 定义权衡策略:你需要定义一个权衡策略来决定在优化过程中分配多少资源(生产能力、广告预算等)给产品A和产品B。例如,你可以分配权重alpha给产品A的利润,权重(1-alpha)给产品B的销售量,其中alpha是一个介于0和1之间的参数,表示你对产品A和产品B的相对重要性。
- 梯度计算:针对每个目标函数,计算其相对于资源分配(例如生产量、广告投入等)的梯度。这将涉及计算Profit_A和Sales_B关于资源分配的梯度。
- 合并梯度:使用权衡策略中的权重alpha和(1-alpha)将两个目标函数的梯度加权合并为一个综合梯度。
- 参数更新:使用合并的综合梯度来更新资源分配的变量。这可能涉及使用标准的梯度下降或其他优化算法来更新资源分配。
- 迭代优化:重复步骤3和步骤4,直到达到停止条件,例如达到最大迭代次数或梯度变化很小。
- 结果分析:最终的优化结果是一组资源分配,这些资源分配在产品A的利润和产品B的销售量之间取得了权衡。
通过调整权衡策略中的参数alpha,你可以探索不同的权衡点,以找到最适合公司目标的资源分配策略。这个例子说明了如何使用MGDA来处理多目标优化问题,并在不同目标之间进行权衡,以找到最佳解决方案。
实现:losses.loss_functions
中的compute_all_losses_and_grads
实现思路如下:
- 新建一个损失和梯度空字典
- 对任务进行分类:
- 正常任务,实现:
losses.loss_functions
中的compute_normal_loss
- 后门任务,实现:
losses.loss_functions
中的compute_backdoor_loss
- 正常任务,实现:
对于正常任务计算损失和梯度,思路如下:
- 得到模型的输出
- 利用交叉熵计算损失
7.权重积累过程
8.更新全局模型过程
9.超参数设置
- 本地学习率:$\eta=0.01$
- 联邦学习的学习率:$\eta_{fl}=10$
10.自己论文的符号表示
本地符号:
- 参与者i:$c_i$
FL整个过程中的符号:
- 参与者集合:$C={c_1,c_2,…,c_n}$
11.查看模型相关信息(√)
这里先搭建一个简单的网络:一共有3层,第一层又包括2个全连接层,第三次也包括2个全连接层。
1 |
|
代码①的结果为:
代码②的结果为:
代码③的结果:先打印整个,再打印每一层。递归出了每一层
代码④的结果:
代码⑤的结果:
代码⑥的结果:
代码⑦的结果:
12.同态加密
实现:fl_task
文件中get_fl_update
查看生成的Paillier加密的公钥的具体数值:可以访问公钥对象的属性。在phe库中,公钥对象通常具有属性n
,它代表了公钥的模数(modulus)。通过访问public_key.n
,您可以获取生成的公钥的模数值,这是Paillier加密中的关键参数之一。这个值通常用于加密数据。请注意,这只是公钥的一部分,其他参数通常也存储在公钥对象中,但模数通常是最重要的部分。
13.同态加密的实现
参考资料:如何从欧氏距离推出余弦距离(HDBSCAN余弦距离)_volcanical的博客-CSDN博客
14.实验中的小技巧
1.让代码在某一行停止,在那一行后面加sys.exit(1)
。
2.模型训练过程中,展示参数。实现:utils.py中的create_table
15.其他小知识学习
1.查看数据集的图片和后门图片
16.其他阅读材料
1.FLAME: Taming Backdoors in Federated Learning 论文笔记与大致实现_volcanical的博客-CSDN博客
2.Pytorch为模型参数添加噪声_pytorch添加噪声_volcanical的博客-CSDN博客
3.pytorch实现联邦学习中state_dict()与named_parameters()的差异_volcanical的博客-CSDN博客
4.联邦学习数据集划分Dirichlet划分法——pytorch实现_pytorch数据集划分_volcanical的博客-CSDN博客
5.如何编写联邦学习训练框架——Pytorch实现_联邦学习框架_volcanical的博客-CSDN博客
6.《Deep Leakage from Gradients》_volcanical的博客-CSDN博客
7.关于梯度爆炸和梯度消失的碎碎念_Mr. Water的博客-CSDN博客
8.【联邦学习实战】基于同态加密和差分隐私混合加密机制的FedAvg_联邦学习fedavg 差分隐私_HERODING77的博客-CSDN博客
9.【阅读笔记】联邦学习实战——联邦学习攻防实战_paillier实现联邦学习_HERODING77的博客-CSDN博客
文末-目前进度
1.目前还要做2次实验,一次是单次攻击的时候,增加敌方权重,设置为50和100(10-12~13)(√)
效果不明显,去查了资料,为10的时候最好,然后攻击者肯定不知道这些参数,因此可以不停的尝试提高权重。当然还可以考虑调整别的后门攻击(pattern、白块、噪声)、比例因子(没效果–√)、学习率、非IID设置(狄利克雷分布为true)
2.多次攻击的时候,白块和噪声已经完成,接着看看随机矩阵是什么问题(10-13),还需要考虑一下训练集、测试集、验证集的效果。
3.做模型替换后门的多次攻击(10-14)
4.将本地防御加进去,开始防御上面的四个攻击,并画好图(10-15~16)
5.将服务器端的防御加进去(10-17)
6.训练整体的防御效果(10.18)
7.开始写论文画图,(10-19)