<jupyter_start><jupyter_text>0 - Pull in dependencies and initiate Duet session<jupyter_code># First lets pull in our dependencies and initiate our duet session
import torch
import random
from torch import nn
from torch import optim
import syft as sy

duet = sy.join_duet(loopback=True)<jupyter_output><empty_output><jupyter_text>1 - Define and send our remote assetsHere we'll define the remote model which will have the remote input data fed into it. This includes;- Our first model segment- Our dummy input data<jupyter_code>from torchvision import datasets
from torchvision import transforms

from six.moves import urllib
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
urllib.request.install_opener(opener)

transform = transforms.Compose([transforms.ToTensor(),
                              transforms.Normalize((0.5,), (0.5,)),
                              ])
trainset = datasets.MNIST('mnist', download=True, train=True, transform=transform)
# valset = datasets.MNIST('mnist', download=True, train=False, transform=transform)

labels = trainset.targets[:5000]
data = duet.store[0]
labels.shape
dataloader = duet.torch.utils.data.DataLoader(data, batch_size=128)
targetloader = torch.utils.data.DataLoader(labels, batch_size=128)
input_size = 784
hidden_sizes = [128, 500]
output_size = 10

class SyNet_client(sy.Module):
    def __init__(self, torch_ref):
        super(SyNet_client, self).__init__(torch_ref=torch_ref)
        self.lin = nn.Linear(input_size, hidden_sizes[0])
        
    def forward(self, x):
        x = self.lin(x)
        x = self.torch_ref.nn.functional.relu(x)
        return x
    
class SyNet_server(sy.Module):
    def __init__(self, torch_ref):
        super(SyNet_server, self).__init__(torch_ref=torch_ref)
        self.lin2 = nn.Linear(hidden_sizes[0], hidden_sizes[1])
        self.lin3 = nn.Linear(hidden_sizes[1], output_size)
        self.sft = nn.LogSoftmax(dim=1) 
        
    def forward(self, x):
        x = self.lin2(x)
        x = nn.ReLU()(x)
        x = self.lin3(x)
        x = self.sft(x)
        return x
#Model 1
model1 = SyNet_client(torch)
model1_ptr = model1.send(duet)
opt1 = duet.torch.optim.SGD(params=model1_ptr.parameters(),lr=0.01)

#Model 2
model2 = SyNet_server(torch)
opt2 = torch.optim.SGD(params=model2.parameters(),lr=0.1)<jupyter_output><empty_output><jupyter_text>3 - Define our training logic<jupyter_code>for images, target in zip(dataloader, targetloader):
    opt1.zero_grad()
    opt2.zero_grad()
    
    print(target.type)
    
    activation_ptr = model1_ptr(images)
    activation = activation_ptr.clone().get(request_block=True)
    
    pred = model2(activation)
    
    criterion = nn.NLLLoss()
#     print(pred)
    loss = criterion(pred, target.long())
    
#     train_correct += pred.max(1)[1].eq(target).sum().item()
#     train_total += pred.shape[0]
#     print(loss)
    
    loss.backward()
    grad_ptr = activation.grad.clone().send(duet)
    activation_ptr.backward(grad_ptr)
    
    opt1.step()
    opt2.step()
    print(loss)<jupyter_output><empty_output><jupyter_text>4 - Pull in our Test Set<jupyter_code>test_kwargs = {
    "batch_size": args["test_batch_size"],
}

test_data = torchvision.datasets.MNIST('../data', train=False, download=True, transform=local_transforms)
test_loader = torch.utils.data.DataLoader(test_data,**train_kwargs)
model1 = model1_ptr.get(request_block=True, reason="run testing ont the model")<jupyter_output><empty_output><jupyter_text>5 - Test our Model<jupyter_code># test_data_length = len(test_loader.dataset)
# test_batches = round((test_data_length / args["test_batch_size"]) + 0.5)
# test_loss = 0.0
# correct = 0.0
    
# for batch_idx, (data, target) in enumerate(test_loader):
#     output = model2(model1(data))
#     iter_loss = torch.nn.functional.nll_loss(output, target, reduction="sum").item()
#     test_loss = test_loss + iter_loss
#     pred = output.argmax(dim=1)
#     total = pred.eq(target).sum().item()
#     correct += total
            
#     if batch_idx >= test_batches - 1:
#                 print("batch_idx >= test_batches, breaking")
#                 break
#     accuracy = correct / test_data_length
#     print(f"Test Set Accuracy: {test_loss}%")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12497085567731406, 'fraction_numerical': 0.018186057356027047, 'mean_word_length': 3.793296089385475, 'pattern_counts': {'":': 1, '<': 21, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '646787', 'license': 'Apache-2.0', 'n_tokens_mistral': 1511, 'n_tokens_neox': 1472, 'n_words': 284, 'path': 'examples/vertical-learning/01_splitnn/advanced/MNIST/DS.ipynb', 'repo_name': 'H4LL/PySyft', 'size': '4289'}