├── FL_client.py ├── FL_server.py ├── Figures ├── CML_1.png ├── CML_1_IID_20.png ├── CML_Sorted.PNG ├── CML_Sorted_20.png ├── CML_Sorted_20_1.png ├── CML_Sorted_20_2.png ├── CML_niid_20.png ├── CML_niid_20_2.png ├── FL_C1_1.png ├── FL_C2_1.png ├── FL_IID_C1_20.png ├── FL_IID_C2_20.png ├── FL_NonIID_C1_20.png ├── FL_NonIID_C2_20.png ├── FL_Sorted_C1_20.png ├── FL_Sorted_C1_20_60000.png ├── FL_Sorted_C2_20.png └── FL_Sorted_C2_20_60000.png ├── MNIST ├── Global_model_dist.py ├── Models │ ├── Client_1 │ │ ├── Global models │ │ │ ├── Client_1_8_5_2021_10_35_47.pth │ │ │ ├── Server_8_5_2021_10_36_33.pth │ │ │ ├── Server_8_5_2021_10_37_19.pth │ │ │ ├── Server_8_5_2021_10_37_56.pth │ │ │ ├── Server_8_5_2021_10_38_35.pth │ │ │ ├── Server_8_5_2021_10_39_14.pth │ │ │ ├── Server_8_5_2021_10_39_55.pth │ │ │ ├── Server_8_5_2021_10_40_35.pth │ │ │ ├── Server_8_5_2021_10_41_16.pth │ │ │ ├── Server_8_5_2021_10_41_56.pth │ │ │ ├── Server_8_5_2021_10_42_36.pth │ │ │ ├── Server_8_5_2021_10_43_17.pth │ │ │ ├── Server_8_5_2021_10_44_10.pth │ │ │ ├── Server_8_5_2021_10_44_50.pth │ │ │ ├── Server_8_5_2021_10_45_30.pth │ │ │ ├── Server_8_5_2021_10_46_11.pth │ │ │ ├── Server_8_5_2021_10_46_55.pth │ │ │ ├── Server_8_5_2021_10_47_51.pth │ │ │ ├── Server_8_5_2021_10_48_41.pth │ │ │ └── Server_8_5_2021_10_49_29.pth │ │ └── Trained local models │ │ │ ├── Trained_8_5_2021_10_36_33.pth │ │ │ ├── Trained_8_5_2021_10_37_19.pth │ │ │ ├── Trained_8_5_2021_10_37_56.pth │ │ │ ├── Trained_8_5_2021_10_38_35.pth │ │ │ ├── Trained_8_5_2021_10_39_14.pth │ │ │ ├── Trained_8_5_2021_10_39_55.pth │ │ │ ├── Trained_8_5_2021_10_40_35.pth │ │ │ ├── Trained_8_5_2021_10_41_16.pth │ │ │ ├── Trained_8_5_2021_10_41_56.pth │ │ │ ├── Trained_8_5_2021_10_42_36.pth │ │ │ ├── Trained_8_5_2021_10_43_16.pth │ │ │ ├── Trained_8_5_2021_10_44_10.pth │ │ │ ├── Trained_8_5_2021_10_44_50.pth │ │ │ ├── Trained_8_5_2021_10_45_30.pth │ │ │ ├── Trained_8_5_2021_10_46_11.pth │ │ │ ├── Trained_8_5_2021_10_46_55.pth │ │ │ ├── Trained_8_5_2021_10_47_51.pth │ │ │ ├── Trained_8_5_2021_10_48_41.pth │ │ │ ├── Trained_8_5_2021_10_49_29.pth │ │ │ └── Trained_8_5_2021_10_50_21.pth │ ├── Client_2 │ │ ├── Global models │ │ │ ├── Client_2_8_5_2021_10_35_51.pth │ │ │ ├── Server_8_5_2021_10_36_47.pth │ │ │ ├── Server_8_5_2021_10_37_27.pth │ │ │ ├── Server_8_5_2021_10_38_4.pth │ │ │ ├── Server_8_5_2021_10_38_42.pth │ │ │ ├── Server_8_5_2021_10_39_22.pth │ │ │ ├── Server_8_5_2021_10_40_2.pth │ │ │ ├── Server_8_5_2021_10_40_43.pth │ │ │ ├── Server_8_5_2021_10_41_24.pth │ │ │ ├── Server_8_5_2021_10_42_4.pth │ │ │ ├── Server_8_5_2021_10_42_44.pth │ │ │ ├── Server_8_5_2021_10_43_28.pth │ │ │ ├── Server_8_5_2021_10_44_17.pth │ │ │ ├── Server_8_5_2021_10_44_57.pth │ │ │ ├── Server_8_5_2021_10_45_37.pth │ │ │ ├── Server_8_5_2021_10_46_19.pth │ │ │ ├── Server_8_5_2021_10_47_2.pth │ │ │ ├── Server_8_5_2021_10_47_59.pth │ │ │ ├── Server_8_5_2021_10_48_49.pth │ │ │ └── Server_8_5_2021_10_49_36.pth │ │ └── Trained local models │ │ │ ├── Trained_8_5_2021_10_36_47.pth │ │ │ ├── Trained_8_5_2021_10_37_27.pth │ │ │ ├── Trained_8_5_2021_10_38_3.pth │ │ │ ├── Trained_8_5_2021_10_38_42.pth │ │ │ ├── Trained_8_5_2021_10_39_22.pth │ │ │ ├── Trained_8_5_2021_10_40_2.pth │ │ │ ├── Trained_8_5_2021_10_40_43.pth │ │ │ ├── Trained_8_5_2021_10_41_24.pth │ │ │ ├── Trained_8_5_2021_10_42_4.pth │ │ │ ├── Trained_8_5_2021_10_42_44.pth │ │ │ ├── Trained_8_5_2021_10_43_28.pth │ │ │ ├── Trained_8_5_2021_10_44_17.pth │ │ │ ├── Trained_8_5_2021_10_44_57.pth │ │ │ ├── Trained_8_5_2021_10_45_37.pth │ │ │ ├── Trained_8_5_2021_10_46_19.pth │ │ │ ├── Trained_8_5_2021_10_47_2.pth │ │ │ ├── Trained_8_5_2021_10_47_59.pth │ │ │ ├── Trained_8_5_2021_10_48_49.pth │ │ │ ├── Trained_8_5_2021_10_49_36.pth │ │ │ └── Trained_8_5_2021_10_50_28.pth │ └── Server │ │ └── Global models │ │ ├── Client_1_initial_8_5_2021_10_35_47.pth │ │ ├── Client_2_initial_8_5_2021_10_35_51.pth │ │ ├── Global model_8_5_2021_10_36_33.pth │ │ ├── Global model_8_5_2021_10_36_47.pth │ │ ├── Global model_8_5_2021_10_37_19.pth │ │ ├── Global model_8_5_2021_10_37_27.pth │ │ ├── Global model_8_5_2021_10_37_56.pth │ │ ├── Global model_8_5_2021_10_38_35.pth │ │ ├── Global model_8_5_2021_10_38_4.pth │ │ ├── Global model_8_5_2021_10_38_42.pth │ │ ├── Global model_8_5_2021_10_39_14.pth │ │ ├── Global model_8_5_2021_10_39_22.pth │ │ ├── Global model_8_5_2021_10_39_55.pth │ │ ├── Global model_8_5_2021_10_40_2.pth │ │ ├── Global model_8_5_2021_10_40_35.pth │ │ ├── Global model_8_5_2021_10_40_43.pth │ │ ├── Global model_8_5_2021_10_41_16.pth │ │ ├── Global model_8_5_2021_10_41_24.pth │ │ ├── Global model_8_5_2021_10_41_56.pth │ │ ├── Global model_8_5_2021_10_42_36.pth │ │ ├── Global model_8_5_2021_10_42_4.pth │ │ ├── Global model_8_5_2021_10_42_44.pth │ │ ├── Global model_8_5_2021_10_43_16.pth │ │ ├── Global model_8_5_2021_10_43_28.pth │ │ ├── Global model_8_5_2021_10_44_10.pth │ │ ├── Global model_8_5_2021_10_44_17.pth │ │ ├── Global model_8_5_2021_10_44_50.pth │ │ ├── Global model_8_5_2021_10_44_57.pth │ │ ├── Global model_8_5_2021_10_45_30.pth │ │ ├── Global model_8_5_2021_10_45_37.pth │ │ ├── Global model_8_5_2021_10_46_11.pth │ │ ├── Global model_8_5_2021_10_46_19.pth │ │ ├── Global model_8_5_2021_10_46_55.pth │ │ ├── Global model_8_5_2021_10_47_2.pth │ │ ├── Global model_8_5_2021_10_47_51.pth │ │ ├── Global model_8_5_2021_10_47_59.pth │ │ ├── Global model_8_5_2021_10_48_41.pth │ │ ├── Global model_8_5_2021_10_48_49.pth │ │ ├── Global model_8_5_2021_10_49_29.pth │ │ └── Global model_8_5_2021_10_49_36.pth ├── NN.py ├── NN_NIID.py ├── NN_NIID_sorted_1.py ├── NN_NIID_sorted_2.py ├── NN_NIID_sorted_all.py ├── call_complete.py ├── call_complete_1.py ├── client_1.py ├── client_1_fixed_e.py ├── client_1_fixed_e_NIID.py ├── client_1_fixed_e_SORTED.py ├── client_1_fixed_e_SORTED_60000.py ├── client_2.py ├── client_2_fixed_e.py ├── client_2_fixed_e_NIID.py ├── client_2_fixed_e_SORTED.py ├── client_2_fixed_e_SORTED_60000.py ├── client_3.py ├── client_4.py └── server.py ├── client_1.py ├── client_2.py ├── server.py └── server_1.py /FL_client.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | 4 | soc = socket.socket() 5 | print("Socket is created.") 6 | 7 | soc.connect(("localhost", 10000)) 8 | print("Connected to the server.") 9 | 10 | msg = "A message from the client." 11 | msg = pickle.dumps(msg) 12 | soc.sendall(msg) 13 | print("Client sent message to the server.") 14 | 15 | received_data = b'' 16 | while str(received_data)[-2] != '.': 17 | data = soc.recv(8) 18 | received_data += data 19 | 20 | received_data = pickle.loads(received_data) 21 | print("Received data from the client: {received_data}".format(received_data=received_data)) 22 | 23 | soc.close() 24 | print("Socket is closed.") 25 | -------------------------------------------------------------------------------- /FL_server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | 4 | soc = socket.socket() 5 | print("Socket is created.") 6 | 7 | soc.bind(("localhost", 10000)) 8 | print("Socket is bound to an address & port number.") 9 | 10 | soc.listen(1) 11 | print("Listening for incoming connection ...") 12 | 13 | connected = False 14 | accept_timeout = 10 15 | soc.settimeout(accept_timeout) 16 | try: 17 | connection, address = soc.accept() 18 | print("Connected to a client: {client_info}.".format(client_info=address)) 19 | connected = True 20 | except socket.timeout: 21 | print("A socket.timeout exception occurred because the server did not receive any connection for {accept_timeout} seconds.".format(accept_timeout=accept_timeout)) 22 | 23 | received_data = b'' 24 | if connected: 25 | while str(received_data)[-2] != '.': 26 | data = connection.recv(8) 27 | received_data += data 28 | received_data = pickle.loads(received_data) 29 | print("Received data from the client: {received_data}".format(received_data=received_data)) 30 | 31 | msg = "Reply from the server." 32 | msg = pickle.dumps(msg) 33 | connection.sendall(msg) 34 | print("Server sent a message to the client.") 35 | 36 | connection.close() 37 | print("Connection is closed with: {client_info}.".format(client_info=address)) 38 | 39 | soc.close() 40 | print("Socket is closed.") -------------------------------------------------------------------------------- /Figures/CML_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_1.png -------------------------------------------------------------------------------- /Figures/CML_1_IID_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_1_IID_20.png -------------------------------------------------------------------------------- /Figures/CML_Sorted.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_Sorted.PNG -------------------------------------------------------------------------------- /Figures/CML_Sorted_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_Sorted_20.png -------------------------------------------------------------------------------- /Figures/CML_Sorted_20_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_Sorted_20_1.png -------------------------------------------------------------------------------- /Figures/CML_Sorted_20_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_Sorted_20_2.png -------------------------------------------------------------------------------- /Figures/CML_niid_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_niid_20.png -------------------------------------------------------------------------------- /Figures/CML_niid_20_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/CML_niid_20_2.png -------------------------------------------------------------------------------- /Figures/FL_C1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_C1_1.png -------------------------------------------------------------------------------- /Figures/FL_C2_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_C2_1.png -------------------------------------------------------------------------------- /Figures/FL_IID_C1_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_IID_C1_20.png -------------------------------------------------------------------------------- /Figures/FL_IID_C2_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_IID_C2_20.png -------------------------------------------------------------------------------- /Figures/FL_NonIID_C1_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_NonIID_C1_20.png -------------------------------------------------------------------------------- /Figures/FL_NonIID_C2_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_NonIID_C2_20.png -------------------------------------------------------------------------------- /Figures/FL_Sorted_C1_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_Sorted_C1_20.png -------------------------------------------------------------------------------- /Figures/FL_Sorted_C1_20_60000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_Sorted_C1_20_60000.png -------------------------------------------------------------------------------- /Figures/FL_Sorted_C2_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_Sorted_C2_20.png -------------------------------------------------------------------------------- /Figures/FL_Sorted_C2_20_60000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/Figures/FL_Sorted_C2_20_60000.png -------------------------------------------------------------------------------- /MNIST/Global_model_dist.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import os 3 | import torchvision 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | from torch.utils.data import DataLoader,Dataset 7 | import torchvision.transforms as transforms 8 | import torch.optim as optim 9 | 10 | from mpl_toolkits.mplot3d import Axes3D 11 | import matplotlib.pyplot as plt 12 | 13 | import numpy as np 14 | 15 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Server\\Completed_Model" 16 | 17 | # NN architecture using PyTorch 18 | # Less parameters 19 | class Net(nn.Module): 20 | def __init__(self): 21 | super(Net, self).__init__() 22 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 23 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 24 | self.conv2_drop = nn.Dropout2d() 25 | self.fc1 = nn.Linear(320, 50) 26 | self.fc2 = nn.Linear(50, 10) 27 | 28 | def forward(self, x): 29 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 30 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 31 | x = x.view(-1, 320) 32 | x = F.relu(self.fc1(x)) 33 | x = F.dropout(x, training=self.training) 34 | x = self.fc2(x) 35 | return F.log_softmax(x) 36 | 37 | def CallModel(idx): 38 | files = os.listdir(Directory) 39 | models = [] 40 | Error = [] 41 | for file in files: 42 | models.append(file) 43 | model_detail = file.split("_") 44 | Error.append(model_detail[0]) 45 | Model = Net() 46 | Model.load_state_dict(torch.load(os.path.join(Directory, models[idx]))) 47 | error = Error[idx] 48 | return Model, error 49 | 50 | 51 | def LowestLocalError(): 52 | files = os.listdir(Directory) 53 | Error = [] 54 | models = [] 55 | for file in files: 56 | models.append(file) 57 | model_detail = file.split("_") 58 | Error.append(model_detail[0]) 59 | Lowest_error_model = models[np.argmin(Error)] 60 | Model = Net() 61 | Model.load_state_dict(torch.load(os.path.join(Directory, Lowest_error_model))) 62 | error = Error[np.argmin(Error)] 63 | return Model, error 64 | 65 | def test(complete_model): 66 | complete_model.eval() 67 | test_loss = 0 68 | correct = 0 69 | with torch.no_grad(): 70 | for data, target in test_loader: 71 | output = complete_model(data) 72 | test_loss += F.nll_loss(output, target, size_average=False).item() 73 | pred = output.data.max(1, keepdim=True)[1] 74 | correct += pred.eq(target.data.view_as(pred)).sum() 75 | test_loss /= len(test_loader.dataset) 76 | test_losses.append(test_loss) 77 | print('\nTest set: Avg. loss: {}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 78 | return test_losses 79 | 80 | 81 | 82 | 83 | 84 | 85 | test_loader = torch.utils.data.DataLoader( 86 | torchvision.datasets.MNIST('/files/', train=False, download=True, 87 | transform=torchvision.transforms.Compose([ 88 | torchvision.transforms.ToTensor(), 89 | torchvision.transforms.Normalize( 90 | (0.1307,), (0.3081,)) 91 | ])), 92 | batch_size=10000, shuffle=True) 93 | 94 | test_losses = [] 95 | 96 | 97 | 98 | 99 | #complete_model = Net() 100 | #model_name = "Completed_model.pth" 101 | #model_path = os.path.join(Directory, "Completed_model") 102 | model_1, error = LowestLocalError() 103 | model_2, error = CallModel(1) 104 | #complete = complete_model.state_dict() 105 | 106 | 107 | #for key in complete: 108 | # print(complete[key]) 109 | 110 | 111 | 112 | test(model_1) 113 | test(model_2) 114 | #for epoch in range(1, n_epochs + 1): 115 | # train(epoch) 116 | # test() 117 | #fig -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Client_1_8_5_2021_10_35_47.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Client_1_8_5_2021_10_35_47.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_36_33.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_36_33.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_37_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_37_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_37_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_37_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_38_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_38_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_39_14.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_39_14.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_39_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_39_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_40_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_40_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_41_16.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_41_16.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_41_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_41_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_42_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_42_36.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_43_17.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_43_17.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_44_10.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_44_10.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_44_50.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_44_50.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_45_30.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_45_30.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_46_11.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_46_11.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_46_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_46_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_47_51.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_47_51.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_48_41.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_48_41.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Global models/Server_8_5_2021_10_49_29.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Global models/Server_8_5_2021_10_49_29.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_36_33.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_36_33.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_37_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_37_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_37_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_37_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_38_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_38_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_39_14.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_39_14.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_39_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_39_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_40_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_40_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_41_16.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_41_16.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_41_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_41_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_42_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_42_36.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_43_16.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_43_16.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_44_10.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_44_10.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_44_50.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_44_50.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_45_30.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_45_30.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_46_11.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_46_11.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_46_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_46_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_47_51.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_47_51.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_48_41.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_48_41.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_49_29.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_49_29.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_50_21.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_1/Trained local models/Trained_8_5_2021_10_50_21.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Client_2_8_5_2021_10_35_51.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Client_2_8_5_2021_10_35_51.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_36_47.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_36_47.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_37_27.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_37_27.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_38_4.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_38_4.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_38_42.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_38_42.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_39_22.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_39_22.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_40_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_40_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_40_43.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_40_43.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_41_24.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_41_24.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_42_4.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_42_4.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_42_44.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_42_44.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_43_28.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_43_28.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_44_17.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_44_17.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_44_57.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_44_57.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_45_37.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_45_37.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_46_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_46_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_47_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_47_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_47_59.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_47_59.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_48_49.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_48_49.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Global models/Server_8_5_2021_10_49_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Global models/Server_8_5_2021_10_49_36.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_36_47.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_36_47.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_37_27.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_37_27.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_38_3.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_38_3.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_38_42.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_38_42.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_39_22.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_39_22.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_40_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_40_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_40_43.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_40_43.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_41_24.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_41_24.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_42_4.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_42_4.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_42_44.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_42_44.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_43_28.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_43_28.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_44_17.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_44_17.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_44_57.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_44_57.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_45_37.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_45_37.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_46_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_46_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_47_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_47_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_47_59.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_47_59.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_48_49.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_48_49.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_49_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_49_36.pth -------------------------------------------------------------------------------- /MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_50_28.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Client_2/Trained local models/Trained_8_5_2021_10_50_28.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Client_1_initial_8_5_2021_10_35_47.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Client_1_initial_8_5_2021_10_35_47.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Client_2_initial_8_5_2021_10_35_51.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Client_2_initial_8_5_2021_10_35_51.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_36_33.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_36_33.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_36_47.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_36_47.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_27.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_27.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_37_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_4.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_4.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_42.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_38_42.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_14.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_14.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_22.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_22.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_39_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_35.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_35.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_43.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_40_43.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_16.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_16.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_24.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_24.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_56.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_41_56.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_36.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_4.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_4.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_44.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_42_44.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_43_16.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_43_16.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_43_28.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_43_28.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_10.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_10.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_17.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_17.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_50.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_50.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_57.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_44_57.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_45_30.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_45_30.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_45_37.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_45_37.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_11.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_11.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_19.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_19.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_55.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_46_55.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_2.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_2.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_51.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_51.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_59.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_47_59.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_48_41.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_48_41.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_48_49.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_48_49.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_49_29.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_49_29.pth -------------------------------------------------------------------------------- /MNIST/Models/Server/Global models/Global model_8_5_2021_10_49_36.pth: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlskit13/Asynchronous-Federated-Learning-MNIST-Image-Classifier/1a8952125555653ea57133cad39b99aed1ce48ef/MNIST/Models/Server/Global models/Global model_8_5_2021_10_49_36.pth -------------------------------------------------------------------------------- /MNIST/NN.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | import torch.optim as optim 6 | from torch.utils.data import DataLoader,Dataset 7 | import torchvision.transforms as transforms 8 | import torch.optim as optim 9 | 10 | from mpl_toolkits.mplot3d import Axes3D 11 | import matplotlib.pyplot as plt 12 | 13 | import numpy as np 14 | 15 | 16 | 17 | # NN architecture using PyTorch 18 | # Less parameters 19 | class Net(nn.Module): 20 | def __init__(self): 21 | super(Net, self).__init__() 22 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 23 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 24 | self.conv2_drop = nn.Dropout2d() 25 | self.fc1 = nn.Linear(320, 50) 26 | self.fc2 = nn.Linear(50, 10) 27 | 28 | def forward(self, x): 29 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 30 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 31 | x = x.view(-1, 320) 32 | x = F.relu(self.fc1(x)) 33 | x = F.dropout(x, training=self.training) 34 | x = self.fc2(x) 35 | return F.log_softmax(x) 36 | 37 | def train(epoch): 38 | network.train() 39 | batch_idxs = [] 40 | for batch_idx, (data, target) in enumerate(train_loader): 41 | batch_idxs.append(batch_idx) 42 | #print(target) 43 | optimizer.zero_grad() 44 | output = network(data) 45 | loss = F.nll_loss(output, target) 46 | loss.backward() 47 | optimizer.step() 48 | if batch_idx % log_interval == 0: 49 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 50 | train_losses.append(loss.item()) 51 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 52 | #torch.save(network.state_dict(), '/results/model.pth') 53 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 54 | #print(train_counter) 55 | 56 | def test(): 57 | network.eval() 58 | test_loss = 0 59 | correct = 0 60 | with torch.no_grad(): 61 | for data, target in test_loader: 62 | output = network(data) 63 | test_loss += F.nll_loss(output, target, size_average=False).item() 64 | pred = output.data.max(1, keepdim=True)[1] 65 | correct += pred.eq(target.data.view_as(pred)).sum() 66 | test_loss /= len(test_loader.dataset) 67 | test_losses.append(test_loss) 68 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 69 | 70 | 71 | n_epochs = 20 72 | batch_size_train = 1000 73 | batch_size_test = 1000 74 | learning_rate = 0.01 75 | momentum = 0.5 76 | log_interval = 10 77 | 78 | 79 | 80 | random_seed = 1 81 | torch.backends.cudnn.enabled = False 82 | torch.manual_seed(random_seed) 83 | 84 | train_loader = torch.utils.data.DataLoader( 85 | torchvision.datasets.MNIST('/files/', train=True, download=True, 86 | transform=torchvision.transforms.Compose([ 87 | torchvision.transforms.ToTensor(), 88 | torchvision.transforms.Normalize( 89 | (0.1307,), (0.3081,)) 90 | ])), 91 | batch_size=batch_size_train) 92 | #, shuffle=True) 93 | 94 | test_loader = torch.utils.data.DataLoader( 95 | torchvision.datasets.MNIST('/files/', train=False, download=True, 96 | transform=torchvision.transforms.Compose([ 97 | torchvision.transforms.ToTensor(), 98 | torchvision.transforms.Normalize( 99 | (0.1307,), (0.3081,)) 100 | ])), 101 | batch_size=batch_size_test) 102 | #, shuffle=True) 103 | #batch_size = 128 104 | 105 | #train_set = ImgDataset(train_x, train_y, transform) 106 | #val_set = ImgDataset(val_x, val_y, transform) 107 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 108 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 109 | 110 | train_losses = [] 111 | train_counter = [] 112 | test_losses = [] 113 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 114 | 115 | examples = enumerate(test_loader) 116 | batch_idx, (example_data, example_targets) = next(examples) 117 | 118 | network = Net() 119 | optimizer = optim.SGD(network.parameters(), lr=learning_rate, 120 | momentum=momentum) 121 | 122 | 123 | 124 | 125 | test() 126 | for epoch in range(1, n_epochs + 1): 127 | train(epoch) 128 | test() 129 | print(test_counter) 130 | 131 | 132 | 133 | #fig = plt.figure() 134 | plt.plot(train_counter, train_losses, color='blue') 135 | plt.scatter(test_counter, test_losses, color='red') 136 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 137 | plt.xlabel('number of training examples seen') 138 | plt.ylabel('negative log likelihood loss') 139 | plt.show() 140 | #fig -------------------------------------------------------------------------------- /MNIST/NN_NIID.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | import torch.optim as optim 6 | from torch.utils.data import DataLoader,Dataset,Subset 7 | from sklearn.model_selection import train_test_split 8 | import torchvision.transforms as transforms 9 | import torch.optim as optim 10 | 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import matplotlib.pyplot as plt 13 | 14 | import numpy as np 15 | 16 | 17 | 18 | # NN architecture using PyTorch 19 | # Less parameters 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super(Net, self).__init__() 23 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 24 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 25 | self.conv2_drop = nn.Dropout2d() 26 | self.fc1 = nn.Linear(320, 50) 27 | self.fc2 = nn.Linear(50, 10) 28 | 29 | def forward(self, x): 30 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 31 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 32 | x = x.view(-1, 320) 33 | x = F.relu(self.fc1(x)) 34 | x = F.dropout(x, training=self.training) 35 | x = self.fc2(x) 36 | return F.log_softmax(x) 37 | 38 | def train_NIID_dataset(dataset): 39 | idx = [] 40 | limit = 0 41 | for i in range(10): 42 | if i < 5: 43 | for x in range(len(dataset.targets)): 44 | if dataset.targets[x] == i: 45 | idx.append(x) 46 | limit += 1 47 | if limit == 5000: 48 | break 49 | limit = 0 50 | print(dataset.targets[x]) 51 | print(len(idx)) 52 | 53 | 54 | else: 55 | for x in range(len(dataset.targets)): 56 | if dataset.targets[x] == i: 57 | idx.append(x) 58 | limit += 1 59 | if limit == 3000: 60 | break 61 | limit = 0 62 | print(dataset.targets[x]) 63 | print(len(idx)) 64 | 65 | 66 | 67 | 68 | 69 | #train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 70 | 71 | split_datasets = {} 72 | split_datasets = Subset(dataset, idx) 73 | 74 | 75 | #split_datasets['train_1'] = Subset(dataset, train_idx) 76 | #split_datasets['train_2'] = Subset(dataset, val_idx) 77 | return split_datasets 78 | 79 | def train(epoch): 80 | network.train() 81 | batch_idxs = [] 82 | for batch_idx, (data, target) in enumerate(train_loader): 83 | batch_idxs.append(batch_idx) 84 | #print(target) 85 | optimizer.zero_grad() 86 | output = network(data) 87 | loss = F.nll_loss(output, target) 88 | loss.backward() 89 | optimizer.step() 90 | if batch_idx % log_interval == 0: 91 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 92 | train_losses.append(loss.item()) 93 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 94 | #torch.save(network.state_dict(), '/results/model.pth') 95 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 96 | #print(train_counter) 97 | 98 | def test(): 99 | network.eval() 100 | test_loss = 0 101 | correct = 0 102 | with torch.no_grad(): 103 | for data, target in test_loader: 104 | output = network(data) 105 | test_loss += F.nll_loss(output, target, size_average=False).item() 106 | pred = output.data.max(1, keepdim=True)[1] 107 | correct += pred.eq(target.data.view_as(pred)).sum() 108 | test_loss /= len(test_loader.dataset) 109 | test_losses.append(test_loss) 110 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 111 | 112 | 113 | n_epochs = 20 114 | batch_size_train = 1000 115 | batch_size_test = 1000 116 | learning_rate = 0.01 117 | momentum = 0.5 118 | log_interval = 10 119 | 120 | 121 | 122 | random_seed = 1 123 | torch.backends.cudnn.enabled = False 124 | torch.manual_seed(random_seed) 125 | 126 | 127 | 128 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 129 | transform=torchvision.transforms.Compose([ 130 | torchvision.transforms.ToTensor(), 131 | torchvision.transforms.Normalize( 132 | (0.1307,), (0.3081,)) 133 | ])) 134 | 135 | datasets = train_NIID_dataset(dataset) 136 | 137 | train_loader = torch.utils.data.DataLoader( 138 | #datasets['train_1'], 139 | datasets, 140 | batch_size=batch_size_train, shuffle=False) 141 | 142 | 143 | 144 | #for x in range(60000): 145 | # print((datasets[x][1])) 146 | 147 | 148 | #print(len(datasets)) 149 | #for x in range(6): 150 | # print((datasets['train_2'][x][1])) 151 | 152 | 153 | 154 | 155 | test_loader = torch.utils.data.DataLoader( 156 | torchvision.datasets.MNIST('/files/', train=False, download=True, 157 | transform=torchvision.transforms.Compose([ 158 | torchvision.transforms.ToTensor(), 159 | torchvision.transforms.Normalize( 160 | (0.1307,), (0.3081,)) 161 | ])), 162 | batch_size=batch_size_test, shuffle=True) 163 | #batch_size = 128 164 | 165 | #train_set = ImgDataset(train_x, train_y, transform) 166 | #val_set = ImgDataset(val_x, val_y, transform) 167 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 168 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 169 | 170 | train_losses = [] 171 | train_counter = [] 172 | test_losses = [] 173 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 174 | 175 | 176 | network = Net() 177 | optimizer = optim.SGD(network.parameters(), lr=learning_rate, 178 | momentum=momentum) 179 | 180 | 181 | 182 | 183 | test() 184 | for epoch in range(1, n_epochs + 1): 185 | train(epoch) 186 | test() 187 | #print(test_counter) 188 | 189 | 190 | 191 | fig = plt.figure() 192 | plt.plot(train_counter, train_losses, color='blue') 193 | plt.scatter(test_counter, test_losses, color='red') 194 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 195 | plt.xlabel('number of training examples seen') 196 | plt.ylabel('negative log likelihood loss') 197 | plt.show() 198 | 199 | 200 | #examples = enumerate(train_loader) 201 | #batch_idx, (example_data, example_targets) = next(examples) 202 | 203 | #fig = plt.figure() 204 | #for i in range(6): 205 | # plt.subplot(2,3,i+1) 206 | # plt.tight_layout() 207 | # plt.imshow(example_data[i][0], cmap='gray', interpolation='none') 208 | # plt.title("Ground Truth: {}".format(example_targets[i])) 209 | # plt.xticks([]) 210 | # plt.yticks([]) 211 | #plt.show() 212 | 213 | #fig -------------------------------------------------------------------------------- /MNIST/NN_NIID_sorted_1.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | import torch.optim as optim 6 | from torch.utils.data import DataLoader,Dataset,Subset 7 | from sklearn.model_selection import train_test_split 8 | import torchvision.transforms as transforms 9 | import torch.optim as optim 10 | 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import matplotlib.pyplot as plt 13 | 14 | import numpy as np 15 | 16 | 17 | 18 | # NN architecture using PyTorch 19 | # Less parameters 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super(Net, self).__init__() 23 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 24 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 25 | self.conv2_drop = nn.Dropout2d() 26 | self.fc1 = nn.Linear(320, 50) 27 | self.fc2 = nn.Linear(50, 10) 28 | 29 | def forward(self, x): 30 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 31 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 32 | x = x.view(-1, 320) 33 | x = F.relu(self.fc1(x)) 34 | x = F.dropout(x, training=self.training) 35 | x = self.fc2(x) 36 | return F.log_softmax(x) 37 | 38 | def train_val_dataset(dataset, val_split=0.5): 39 | idx = [] 40 | for i in range(10): 41 | for x in range(len(dataset.targets)): 42 | if dataset.targets[x] == i: 43 | idx.append(x) 44 | 45 | 46 | train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 47 | split_datasets = {} 48 | #split_datasets = Subset(dataset, idx) 49 | 50 | 51 | split_datasets['train_1'] = Subset(dataset, train_idx) 52 | split_datasets['train_2'] = Subset(dataset, val_idx) 53 | return split_datasets 54 | 55 | def train(epoch): 56 | network.train() 57 | batch_idxs = [] 58 | for batch_idx, (data, target) in enumerate(train_loader): 59 | batch_idxs.append(batch_idx) 60 | #print(target) 61 | optimizer.zero_grad() 62 | output = network(data) 63 | loss = F.nll_loss(output, target) 64 | loss.backward() 65 | optimizer.step() 66 | if batch_idx % log_interval == 0: 67 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 68 | train_losses.append(loss.item()) 69 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 70 | #torch.save(network.state_dict(), '/results/model.pth') 71 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 72 | #print(train_counter) 73 | 74 | def test(): 75 | network.eval() 76 | test_loss = 0 77 | correct = 0 78 | with torch.no_grad(): 79 | for data, target in test_loader: 80 | output = network(data) 81 | test_loss += F.nll_loss(output, target, size_average=False).item() 82 | pred = output.data.max(1, keepdim=True)[1] 83 | correct += pred.eq(target.data.view_as(pred)).sum() 84 | test_loss /= len(test_loader.dataset) 85 | test_losses.append(test_loss) 86 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 87 | 88 | 89 | n_epochs = 20 90 | batch_size_train = 1000 91 | batch_size_test = 1000 92 | learning_rate = 0.01 93 | momentum = 0.5 94 | log_interval = 10 95 | 96 | 97 | 98 | random_seed = 1 99 | torch.backends.cudnn.enabled = False 100 | torch.manual_seed(random_seed) 101 | 102 | 103 | 104 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 105 | transform=torchvision.transforms.Compose([ 106 | torchvision.transforms.ToTensor(), 107 | torchvision.transforms.Normalize( 108 | (0.1307,), (0.3081,)) 109 | ])) 110 | 111 | datasets = train_val_dataset(dataset) 112 | 113 | train_loader = torch.utils.data.DataLoader( 114 | datasets['train_1'], 115 | #datasets, 116 | batch_size=batch_size_train, shuffle=False) 117 | 118 | 119 | 120 | #for x in range(60000): 121 | # print((datasets[x][1])) 122 | 123 | 124 | #print(len(datasets['train_1'])) 125 | #for x in range(6): 126 | # print((datasets['train_2'][x][1])) 127 | 128 | 129 | 130 | 131 | test_loader = torch.utils.data.DataLoader( 132 | torchvision.datasets.MNIST('/files/', train=False, download=True, 133 | transform=torchvision.transforms.Compose([ 134 | torchvision.transforms.ToTensor(), 135 | torchvision.transforms.Normalize( 136 | (0.1307,), (0.3081,)) 137 | ])), 138 | batch_size=batch_size_test, shuffle=True) 139 | #batch_size = 128 140 | 141 | #train_set = ImgDataset(train_x, train_y, transform) 142 | #val_set = ImgDataset(val_x, val_y, transform) 143 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 144 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 145 | 146 | train_losses = [] 147 | train_counter = [] 148 | test_losses = [] 149 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 150 | 151 | 152 | network = Net() 153 | optimizer = optim.SGD(network.parameters(), lr=learning_rate, 154 | momentum=momentum) 155 | 156 | 157 | 158 | 159 | test() 160 | for epoch in range(1, n_epochs + 1): 161 | train(epoch) 162 | test() 163 | print(test_counter) 164 | 165 | 166 | 167 | fig = plt.figure() 168 | plt.plot(train_counter, train_losses, color='blue') 169 | plt.scatter(test_counter, test_losses, color='red') 170 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 171 | plt.xlabel('number of training examples seen') 172 | plt.ylabel('negative log likelihood loss') 173 | plt.show() 174 | 175 | 176 | #examples = enumerate(train_loader) 177 | #batch_idx, (example_data, example_targets) = next(examples) 178 | 179 | #fig = plt.figure() 180 | #for i in range(6): 181 | # plt.subplot(2,3,i+1) 182 | # plt.tight_layout() 183 | # plt.imshow(example_data[i][0], cmap='gray', interpolation='none') 184 | # plt.title("Ground Truth: {}".format(example_targets[i])) 185 | # plt.xticks([]) 186 | # plt.yticks([]) 187 | #plt.show() 188 | 189 | #fig -------------------------------------------------------------------------------- /MNIST/NN_NIID_sorted_2.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | import torch.optim as optim 6 | from torch.utils.data import DataLoader,Dataset,Subset 7 | from sklearn.model_selection import train_test_split 8 | import torchvision.transforms as transforms 9 | import torch.optim as optim 10 | 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import matplotlib.pyplot as plt 13 | 14 | import numpy as np 15 | 16 | 17 | 18 | # NN architecture using PyTorch 19 | # Less parameters 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super(Net, self).__init__() 23 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 24 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 25 | self.conv2_drop = nn.Dropout2d() 26 | self.fc1 = nn.Linear(320, 50) 27 | self.fc2 = nn.Linear(50, 10) 28 | 29 | def forward(self, x): 30 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 31 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 32 | x = x.view(-1, 320) 33 | x = F.relu(self.fc1(x)) 34 | x = F.dropout(x, training=self.training) 35 | x = self.fc2(x) 36 | return F.log_softmax(x) 37 | 38 | def train_val_dataset(dataset, val_split=0.5): 39 | idx = [] 40 | for i in range(10): 41 | for x in range(len(dataset.targets)): 42 | if dataset.targets[x] == i: 43 | idx.append(x) 44 | 45 | 46 | train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 47 | split_datasets = {} 48 | #split_datasets = Subset(dataset, idx) 49 | 50 | 51 | split_datasets['train_1'] = Subset(dataset, train_idx) 52 | split_datasets['train_2'] = Subset(dataset, val_idx) 53 | return split_datasets 54 | 55 | def train(epoch): 56 | network.train() 57 | batch_idxs = [] 58 | for batch_idx, (data, target) in enumerate(train_loader): 59 | batch_idxs.append(batch_idx) 60 | #print(target) 61 | optimizer.zero_grad() 62 | output = network(data) 63 | loss = F.nll_loss(output, target) 64 | loss.backward() 65 | optimizer.step() 66 | if batch_idx % log_interval == 0: 67 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 68 | train_losses.append(loss.item()) 69 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 70 | #torch.save(network.state_dict(), '/results/model.pth') 71 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 72 | #print(train_counter) 73 | 74 | def test(): 75 | network.eval() 76 | test_loss = 0 77 | correct = 0 78 | with torch.no_grad(): 79 | for data, target in test_loader: 80 | output = network(data) 81 | test_loss += F.nll_loss(output, target, size_average=False).item() 82 | pred = output.data.max(1, keepdim=True)[1] 83 | correct += pred.eq(target.data.view_as(pred)).sum() 84 | test_loss /= len(test_loader.dataset) 85 | test_losses.append(test_loss) 86 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 87 | 88 | 89 | n_epochs = 20 90 | batch_size_train = 1000 91 | batch_size_test = 1000 92 | learning_rate = 0.01 93 | momentum = 0.5 94 | log_interval = 10 95 | 96 | 97 | 98 | random_seed = 1 99 | torch.backends.cudnn.enabled = False 100 | torch.manual_seed(random_seed) 101 | 102 | 103 | 104 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 105 | transform=torchvision.transforms.Compose([ 106 | torchvision.transforms.ToTensor(), 107 | torchvision.transforms.Normalize( 108 | (0.1307,), (0.3081,)) 109 | ])) 110 | 111 | datasets = train_val_dataset(dataset) 112 | 113 | train_loader = torch.utils.data.DataLoader( 114 | datasets['train_2'], 115 | #datasets, 116 | batch_size=batch_size_train, shuffle=False) 117 | 118 | 119 | 120 | #for x in range(60000): 121 | # print((datasets[x][1])) 122 | 123 | 124 | #print(len(datasets['train_1'])) 125 | #for x in range(6): 126 | # print((datasets['train_2'][x][1])) 127 | 128 | 129 | 130 | 131 | test_loader = torch.utils.data.DataLoader( 132 | torchvision.datasets.MNIST('/files/', train=False, download=True, 133 | transform=torchvision.transforms.Compose([ 134 | torchvision.transforms.ToTensor(), 135 | torchvision.transforms.Normalize( 136 | (0.1307,), (0.3081,)) 137 | ])), 138 | batch_size=batch_size_test, shuffle=True) 139 | #batch_size = 128 140 | 141 | #train_set = ImgDataset(train_x, train_y, transform) 142 | #val_set = ImgDataset(val_x, val_y, transform) 143 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 144 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 145 | 146 | train_losses = [] 147 | train_counter = [] 148 | test_losses = [] 149 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 150 | 151 | 152 | network = Net() 153 | optimizer = optim.SGD(network.parameters(), lr=learning_rate, 154 | momentum=momentum) 155 | 156 | 157 | 158 | 159 | test() 160 | for epoch in range(1, n_epochs + 1): 161 | train(epoch) 162 | test() 163 | print(test_counter) 164 | 165 | 166 | 167 | fig = plt.figure() 168 | plt.plot(train_counter, train_losses, color='blue') 169 | plt.scatter(test_counter, test_losses, color='red') 170 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 171 | plt.xlabel('number of training examples seen') 172 | plt.ylabel('negative log likelihood loss') 173 | plt.show() 174 | 175 | 176 | #examples = enumerate(train_loader) 177 | #batch_idx, (example_data, example_targets) = next(examples) 178 | 179 | #fig = plt.figure() 180 | #for i in range(6): 181 | # plt.subplot(2,3,i+1) 182 | # plt.tight_layout() 183 | # plt.imshow(example_data[i][0], cmap='gray', interpolation='none') 184 | # plt.title("Ground Truth: {}".format(example_targets[i])) 185 | # plt.xticks([]) 186 | # plt.yticks([]) 187 | #plt.show() 188 | 189 | #fig -------------------------------------------------------------------------------- /MNIST/NN_NIID_sorted_all.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torch.nn as nn 4 | import torch.nn.functional as F 5 | import torch.optim as optim 6 | from torch.utils.data import DataLoader,Dataset,Subset 7 | from sklearn.model_selection import train_test_split 8 | import torchvision.transforms as transforms 9 | import torch.optim as optim 10 | 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import matplotlib.pyplot as plt 13 | 14 | import numpy as np 15 | 16 | 17 | 18 | # NN architecture using PyTorch 19 | # Less parameters 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super(Net, self).__init__() 23 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 24 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 25 | self.conv2_drop = nn.Dropout2d() 26 | self.fc1 = nn.Linear(320, 50) 27 | self.fc2 = nn.Linear(50, 10) 28 | 29 | def forward(self, x): 30 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 31 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 32 | x = x.view(-1, 320) 33 | x = F.relu(self.fc1(x)) 34 | x = F.dropout(x, training=self.training) 35 | x = self.fc2(x) 36 | return F.log_softmax(x) 37 | 38 | def train_val_dataset(dataset, val_split=0.5): 39 | idx = [] 40 | for i in range(10): 41 | for x in range(len(dataset.targets)): 42 | if dataset.targets[x] == i: 43 | idx.append(x) 44 | 45 | 46 | #train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 47 | split_datasets = {} 48 | split_datasets = Subset(dataset, idx) 49 | 50 | 51 | #split_datasets['train_1'] = Subset(dataset, train_idx) 52 | #split_datasets['train_2'] = Subset(dataset, val_idx) 53 | return split_datasets 54 | 55 | def train(epoch): 56 | network.train() 57 | batch_idxs = [] 58 | for batch_idx, (data, target) in enumerate(train_loader): 59 | batch_idxs.append(batch_idx) 60 | #print(target) 61 | optimizer.zero_grad() 62 | output = network(data) 63 | loss = F.nll_loss(output, target) 64 | loss.backward() 65 | optimizer.step() 66 | if batch_idx % log_interval == 0: 67 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 68 | train_losses.append(loss.item()) 69 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 70 | #torch.save(network.state_dict(), '/results/model.pth') 71 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 72 | #print(train_counter) 73 | 74 | def test(): 75 | network.eval() 76 | test_loss = 0 77 | correct = 0 78 | with torch.no_grad(): 79 | for data, target in test_loader: 80 | output = network(data) 81 | test_loss += F.nll_loss(output, target, size_average=False).item() 82 | pred = output.data.max(1, keepdim=True)[1] 83 | correct += pred.eq(target.data.view_as(pred)).sum() 84 | test_loss /= len(test_loader.dataset) 85 | test_losses.append(test_loss) 86 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 87 | 88 | 89 | n_epochs = 20 90 | batch_size_train = 1000 91 | batch_size_test = 1000 92 | learning_rate = 0.01 93 | momentum = 0.5 94 | log_interval = 10 95 | 96 | 97 | 98 | random_seed = 1 99 | torch.backends.cudnn.enabled = False 100 | torch.manual_seed(random_seed) 101 | 102 | 103 | 104 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 105 | transform=torchvision.transforms.Compose([ 106 | torchvision.transforms.ToTensor(), 107 | torchvision.transforms.Normalize( 108 | (0.1307,), (0.3081,)) 109 | ])) 110 | 111 | datasets = train_val_dataset(dataset) 112 | 113 | train_loader = torch.utils.data.DataLoader( 114 | #datasets['train_1'], 115 | datasets, 116 | batch_size=batch_size_train, shuffle=False) 117 | 118 | 119 | 120 | #for x in range(60000): 121 | # print((datasets[x][1])) 122 | 123 | 124 | #print(len(datasets['train_1'])) 125 | #for x in range(6): 126 | # print((datasets['train_2'][x][1])) 127 | 128 | 129 | 130 | 131 | test_loader = torch.utils.data.DataLoader( 132 | torchvision.datasets.MNIST('/files/', train=False, download=True, 133 | transform=torchvision.transforms.Compose([ 134 | torchvision.transforms.ToTensor(), 135 | torchvision.transforms.Normalize( 136 | (0.1307,), (0.3081,)) 137 | ])), 138 | batch_size=batch_size_test, shuffle=True) 139 | #batch_size = 128 140 | 141 | #train_set = ImgDataset(train_x, train_y, transform) 142 | #val_set = ImgDataset(val_x, val_y, transform) 143 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 144 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 145 | 146 | train_losses = [] 147 | train_counter = [] 148 | test_losses = [] 149 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 150 | 151 | 152 | network = Net() 153 | optimizer = optim.SGD(network.parameters(), lr=learning_rate, 154 | momentum=momentum) 155 | 156 | 157 | 158 | 159 | test() 160 | for epoch in range(1, n_epochs + 1): 161 | train(epoch) 162 | test() 163 | print(test_counter) 164 | 165 | 166 | 167 | fig = plt.figure() 168 | plt.plot(train_counter, train_losses, color='blue') 169 | plt.scatter(test_counter, test_losses, color='red') 170 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 171 | plt.xlabel('number of training examples seen') 172 | plt.ylabel('negative log likelihood loss') 173 | plt.show() 174 | 175 | 176 | #examples = enumerate(train_loader) 177 | #batch_idx, (example_data, example_targets) = next(examples) 178 | 179 | #fig = plt.figure() 180 | #for i in range(6): 181 | # plt.subplot(2,3,i+1) 182 | # plt.tight_layout() 183 | # plt.imshow(example_data[i][0], cmap='gray', interpolation='none') 184 | # plt.title("Ground Truth: {}".format(example_targets[i])) 185 | # plt.xticks([]) 186 | # plt.yticks([]) 187 | #plt.show() 188 | 189 | #fig -------------------------------------------------------------------------------- /MNIST/call_complete.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import os 3 | import torchvision 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | from torch.utils.data import DataLoader,Dataset 7 | import torchvision.transforms as transforms 8 | import torch.optim as optim 9 | 10 | from mpl_toolkits.mplot3d import Axes3D 11 | import matplotlib.pyplot as plt 12 | 13 | import numpy as np 14 | 15 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 16 | 17 | # NN architecture using PyTorch 18 | # Less parameters 19 | class Net(nn.Module): 20 | def __init__(self): 21 | super(Net, self).__init__() 22 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 23 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 24 | self.conv2_drop = nn.Dropout2d() 25 | self.fc1 = nn.Linear(320, 50) 26 | self.fc2 = nn.Linear(50, 10) 27 | 28 | def forward(self, x): 29 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 30 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 31 | x = x.view(-1, 320) 32 | x = F.relu(self.fc1(x)) 33 | x = F.dropout(x, training=self.training) 34 | x = self.fc2(x) 35 | return F.log_softmax(x) 36 | 37 | 38 | 39 | def test(complete_model): 40 | complete_model.eval() 41 | test_loss = 0 42 | correct = 0 43 | with torch.no_grad(): 44 | for data, target in test_loader: 45 | output = complete_model(data) 46 | test_loss += F.nll_loss(output, target, size_average=False).item() 47 | pred = output.data.max(1, keepdim=True)[1] 48 | correct += pred.eq(target.data.view_as(pred)).sum() 49 | test_loss /= len(test_loader.dataset) 50 | test_losses.append(test_loss) 51 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 52 | return test_losses 53 | 54 | 55 | 56 | 57 | 58 | 59 | test_loader = torch.utils.data.DataLoader( 60 | torchvision.datasets.MNIST('/files/', train=False, download=True, 61 | transform=torchvision.transforms.Compose([ 62 | torchvision.transforms.ToTensor(), 63 | torchvision.transforms.Normalize( 64 | (0.1307,), (0.3081,)) 65 | ])), 66 | batch_size=1000, shuffle=True) 67 | #batch_size = 128 68 | 69 | #train_set = ImgDataset(train_x, train_y, transform) 70 | #val_set = ImgDataset(val_x, val_y, transform) 71 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 72 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 73 | 74 | 75 | test_losses = [] 76 | 77 | 78 | 79 | 80 | complete_model = Net() 81 | model_name = "Completed_model.pth" 82 | model_path = os.path.join(Directory, "Completed_model") 83 | complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 84 | 85 | complete = complete_model.state_dict() 86 | 87 | for key in complete: 88 | print(complete[key]) 89 | 90 | 91 | 92 | test(complete_model) 93 | #for epoch in range(1, n_epochs + 1): 94 | # train(epoch) 95 | # test() 96 | #fig -------------------------------------------------------------------------------- /MNIST/call_complete_1.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import os 3 | import torchvision 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | import torch.optim as optim 7 | from torch.utils.data import DataLoader,Dataset 8 | import torchvision.transforms as transforms 9 | import torch.optim as optim 10 | 11 | from mpl_toolkits.mplot3d import Axes3D 12 | import matplotlib.pyplot as plt 13 | 14 | import numpy as np 15 | 16 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_1" 17 | 18 | # NN architecture using PyTorch 19 | # Less parameters 20 | class Net(nn.Module): 21 | def __init__(self): 22 | super(Net, self).__init__() 23 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 24 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 25 | self.conv2_drop = nn.Dropout2d() 26 | self.fc1 = nn.Linear(320, 50) 27 | self.fc2 = nn.Linear(50, 10) 28 | 29 | def forward(self, x): 30 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 31 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 32 | x = x.view(-1, 320) 33 | x = F.relu(self.fc1(x)) 34 | x = F.dropout(x, training=self.training) 35 | x = self.fc2(x) 36 | return F.log_softmax(x) 37 | 38 | 39 | 40 | def test(complete_model): 41 | complete_model.eval() 42 | test_loss = 0 43 | correct = 0 44 | with torch.no_grad(): 45 | for data, target in test_loader: 46 | output = complete_model(data) 47 | test_loss += F.nll_loss(output, target, size_average=False).item() 48 | pred = output.data.max(1, keepdim=True)[1] 49 | correct += pred.eq(target.data.view_as(pred)).sum() 50 | test_loss /= len(test_loader.dataset) 51 | test_losses.append(test_loss) 52 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 53 | return test_losses 54 | 55 | 56 | 57 | 58 | 59 | 60 | test_loader = torch.utils.data.DataLoader( 61 | torchvision.datasets.MNIST('/files/', train=False, download=True, 62 | transform=torchvision.transforms.Compose([ 63 | torchvision.transforms.ToTensor(), 64 | torchvision.transforms.Normalize( 65 | (0.1307,), (0.3081,)) 66 | ])), 67 | batch_size=1000, shuffle=True) 68 | #batch_size = 128 69 | 70 | #train_set = ImgDataset(train_x, train_y, transform) 71 | #val_set = ImgDataset(val_x, val_y, transform) 72 | #train_loader = DataLoader(train_set, batch_size=batch_size, shuffle=True) 73 | #val_loader = DataLoader(val_set, batch_size=batch_size, shuffle=False) 74 | 75 | 76 | test_losses = [] 77 | 78 | 79 | 80 | 81 | complete_model = Net() 82 | model_name = "Completed_model" 83 | model_path = os.path.join(Directory, model_name) 84 | complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 85 | 86 | complete = complete_model.state_dict() 87 | 88 | for key in complete: 89 | print(complete[key]) 90 | 91 | 92 | 93 | test(complete_model) 94 | #for epoch in range(1, n_epochs + 1): 95 | # train(epoch) 96 | # test() 97 | #fig -------------------------------------------------------------------------------- /MNIST/client_1.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset 10 | import torchvision.transforms as transforms 11 | 12 | from mpl_toolkits.mplot3d import Axes3D 13 | import matplotlib.pyplot as plt 14 | import time 15 | import os 16 | import numpy as np 17 | from pathlib import Path 18 | 19 | 20 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_1" 21 | 22 | #torch.manual_seed(446) 23 | #np.random.seed(446) 24 | 25 | 26 | class Net(nn.Module): 27 | def __init__(self): 28 | super(Net, self).__init__() 29 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 30 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 31 | self.conv2_drop = nn.Dropout2d() 32 | self.fc1 = nn.Linear(320, 50) 33 | self.fc2 = nn.Linear(50, 10) 34 | 35 | def forward(self, x): 36 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 37 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 38 | x = x.view(-1, 320) 39 | x = F.relu(self.fc1(x)) 40 | x = F.dropout(x, training=self.training) 41 | x = self.fc2(x) 42 | return F.log_softmax(x) 43 | 44 | def train(epoch, model): 45 | 46 | for batch_idx, (data, target) in enumerate(train_loader): 47 | optimizer.zero_grad() 48 | output = model(data) 49 | loss = F.nll_loss(output, target) 50 | loss.backward() 51 | optimizer.step() 52 | if batch_idx % log_interval == 0: 53 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 54 | train_losses.append(loss.item()) 55 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 56 | 57 | #torch.save(network.state_dict(), '/results/model.pth') 58 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 59 | 60 | def test(model): 61 | model.eval() 62 | test_loss = 0 63 | correct = 0 64 | with torch.no_grad(): 65 | for data, target in test_loader: 66 | #print(data) 67 | output = model(data) 68 | test_loss += F.nll_loss(output, target, size_average=False).item() 69 | pred = output.data.max(1, keepdim=True)[1] 70 | correct += pred.eq(target.data.view_as(pred)).sum() 71 | test_loss /= len(test_loader.dataset) 72 | test_losses.append(test_loss) 73 | 74 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 75 | return test_loss 76 | 77 | 78 | 79 | def recv(soc, buffer_size=4096, recv_timeout=100): 80 | received_data = b"" 81 | while str(received_data)[-2] != '.': 82 | try: 83 | soc.settimeout(recv_timeout) 84 | received_data += soc.recv(buffer_size) 85 | except socket.timeout: 86 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 87 | return None, 0 88 | except BaseException as e: 89 | return None, 0 90 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 91 | 92 | try: 93 | received_data = pickle.loads(received_data) 94 | except BaseException as e: 95 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 96 | return None, 0 97 | 98 | return received_data, 1 99 | 100 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 101 | print("Socket Created.\n") 102 | 103 | try: 104 | soc.connect(("localhost", 10000)) 105 | print("Successful Connection to the Server.\n") 106 | except BaseException as e: 107 | print("Error Connecting to the Server: {msg}".format(msg=e)) 108 | soc.close() 109 | print("Socket Closed.") 110 | 111 | subject = "echo" 112 | NN_instance = None 113 | Client_ID = "Client_1" 114 | test_loss = 10 115 | 116 | n_epochs = 1 117 | train_losses = [] 118 | train_counter = [] 119 | test_losses = [] 120 | 121 | while True: 122 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 123 | data_byte = pickle.dumps(data_client) 124 | 125 | print("Sending the Model to the Server.\n") 126 | soc.sendall(data_byte) 127 | 128 | 129 | print("Receiving Reply from the Server.") 130 | received_data, status = recv(soc=soc, 131 | buffer_size=100000, 132 | recv_timeout=100) 133 | if status == 0: 134 | print("Nothing Received from the Server.") 135 | break 136 | else: 137 | print(received_data, end="\n\n") 138 | 139 | subject = received_data["subject"] 140 | if subject == "model": 141 | ID = received_data["ID"] 142 | NN_instance = received_data["data"] 143 | time_struct = time.gmtime() 144 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 145 | model_path = os.path.join(Directory, "Global models") 146 | Path(model_path).mkdir(parents=True, exist_ok=True) 147 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 148 | print("Received model saved in {path}".format(path=model_path)) 149 | 150 | elif subject == "done": 151 | print("The server said the model is trained successfully and no need for further updates its parameters.") 152 | subject = "end" 153 | NN_instance = None 154 | 155 | 156 | 157 | elif subject == "end": 158 | 159 | print("Received completed model from server.") 160 | ID = received_data["ID"] 161 | Completed_NN_instance = received_data["data"] 162 | time_struct = time.gmtime() 163 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 164 | model_name = "Completed_model" 165 | model_path = os.path.join(Directory, model_name) 166 | Path(model_path).mkdir(parents=True, exist_ok=True) 167 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 168 | print("Completed model saved in {path}".format(path=model_path)) 169 | break 170 | else: 171 | print("Unrecognized message type.") 172 | break 173 | 174 | 175 | subject = "model" 176 | 177 | 178 | 179 | 180 | 181 | batch_size_train = 1000 182 | batch_size_test = 1000 183 | learning_rate = 0.01 184 | momentum = 0.5 185 | log_interval = 10 186 | 187 | #random_seed = 1 188 | #torch.backends.cudnn.enabled = False 189 | #torch.manual_seed(random_seed) 190 | 191 | train_loader = torch.utils.data.DataLoader( 192 | torchvision.datasets.MNIST('/files/', train=True, download=True, 193 | transform=torchvision.transforms.Compose([ 194 | torchvision.transforms.ToTensor(), 195 | torchvision.transforms.Normalize( 196 | (0.1307,), (0.3081,)) 197 | ])), 198 | batch_size=batch_size_train, shuffle=True) 199 | test_loader = torch.utils.data.DataLoader( 200 | torchvision.datasets.MNIST('/files/', train=False, download=True, 201 | transform=torchvision.transforms.Compose([ 202 | torchvision.transforms.ToTensor(), 203 | torchvision.transforms.Normalize( 204 | (0.1307,), (0.3081,)) 205 | ])), 206 | batch_size=batch_size_test, shuffle=True) 207 | 208 | 209 | 210 | 211 | 212 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 213 | 214 | 215 | 216 | examples = enumerate(test_loader) 217 | batch_idx, (example_data, example_targets) = next(examples) 218 | 219 | 220 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 221 | momentum=momentum) 222 | 223 | 224 | 225 | if ID == f"{Client_ID}_initial": 226 | 227 | test_loss = test(NN_instance) 228 | train(n_epochs, NN_instance) 229 | n_epochs += 1 230 | 231 | test_loss = test(NN_instance) 232 | 233 | else: 234 | 235 | #for epoch in range(1, n_epochs + 1): 236 | train(n_epochs, NN_instance) 237 | n_epochs += 1 238 | test_loss = test(NN_instance) 239 | 240 | time_struct = time.gmtime() 241 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 242 | model_path = os.path.join(Directory, "Trained local models") 243 | Path(model_path).mkdir(parents=True, exist_ok=True) 244 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 245 | print("Trained local model saved in {path}".format(path=model_path)) 246 | 247 | #complete_model = Net() 248 | 249 | 250 | #model_name = "Completed_model" 251 | #model_path = os.path.join(Directory, model_name) 252 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 253 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 254 | 255 | #print(train_counter) 256 | #print(test_counter) 257 | #print(train_losses) 258 | #print(test_losses) 259 | 260 | plt.plot(train_counter, train_losses, color='blue') 261 | plt.scatter(test_counter, test_losses, color='red') 262 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 263 | plt.xlabel('number of training examples seen') 264 | plt.ylabel('negative log likelihood loss') 265 | plt.title('Client_1 Test loss.') 266 | plt.show() 267 | 268 | soc.close() 269 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_1_fixed_e.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset 10 | import torchvision.transforms as transforms 11 | 12 | from mpl_toolkits.mplot3d import Axes3D 13 | import matplotlib.pyplot as plt 14 | import time 15 | import os 16 | import numpy as np 17 | from pathlib import Path 18 | 19 | 20 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_1" 21 | 22 | #torch.manual_seed(446) 23 | #np.random.seed(446) 24 | 25 | 26 | class Net(nn.Module): 27 | def __init__(self): 28 | super(Net, self).__init__() 29 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 30 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 31 | self.conv2_drop = nn.Dropout2d() 32 | self.fc1 = nn.Linear(320, 50) 33 | self.fc2 = nn.Linear(50, 10) 34 | 35 | def forward(self, x): 36 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 37 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 38 | x = x.view(-1, 320) 39 | x = F.relu(self.fc1(x)) 40 | x = F.dropout(x, training=self.training) 41 | x = self.fc2(x) 42 | return F.log_softmax(x) 43 | 44 | def train(epoch, model): 45 | 46 | for batch_idx, (data, target) in enumerate(train_loader): 47 | optimizer.zero_grad() 48 | output = model(data) 49 | loss = F.nll_loss(output, target) 50 | loss.backward() 51 | optimizer.step() 52 | if batch_idx % log_interval == 0: 53 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 54 | train_losses.append(loss.item()) 55 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 56 | 57 | #torch.save(network.state_dict(), '/results/model.pth') 58 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 59 | 60 | def test(model): 61 | model.eval() 62 | test_loss = 0 63 | correct = 0 64 | with torch.no_grad(): 65 | for data, target in test_loader: 66 | #print(data) 67 | output = model(data) 68 | test_loss += F.nll_loss(output, target, size_average=False).item() 69 | pred = output.data.max(1, keepdim=True)[1] 70 | correct += pred.eq(target.data.view_as(pred)).sum() 71 | test_loss /= len(test_loader.dataset) 72 | test_losses.append(test_loss) 73 | 74 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 75 | return test_loss 76 | 77 | 78 | 79 | def recv(soc, buffer_size=4096, recv_timeout=100): 80 | received_data = b"" 81 | while str(received_data)[-2] != '.': 82 | try: 83 | soc.settimeout(recv_timeout) 84 | received_data += soc.recv(buffer_size) 85 | except socket.timeout: 86 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 87 | return None, 0 88 | except BaseException as e: 89 | return None, 0 90 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 91 | 92 | try: 93 | received_data = pickle.loads(received_data) 94 | except BaseException as e: 95 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 96 | return None, 0 97 | 98 | return received_data, 1 99 | 100 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 101 | print("Socket Created.\n") 102 | 103 | try: 104 | soc.connect(("localhost", 10000)) 105 | print("Successful Connection to the Server.\n") 106 | except BaseException as e: 107 | print("Error Connecting to the Server: {msg}".format(msg=e)) 108 | soc.close() 109 | print("Socket Closed.") 110 | 111 | subject = "echo" 112 | NN_instance = None 113 | Client_ID = "Client_1" 114 | test_loss = 10 115 | 116 | n_epochs = 1 117 | train_losses = [] 118 | train_counter = [] 119 | test_losses = [] 120 | 121 | # n_epoch == local training rounds, must be even number 122 | while n_epochs <= 20: 123 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 124 | data_byte = pickle.dumps(data_client) 125 | 126 | print("Sending the Model to the Server.\n") 127 | soc.sendall(data_byte) 128 | 129 | 130 | print("Receiving Reply from the Server.") 131 | received_data, status = recv(soc=soc, 132 | buffer_size=100000, 133 | recv_timeout=100) 134 | if status == 0: 135 | print("Nothing Received from the Server.") 136 | break 137 | else: 138 | print(received_data, end="\n\n") 139 | 140 | subject = received_data["subject"] 141 | if subject == "model": 142 | ID = received_data["ID"] 143 | NN_instance = received_data["data"] 144 | time_struct = time.gmtime() 145 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 146 | model_path = os.path.join(Directory, "Global models") 147 | Path(model_path).mkdir(parents=True, exist_ok=True) 148 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 149 | print("Received model saved in {path}".format(path=model_path)) 150 | 151 | elif subject == "done": 152 | print("The server said the model is trained successfully and no need for further updates its parameters.") 153 | subject = "end" 154 | NN_instance = None 155 | 156 | 157 | 158 | elif subject == "end": 159 | 160 | print("Received completed model from server.") 161 | ID = received_data["ID"] 162 | Completed_NN_instance = received_data["data"] 163 | time_struct = time.gmtime() 164 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 165 | model_name = "Completed_model" 166 | model_path = os.path.join(Directory, model_name) 167 | Path(model_path).mkdir(parents=True, exist_ok=True) 168 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 169 | print("Completed model saved in {path}".format(path=model_path)) 170 | break 171 | else: 172 | print("Unrecognized message type.") 173 | break 174 | 175 | 176 | subject = "model" 177 | 178 | 179 | 180 | 181 | 182 | batch_size_train = 1000 183 | batch_size_test = 1000 184 | learning_rate = 0.01 185 | momentum = 0.5 186 | log_interval = 10 187 | 188 | #random_seed = 1 189 | #torch.backends.cudnn.enabled = False 190 | #torch.manual_seed(random_seed) 191 | 192 | train_loader = torch.utils.data.DataLoader( 193 | torchvision.datasets.MNIST('/files/', train=True, download=True, 194 | transform=torchvision.transforms.Compose([ 195 | torchvision.transforms.ToTensor(), 196 | torchvision.transforms.Normalize( 197 | (0.1307,), (0.3081,)) 198 | ])), 199 | batch_size=batch_size_train, shuffle=True) 200 | test_loader = torch.utils.data.DataLoader( 201 | torchvision.datasets.MNIST('/files/', train=False, download=True, 202 | transform=torchvision.transforms.Compose([ 203 | torchvision.transforms.ToTensor(), 204 | torchvision.transforms.Normalize( 205 | (0.1307,), (0.3081,)) 206 | ])), 207 | batch_size=batch_size_test, shuffle=True) 208 | 209 | 210 | 211 | 212 | 213 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 214 | 215 | 216 | 217 | examples = enumerate(test_loader) 218 | batch_idx, (example_data, example_targets) = next(examples) 219 | 220 | 221 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 222 | momentum=momentum) 223 | 224 | 225 | 226 | if ID == f"{Client_ID}": 227 | 228 | test_loss = test(NN_instance) 229 | train(n_epochs, NN_instance) 230 | n_epochs += 1 231 | 232 | test_loss = test(NN_instance) 233 | 234 | else: 235 | 236 | #for epoch in range(1, n_epochs + 1): 237 | train(n_epochs, NN_instance) 238 | n_epochs += 1 239 | test_loss = test(NN_instance) 240 | 241 | time_struct = time.gmtime() 242 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 243 | model_path = os.path.join(Directory, "Trained local models") 244 | Path(model_path).mkdir(parents=True, exist_ok=True) 245 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 246 | print("Trained local model saved in {path}".format(path=model_path)) 247 | 248 | #complete_model = Net() 249 | 250 | 251 | #model_name = "Completed_model" 252 | #model_path = os.path.join(Directory, model_name) 253 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 254 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 255 | 256 | #print(train_counter) 257 | #print(test_counter) 258 | #print(train_losses) 259 | #print(test_losses) 260 | 261 | plt.plot(train_counter, train_losses, color='blue') 262 | plt.scatter(test_counter, test_losses, color='red') 263 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 264 | plt.xlabel('number of training examples seen') 265 | plt.ylabel('negative log likelihood loss') 266 | plt.title('Client_1 Test loss.') 267 | plt.show() 268 | 269 | soc.close() 270 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_1_fixed_e_SORTED.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset,Subset 10 | from sklearn.model_selection import train_test_split 11 | import torchvision.transforms as transforms 12 | 13 | from mpl_toolkits.mplot3d import Axes3D 14 | import matplotlib.pyplot as plt 15 | import time 16 | import os 17 | import numpy as np 18 | from pathlib import Path 19 | 20 | 21 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_1" 22 | 23 | #torch.manual_seed(446) 24 | #np.random.seed(446) 25 | 26 | 27 | class Net(nn.Module): 28 | def __init__(self): 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 31 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 32 | self.conv2_drop = nn.Dropout2d() 33 | self.fc1 = nn.Linear(320, 50) 34 | self.fc2 = nn.Linear(50, 10) 35 | 36 | def forward(self, x): 37 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 38 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 39 | x = x.view(-1, 320) 40 | x = F.relu(self.fc1(x)) 41 | x = F.dropout(x, training=self.training) 42 | x = self.fc2(x) 43 | return F.log_softmax(x) 44 | 45 | def train_val_dataset(dataset, val_split=0.5): 46 | idx = [] 47 | for i in range(10): 48 | for x in range(len(dataset.targets)): 49 | if dataset.targets[x] == i: 50 | idx.append(x) 51 | 52 | 53 | train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 54 | split_datasets = {} 55 | #split_datasets = Subset(dataset, idx) 56 | 57 | 58 | split_datasets['train_1'] = Subset(dataset, train_idx) 59 | split_datasets['train_2'] = Subset(dataset, val_idx) 60 | return split_datasets 61 | 62 | def train(epoch, model): 63 | 64 | for batch_idx, (data, target) in enumerate(train_loader): 65 | optimizer.zero_grad() 66 | output = model(data) 67 | loss = F.nll_loss(output, target) 68 | loss.backward() 69 | optimizer.step() 70 | if batch_idx % log_interval == 0: 71 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 72 | train_losses.append(loss.item()) 73 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 74 | 75 | #torch.save(network.state_dict(), '/results/model.pth') 76 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 77 | 78 | def test(model): 79 | model.eval() 80 | test_loss = 0 81 | correct = 0 82 | with torch.no_grad(): 83 | for data, target in test_loader: 84 | #print(data) 85 | output = model(data) 86 | test_loss += F.nll_loss(output, target, size_average=False).item() 87 | pred = output.data.max(1, keepdim=True)[1] 88 | correct += pred.eq(target.data.view_as(pred)).sum() 89 | test_loss /= len(test_loader.dataset) 90 | test_losses.append(test_loss) 91 | 92 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 93 | return test_loss 94 | 95 | 96 | 97 | def recv(soc, buffer_size=4096, recv_timeout=100): 98 | received_data = b"" 99 | while str(received_data)[-2] != '.': 100 | try: 101 | soc.settimeout(recv_timeout) 102 | received_data += soc.recv(buffer_size) 103 | except socket.timeout: 104 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 105 | return None, 0 106 | except BaseException as e: 107 | return None, 0 108 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 109 | 110 | try: 111 | received_data = pickle.loads(received_data) 112 | except BaseException as e: 113 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 114 | return None, 0 115 | 116 | return received_data, 1 117 | 118 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 119 | print("Socket Created.\n") 120 | 121 | try: 122 | soc.connect(("localhost", 10000)) 123 | print("Successful Connection to the Server.\n") 124 | except BaseException as e: 125 | print("Error Connecting to the Server: {msg}".format(msg=e)) 126 | soc.close() 127 | print("Socket Closed.") 128 | 129 | subject = "echo" 130 | NN_instance = None 131 | Client_ID = "Client_1" 132 | test_loss = 10 133 | 134 | n_epochs = 1 135 | train_losses = [] 136 | train_counter = [] 137 | test_losses = [] 138 | 139 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 140 | transform=torchvision.transforms.Compose([ 141 | torchvision.transforms.ToTensor(), 142 | torchvision.transforms.Normalize( 143 | (0.1307,), (0.3081,)) 144 | ])) 145 | 146 | datasets = train_val_dataset(dataset) 147 | 148 | # n_epoch == local training rounds, must be even number 149 | while n_epochs <= 20: 150 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 151 | data_byte = pickle.dumps(data_client) 152 | 153 | print("Sending the Model to the Server.\n") 154 | soc.sendall(data_byte) 155 | 156 | 157 | print("Receiving Reply from the Server.") 158 | received_data, status = recv(soc=soc, 159 | buffer_size=100000, 160 | recv_timeout=100) 161 | if status == 0: 162 | print("Nothing Received from the Server.") 163 | break 164 | else: 165 | print(received_data, end="\n\n") 166 | 167 | subject = received_data["subject"] 168 | if subject == "model": 169 | ID = received_data["ID"] 170 | NN_instance = received_data["data"] 171 | time_struct = time.gmtime() 172 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 173 | model_path = os.path.join(Directory, "Global models") 174 | Path(model_path).mkdir(parents=True, exist_ok=True) 175 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 176 | print("Received model saved in {path}".format(path=model_path)) 177 | 178 | elif subject == "done": 179 | print("The server said the model is trained successfully and no need for further updates its parameters.") 180 | subject = "end" 181 | NN_instance = None 182 | 183 | 184 | 185 | elif subject == "end": 186 | 187 | print("Received completed model from server.") 188 | ID = received_data["ID"] 189 | Completed_NN_instance = received_data["data"] 190 | time_struct = time.gmtime() 191 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 192 | model_name = "Completed_model" 193 | model_path = os.path.join(Directory, model_name) 194 | Path(model_path).mkdir(parents=True, exist_ok=True) 195 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 196 | print("Completed model saved in {path}".format(path=model_path)) 197 | break 198 | else: 199 | print("Unrecognized message type.") 200 | break 201 | 202 | 203 | subject = "model" 204 | 205 | 206 | 207 | 208 | 209 | batch_size_train = 1000 210 | batch_size_test = 1000 211 | learning_rate = 0.01 212 | momentum = 0.5 213 | log_interval = 10 214 | 215 | #random_seed = 1 216 | #torch.backends.cudnn.enabled = False 217 | #torch.manual_seed(random_seed) 218 | 219 | 220 | 221 | #train_loader = torch.utils.data.DataLoader( 222 | # torchvision.datasets.MNIST('/files/', train=True, download=True, 223 | # transform=torchvision.transforms.Compose([ 224 | # torchvision.transforms.ToTensor(), 225 | # torchvision.transforms.Normalize( 226 | # (0.1307,), (0.3081,)) 227 | # ])), 228 | # batch_size=batch_size_train, shuffle=True) 229 | 230 | train_loader = torch.utils.data.DataLoader( 231 | datasets['train_1'], 232 | batch_size=batch_size_train, shuffle=True) 233 | 234 | 235 | 236 | test_loader = torch.utils.data.DataLoader( 237 | torchvision.datasets.MNIST('/files/', train=False, download=True, 238 | transform=torchvision.transforms.Compose([ 239 | torchvision.transforms.ToTensor(), 240 | torchvision.transforms.Normalize( 241 | (0.1307,), (0.3081,)) 242 | ])), 243 | batch_size=batch_size_test, shuffle=True) 244 | 245 | 246 | 247 | 248 | 249 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 250 | 251 | 252 | 253 | examples = enumerate(test_loader) 254 | batch_idx, (example_data, example_targets) = next(examples) 255 | 256 | 257 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 258 | momentum=momentum) 259 | 260 | 261 | 262 | if ID == f"{Client_ID}": 263 | 264 | test_loss = test(NN_instance) 265 | train(n_epochs, NN_instance) 266 | n_epochs += 1 267 | 268 | test_loss = test(NN_instance) 269 | 270 | else: 271 | 272 | #for epoch in range(1, n_epochs + 1): 273 | train(n_epochs, NN_instance) 274 | n_epochs += 1 275 | test_loss = test(NN_instance) 276 | 277 | time_struct = time.gmtime() 278 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 279 | model_path = os.path.join(Directory, "Trained local models") 280 | Path(model_path).mkdir(parents=True, exist_ok=True) 281 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 282 | print("Trained local model saved in {path}".format(path=model_path)) 283 | 284 | #complete_model = Net() 285 | 286 | 287 | #model_name = "Completed_model" 288 | #model_path = os.path.join(Directory, model_name) 289 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 290 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 291 | 292 | #print(train_counter) 293 | #print(test_counter) 294 | #print(train_losses) 295 | #print(test_losses) 296 | 297 | plt.plot(train_counter, train_losses, color='blue') 298 | plt.scatter(test_counter, test_losses, color='red') 299 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 300 | plt.xlabel('number of training examples seen') 301 | plt.ylabel('negative log likelihood loss') 302 | plt.title('Client_1 Test loss.') 303 | plt.show() 304 | 305 | soc.close() 306 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_1_fixed_e_SORTED_60000.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset,Subset 10 | from sklearn.model_selection import train_test_split 11 | import torchvision.transforms as transforms 12 | 13 | from mpl_toolkits.mplot3d import Axes3D 14 | import matplotlib.pyplot as plt 15 | import time 16 | import os 17 | import numpy as np 18 | from pathlib import Path 19 | 20 | 21 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_1" 22 | 23 | #torch.manual_seed(446) 24 | #np.random.seed(446) 25 | 26 | 27 | class Net(nn.Module): 28 | def __init__(self): 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 31 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 32 | self.conv2_drop = nn.Dropout2d() 33 | self.fc1 = nn.Linear(320, 50) 34 | self.fc2 = nn.Linear(50, 10) 35 | 36 | def forward(self, x): 37 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 38 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 39 | x = x.view(-1, 320) 40 | x = F.relu(self.fc1(x)) 41 | x = F.dropout(x, training=self.training) 42 | x = self.fc2(x) 43 | return F.log_softmax(x) 44 | 45 | def train_val_dataset(dataset, val_split=0.5): 46 | idx = [] 47 | for i in range(10): 48 | for x in range(len(dataset.targets)): 49 | if dataset.targets[x] == i: 50 | idx.append(x) 51 | 52 | 53 | #train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 54 | split_datasets = {} 55 | split_datasets = Subset(dataset, idx) 56 | 57 | 58 | #split_datasets['train_1'] = Subset(dataset, train_idx) 59 | #split_datasets['train_2'] = Subset(dataset, val_idx) 60 | return split_datasets 61 | 62 | def train(epoch, model): 63 | 64 | for batch_idx, (data, target) in enumerate(train_loader): 65 | optimizer.zero_grad() 66 | output = model(data) 67 | loss = F.nll_loss(output, target) 68 | loss.backward() 69 | optimizer.step() 70 | if batch_idx % log_interval == 0: 71 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 72 | train_losses.append(loss.item()) 73 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 74 | 75 | #torch.save(network.state_dict(), '/results/model.pth') 76 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 77 | 78 | def test(model): 79 | model.eval() 80 | test_loss = 0 81 | correct = 0 82 | with torch.no_grad(): 83 | for data, target in test_loader: 84 | #print(data) 85 | output = model(data) 86 | test_loss += F.nll_loss(output, target, size_average=False).item() 87 | pred = output.data.max(1, keepdim=True)[1] 88 | correct += pred.eq(target.data.view_as(pred)).sum() 89 | test_loss /= len(test_loader.dataset) 90 | test_losses.append(test_loss) 91 | 92 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 93 | return test_loss 94 | 95 | 96 | 97 | def recv(soc, buffer_size=4096, recv_timeout=100): 98 | received_data = b"" 99 | while str(received_data)[-2] != '.': 100 | try: 101 | soc.settimeout(recv_timeout) 102 | received_data += soc.recv(buffer_size) 103 | except socket.timeout: 104 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 105 | return None, 0 106 | except BaseException as e: 107 | return None, 0 108 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 109 | 110 | try: 111 | received_data = pickle.loads(received_data) 112 | except BaseException as e: 113 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 114 | return None, 0 115 | 116 | return received_data, 1 117 | 118 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 119 | print("Socket Created.\n") 120 | 121 | try: 122 | soc.connect(("localhost", 10000)) 123 | print("Successful Connection to the Server.\n") 124 | except BaseException as e: 125 | print("Error Connecting to the Server: {msg}".format(msg=e)) 126 | soc.close() 127 | print("Socket Closed.") 128 | 129 | subject = "echo" 130 | NN_instance = None 131 | Client_ID = "Client_1" 132 | test_loss = 10 133 | 134 | n_epochs = 1 135 | train_losses = [] 136 | train_counter = [] 137 | test_losses = [] 138 | 139 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 140 | transform=torchvision.transforms.Compose([ 141 | torchvision.transforms.ToTensor(), 142 | torchvision.transforms.Normalize( 143 | (0.1307,), (0.3081,)) 144 | ])) 145 | 146 | datasets = train_val_dataset(dataset) 147 | 148 | # n_epoch == local training rounds, must be even number 149 | while n_epochs <= 20: 150 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 151 | data_byte = pickle.dumps(data_client) 152 | 153 | print("Sending the Model to the Server.\n") 154 | soc.sendall(data_byte) 155 | 156 | 157 | print("Receiving Reply from the Server.") 158 | received_data, status = recv(soc=soc, 159 | buffer_size=100000, 160 | recv_timeout=100) 161 | if status == 0: 162 | print("Nothing Received from the Server.") 163 | break 164 | else: 165 | print(received_data, end="\n\n") 166 | 167 | subject = received_data["subject"] 168 | if subject == "model": 169 | ID = received_data["ID"] 170 | NN_instance = received_data["data"] 171 | time_struct = time.gmtime() 172 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 173 | model_path = os.path.join(Directory, "Global models") 174 | Path(model_path).mkdir(parents=True, exist_ok=True) 175 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 176 | print("Received model saved in {path}".format(path=model_path)) 177 | 178 | elif subject == "done": 179 | print("The server said the model is trained successfully and no need for further updates its parameters.") 180 | subject = "end" 181 | NN_instance = None 182 | 183 | 184 | 185 | elif subject == "end": 186 | 187 | print("Received completed model from server.") 188 | ID = received_data["ID"] 189 | Completed_NN_instance = received_data["data"] 190 | time_struct = time.gmtime() 191 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 192 | model_name = "Completed_model" 193 | model_path = os.path.join(Directory, model_name) 194 | Path(model_path).mkdir(parents=True, exist_ok=True) 195 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 196 | print("Completed model saved in {path}".format(path=model_path)) 197 | break 198 | else: 199 | print("Unrecognized message type.") 200 | break 201 | 202 | 203 | subject = "model" 204 | 205 | 206 | 207 | 208 | 209 | batch_size_train = 1000 210 | batch_size_test = 1000 211 | learning_rate = 0.01 212 | momentum = 0.5 213 | log_interval = 10 214 | 215 | #random_seed = 1 216 | #torch.backends.cudnn.enabled = False 217 | #torch.manual_seed(random_seed) 218 | 219 | 220 | 221 | #train_loader = torch.utils.data.DataLoader( 222 | # torchvision.datasets.MNIST('/files/', train=True, download=True, 223 | # transform=torchvision.transforms.Compose([ 224 | # torchvision.transforms.ToTensor(), 225 | # torchvision.transforms.Normalize( 226 | # (0.1307,), (0.3081,)) 227 | # ])), 228 | # batch_size=batch_size_train, shuffle=True) 229 | 230 | train_loader = torch.utils.data.DataLoader( 231 | #datasets['train_1'], 232 | datasets, 233 | batch_size=batch_size_train, shuffle=False) 234 | 235 | 236 | 237 | test_loader = torch.utils.data.DataLoader( 238 | torchvision.datasets.MNIST('/files/', train=False, download=True, 239 | transform=torchvision.transforms.Compose([ 240 | torchvision.transforms.ToTensor(), 241 | torchvision.transforms.Normalize( 242 | (0.1307,), (0.3081,)) 243 | ])), 244 | batch_size=batch_size_test, shuffle=True) 245 | 246 | 247 | 248 | 249 | 250 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 251 | 252 | 253 | 254 | examples = enumerate(test_loader) 255 | batch_idx, (example_data, example_targets) = next(examples) 256 | 257 | 258 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 259 | momentum=momentum) 260 | 261 | 262 | 263 | if ID == f"{Client_ID}": 264 | 265 | test_loss = test(NN_instance) 266 | train(n_epochs, NN_instance) 267 | n_epochs += 1 268 | 269 | test_loss = test(NN_instance) 270 | 271 | else: 272 | 273 | #for epoch in range(1, n_epochs + 1): 274 | train(n_epochs, NN_instance) 275 | n_epochs += 1 276 | test_loss = test(NN_instance) 277 | 278 | time_struct = time.gmtime() 279 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 280 | model_path = os.path.join(Directory, "Trained local models") 281 | Path(model_path).mkdir(parents=True, exist_ok=True) 282 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 283 | print("Trained local model saved in {path}".format(path=model_path)) 284 | 285 | #complete_model = Net() 286 | 287 | 288 | #model_name = "Completed_model" 289 | #model_path = os.path.join(Directory, model_name) 290 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 291 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 292 | 293 | #print(train_counter) 294 | #print(test_counter) 295 | #print(train_losses) 296 | #print(test_losses) 297 | 298 | plt.plot(train_counter, train_losses, color='blue') 299 | plt.scatter(test_counter, test_losses, color='red') 300 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 301 | plt.xlabel('number of training examples seen') 302 | plt.ylabel('negative log likelihood loss') 303 | plt.title('Client_1 Test loss.') 304 | plt.show() 305 | 306 | soc.close() 307 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_2.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset 10 | import torchvision.transforms as transforms 11 | 12 | from mpl_toolkits.mplot3d import Axes3D 13 | import matplotlib.pyplot as plt 14 | import time 15 | import os 16 | import numpy as np 17 | from pathlib import Path 18 | 19 | 20 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 21 | 22 | #torch.manual_seed(446) 23 | #np.random.seed(446) 24 | 25 | 26 | class Net(nn.Module): 27 | def __init__(self): 28 | super(Net, self).__init__() 29 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 30 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 31 | self.conv2_drop = nn.Dropout2d() 32 | self.fc1 = nn.Linear(320, 50) 33 | self.fc2 = nn.Linear(50, 10) 34 | 35 | def forward(self, x): 36 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 37 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 38 | x = x.view(-1, 320) 39 | x = F.relu(self.fc1(x)) 40 | x = F.dropout(x, training=self.training) 41 | x = self.fc2(x) 42 | return F.log_softmax(x) 43 | 44 | def train(epoch, model): 45 | 46 | for batch_idx, (data, target) in enumerate(train_loader): 47 | optimizer.zero_grad() 48 | output = model(data) 49 | loss = F.nll_loss(output, target) 50 | loss.backward() 51 | optimizer.step() 52 | if batch_idx % log_interval == 0: 53 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 54 | train_losses.append(loss.item()) 55 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 56 | 57 | #torch.save(network.state_dict(), '/results/model.pth') 58 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 59 | 60 | def test(model): 61 | model.eval() 62 | test_loss = 0 63 | correct = 0 64 | with torch.no_grad(): 65 | for data, target in test_loader: 66 | #print(data) 67 | output = model(data) 68 | test_loss += F.nll_loss(output, target, size_average=False).item() 69 | pred = output.data.max(1, keepdim=True)[1] 70 | correct += pred.eq(target.data.view_as(pred)).sum() 71 | test_loss /= len(test_loader.dataset) 72 | test_losses.append(test_loss) 73 | 74 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 75 | return test_loss 76 | 77 | 78 | 79 | def recv(soc, buffer_size=4096, recv_timeout=100): 80 | received_data = b"" 81 | while str(received_data)[-2] != '.': 82 | try: 83 | soc.settimeout(recv_timeout) 84 | received_data += soc.recv(buffer_size) 85 | except socket.timeout: 86 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 87 | return None, 0 88 | except BaseException as e: 89 | return None, 0 90 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 91 | 92 | try: 93 | received_data = pickle.loads(received_data) 94 | except BaseException as e: 95 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 96 | return None, 0 97 | 98 | return received_data, 1 99 | 100 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 101 | print("Socket Created.\n") 102 | 103 | try: 104 | soc.connect(("localhost", 10000)) 105 | print("Successful Connection to the Server.\n") 106 | except BaseException as e: 107 | print("Error Connecting to the Server: {msg}".format(msg=e)) 108 | soc.close() 109 | print("Socket Closed.") 110 | 111 | subject = "echo" 112 | NN_instance = None 113 | Client_ID = "Client_2" 114 | test_loss = 10 115 | 116 | n_epochs = 1 117 | train_losses = [] 118 | train_counter = [] 119 | test_losses = [] 120 | 121 | while True: 122 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 123 | data_byte = pickle.dumps(data_client) 124 | 125 | print("Sending the Model to the Server.\n") 126 | soc.sendall(data_byte) 127 | 128 | 129 | print("Receiving Reply from the Server.") 130 | received_data, status = recv(soc=soc, 131 | buffer_size=100000, 132 | recv_timeout=100) 133 | if status == 0: 134 | print("Nothing Received from the Server.") 135 | break 136 | else: 137 | print(received_data, end="\n\n") 138 | 139 | subject = received_data["subject"] 140 | if subject == "model": 141 | ID = received_data["ID"] 142 | NN_instance = received_data["data"] 143 | time_struct = time.gmtime() 144 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 145 | model_path = os.path.join(Directory, "Global models") 146 | Path(model_path).mkdir(parents=True, exist_ok=True) 147 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 148 | print("Received model saved in {path}".format(path=model_path)) 149 | 150 | elif subject == "done": 151 | print("The server said the model is trained successfully and no need for further updates its parameters.") 152 | subject = "end" 153 | NN_instance = None 154 | 155 | 156 | 157 | elif subject == "end": 158 | 159 | print("Received completed model from server.") 160 | ID = received_data["ID"] 161 | Completed_NN_instance = received_data["data"] 162 | time_struct = time.gmtime() 163 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 164 | model_name = "Completed_model" 165 | model_path = os.path.join(Directory, model_name) 166 | Path(model_path).mkdir(parents=True, exist_ok=True) 167 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 168 | print("Completed model saved in {path}".format(path=model_path)) 169 | break 170 | else: 171 | print("Unrecognized message type.") 172 | break 173 | 174 | 175 | subject = "model" 176 | 177 | 178 | 179 | 180 | 181 | batch_size_train = 1000 182 | batch_size_test = 1000 183 | learning_rate = 0.01 184 | momentum = 0.5 185 | log_interval = 10 186 | 187 | #random_seed = 1 188 | #torch.backends.cudnn.enabled = False 189 | #torch.manual_seed(random_seed) 190 | 191 | train_loader = torch.utils.data.DataLoader( 192 | torchvision.datasets.MNIST('/files/', train=True, download=True, 193 | transform=torchvision.transforms.Compose([ 194 | torchvision.transforms.ToTensor(), 195 | torchvision.transforms.Normalize( 196 | (0.1307,), (0.3081,)) 197 | ])), 198 | batch_size=batch_size_train, shuffle=True) 199 | test_loader = torch.utils.data.DataLoader( 200 | torchvision.datasets.MNIST('/files/', train=False, download=True, 201 | transform=torchvision.transforms.Compose([ 202 | torchvision.transforms.ToTensor(), 203 | torchvision.transforms.Normalize( 204 | (0.1307,), (0.3081,)) 205 | ])), 206 | batch_size=batch_size_test, shuffle=True) 207 | 208 | 209 | 210 | 211 | 212 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 213 | 214 | 215 | 216 | examples = enumerate(test_loader) 217 | batch_idx, (example_data, example_targets) = next(examples) 218 | 219 | 220 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 221 | momentum=momentum) 222 | 223 | 224 | 225 | if ID == f"{Client_ID}_initial": 226 | 227 | test_loss = test(NN_instance) 228 | train(n_epochs, NN_instance) 229 | n_epochs += 1 230 | 231 | test_loss = test(NN_instance) 232 | 233 | else: 234 | 235 | #for epoch in range(1, n_epochs + 1): 236 | train(n_epochs, NN_instance) 237 | n_epochs += 1 238 | test_loss = test(NN_instance) 239 | 240 | time_struct = time.gmtime() 241 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 242 | model_path = os.path.join(Directory, "Trained local models") 243 | Path(model_path).mkdir(parents=True, exist_ok=True) 244 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 245 | print("Trained local model saved in {path}".format(path=model_path)) 246 | 247 | #complete_model = Net() 248 | 249 | 250 | #model_name = "Completed_model" 251 | #model_path = os.path.join(Directory, model_name) 252 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 253 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 254 | 255 | #print(train_counter) 256 | #print(test_counter) 257 | #print(train_losses) 258 | #print(test_losses) 259 | 260 | plt.plot(train_counter, train_losses, color='blue') 261 | plt.scatter(test_counter, test_losses, color='red') 262 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 263 | plt.xlabel('number of training examples seen') 264 | plt.ylabel('negative log likelihood loss') 265 | plt.title('Client_2 Test loss.') 266 | plt.show() 267 | 268 | soc.close() 269 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_2_fixed_e.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset 10 | import torchvision.transforms as transforms 11 | 12 | from mpl_toolkits.mplot3d import Axes3D 13 | import matplotlib.pyplot as plt 14 | import time 15 | import os 16 | import numpy as np 17 | from pathlib import Path 18 | 19 | 20 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 21 | 22 | #torch.manual_seed(446) 23 | #np.random.seed(446) 24 | 25 | 26 | class Net(nn.Module): 27 | def __init__(self): 28 | super(Net, self).__init__() 29 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 30 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 31 | self.conv2_drop = nn.Dropout2d() 32 | self.fc1 = nn.Linear(320, 50) 33 | self.fc2 = nn.Linear(50, 10) 34 | 35 | def forward(self, x): 36 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 37 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 38 | x = x.view(-1, 320) 39 | x = F.relu(self.fc1(x)) 40 | x = F.dropout(x, training=self.training) 41 | x = self.fc2(x) 42 | return F.log_softmax(x) 43 | 44 | def train(epoch, model): 45 | 46 | for batch_idx, (data, target) in enumerate(train_loader): 47 | optimizer.zero_grad() 48 | output = model(data) 49 | loss = F.nll_loss(output, target) 50 | loss.backward() 51 | optimizer.step() 52 | if batch_idx % log_interval == 0: 53 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 54 | train_losses.append(loss.item()) 55 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 56 | 57 | #torch.save(network.state_dict(), '/results/model.pth') 58 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 59 | 60 | def test(model): 61 | model.eval() 62 | test_loss = 0 63 | correct = 0 64 | with torch.no_grad(): 65 | for data, target in test_loader: 66 | #print(data) 67 | output = model(data) 68 | test_loss += F.nll_loss(output, target, size_average=False).item() 69 | pred = output.data.max(1, keepdim=True)[1] 70 | correct += pred.eq(target.data.view_as(pred)).sum() 71 | test_loss /= len(test_loader.dataset) 72 | test_losses.append(test_loss) 73 | 74 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 75 | return test_loss 76 | 77 | 78 | 79 | def recv(soc, buffer_size=4096, recv_timeout=100): 80 | received_data = b"" 81 | while str(received_data)[-2] != '.': 82 | try: 83 | soc.settimeout(recv_timeout) 84 | received_data += soc.recv(buffer_size) 85 | except socket.timeout: 86 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 87 | return None, 0 88 | except BaseException as e: 89 | return None, 0 90 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 91 | 92 | try: 93 | received_data = pickle.loads(received_data) 94 | except BaseException as e: 95 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 96 | return None, 0 97 | 98 | return received_data, 1 99 | 100 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 101 | print("Socket Created.\n") 102 | 103 | try: 104 | soc.connect(("localhost", 10000)) 105 | print("Successful Connection to the Server.\n") 106 | except BaseException as e: 107 | print("Error Connecting to the Server: {msg}".format(msg=e)) 108 | soc.close() 109 | print("Socket Closed.") 110 | 111 | subject = "echo" 112 | NN_instance = None 113 | Client_ID = "Client_2" 114 | test_loss = 10 115 | 116 | n_epochs = 1 117 | train_losses = [] 118 | train_counter = [] 119 | test_losses = [] 120 | 121 | # n_epoch == local training rounds, must be even number 122 | while n_epochs <= 20: 123 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 124 | data_byte = pickle.dumps(data_client) 125 | 126 | print("Sending the Model to the Server.\n") 127 | soc.sendall(data_byte) 128 | 129 | 130 | print("Receiving Reply from the Server.") 131 | received_data, status = recv(soc=soc, 132 | buffer_size=100000, 133 | recv_timeout=100) 134 | if status == 0: 135 | print("Nothing Received from the Server.") 136 | break 137 | else: 138 | print(received_data, end="\n\n") 139 | 140 | subject = received_data["subject"] 141 | if subject == "model": 142 | ID = received_data["ID"] 143 | NN_instance = received_data["data"] 144 | time_struct = time.gmtime() 145 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 146 | model_path = os.path.join(Directory, "Global models") 147 | Path(model_path).mkdir(parents=True, exist_ok=True) 148 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 149 | print("Received model saved in {path}".format(path=model_path)) 150 | 151 | elif subject == "done": 152 | print("The server said the model is trained successfully and no need for further updates its parameters.") 153 | subject = "end" 154 | NN_instance = None 155 | 156 | 157 | 158 | elif subject == "end": 159 | 160 | print("Received completed model from server.") 161 | ID = received_data["ID"] 162 | Completed_NN_instance = received_data["data"] 163 | time_struct = time.gmtime() 164 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 165 | model_name = "Completed_model" 166 | model_path = os.path.join(Directory, model_name) 167 | Path(model_path).mkdir(parents=True, exist_ok=True) 168 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 169 | print("Completed model saved in {path}".format(path=model_path)) 170 | break 171 | else: 172 | print("Unrecognized message type.") 173 | break 174 | 175 | 176 | subject = "model" 177 | 178 | 179 | 180 | 181 | 182 | batch_size_train = 1000 183 | batch_size_test = 1000 184 | learning_rate = 0.01 185 | momentum = 0.5 186 | log_interval = 10 187 | 188 | #random_seed = 1 189 | #torch.backends.cudnn.enabled = False 190 | #torch.manual_seed(random_seed) 191 | 192 | train_loader = torch.utils.data.DataLoader( 193 | torchvision.datasets.MNIST('/files/', train=True, download=True, 194 | transform=torchvision.transforms.Compose([ 195 | torchvision.transforms.ToTensor(), 196 | torchvision.transforms.Normalize( 197 | (0.1307,), (0.3081,)) 198 | ])), 199 | batch_size=batch_size_train) 200 | #, shuffle=True) 201 | test_loader = torch.utils.data.DataLoader( 202 | torchvision.datasets.MNIST('/files/', train=False, download=True, 203 | transform=torchvision.transforms.Compose([ 204 | torchvision.transforms.ToTensor(), 205 | torchvision.transforms.Normalize( 206 | (0.1307,), (0.3081,)) 207 | ])), 208 | batch_size=batch_size_test) 209 | #, shuffle=True) 210 | 211 | 212 | 213 | 214 | 215 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 216 | 217 | 218 | 219 | examples = enumerate(test_loader) 220 | batch_idx, (example_data, example_targets) = next(examples) 221 | 222 | 223 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 224 | momentum=momentum) 225 | 226 | 227 | 228 | if ID == f"{Client_ID}": 229 | 230 | test_loss = test(NN_instance) 231 | train(n_epochs, NN_instance) 232 | n_epochs += 1 233 | 234 | test_loss = test(NN_instance) 235 | 236 | else: 237 | 238 | #for epoch in range(1, n_epochs + 1): 239 | train(n_epochs, NN_instance) 240 | n_epochs += 1 241 | test_loss = test(NN_instance) 242 | 243 | time_struct = time.gmtime() 244 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 245 | model_path = os.path.join(Directory, "Trained local models") 246 | Path(model_path).mkdir(parents=True, exist_ok=True) 247 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 248 | print("Trained local model saved in {path}".format(path=model_path)) 249 | 250 | #complete_model = Net() 251 | 252 | 253 | #model_name = "Completed_model" 254 | #model_path = os.path.join(Directory, model_name) 255 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 256 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 257 | 258 | #print(train_counter) 259 | #print(test_counter) 260 | #print(train_losses) 261 | #print(test_losses) 262 | 263 | plt.plot(train_counter, train_losses, color='blue') 264 | plt.scatter(test_counter, test_losses, color='red') 265 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 266 | plt.xlabel('number of training examples seen') 267 | plt.ylabel('negative log likelihood loss') 268 | plt.title('Client_2 Test loss.') 269 | plt.show() 270 | 271 | soc.close() 272 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_2_fixed_e_NIID.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset,Subset 10 | from sklearn.model_selection import train_test_split 11 | import torchvision.transforms as transforms 12 | 13 | from mpl_toolkits.mplot3d import Axes3D 14 | import matplotlib.pyplot as plt 15 | import time 16 | import os 17 | import numpy as np 18 | from pathlib import Path 19 | 20 | 21 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 22 | 23 | #torch.manual_seed(446) 24 | #np.random.seed(446) 25 | 26 | 27 | class Net(nn.Module): 28 | def __init__(self): 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 31 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 32 | self.conv2_drop = nn.Dropout2d() 33 | self.fc1 = nn.Linear(320, 50) 34 | self.fc2 = nn.Linear(50, 10) 35 | 36 | def forward(self, x): 37 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 38 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 39 | x = x.view(-1, 320) 40 | x = F.relu(self.fc1(x)) 41 | x = F.dropout(x, training=self.training) 42 | x = self.fc2(x) 43 | return F.log_softmax(x) 44 | 45 | def train(epoch, model): 46 | 47 | for batch_idx, (data, target) in enumerate(train_loader): 48 | optimizer.zero_grad() 49 | output = model(data) 50 | loss = F.nll_loss(output, target) 51 | loss.backward() 52 | optimizer.step() 53 | if batch_idx % log_interval == 0: 54 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 55 | train_losses.append(loss.item()) 56 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 57 | 58 | #torch.save(network.state_dict(), '/results/model.pth') 59 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 60 | 61 | def test(model): 62 | model.eval() 63 | test_loss = 0 64 | correct = 0 65 | with torch.no_grad(): 66 | for data, target in test_loader: 67 | #print(data) 68 | output = model(data) 69 | test_loss += F.nll_loss(output, target, size_average=False).item() 70 | pred = output.data.max(1, keepdim=True)[1] 71 | correct += pred.eq(target.data.view_as(pred)).sum() 72 | test_loss /= len(test_loader.dataset) 73 | test_losses.append(test_loss) 74 | 75 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 76 | return test_loss 77 | 78 | def train_NIID_dataset(dataset): 79 | idx = [] 80 | limit = 0 81 | for i in range(10): 82 | if i < 5: 83 | for x in range(len(dataset.targets)): 84 | if dataset.targets[x] == i: 85 | idx.append(x) 86 | limit += 1 87 | if limit == 3000: 88 | break 89 | limit = 0 90 | print(dataset.targets[x]) 91 | print(len(idx)) 92 | 93 | 94 | else: 95 | for x in range(len(dataset.targets)): 96 | if dataset.targets[x] == i: 97 | idx.append(x) 98 | limit += 1 99 | if limit == 5000: 100 | break 101 | limit = 0 102 | print(dataset.targets[x]) 103 | print(len(idx)) 104 | 105 | split_datasets = {} 106 | split_datasets = Subset(dataset, idx) 107 | return split_datasets 108 | 109 | 110 | def recv(soc, buffer_size=4096, recv_timeout=100): 111 | received_data = b"" 112 | while str(received_data)[-2] != '.': 113 | try: 114 | soc.settimeout(recv_timeout) 115 | received_data += soc.recv(buffer_size) 116 | except socket.timeout: 117 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 118 | return None, 0 119 | except BaseException as e: 120 | return None, 0 121 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 122 | 123 | try: 124 | received_data = pickle.loads(received_data) 125 | except BaseException as e: 126 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 127 | return None, 0 128 | 129 | return received_data, 1 130 | 131 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 132 | print("Socket Created.\n") 133 | 134 | try: 135 | soc.connect(("localhost", 10000)) 136 | print("Successful Connection to the Server.\n") 137 | except BaseException as e: 138 | print("Error Connecting to the Server: {msg}".format(msg=e)) 139 | soc.close() 140 | print("Socket Closed.") 141 | 142 | subject = "echo" 143 | NN_instance = None 144 | Client_ID = "Client_2" 145 | test_loss = 10 146 | 147 | n_epochs = 1 148 | train_losses = [] 149 | train_counter = [] 150 | test_losses = [] 151 | 152 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 153 | transform=torchvision.transforms.Compose([ 154 | torchvision.transforms.ToTensor(), 155 | torchvision.transforms.Normalize( 156 | (0.1307,), (0.3081,)) 157 | ])) 158 | 159 | datasets = train_NIID_dataset(dataset) 160 | 161 | # n_epoch == local training rounds, must be even number 162 | while n_epochs <= 20: 163 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 164 | data_byte = pickle.dumps(data_client) 165 | 166 | print("Sending the Model to the Server.\n") 167 | soc.sendall(data_byte) 168 | 169 | 170 | print("Receiving Reply from the Server.") 171 | received_data, status = recv(soc=soc, 172 | buffer_size=100000, 173 | recv_timeout=100) 174 | if status == 0: 175 | print("Nothing Received from the Server.") 176 | break 177 | else: 178 | print(received_data, end="\n\n") 179 | 180 | subject = received_data["subject"] 181 | if subject == "model": 182 | ID = received_data["ID"] 183 | NN_instance = received_data["data"] 184 | time_struct = time.gmtime() 185 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 186 | model_path = os.path.join(Directory, "Global models") 187 | Path(model_path).mkdir(parents=True, exist_ok=True) 188 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 189 | print("Received model saved in {path}".format(path=model_path)) 190 | 191 | elif subject == "done": 192 | print("The server said the model is trained successfully and no need for further updates its parameters.") 193 | subject = "end" 194 | NN_instance = None 195 | 196 | 197 | 198 | elif subject == "end": 199 | 200 | print("Received completed model from server.") 201 | ID = received_data["ID"] 202 | Completed_NN_instance = received_data["data"] 203 | time_struct = time.gmtime() 204 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 205 | model_name = "Completed_model" 206 | model_path = os.path.join(Directory, model_name) 207 | Path(model_path).mkdir(parents=True, exist_ok=True) 208 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 209 | print("Completed model saved in {path}".format(path=model_path)) 210 | break 211 | else: 212 | print("Unrecognized message type.") 213 | break 214 | 215 | 216 | subject = "model" 217 | 218 | 219 | 220 | 221 | 222 | batch_size_train = 1000 223 | batch_size_test = 1000 224 | learning_rate = 0.01 225 | momentum = 0.5 226 | log_interval = 10 227 | 228 | #random_seed = 1 229 | #torch.backends.cudnn.enabled = False 230 | #torch.manual_seed(random_seed) 231 | 232 | train_loader = torch.utils.data.DataLoader( 233 | datasets, 234 | batch_size=batch_size_train, shuffle=True) 235 | 236 | test_loader = torch.utils.data.DataLoader( 237 | torchvision.datasets.MNIST('/files/', train=False, download=True, 238 | transform=torchvision.transforms.Compose([ 239 | torchvision.transforms.ToTensor(), 240 | torchvision.transforms.Normalize( 241 | (0.1307,), (0.3081,)) 242 | ])), 243 | batch_size=batch_size_test, shuffle=True) 244 | 245 | 246 | 247 | 248 | 249 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 250 | 251 | 252 | 253 | examples = enumerate(test_loader) 254 | batch_idx, (example_data, example_targets) = next(examples) 255 | 256 | 257 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 258 | momentum=momentum) 259 | 260 | 261 | 262 | if ID == f"{Client_ID}": 263 | 264 | test_loss = test(NN_instance) 265 | train(n_epochs, NN_instance) 266 | n_epochs += 1 267 | 268 | test_loss = test(NN_instance) 269 | 270 | else: 271 | 272 | #for epoch in range(1, n_epochs + 1): 273 | train(n_epochs, NN_instance) 274 | n_epochs += 1 275 | test_loss = test(NN_instance) 276 | 277 | time_struct = time.gmtime() 278 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 279 | model_path = os.path.join(Directory, "Trained local models") 280 | Path(model_path).mkdir(parents=True, exist_ok=True) 281 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 282 | print("Trained local model saved in {path}".format(path=model_path)) 283 | 284 | #complete_model = Net() 285 | 286 | 287 | #model_name = "Completed_model" 288 | #model_path = os.path.join(Directory, model_name) 289 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 290 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 291 | 292 | #print(train_counter) 293 | #print(test_counter) 294 | #print(train_losses) 295 | #print(test_losses) 296 | 297 | plt.plot(train_counter, train_losses, color='blue') 298 | plt.scatter(test_counter, test_losses, color='red') 299 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 300 | plt.xlabel('number of training examples seen') 301 | plt.ylabel('negative log likelihood loss') 302 | plt.title('Client_2 Test loss.') 303 | plt.show() 304 | 305 | soc.close() 306 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_2_fixed_e_SORTED.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset,Subset 10 | from sklearn.model_selection import train_test_split 11 | import torchvision.transforms as transforms 12 | 13 | from mpl_toolkits.mplot3d import Axes3D 14 | import matplotlib.pyplot as plt 15 | import time 16 | import os 17 | import numpy as np 18 | from pathlib import Path 19 | 20 | 21 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 22 | 23 | #torch.manual_seed(446) 24 | #np.random.seed(446) 25 | 26 | 27 | class Net(nn.Module): 28 | def __init__(self): 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 31 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 32 | self.conv2_drop = nn.Dropout2d() 33 | self.fc1 = nn.Linear(320, 50) 34 | self.fc2 = nn.Linear(50, 10) 35 | 36 | def forward(self, x): 37 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 38 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 39 | x = x.view(-1, 320) 40 | x = F.relu(self.fc1(x)) 41 | x = F.dropout(x, training=self.training) 42 | x = self.fc2(x) 43 | return F.log_softmax(x) 44 | 45 | def train(epoch, model): 46 | 47 | for batch_idx, (data, target) in enumerate(train_loader): 48 | optimizer.zero_grad() 49 | output = model(data) 50 | loss = F.nll_loss(output, target) 51 | loss.backward() 52 | optimizer.step() 53 | if batch_idx % log_interval == 0: 54 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 55 | train_losses.append(loss.item()) 56 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 57 | 58 | #torch.save(network.state_dict(), '/results/model.pth') 59 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 60 | 61 | def test(model): 62 | model.eval() 63 | test_loss = 0 64 | correct = 0 65 | with torch.no_grad(): 66 | for data, target in test_loader: 67 | #print(data) 68 | output = model(data) 69 | test_loss += F.nll_loss(output, target, size_average=False).item() 70 | pred = output.data.max(1, keepdim=True)[1] 71 | correct += pred.eq(target.data.view_as(pred)).sum() 72 | test_loss /= len(test_loader.dataset) 73 | test_losses.append(test_loss) 74 | 75 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 76 | return test_loss 77 | 78 | def train_val_dataset(dataset, val_split=0.5): 79 | idx = [] 80 | for i in range(10): 81 | for x in range(len(dataset.targets)): 82 | if dataset.targets[x] == i: 83 | idx.append(x) 84 | 85 | 86 | train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 87 | split_datasets = {} 88 | #split_datasets = Subset(dataset, idx) 89 | 90 | 91 | split_datasets['train_1'] = Subset(dataset, train_idx) 92 | split_datasets['train_2'] = Subset(dataset, val_idx) 93 | return split_datasets 94 | 95 | 96 | def recv(soc, buffer_size=4096, recv_timeout=100): 97 | received_data = b"" 98 | while str(received_data)[-2] != '.': 99 | try: 100 | soc.settimeout(recv_timeout) 101 | received_data += soc.recv(buffer_size) 102 | except socket.timeout: 103 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 104 | return None, 0 105 | except BaseException as e: 106 | return None, 0 107 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 108 | 109 | try: 110 | received_data = pickle.loads(received_data) 111 | except BaseException as e: 112 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 113 | return None, 0 114 | 115 | return received_data, 1 116 | 117 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 118 | print("Socket Created.\n") 119 | 120 | try: 121 | soc.connect(("localhost", 10000)) 122 | print("Successful Connection to the Server.\n") 123 | except BaseException as e: 124 | print("Error Connecting to the Server: {msg}".format(msg=e)) 125 | soc.close() 126 | print("Socket Closed.") 127 | 128 | subject = "echo" 129 | NN_instance = None 130 | Client_ID = "Client_2" 131 | test_loss = 10 132 | 133 | n_epochs = 1 134 | train_losses = [] 135 | train_counter = [] 136 | test_losses = [] 137 | 138 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 139 | transform=torchvision.transforms.Compose([ 140 | torchvision.transforms.ToTensor(), 141 | torchvision.transforms.Normalize( 142 | (0.1307,), (0.3081,)) 143 | ])) 144 | 145 | datasets = train_val_dataset(dataset) 146 | 147 | # n_epoch == local training rounds, must be even number 148 | while n_epochs <= 20: 149 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 150 | data_byte = pickle.dumps(data_client) 151 | 152 | print("Sending the Model to the Server.\n") 153 | soc.sendall(data_byte) 154 | 155 | 156 | print("Receiving Reply from the Server.") 157 | received_data, status = recv(soc=soc, 158 | buffer_size=100000, 159 | recv_timeout=100) 160 | if status == 0: 161 | print("Nothing Received from the Server.") 162 | break 163 | else: 164 | print(received_data, end="\n\n") 165 | 166 | subject = received_data["subject"] 167 | if subject == "model": 168 | ID = received_data["ID"] 169 | NN_instance = received_data["data"] 170 | time_struct = time.gmtime() 171 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 172 | model_path = os.path.join(Directory, "Global models") 173 | Path(model_path).mkdir(parents=True, exist_ok=True) 174 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 175 | print("Received model saved in {path}".format(path=model_path)) 176 | 177 | elif subject == "done": 178 | print("The server said the model is trained successfully and no need for further updates its parameters.") 179 | subject = "end" 180 | NN_instance = None 181 | 182 | 183 | 184 | elif subject == "end": 185 | 186 | print("Received completed model from server.") 187 | ID = received_data["ID"] 188 | Completed_NN_instance = received_data["data"] 189 | time_struct = time.gmtime() 190 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 191 | model_name = "Completed_model" 192 | model_path = os.path.join(Directory, model_name) 193 | Path(model_path).mkdir(parents=True, exist_ok=True) 194 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 195 | print("Completed model saved in {path}".format(path=model_path)) 196 | break 197 | else: 198 | print("Unrecognized message type.") 199 | break 200 | 201 | 202 | subject = "model" 203 | 204 | 205 | 206 | 207 | 208 | batch_size_train = 1000 209 | batch_size_test = 1000 210 | learning_rate = 0.01 211 | momentum = 0.5 212 | log_interval = 10 213 | 214 | #random_seed = 1 215 | #torch.backends.cudnn.enabled = False 216 | #torch.manual_seed(random_seed) 217 | 218 | train_loader = torch.utils.data.DataLoader( 219 | datasets['train_2'], 220 | batch_size=batch_size_train, shuffle=True) 221 | 222 | test_loader = torch.utils.data.DataLoader( 223 | torchvision.datasets.MNIST('/files/', train=False, download=True, 224 | transform=torchvision.transforms.Compose([ 225 | torchvision.transforms.ToTensor(), 226 | torchvision.transforms.Normalize( 227 | (0.1307,), (0.3081,)) 228 | ])), 229 | batch_size=batch_size_test, shuffle=True) 230 | 231 | 232 | 233 | 234 | 235 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 236 | 237 | 238 | 239 | examples = enumerate(test_loader) 240 | batch_idx, (example_data, example_targets) = next(examples) 241 | 242 | 243 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 244 | momentum=momentum) 245 | 246 | 247 | 248 | if ID == f"{Client_ID}": 249 | 250 | test_loss = test(NN_instance) 251 | train(n_epochs, NN_instance) 252 | n_epochs += 1 253 | 254 | test_loss = test(NN_instance) 255 | 256 | else: 257 | 258 | #for epoch in range(1, n_epochs + 1): 259 | train(n_epochs, NN_instance) 260 | n_epochs += 1 261 | test_loss = test(NN_instance) 262 | 263 | time_struct = time.gmtime() 264 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 265 | model_path = os.path.join(Directory, "Trained local models") 266 | Path(model_path).mkdir(parents=True, exist_ok=True) 267 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 268 | print("Trained local model saved in {path}".format(path=model_path)) 269 | 270 | #complete_model = Net() 271 | 272 | 273 | #model_name = "Completed_model" 274 | #model_path = os.path.join(Directory, model_name) 275 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 276 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 277 | 278 | #print(train_counter) 279 | #print(test_counter) 280 | #print(train_losses) 281 | #print(test_losses) 282 | 283 | plt.plot(train_counter, train_losses, color='blue') 284 | plt.scatter(test_counter, test_losses, color='red') 285 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 286 | plt.xlabel('number of training examples seen') 287 | plt.ylabel('negative log likelihood loss') 288 | plt.title('Client_2 Test loss.') 289 | plt.show() 290 | 291 | soc.close() 292 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_2_fixed_e_SORTED_60000.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torchvision 5 | import torch.nn as nn 6 | import torch.optim as optim 7 | import torch.nn.functional as F 8 | 9 | from torch.utils.data import DataLoader,Dataset,Subset 10 | from sklearn.model_selection import train_test_split 11 | import torchvision.transforms as transforms 12 | 13 | from mpl_toolkits.mplot3d import Axes3D 14 | import matplotlib.pyplot as plt 15 | import time 16 | import os 17 | import numpy as np 18 | from pathlib import Path 19 | 20 | 21 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\MNIST\\Models\\Client_2" 22 | 23 | #torch.manual_seed(446) 24 | #np.random.seed(446) 25 | 26 | 27 | class Net(nn.Module): 28 | def __init__(self): 29 | super(Net, self).__init__() 30 | self.conv1 = nn.Conv2d(1, 10, kernel_size=5) 31 | self.conv2 = nn.Conv2d(10, 20, kernel_size=5) 32 | self.conv2_drop = nn.Dropout2d() 33 | self.fc1 = nn.Linear(320, 50) 34 | self.fc2 = nn.Linear(50, 10) 35 | 36 | def forward(self, x): 37 | x = F.relu(F.max_pool2d(self.conv1(x), 2)) 38 | x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2)) 39 | x = x.view(-1, 320) 40 | x = F.relu(self.fc1(x)) 41 | x = F.dropout(x, training=self.training) 42 | x = self.fc2(x) 43 | return F.log_softmax(x) 44 | 45 | def train(epoch, model): 46 | 47 | for batch_idx, (data, target) in enumerate(train_loader): 48 | optimizer.zero_grad() 49 | output = model(data) 50 | loss = F.nll_loss(output, target) 51 | loss.backward() 52 | optimizer.step() 53 | if batch_idx % log_interval == 0: 54 | print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) 55 | train_losses.append(loss.item()) 56 | train_counter.append((batch_idx*1000) + ((epoch-1)*len(train_loader.dataset))) 57 | 58 | #torch.save(network.state_dict(), '/results/model.pth') 59 | #torch.save(optimizer.state_dict(), '/results/optimizer.pth') 60 | 61 | def test(model): 62 | model.eval() 63 | test_loss = 0 64 | correct = 0 65 | with torch.no_grad(): 66 | for data, target in test_loader: 67 | #print(data) 68 | output = model(data) 69 | test_loss += F.nll_loss(output, target, size_average=False).item() 70 | pred = output.data.max(1, keepdim=True)[1] 71 | correct += pred.eq(target.data.view_as(pred)).sum() 72 | test_loss /= len(test_loader.dataset) 73 | test_losses.append(test_loss) 74 | 75 | print('\nTest set: Avg. loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(test_loss, correct, len(test_loader.dataset), 100. * correct / len(test_loader.dataset))) 76 | return test_loss 77 | 78 | def train_val_dataset(dataset, val_split=0.5): 79 | idx = [] 80 | for i in range(10): 81 | for x in range(len(dataset.targets)): 82 | if dataset.targets[x] == i: 83 | idx.append(x) 84 | 85 | 86 | #train_idx, val_idx = train_test_split(idx, test_size = val_split, shuffle=False) 87 | split_datasets = {} 88 | split_datasets = Subset(dataset, idx) 89 | 90 | 91 | #split_datasets['train_1'] = Subset(dataset, train_idx) 92 | #split_datasets['train_2'] = Subset(dataset, val_idx) 93 | return split_datasets 94 | 95 | 96 | def recv(soc, buffer_size=4096, recv_timeout=100): 97 | received_data = b"" 98 | while str(received_data)[-2] != '.': 99 | try: 100 | soc.settimeout(recv_timeout) 101 | received_data += soc.recv(buffer_size) 102 | except socket.timeout: 103 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 104 | return None, 0 105 | except BaseException as e: 106 | return None, 0 107 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 108 | 109 | try: 110 | received_data = pickle.loads(received_data) 111 | except BaseException as e: 112 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 113 | return None, 0 114 | 115 | return received_data, 1 116 | 117 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 118 | print("Socket Created.\n") 119 | 120 | try: 121 | soc.connect(("localhost", 10000)) 122 | print("Successful Connection to the Server.\n") 123 | except BaseException as e: 124 | print("Error Connecting to the Server: {msg}".format(msg=e)) 125 | soc.close() 126 | print("Socket Closed.") 127 | 128 | subject = "echo" 129 | NN_instance = None 130 | Client_ID = "Client_2" 131 | test_loss = 10 132 | 133 | n_epochs = 1 134 | train_losses = [] 135 | train_counter = [] 136 | test_losses = [] 137 | 138 | dataset = torchvision.datasets.MNIST('/files/', train=True, download=True, 139 | transform=torchvision.transforms.Compose([ 140 | torchvision.transforms.ToTensor(), 141 | torchvision.transforms.Normalize( 142 | (0.1307,), (0.3081,)) 143 | ])) 144 | 145 | datasets = train_val_dataset(dataset) 146 | 147 | # n_epoch == local training rounds, must be even number 148 | while n_epochs <= 20: 149 | data_client = {"ID": Client_ID, "subject": subject, "data": NN_instance, "test_loss": test_loss} 150 | data_byte = pickle.dumps(data_client) 151 | 152 | print("Sending the Model to the Server.\n") 153 | soc.sendall(data_byte) 154 | 155 | 156 | print("Receiving Reply from the Server.") 157 | received_data, status = recv(soc=soc, 158 | buffer_size=100000, 159 | recv_timeout=100) 160 | if status == 0: 161 | print("Nothing Received from the Server.") 162 | break 163 | else: 164 | print(received_data, end="\n\n") 165 | 166 | subject = received_data["subject"] 167 | if subject == "model": 168 | ID = received_data["ID"] 169 | NN_instance = received_data["data"] 170 | time_struct = time.gmtime() 171 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 172 | model_path = os.path.join(Directory, "Global models") 173 | Path(model_path).mkdir(parents=True, exist_ok=True) 174 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 175 | print("Received model saved in {path}".format(path=model_path)) 176 | 177 | elif subject == "done": 178 | print("The server said the model is trained successfully and no need for further updates its parameters.") 179 | subject = "end" 180 | NN_instance = None 181 | 182 | 183 | 184 | elif subject == "end": 185 | 186 | print("Received completed model from server.") 187 | ID = received_data["ID"] 188 | Completed_NN_instance = received_data["data"] 189 | time_struct = time.gmtime() 190 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 191 | model_name = "Completed_model" 192 | model_path = os.path.join(Directory, model_name) 193 | Path(model_path).mkdir(parents=True, exist_ok=True) 194 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 195 | print("Completed model saved in {path}".format(path=model_path)) 196 | break 197 | else: 198 | print("Unrecognized message type.") 199 | break 200 | 201 | 202 | subject = "model" 203 | 204 | 205 | 206 | 207 | 208 | batch_size_train = 1000 209 | batch_size_test = 1000 210 | learning_rate = 0.01 211 | momentum = 0.5 212 | log_interval = 10 213 | 214 | #random_seed = 1 215 | #torch.backends.cudnn.enabled = False 216 | #torch.manual_seed(random_seed) 217 | 218 | train_loader = torch.utils.data.DataLoader( 219 | #datasets['train_2'], 220 | datasets, 221 | batch_size=batch_size_train, shuffle=False) 222 | 223 | test_loader = torch.utils.data.DataLoader( 224 | torchvision.datasets.MNIST('/files/', train=False, download=True, 225 | transform=torchvision.transforms.Compose([ 226 | torchvision.transforms.ToTensor(), 227 | torchvision.transforms.Normalize( 228 | (0.1307,), (0.3081,)) 229 | ])), 230 | batch_size=batch_size_test, shuffle=True) 231 | 232 | 233 | 234 | 235 | 236 | test_counter = [i*len(train_loader.dataset) for i in range(n_epochs + 1)] 237 | 238 | 239 | 240 | examples = enumerate(test_loader) 241 | batch_idx, (example_data, example_targets) = next(examples) 242 | 243 | 244 | optimizer = optim.SGD(NN_instance.parameters(), lr=learning_rate, 245 | momentum=momentum) 246 | 247 | 248 | 249 | if ID == f"{Client_ID}": 250 | 251 | test_loss = test(NN_instance) 252 | train(n_epochs, NN_instance) 253 | n_epochs += 1 254 | 255 | test_loss = test(NN_instance) 256 | 257 | else: 258 | 259 | #for epoch in range(1, n_epochs + 1): 260 | train(n_epochs, NN_instance) 261 | n_epochs += 1 262 | test_loss = test(NN_instance) 263 | 264 | time_struct = time.gmtime() 265 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 266 | model_path = os.path.join(Directory, "Trained local models") 267 | Path(model_path).mkdir(parents=True, exist_ok=True) 268 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 269 | print("Trained local model saved in {path}".format(path=model_path)) 270 | 271 | #complete_model = Net() 272 | 273 | 274 | #model_name = "Completed_model" 275 | #model_path = os.path.join(Directory, model_name) 276 | #complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 277 | #print("Completed model loaded: {model_name}.".format(model_name=model_name)) 278 | 279 | #print(train_counter) 280 | #print(test_counter) 281 | #print(train_losses) 282 | #print(test_losses) 283 | 284 | plt.plot(train_counter, train_losses, color='blue') 285 | plt.scatter(test_counter, test_losses, color='red') 286 | plt.legend(['Train Loss', 'Test Loss'], loc='upper right') 287 | plt.xlabel('number of training examples seen') 288 | plt.ylabel('negative log likelihood loss') 289 | plt.title('Client_2 Test loss.') 290 | plt.show() 291 | 292 | soc.close() 293 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /MNIST/client_3.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import torch 4 | import torch.nn as nn 5 | import torch.nn.functional as F 6 | 7 | from mpl_toolkits.mplot3d import Axes3D 8 | import matplotlib.pyplot as plt 9 | import time 10 | import os 11 | import numpy as np 12 | from pathlib import Path 13 | 14 | 15 | Directory = "C:\\Users\\z5278080\\Fritz_FL_demo\\New folder\\Models\\Client_3" 16 | 17 | #torch.manual_seed(446) 18 | #np.random.seed(446) 19 | 20 | d = 1 21 | n = 200 22 | X = torch.rand(n,d) 23 | y = 4 * torch.sin(np.pi * X) * torch.cos(6*np.pi*X**2) 24 | 25 | 26 | step_size = 0.05 27 | n_epochs = 1000 28 | 29 | 30 | def recv(soc, buffer_size=4096, recv_timeout=100): 31 | received_data = b"" 32 | while str(received_data)[-2] != '.': 33 | try: 34 | soc.settimeout(recv_timeout) 35 | received_data += soc.recv(buffer_size) 36 | except socket.timeout: 37 | print("A socket.timeout exception occurred because the server did not send any data for {recv_timeout} seconds. There may be an error or the model may be trained successfully.".format(recv_timeout=recv_timeout)) 38 | return None, 0 39 | except BaseException as e: 40 | return None, 0 41 | print("An error occurred while receiving data from the server {msg}.".format(msg=e)) 42 | 43 | try: 44 | received_data = pickle.loads(received_data) 45 | except BaseException as e: 46 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 47 | return None, 0 48 | 49 | return received_data, 1 50 | 51 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 52 | print("Socket Created.\n") 53 | 54 | try: 55 | soc.connect(("localhost", 10000)) 56 | print("Successful Connection to the Server.\n") 57 | except BaseException as e: 58 | print("Error Connecting to the Server: {msg}".format(msg=e)) 59 | soc.close() 60 | print("Socket Closed.") 61 | 62 | subject = "echo" 63 | NN_instance = None 64 | Client_ID = "Client_3" 65 | #best_sol_idx = -1 66 | 67 | while True: 68 | data = {"ID": Client_ID, "subject": subject, "data": NN_instance} 69 | data_byte = pickle.dumps(data) 70 | 71 | print("Sending the Model to the Server.\n") 72 | soc.sendall(data_byte) 73 | #if subject == "model": 74 | #print("Client's Message Subject is {model}.".format(model=NN_instance.state_dict())) 75 | 76 | print("Receiving Reply from the Server.") 77 | received_data, status = recv(soc=soc, 78 | buffer_size=4096, 79 | recv_timeout=100) 80 | if status == 0: 81 | print("Nothing Received from the Server.") 82 | break 83 | else: 84 | print(received_data, end="\n\n") 85 | 86 | subject = received_data["subject"] 87 | if subject == "model": 88 | ID = received_data["ID"] 89 | NN_instance = received_data["data"] 90 | time_struct = time.gmtime() 91 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 92 | model_path = os.path.join(Directory, "Global models") 93 | Path(model_path).mkdir(parents=True, exist_ok=True) 94 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 95 | print("Received model saved in {path}".format(path=model_path)) 96 | elif subject == "done": 97 | 98 | print("The server said the model is trained successfully and no need for further updates its parameters.") 99 | ID = received_data["ID"] 100 | Completed_NN_instance = received_data["data"] 101 | time_struct = time.gmtime() 102 | #model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID=ID, year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 103 | model_name = "Completed_model" 104 | model_path = os.path.join(Directory, model_name) 105 | Path(model_path).mkdir(parents=True, exist_ok=True) 106 | torch.save(Completed_NN_instance.state_dict(), os.path.join(model_path, model_name)) 107 | print("Completed model saved in {path}".format(path=model_path)) 108 | break 109 | else: 110 | print("Unrecognized message type.") 111 | break 112 | 113 | 114 | #ga_instance = prepare_GA(GANN_instance) 115 | 116 | #ga_instance.run() 117 | 118 | #ga_instance.plot_result() 119 | 120 | subject = "model" 121 | #best_sol_idx = ga_instance.best_solution()[2] 122 | optim = torch.optim.SGD(NN_instance.parameters(), lr=step_size) 123 | #print('iter,\tloss') 124 | loss_func = nn.MSELoss() 125 | running_loss = [] 126 | for i in range(n_epochs): 127 | y_hat = NN_instance(X) 128 | loss = loss_func(y_hat, y) 129 | optim.zero_grad() 130 | loss.backward() 131 | optim.step() 132 | running_loss.append(loss.detach().numpy()) 133 | 134 | print("Epoch: {epoch}, Loss: {loss}".format(loss=loss, epoch=n_epochs)) 135 | #print("Weight: {parameters}".format(parameters=NN_instance.parameters())) 136 | #epochs = range(1,1001) 137 | time_struct = time.gmtime() 138 | model_name = "{ID}_{day}_{month}_{year}_{hour}_{minute}_{second}.pth".format(ID="Trained", year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 139 | model_path = os.path.join(Directory, "Trained local models") 140 | Path(model_path).mkdir(parents=True, exist_ok=True) 141 | torch.save(NN_instance.state_dict(), os.path.join(model_path, model_name)) 142 | print("Trained local model saved in {path}".format(path=model_path)) 143 | #plt.plot(epochs, running_loss, 'g', label='Training loss') 144 | #plt.plot(n_epochs, loss_val, 'b', label='validation loss') 145 | #plt.title('Training loss_Client_1') 146 | #plt.xlabel('Epochs') 147 | #plt.ylabel('Loss') 148 | #plt.legend() 149 | #plt.show() 150 | 151 | 152 | 153 | #updates = {"subject": subject, "data": NN_instance} 154 | #data_byte = pickle.dumps(updates) 155 | 156 | #print("Sending the Model to the Server.\n") 157 | #soc.sendall(data_byte) 158 | 159 | 160 | #predictions = NN_instance(X) 161 | #print(predictions) 162 | n_hidden_1 = 32 163 | n_hidden_2 = 32 164 | d_out = 1 165 | complete_model = nn.Sequential( 166 | nn.Linear(d, n_hidden_1), 167 | nn.Tanh(), 168 | nn.Linear(n_hidden_1, n_hidden_2), 169 | nn.Tanh(), 170 | nn.Linear(n_hidden_2, d_out) 171 | ) 172 | 173 | 174 | model_name = "Completed_model" 175 | model_path = os.path.join(Directory, model_name) 176 | complete_model.load_state_dict(torch.load(os.path.join(model_path, model_name))) 177 | print("Completed model loaded: {model_name}.".format(model_name=model_name)) 178 | 179 | lossfunc = nn.MSELoss() 180 | y_hat = complete_model(X) 181 | error = lossfunc(y_hat, y) 182 | print("Completed model Error: {error}".format(error=error)) 183 | 184 | X_grid = torch.from_numpy(np.linspace(0,1,50)).float().view(-1, d) 185 | y_hat = complete_model(X_grid) 186 | plt.scatter(X.numpy(), y.numpy()) 187 | plt.plot(X_grid.detach().numpy(), y_hat.detach().numpy(), 'r') 188 | plt.title('plot of $f(x)$ and $\hat{f}(x)$ Client_3') 189 | plt.xlabel('$x$') 190 | plt.ylabel('$y$') 191 | plt.show() 192 | 193 | 194 | epochs = range(1,1001) 195 | plt.plot(epochs, running_loss, 'g', label='Training loss') 196 | plt.title('Training loss_Client_3') 197 | plt.xlabel('Epochs') 198 | plt.ylabel('Error') 199 | plt.legend() 200 | plt.show() 201 | 202 | 203 | soc.close() 204 | print("Socket Closed.\n") -------------------------------------------------------------------------------- /client_1.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | 4 | soc = socket.socket() 5 | print("Socket is created.") 6 | 7 | soc.connect(("localhost", 10000)) 8 | print("Connected to the server.") 9 | 10 | msg = "A message from the client." 11 | msg = pickle.dumps(msg) 12 | soc.sendall(msg) 13 | print("Client sent a message to the server.") 14 | 15 | received_data = b'' 16 | while str(received_data)[-2] != '.': 17 | data = soc.recv(8) 18 | received_data += data 19 | 20 | received_data = pickle.loads(received_data) 21 | print("Received data from the client: {received_data}".format(received_data=received_data)) 22 | 23 | msg = "Another message from the client." 24 | msg = pickle.dumps(msg) 25 | soc.sendall(msg) 26 | print("Client sent a message to the server.") 27 | 28 | received_data = b'' 29 | while str(received_data)[-2] != '.': 30 | data = soc.recv(8) 31 | received_data += data 32 | 33 | received_data = pickle.loads(received_data) 34 | print("Received data from the client: {received_data}".format(received_data=received_data)) 35 | 36 | soc.close() 37 | print("Socket is closed.") -------------------------------------------------------------------------------- /client_2.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | 4 | import torch 5 | import torch.nn as nn 6 | import torch.nn.functional as F 7 | 8 | from mpl_toolkits.mplot3d import Axes3D 9 | import matplotlib.pyplot as plt 10 | 11 | import numpy as np 12 | 13 | torch.manual_seed(446) 14 | np.random.seed(446) 15 | 16 | d = 1 17 | n = 200 18 | X = torch.rand(n,d) 19 | y = 4 * torch.sin(np.pi * X) * torch.cos(6*np.pi*X**2) 20 | 21 | step_size = 0.05 22 | n_epochs = 6000 23 | #n_hidden_1 = 32 24 | #n_hidden_2 = 32 25 | #d_out = 1 26 | #model = nn.Sequential( 27 | # nn.Linear(d, n_hidden_1), 28 | # nn.Tanh(), 29 | # nn.Linear(n_hidden_1, n_hidden_2), 30 | # nn.Tanh(), 31 | # nn.Linear(n_hidden_2, d_out) 32 | # ) 33 | 34 | 35 | def recv(soc, buffer_size=1024, recv_timeout=10): 36 | received_data = b"" 37 | while str(received_data)[-2] != '.': 38 | try: 39 | soc.settimeout(recv_timeout) 40 | received_data += soc.recv(buffer_size) 41 | 42 | except socket.timeout: 43 | print("A socket.timeout exception occured because the server did not send any data for {recv_timeout} seconds or due to error or model completly trained.".format(recv.recv_timeout)) 44 | return None, 0 45 | 46 | except BaseException as e: 47 | return None, 0 48 | print("Error occured while receiving data from the server {msg}.".format(msg=e)) 49 | 50 | try: 51 | received_data = pickle.loads(received_data) 52 | 53 | except BaseException as e: 54 | print("Error decoding the client's data: {msg}.\n".format(msg=e)) 55 | return None, 0 56 | 57 | return received_data, 1 58 | 59 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 60 | print("Socket Created.\n") 61 | 62 | try: 63 | soc.connect(("localhost", 10000)) 64 | print("Successful connection to the server.\n") 65 | 66 | except BaseException as e: 67 | print("Error connecting the server: {msg}".format(msg=e)) 68 | soc.close() 69 | print("Socket closed.") 70 | 71 | #soc = socket.socket() 72 | #print("Socket is created.") 73 | 74 | #soc.connect(("localhost", 10000)) 75 | #print("Connected to the server.") 76 | 77 | 78 | #msg = "Another message from the client." 79 | #msg = model 80 | #msg = params 81 | #msg = params.numpy() 82 | #msg = pickle.dumps(msg) 83 | #soc.sendall(msg) 84 | #print("Client sent a message to the server.") 85 | 86 | status = 1 87 | while status == 1: 88 | #data = {"subject": subject, "data": GANN_instance, "best_solution_idx": best_sol_idx} 89 | #data_byte = pickle.dumps(data) 90 | 91 | #print("Sending the model to the server.\n") 92 | #soc.sendall(data_byte) 93 | status = 1 94 | print("Receiving reply from the server.") 95 | received_data, status = recv(soc=soc, buffer_size=1024, recv_timeout=10) 96 | 97 | if status == 0: 98 | print("Nothing is received from the server.") 99 | break 100 | else: 101 | print(received_data, end="\n\n") 102 | 103 | subject = received_data["subject"] 104 | 105 | if subject == "model": 106 | model = received_data["data"] 107 | loss_func = nn.MSELoss() 108 | 109 | optim = torch.optim.SGD(received_data.parameters(), lr=step_size) 110 | #print('iter,\tloss') 111 | for i in range(n_epochs): 112 | y_hat = received_data(X) 113 | loss = loss_func(y_hat, y) 114 | optim.zero_grad() 115 | loss.backward() 116 | optim.step() 117 | 118 | msg = {"subject": "model", "data": received_data} 119 | msg = pickle.dumps(msg) 120 | soc.sendall(msg) 121 | print("Client sent a message to the server.") 122 | 123 | elif subject == "done": 124 | print("The server said the model is trained successfully.") 125 | break 126 | else: 127 | print("Unregconized message type.") 128 | break 129 | 130 | 131 | soc.close() 132 | print("Socket closed.\n") 133 | 134 | #received_data = b'' 135 | #while str(received_data)[-2] != '.': 136 | # data = soc.recv(1024) 137 | # received_data += data 138 | 139 | #received_data = pickle.loads(received_data) 140 | #print("Received data from the client: {received_data}".format(received_data=received_data.type())) 141 | 142 | 143 | 144 | #if i % (n_epochs // 10) == 0: 145 | # print('{},\t{:.2f}'.format(i, loss.item())) 146 | 147 | #for params in received_data.parameters(): 148 | # print(params) 149 | 150 | #msg = received_data 151 | #msg = pickle.dumps(msg) 152 | #soc.sendall(msg) 153 | #print("Client sent a message to the server.") 154 | 155 | #received_data = b'' 156 | #while str(received_data)[-2] != '.': 157 | # data = soc.recv(1024) 158 | # received_data += data 159 | 160 | #received_data = pickle.loads(received_data) 161 | 162 | #print("Received data from the client: {received_data}".format(received_data=received_data)) 163 | 164 | 165 | #soc.close() 166 | #print("Socket is closed.") -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import time 4 | import threading 5 | 6 | import torch 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | 10 | #from mpl_toolkits.mplot3d import Axes3D 11 | #import matplotlib.pyplot as plt 12 | 13 | import numpy as np 14 | 15 | torch.manual_seed(446) 16 | np.random.seed(446) 17 | 18 | d = 2 19 | #n = 50 20 | #X = torch.randn(n,d) 21 | #true_w = torch.tensor([[-1.0], [2.0]]) 22 | #y = X @ true_w + torch.randn(n,1) * 0.1 23 | 24 | #step_size = 0.05 25 | #n_epochs = 6000 26 | n_hidden_1 = 32 27 | n_hidden_2 = 32 28 | d_out = 1 29 | model = nn.Sequential( 30 | nn.Linear(d, n_hidden_1), 31 | nn.Tanh(), 32 | nn.Linear(n_hidden_1, n_hidden_2), 33 | nn.Tanh(), 34 | nn.Linear(n_hidden_2, d_out) 35 | ) 36 | 37 | class SocketThread(threading.Thread): 38 | def __init__(self, connection, client_info, buffer_size=1024, recv_timeout=5): 39 | threading.Thread.__init__(self) 40 | self.connection = connection 41 | self.client_info = client_info 42 | self.buffer_size = buffer_size 43 | self.recv_timeout = recv_timeout 44 | 45 | def run(self): 46 | 47 | # This while loop allows the server to wait for the client to send data more than once within the same connection. 48 | while True: 49 | self.recv_start_time = time.time() 50 | time_struct = time.gmtime() 51 | date_time = "\nWaiting to Receive Data from {client_info} Starting from {day}/{month}/{year} {hour}:{minute}:{second} GMT".format(year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec, client_info=self.client_info) 52 | print(date_time) 53 | received_data, status = self.recv() 54 | if status == 0: 55 | self.connection.close() 56 | print("\nConnection Closed with {client_info} either due to inactivity for {recv_timeout} seconds or due to an error.".format(client_info=self.client_info, recv_timeout=self.recv_timeout), end="\n\n") 57 | break 58 | 59 | # print(received_data) 60 | self.reply(received_data) 61 | 62 | 63 | def recv(self): 64 | received_data = b"" 65 | while True: 66 | try: 67 | data = self.connection.recv(self.buffer_size) 68 | received_data += data 69 | 70 | if data == b'': # Nothing received from the client. 71 | received_data = b"" 72 | # If still nothing received for a number of seconds specified by the recv_timeout attribute, return with status 0 to close the connection. 73 | if (time.time() - self.recv_start_time) > self.recv_timeout: 74 | return None, 0 # 0 means the connection is no longer active and it should be closed. 75 | 76 | elif str(data)[-2] == '.': 77 | print("All data ({data_len} bytes) Received from {client_info}.".format(client_info=self.client_info, data_len=len(received_data))) 78 | 79 | if len(received_data) > 0: 80 | try: 81 | # Decoding the data (bytes). 82 | received_data = pickle.loads(received_data) 83 | # Returning the decoded data. 84 | return received_data, 1 85 | 86 | except BaseException as e: 87 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 88 | return None, 0 89 | 90 | else: 91 | # In case data are received from the client, update the recv_start_time to the current time to reset the timeout counter. 92 | self.recv_start_time = time.time() 93 | 94 | except BaseException as e: 95 | print("Error Receiving Data from the Client: {msg}.\n".format(msg=e)) 96 | return None, 0 97 | 98 | def model_averaging(self, model1, model2): 99 | 100 | sdA = model1.state_dict() 101 | sdB = model2.state_dict() 102 | for key in sdA: 103 | sdA[key] = (sdB[key] + sdA[key]) / 2. 104 | 105 | model = nn.Sequential(nn.Linear(d, n_hidden_1), 106 | nn.Tanh(), 107 | nn.Linear(n_hidden_1, n_hidden_2), 108 | nn.Tanh(), 109 | nn.Linear(n_hidden_2, d_out) 110 | ) 111 | 112 | model.load_state_dict(sdA) 113 | 114 | return model 115 | 116 | def reply(self, received_data): 117 | global model 118 | if (type(received_data) is dict): 119 | if (("data" in received_data.keys()) and ("subject" in received_data.keys())): 120 | subject = received_data["subject"] 121 | print("Client's Message Subject is {subject}.".format(subject=subject)) 122 | 123 | print("Replying to the Client.") 124 | if subject == "echo": 125 | if model is None: 126 | data = {"subject": "model", "data": model} 127 | #else: 128 | #predictions = pygad.nn.predict(last_layer=model, data_inputs=data_inputs) 129 | #error = numpy.sum(numpy.abs(predictions - data_outputs)) 130 | # In case a client sent a model to the server despite that the model error is 0.0. In this case, no need to make changes in the model. 131 | #if error == 0: 132 | # data = {"subject": "done", "data": None} 133 | # print("The client asked for the model but it was already trained successfully. There is no need to send the model to the client for retraining.") 134 | #else: 135 | # data = {"subject": "model", "data": GANN_instance} 136 | 137 | try: 138 | response = pickle.dumps(data) 139 | except BaseException as e: 140 | print("Error Encoding the Message: {msg}.\n".format(msg=e)) 141 | elif subject == "model": 142 | try: 143 | model = received_data["data"] 144 | #best_model_idx = received_data["best_solution_idx"] 145 | 146 | #best_model = GANN_instance.population_networks[best_model_idx] 147 | #if model is None: 148 | # model = best_model 149 | #else: 150 | # predictions = pygad.nn.predict(last_layer=model, data_inputs=data_inputs) 151 | 152 | # error = numpy.sum(numpy.abs(predictions - data_outputs)) 153 | 154 | # In case a client sent a model to the server despite that the model error is 0.0. In this case, no need to make changes in the model. 155 | # if error == 0: 156 | # data = {"subject": "done", "data": None} 157 | # response = pickle.dumps(data) 158 | # print("The model is trained successfully and no need to send the model to the client for retraining.") 159 | # return 160 | 161 | #self.model_averaging(model, model) 162 | data = {"subject": "model", "data": self.model_averaging(model, model)} 163 | response = pickle.dumps(data) 164 | print("\n*****The Model is Aggregated Successfully*****\n\n") 165 | 166 | except BaseException as e: 167 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 168 | else: 169 | response = pickle.dumps("Response from the Server") 170 | 171 | try: 172 | self.connection.sendall(response) 173 | except BaseException as e: 174 | print("Error Sending Data to the Client: {msg}.\n".format(msg=e)) 175 | 176 | else: 177 | print("The received dictionary from the client must have the 'subject' and 'data' keys available. The existing keys are {d_keys}.".format(d_keys=received_data.keys())) 178 | else: 179 | print("A dictionary is expected to be received from the client but {d_type} received.".format(d_type=type(received_data))) 180 | 181 | 182 | 183 | 184 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 185 | print("Socket Created.\n") 186 | 187 | try: 188 | soc.connect(("localhost", 10000)) 189 | print("Successful connection to the server.\n") 190 | 191 | except BaseException as e: 192 | print("Error connecting the server: {msg}".format(msg=e)) 193 | soc.close() 194 | print("Socket closed.") 195 | 196 | soc = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) 197 | print("Socket Created.\n") 198 | 199 | status = 1 200 | while status == 1: 201 | data = {"subject": "model", "data": model} 202 | data_byte = pickle.dumps(data) 203 | 204 | print("Sending the initial model to the clients.\n") 205 | soc.sendall(data_byte) 206 | status = 0 207 | if status == 0: 208 | break 209 | 210 | 211 | 212 | soc.close() 213 | print("Socket closed.\n") 214 | 215 | # Timeout after which the socket will be closed. 216 | # soc.settimeout(5) 217 | 218 | soc.bind(("localhost", 10000)) 219 | print("Socket Bound to IPv4 Address & Port Number.\n") 220 | 221 | soc.listen(1) 222 | print("Socket is Listening for Connections ....\n") 223 | 224 | all_data = b"" 225 | while True: 226 | try: 227 | connection, client_info = soc.accept() 228 | print("\nNew Connection from {client_info}.".format(client_info=client_info)) 229 | socket_thread = SocketThread(connection=connection, 230 | client_info=client_info, 231 | buffer_size=1024, 232 | recv_timeout=10) 233 | socket_thread.start() 234 | except: 235 | soc.close() 236 | print("(Timeout) Socket Closed Because no Connections Received.\n") 237 | break -------------------------------------------------------------------------------- /server_1.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import pickle 3 | import time 4 | import threading 5 | 6 | import torch 7 | import torch.nn as nn 8 | import torch.nn.functional as F 9 | 10 | from mpl_toolkits.mplot3d import Axes3D 11 | import matplotlib.pyplot as plt 12 | 13 | import numpy as np 14 | 15 | torch.manual_seed(446) 16 | np.random.seed(446) 17 | 18 | d_in = 3 19 | d_hidden = 4 20 | d_out = 1 21 | model = torch.nn.Sequential( 22 | nn.Linear(d_in, d_hidden), 23 | nn.Tanh(), 24 | nn.Linear(d_hidden, d_out), 25 | nn.Sigmoid() 26 | ) 27 | 28 | class SocketThread(threading.Thread): 29 | 30 | def __init__(self, connection, client_info, buffer_size=1024, recv_timeout=5): 31 | thread.Thread.__init__(self) 32 | self.connection = connection 33 | self.client_info = client_info 34 | self.buffer_size = buffer_size 35 | self.recv_timeout = recv_timeout 36 | 37 | def recv(self): 38 | received_data = b"" 39 | while True: 40 | try: 41 | data = connection.recv(self.buffer_size) 42 | received_data += data 43 | 44 | if data == b'': # Received nothing 45 | received_data = b"" 46 | # If still no data is received after recv_timeout, return status 0 to close connection 47 | if (time.time() - self.recv_start_time) > self.recv_timeout: 48 | return None, 0 # 0 means the connection is no longer active and it should be closed 49 | 50 | elif str(data)[-2] == '.': 51 | print("All data ({data_len} bytes) Received from {client_info}.".format(client_info=self.client_info, data_len=len(received_data))) 52 | 53 | if len(received_data) > 0: 54 | try: 55 | # Decoding the data (bytes). 56 | received_data = pickle.loads(received_data) 57 | # Return the decoded data 58 | return received_data, 1 59 | 60 | except BaseException as e: 61 | print("Error Decoding the Client's Data: {msg}.\n".format(msg=e)) 62 | return None, 0 63 | 64 | else: 65 | # If any case is received from the client, reset the time counter 66 | self.recv_start_time = time.time() 67 | 68 | except BaseException as e: 69 | print("Error Receving Data from the Client: {msg}.\n".format(msg=e)) 70 | return None, 0 71 | 72 | def run(self): 73 | while True: 74 | self.recv_start_time = time.time() 75 | time_struct = time.gmtime() 76 | date_time = "Waiting to Receive Data Starting from {day}/{month}/{year} {hour}:{minute}:{second} GMT".format(year=time_struct.tm_year, month=time_struct.tm_mon, day=time_struct.tm_mday, hour=time_struct.tm_hour, minute=time_struct.tm_min, second=time_struct.tm_sec) 77 | print(date_time) 78 | received_data, status = self.recv() 79 | if status == 0: 80 | self.connection.close() 81 | print("Connection closed with {client_info} either due to inactivity for {recv_timeout} seconds or due to an error.".format(client_info=self.client_info, recv_timeout=self.recv_timeout), end="\n\n") 82 | break 83 | 84 | msg = model 85 | msg = pickle.dumps(msg) 86 | connection.sendall(msg) 87 | print("Server sent a message to the client.") 88 | 89 | soc = socket.socket() 90 | print("Socket is created.") 91 | 92 | soc.bind(("localhost", 10000)) 93 | print("Socket is bound to an address & port number.") 94 | 95 | soc.listen(1) 96 | print("Waiting for incoming connection...") 97 | 98 | while True: 99 | try: 100 | connection, client_info = soc.accept() 101 | print("New Connection from {client_info}.".format(client_info=client_info)) 102 | socket_thread = SocketThread(connection=connection, 103 | client_info=client_info, 104 | buffer_size=1024, 105 | recv_timeout=10 106 | ) 107 | socket_thread.start() 108 | except: 109 | soc.close() 110 | print("(Timeout) Socket Closed Because no Connection is received.\n") 111 | break 112 | 113 | --------------------------------------------------------------------------------