#### 2.3 数据操作
print(a1) # tensor([1, 2, 3, 4, 5], dtype=torch.int32)
print(a2) # tensor([10, 2, 3, 4, 5], dtype=torch.int32)
a1 + a2 # tensor([11, 4, 6, 8, 10], dtype=torch.int32)
torch.add(a1, a2) # tensor([11, 4, 6, 8, 10], dtype=torch.int32)
x = torch.tensor([1, 2, 3])
y = torch.tensor([4, 5, 6])
x.add_(y) # add_为就地加法,即直接加载x张量上,执行操作以后x为tensor([5, 7, 9])
x=torch.tensor([1,2,3])
x.device # 初始时,张量x的数据默认存放在CPU上
if torch.cuda.is_available():
x = x.cuda()
x.device # 如果系统有GPU设备,张量x的数据将存放在GPU上
#### 2.4 自动求导
自动求导功能是PyTorch进行模型训练的核心模块,PyTorch的自动求导功能通过autograd包实现。
autoqrad包求导时,首先要求Tensor将requires grad属性设置为True。
随后,PyTorch将自动跟踪该Tensor的所有操作。
当调用backward()进行反向计算时,将自动计算梯度值并保存在grad属性中。
import torch
x = torch.ones(2,2,requires_grad=True)
y = x + 2
z = y * y * 3
out = z.mean()
out.backward()
x.grad #求取x的梯度值为(4.5,4.5,4.5,4.5)
### 3. 用python实现横向联邦学习图像分类
本节我们使用Python从零开始实现一个简单的横向联邦学习模型。具体来说,我们将用横向联邦来实现对cifar10图像数据集的分类,模型使用的是ResNet-18。
我们将分别从服务端、客户端和配置文件三个角度详细讲解设计一个横向联邦所需要的基本操作。需要注意的是,为了方便实现,本章没有采用网络通信的方式来模拟客户端和服务端的通信,而是在本地以循环的方式来模拟。
此外,我们本章节用到很多开源库,因此读者对代码做了相应的注释。如果仍有读者对API比较陌生,觉得阅读代码有困难,推荐可以边阅读边查阅相关API的用法,因为模型训练本就是一个边尝试边学习的过程。
#### 3.1 配置信息
联邦学习在模型训练之前,会将配置信息分别发送到服务端和客户端中保存,如果配 置信息发生改变,也会同时对所有参与方进行同步,以保证各参与方的配置信息一致。
导包
from torchvision import transforms, models, datasets
import random
conf = {
“model_name”: “resnet18”, # 模型名称
“no_models”: 10, # 客户端数量
“type”: “cifar”, # 数据集名称
“global_epochs”: 20, # 全局epoch
“local_epochs”: 3, # 局部训练迭代次数
“k”: 6, # 随机从所有客户端中选取k个做训练
“batch_size”: 32, # 局部训练批处理大小
“lr”: 0.001, # 学习率
“momentum”: 0.0001, # 优化器动量,加速优化
“lambda”:0.1 # 在聚合过程中使用的系数,用于控制从客户端收集的更新对全局模型的影响程度
}
#### 3.2 训练数据集
我们使用torchvision的 datasets模块内置的cifar10数据集
def get_dataset(dir, name):
# 根据指定的数据集名称,加载并返回训练和评估数据集
if name == ‘mnist’:
# 加载MNIST数据集