当前位置:   article > 正文

pysyft对MNIST数据集进行加载训练_sy.federateddataloader

sy.federateddataloader

利用pysyft加载MNIST数据集,通过神经网络进行训练,参考官方文档,自己改了些数值,每一行代码基本都注释了对应的含义

  1. 导入pytorch
  2. import logging
  3. import torch.utils.data
  4. # 用于构建NN
  5. import torch.nn as nn
  6. # 需要用到这个库里面的激活函数
  7. import torch.nn.functional as F
  8. # 用于构建优化器
  9. import torch.optim as optim
  10. # 用于初始化数据
  11. from torchvision import datasets, transforms
  12. # 用于分布式训练
  13. import syft as sy
  14. hook = sy.TorchHook(torch)
  15. Bob = sy.VirtualWorker(hook,id='Bob')
  16. Alice = sy.VirtualWorker(hook,id='Alice')
  17. class Arguments(object):
  18. def __init__(self):
  19. self.batch_size = 1
  20. self.test_batch_size = 1000
  21. self.epochs = 3
  22. self.lr = 0.01
  23. self.momentum = 0.5
  24. self.no_cuda = False
  25. self.seed = 1
  26. self.log_interval = 30
  27. self.save_model = False
  28. #实例化参数类
  29. args = Arguments()
  30. #判断是否使用GPu
  31. use_cuda = not args.no_cuda and torch.cuda.is_available()
  32. #固定化随机数种子,使得每次训练的随机数都是固定的
  33. torch.manual_seed(args.seed)
  34. #判断是否使用GPU
  35. device = torch.device('cuda' if use_cuda else 'cpu')
  36. #tramsform将图片转化为Tensor,Normalize用来正则化,降低模型复杂度
  37. fed_dataset = datasets.MNIST('data',download=True,train=True,
  38. transform=transforms.Compose([transforms.ToTensor()]))
  39. #定义数据加载器,shuffle是采用随机的方式抽取数据,顺便也把数据集定义在了客户端上
  40. fed_loader = sy.FederatedDataLoader(federated_dataset=fed_dataset.federate((Alice,Bob)),batch_size=args.batch_size,shuffle=True)
  41. # print('Bob\'object: {}'.format(Bob._objects)) #检验分发的数据
  42. # print('Alice\'object: {}'.format(Alice._objects)) #检验分发的数据
  43. #定义测试集
  44. test_dataset = datasets.MNIST('data',download=True,train=False,
  45. transform=transforms.Compose([transforms.ToTensor()]))
  46. #定义测试集加载器
  47. test_loader = torch.utils.data.DataLoader(test_dataset,batch_size=args.test_batch_size,shuffle=True)
  48. #构建神经网络模型
  49. class Net(nn.Module):
  50. def __init__(self):
  51. super(Net,self).__init__()
  52. #输入维度为1,输出维度为20,卷积核大小为:5*5,步幅为1
  53. self.conv1 = nn.Conv2d(1,20,5,1) #灰度图片的通道
  54. self.conv2 = nn.Conv2d(20,50,5,1) #输入为20,输出为50,卷积核5*5,步幅为1
  55. self.fc1 = nn.Linear(4*4*50,500)
  56. #最后映射到10维上
  57. self.fc2 = nn.Linear(500,10)
  58. def forward(self,x):
  59. #print(x.shape)
  60. x = F.relu(self.conv1(x))#28*28*1 -> 24*24*20 (28-5+1=24)
  61. #print(x.shape)
  62. #卷机核:2*2 步幅:2
  63. x = F.max_pool2d(x,2,2)#24*24*20 -> 12*12*20 池化,通道不变,维度降半
  64. #print(x.shape)
  65. x = F.relu(self.conv2(x))#12*12*20 -> 8*8*50 (12-5+1=8)
  66. # #print(x.shape)
  67. x = F.max_pool2d(x,2,2)#8*8*50 -> 4*4*50
  68. #print(x.shape)
  69. x = x.view(-1,4*4*50) #拉伸 -1自动计算维度
  70. x = F.relu(self.fc1(x))
  71. x = self.fc2(x)
  72. #使用logistic函数作为softmax进行激活吗就
  73. return F.log_softmax(x, dim = 1) #计算分类够每个数字的概率值
  74. #定义数据训练:
  75. model = Net().to(device)
  76. optimizer = optim.SGD(model.parameters(), lr=args.lr)
  77. def train(model:model, device:device, fed_loader:sy.FederatedDataLoader, optimizer:optimizer, epoch:args.epochs):
  78. model.train()
  79. # 远程迭代
  80. for batch_idx, (data,target) in enumerate(fed_loader): # enumerate用来编序号
  81. model.send(data.location) # 发送模型到远程
  82. data, target = data.to(device), target.to(device) #部署到device #此行有问题
  83. optimizer.zero_grad() #梯度清0
  84. output = model(data)
  85. loss = F.nll_loss(output, target) #计算损失
  86. loss.backward() #反向传播
  87. optimizer.step()
  88. model.get() # 以上都是发送命令给远程,下面是取回更新的模型
  89. if batch_idx % args.log_interval== 0: # 打印间隔时间
  90. # 由于损失也是在远处产生的,因此我们需要把它取回来
  91. loss=loss.get()
  92. print('Train Epoch : {} [ {} / {} ({:.0f}%)] \tLoss: {:.6f}'.format(
  93. epoch,
  94. batch_idx * args.batch_size,
  95. len(fed_loader)*args.batch_size,
  96. 100.*batch_idx/len(fed_loader),
  97. loss.item())
  98. )
  99. def test(model:model, device:device, test_loader:torch.utils.data.DataLoader):
  100. model.eval()
  101. test_loss = 0 #测试损失
  102. correct=0 #正确率
  103. with torch.no_grad():
  104. for data,target in test_loader:
  105. data,target = data.to(device),target.to(device)
  106. output=model(data)
  107. #将损失加起来
  108. test_loss+=F.nll_loss(output,target,reduction='sum').item()
  109. #进行预测最可能的分类
  110. pred =output.argmax(dim=1,keepdim=True)
  111. correct+=pred.eq(target.view_as(pred)).sum().item()
  112. test_loss/=len(test_loader.dataset)
  113. print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
  114. test_loss, correct, len(test_loader.dataset),
  115. 100. * correct / len(test_loader.dataset)))
  116. logging.info("开始训练!!\n")
  117. for epoch in range(1, args.epochs + 1):
  118. train(model, device, fed_loader, optimizer, epoch)
  119. test(model, device, test_loader)

训练效果还不错

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/239278?site
推荐阅读
相关标签
  

闽ICP备14008679号