联邦学习PySyft

2019/12/05 19:46
阅读数 1.2K

Steps involved in the Federated Learning Approach

  • The mobile devices download the global ML model

  • Data is being generated while the user is using application linked with the ML model

  • As the user starts to interact with the application more, the user gets much better predictions according to his usage

  • Once the model is ready for the scheduled sync with the server. The personalised model that was getting trained with the on device capability is sent to the server.

  • Models from all the devices are collected and a Federated average function is used to generate a much imporved version of the model than the previous one

  • Once trained the improved version is sent to all the devices where the user gets the experience based on the usage by all the devices arround the globe.

Installing PySyft

In order to install PySyft, it is recommended that you set up a conda environment first

conda create -n pysyft python=3
conda activate pysyft
conda install jupyter notebook

You then need to install the package

pip install syft

Step by Step guide to develop the neural network using federated learning approach

Importing the libraries:

  • Numpy

  • PyTorch

  • PySyft

  • Pickle

import pickle
import torch 
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader
import time
import copy 
import numpy as np
import syft as sy
from syft.frameworks.torch.federated import utils
from syft.workers.websocket_client import WebsocketClientWorker

Initializing the training parameters

Learning rate 0.001

Neural network 100 epoches

total batches 8

class Parser:
    def __init__(self):
        self.epoches = 100
        self.lr = 0.001
        self.test_batch_size = 8
        self.batch_size =8
        self.log_interval = 10
        self.seed = 1
        
args = Parser()
torch.manual_seed(args.seed)

Dataset Preprocessing

with open('boston_housing.pickle','rb') as f:
    ((x,y),(x_test,y_test)) = pickle.load(f)
    
x = torch.from_numpy(x).float()
y = torch.from_numpy(y).float()

x_test = torch.from_numpy(x_test).float()
y_test = torch.from_numpy(y_test).float()

mean = x.mean(0,keepdim=True)

dev = x.std(0,keepdim=True)

mean[:,3] = 0.

dev[:,3] = 1.

x = (x-mean)/dev
x_test = (x_test - mean)/dev

train = TensorDataset(x,y)
test = TensorDataset(x_test,y_test)

train_loader = DataLoader(train,batch_size = args.batch_size,shuffle=True)
train_loader = DataLoader(test,batch_size=args.test_batch_size,shuffle=True)


Creating Neural Network with PyTorch

Creating the architecture of the neural network model

class Net(nn.Module):
	def __init__(self):
		super(Net,self).__init__()
		self.fc1 = nn.Linear(13,32)
		self.fc2 = nn.Linear(32,24)
		self.fc3 = nn.Linear(24,16)
		self.fc4 = nn.Linear(16,1)
	
	def __init__(self):
		x = x.view(-1,13)
		x = F.relu(self.fc1(x))
		x = F.relu(self.fc2(x))
		x = F.relu(self.fc4(x))
		x = self.fc(x)
		return x

Connecting the data with the remote mobile devices

Though data will be available offline for federated learning with the workers but here we are sending the data over to the workers for training with ondevice capability

remote_dataset = (list(), list())
train_distributed_dataset = []

for batch_idx, (data,target) in enumerate(train_loader):
    data = data.send(compute_nodes[batch_idx % len(compute_nodes)])
    target = target.send(compute_nodes[batch_idx % len(compute_nodes)])
    remote_dataset[batch_idx % len(compute_nodes)].append((data, target))
    
bobs_model = Net()
alices_model = Net()
bobs_optimizer = optim.SGD(bobs_model.parameters(), lr=args.lr)
alices_optimizer = optim.SGD(alices_model.parameters(), lr=args.lr)

models = [bobs_model,alices_model]
optimizers = [bobs_optimizer,alices_optimizer]

model = Net()

Connect to the workers or the devices for training

hook = sy.TorchHook(torch)
bob_worker = sy.VirtualWorker(hook, id="bob")
alice_worker = sy.VirtualWorker(hook, id="alice")
compute_nodes = [bob_worker, alice_worker]		

Training the Neural Network

def update(data, target, model, optimizer):
    model.send(data.location)
    optimizer.zero_grad()
    prediction = model(data)
    loss = F.mse_loss(prediction.view(-1), target)
    loss.backward()
    optimizer.step()
    return model

def train():
    for data_index in range(len(remote_dataset[0])-1):
        for remote_index in range(len(compute_nodes)):
            data, target = remote_dataset[remote_index][data_index]
            models[remote_index] = update(data, target, models[remote_index], optimizers[remote_index])
        for model in models:
            model.get()
        return utils.federated_avg({
            "bob": models[0],
            "alice": models[1]
        })

def test(federated_model):
    federated_model.eval()
    test_loss = 0
    for data, target in test_loader:
        output = federated_model(data)
        test_loss += F.mse_loss(output.view(-1), target, reduction='sum').item()
        predection = output.data.max(1, keepdim=True)[1]
        
    test_loss /= len(test_loader.dataset)
    print('Test set: Average loss: {:.4f}'.format(test_loss))

for epoch in range(args.epochs):
    start_time = time.time()
    print(f"Epoch Number {epoch + 1}")
    federated_model = train()
    model = federated_model
    test(federated_model)
    total_time = time.time() - start_time
    print('Communication time over the network', round(total_time, 2), 's\n')

References:

Federated Learning with PySyft

展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
返回顶部
顶部