Reputation: 1
I am a college student doing federation learning with flower+pytorch, and I have made a demo of it. The server files and client files are already written and run separately from the console. Now there is a problem, the error message says AttributeError: 'Parameters' object has no attribute 'parameters' My code is short, so I write it all out:
import pandas as pd
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from model import MLP
import flwr as fl
from torch.utils.data import TensorDataset, DataLoader
import multiprocessing
import io
import torch
def preprocess_data(file_path):
data = pd.read_csv(file_path)
if data.isnull().sum().sum() > 0:
num_imputer = SimpleImputer(strategy='median')
data[data.columns] = num_imputer.fit_transform(data[data.columns])
scaler = StandardScaler()
data[data.columns[1:-1]] = scaler.fit_transform(data[data.columns[1:-1]])
X = data[data.columns[1:-1]].values
y = data['Class'].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.long)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.long)
return X_train, y_train, X_test, y_test
def train_model(model, trainloader, epochs):
"""Train the model on the training set."""
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
for epoch in range(epochs):
for inputs, labels in trainloader:
outputs = model(inputs)
loss = criterion(outputs, labels)
optimizer.zero_grad()
loss.backward()
optimizer.step()
def test_model(model, testloader):
"""Validate the model on the test set."""
criterion = torch.nn.CrossEntropyLoss()
correct, total, loss = 0, 0, 0.0
with torch.no_grad():
for inputs, labels in testloader:
outputs = model(inputs)
loss += criterion(outputs, labels).item()
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()
accuracy = correct / total
return loss / len(testloader), accuracy
def load_data(file_path, batch_size=32):
"""Load and preprocess data from a file."""
# Preprocess the data
X_train, y_train, X_test, y_test = preprocess_data(file_path)
# Create TensorDatasets
train_data = TensorDataset(X_train, y_train)
test_data = TensorDataset(X_test, y_test)
# Create DataLoaders
trainloader = DataLoader(train_data, batch_size=batch_size, shuffle=True)
testloader = DataLoader(test_data, batch_size=batch_size)
return trainloader, testloader
def start_client(client_id, features):
# Load and preprocess data
trainloader, testloader = load_data('C:\\Users\\Fantasy\\Desktop\\毕设\\程序\\dataset\\creditcard_2023.csv')
# Create an MLP model instance, the size of the input layer is the number of features
model = MLP(len(features))
# Create a client instance
client = Client(trainloader, testloader, model)
fl.client.start_client(server_address="127.0.0.1:8080", client=client)
class Client(fl.client.NumPyClient):
def __init__(self, trainloader, testloader, model):
self.model = model
self.trainloader = trainloader
self.testloader = testloader
def get_parameters(self, config):
parameters = {name: io.BytesIO() for name, _ in self.model.named_parameters()}
for name, param in self.model.named_parameters():
torch.save(param.detach().cpu(), parameters[name])
return fl.common.Parameters(parameters, tensor_type="float32")
def set_parameters(self, parameters):
self.model.load_state_dict(parameters)
def fit(self, parameters, config):
self.set_parameters(parameters)
train_model(self.model, self.trainloader, epochs=1)
return self.get_parameters(config={}), len(self.trainloader.dataset), {}
def evaluate(self, parameters, config):
self.set_parameters(parameters)
loss, accuracy = test_model(self.model, self.testloader)
return loss, len(self.testloader.dataset), {"accuracy": accuracy}
def main():
# Define the features for each client
features_list = [['V1', 'V2', 'V3', 'V4'], ['V5', 'V6', 'V7', 'V8'], ['V9', 'V10', 'V11', 'V12']]
# Create a process for each client
processes = []
for i in range(3): # Replace with the actual number of clients
features = features_list[i % len(features_list)] # Assign features to clients in a round-robin fashion
process = multiprocessing.Process(target=start_client, args=(i, features))
processes.append(process)
# Start all processes
for process in processes:
process.start()
# Wait for all processes to finish
for process in processes:
process.join()
if __name__ == "__main__":
main()
I hope someone can help me solve it, because this is the prototype of my graduation project, so I am in a hurry.
The error message is as follows:
Process Process-1:
Traceback (most recent call last):
File "C:\Users\Fantasy\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 314, in _bootstrap
self.run()
File "C:\Users\Fantasy\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\Fantasy\Desktop\毕设\程序\code\main.py", line 100, in start_client
fl.client.start_client(server_address="127.0.0.1:8080", client=client)
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\client\app.py", line 248, in start_client
_start_client_internal(
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\client\app.py", line 382, in _start_client_internal
out_message = app(message=message, context=context)
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\client\flower.py", line 76, in __call__
return self._call(message, context)
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\client\flower.py", line 66, in ffn
out_message = handle_legacy_message_from_tasktype(
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\client\message_handler\message_handler.py", line 130, in handle_legacy_message_from_tasktype
out_recordset = getparametersres_to_recordset(
File "C:\Users\Fantasy\Desktop\毕设\程序\code\venv\lib\site-packages\flwr\common\recordset_compat.py", line 342, in getparametersres_to_recordset
getparametersres.parameters, keep_input=keep_input
AttributeError: 'Parameters' object has no attribute 'parameters'
I don't know what the problem is, so I can't fix it。This is the first time I've asked a question on stack overflow.
Upvotes: 0
Views: 235