I am trying to implement federated learning system using the Flower platform, I am using the CatBoost tree-based model as my FL model.
As shown in the Flower instruction, I am running the server and the client.py files in parallel to initiate the federated learning system, however whever I run the client code I get the following error:
return Parameters(tensors=parameters.tensors, tensor_type=parameters.tensor_type) TypeError: None has type NoneType, but expected one of: bytes
Following is a snapshot of the Client.py file where I encounter the error:
parser = argparse.ArgumentParser()
parser.add_argument(
"--node-id",
default=0,
type=int,
help="Node ID used for the current client.",
)
args = parser.parse_args()
####*********
# Load and partition the dataset
fds = pd.read_csv('Noisy_Data.csv')
partition = fds.to_numpy()
# Data partitioning related functions
def transform_dataset_to_pool(data):
x = data[:, 0:-1]
y = data[:, -1]
new_data = catboost.Pool(x, label=y)
return new_data
train_data, valid_data = train_test_split(partition, test_size=20, random_state=32)
num_train = len(train_data)
num_val = len(valid_data)
train_pool = transform_dataset_to_pool(train_data)
valid_pool = transform_dataset_to_pool(valid_data)
# Hyper-parameters for CatBoost training
num_local_round = 5
params = {
"iterations": 2,
"learning_rate": 0.1,
"depth": 5,
"loss_function": "Logloss",
"eval_metric": "AUC",
}
# Flower client
class CatBoostClient(fl.client.Client):
def __init__(self):
self.model = None
def get_parameters(self, ins: GetParametersIns) -> GetParametersRes:
_ = (self, ins)
return GetParametersRes(
status=Status(
code=Code.OK,
message="OK",
),
parameters=Parameters(tensor_type="", tensors=[]),
)
def fit(self, ins):
if not self.model:
log(INFO, "Start training at round 1")
model = CatBoostClassifier(**params)
model.fit(train_pool, eval_set=valid_pool, verbose=10)
self.model = model
else:
for item in ins.parameters.tensors:
global_model = bytearray(item)
self.model.load_model(global_model)
self.model.fit(train_pool, eval_set=valid_pool, verbose=10)
local_model = model.save_model('model_name')
#local_model_bytes = bytes(local_model)
return FitRes(
status=Status(
code=Code.OK,
message="OK",
),
parameters=Parameters(tensor_type="", tensors=[local_model]),
num_examples=num_train,
metrics={},
)
def evaluate(self, ins):
eval_results = self.model.eval_metrics(valid_pool, ["AUC"])
auc = round(eval_results['AUC'][-1], 4)
return fl.common.EvaluateRes(
status=fl.common.Status.OK,
loss=0.0,
num_examples=num_val,
metrics={"AUC": auc},
)
# Start Flower client
fl.client.start_client(server_address="127.0.0.1:8080", client=CatBoostClient())
And below is a snapshot of the server.py error:
import flwr as fl
from flwr.server.strategy import FedAvg
# FL experimental settings
pool_size = 2
num_rounds = 5
num_clients_per_round = 2
num_evaluate_clients = 2
# Define strategy
strategy = FedAvg(
fraction_fit=(float(num_clients_per_round) / pool_size),
min_fit_clients=num_clients_per_round,
min_available_clients=pool_size,
min_evaluate_clients=num_evaluate_clients,
fraction_evaluate=1.0,
)
# Start Flower server
fl.server.start_server(
server_address="0.0.0.0:8080",
config=fl.server.ServerConfig(num_rounds=num_rounds),
strategy=strategy,
)
Any suggestions on what might be the cause of the error?