I am working on eavesdropper detection on B5G system with Deep Learning. The training dataset contains 1200 CSI images of legitimate and malicious UEs and an .xlsx file with their positions, power, nearest BS and ladels.
I have created a DCNN model (with Keras Sequential()) that takes as input only the images, and another one with similar structures that takes into account both the images and the categorical data.
Both models seem to achieve excellect accuracy and f1-score (>95%), even with the 1/3 of the dataset, in Centralized Learning tecnhique.
I want to test these models with Federated Learning. For this reason, I devide the data to BSs, based on the nearest one to each UE. The results are really bad. The maximum accuracy I can achieve reaches 70% in training set and 60% in test set (which also has very high loss), no matter if I use 3 BSs or 18 BSs as clients.
I attach the relative code. I have tried anything (augmentation, balancing, extra dropout layers on models but nothing).
def split_data_by_bs(df, input_images, input_positions, input_labels):
bs_data = {}
bs_mapping = {}
group_1 = [1, 4, 7, 10, 13, 16]
group_2 = [2, 5, 8, 11, 14, 17]
group_3 = [3, 6, 9, 12, 15, 18]
for bs_id in df[4].unique():
if bs_id in group_1:
bs_mapping[bs_id] = 1
elif bs_id in group_2:
bs_mapping[bs_id] = 2
elif bs_id in group_3:
bs_mapping[bs_id] = 3
for bs_id, mapped_bs_id in bs_mapping.items():
indices = df[df[4] == bs_id].index
X = input_images[indices]
pos = input_positions[indices]
y = input_labels[indices]
if mapped_bs_id not in bs_data:
bs_data[mapped_bs_id] = (X, pos, y)
else:
bs_data[mapped_bs_id] = (
np.concatenate([bs_data[mapped_bs_id][0], X], axis=0),
np.concatenate([bs_data[mapped_bs_id][1], pos], axis=0),
np.concatenate([bs_data[mapped_bs_id][2], y], axis=0)
)
return bs_data
def preprocess_data(images, labels):
return tf.data.Dataset.from_tensor_slices((images, labels)).batch(32)
train_datasets = []
val_datasets = []
train_datasets = [preprocess_data(images, labels) for _, (images, _, labels) in bs_data_train.items()]
val_datasets = [preprocess_data(images, labels) for _, (images, _, labels) in bs_data_val.items()]
def model_fn():
keras_model = create_dcnn_model()
# for layer in keras_model.layers:
# if hasattr(layer, 'kernel_initializer'):
# layer.kernel.initializer = tf.keras.initializers.GlorotUniform()
return tff.learning.models.from_keras_model(
keras_model,
input_spec=train_datasets[0].element_spec,
loss=tf.keras.losses.BinaryCrossentropy(),
metrics=[tf.keras.metrics.BinaryAccuracy()]
)
iterative_process = []
iterative_process = tff.learning.algorithms.build_weighted_fed_avg(
model_fn,
client_optimizer_fn=tff.learning.optimizers.build_adam(learning_rate=0.0005),
server_optimizer_fn=tff.learning.optimizers.build_adam(learning_rate=0.001)
)
state = iterative_process.initialize()
NUM_ROUNDS = 50
metrics_per_round = []
for round_num in range(1, NUM_ROUNDS+1):
result = iterative_process.next(state, train_datasets)
train_state = result.state
train_metrics = result.metrics
metrics_per_round.append(train_metrics)
print('round {:2d}, metrics={}'.format(round_num, train_metrics))
Debugging: Weight Difference remains the SAME after every round...
weights = iterative_process.get_model_weights(state).trainable
weight_diff = sum([tf.reduce_sum(tf.abs(w)).numpy() for w in weights])
print(f"Weight Difference after Round {round_num}: {weight_diff}")
evaluation_obj = tff.learning.algorithms.build_fed_eval(
model_fn=model_fn
)
evaluation_state = evaluation_obj.initialize()
model_weights = iterative_process.get_model_weights(train_state)
evaluation_state = evaluation_obj.set_model_weights(evaluation_state, model_weights)
evaluation_output = evaluation_obj.next(evaluation_state, val_datasets)
print(f"Validation Metrics: {evaluation_output.metrics}")
Fine-tuning (Personalized FL)
for bs_id, (images, _, labels) in bs_data_val.items():
fine_tune_model = create_dcnn_model()
fine_tune_model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
fine_tune_model.fit(images, labels, epochs=3, batch_size=32)
fine_tune_eval = fine_tune_model.evaluate(images, labels, batch_size=32)
print(f"Fine-tuned Model for BS {bs_id}: {fine_tune_eval}")
As you can see above, I also tried FineTuning to each BS and some are doing very well, while others are doing very badly.
Any help is appreciated.