I would like to reproduce a federated code with PySyft
with image dataset (224,224,3)
So here is my code
hook = sy.TorchHook(torch)
bob = sy.VirtualWorker(hook, id="bob")
alice = sy.VirtualWorker(hook, id="alice")
class Arguments():
def __init__(self):
self.batch_size = 2
self.test_batch_size = 2
self.epochs = 100
self.lr = 0.001
self.momentum = 0.5
self.no_cuda = False
self.seed = 1
self.log_interval = 10
self.save_model = False
args = Arguments()
transform = transforms.Compose([
transforms.Resize(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
training_dataset = datasets.ImageFolder(path,transform=transform)
train_set = torch.utils.data.DataLoader(training_dataset, batch_size=2, shuffle=True)
test_dataset = datasets.ImageFolder(path2,transform=transform)
test_loader = torch.utils.data.DataLoader(training_dataset, batch_size=2, shuffle=True)
dataiter = iter(train_set)
images, labels = next(dataiter)
base=sy.BaseDataset(images,labels)
base_federated=base.federate((bob, alice))
federated_train_loader = sy.FederatedDataLoader(base_federated,batch_size=args.batch_size)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.model = models.resnet50(pretrained=True)
self.fc1 = nn.Linear(2048,2048)
self.fc2 = nn.Linear(2048, 3)
self.dropout = nn.Dropout(0.3)
def forward(self, x):
x = torch.nn.functional.relu(self.model.conv1(x))
print('model_shape:',x.shape)
x = x.view(-1,2048*1*1)
x = torch.nn.functional.relu(self.fc1(x))
x = F.log_softmax(self.fc2(x), dim=1)
return x
def train(args, model, device, train_loader, optimizer, epoch):
model.train()
for batch_idx, (data, target) in enumerate(federated_train_loader):
model.send(data.location)
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
print('x_shape:',data.shape)
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
model.get()
if batch_idx % args.log_interval == 0:
loss = loss.get()
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * args.batch_size, len(train_loader) * args.batch_size, #batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
def test(args, model, device, test_loader):
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item()
pred = output.argmax(1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
model = Net().to(device)
optimizer = optim.SGD(model.parameters(), lr=args.lr) # TODO momentum is not supported at the moment
for epoch in range(1, args.epochs + 1):
train(args, model, device, federated_train_loader, optimizer, epoch)
test(args, model, device, test_loader)
I don't understand if it is a conflict between data shape and model shape
so when I print model.shape, I find : torch.Size([1, 64, 112, 112])
and when I print data.shape, I find : torch.Size([1, 3, 224, 224])
Also I don't understand why 1 instead of 2 which is batch_size