# Directory Structure
# ├── main_flower.py
# ├── client/
# │ ├── [Link]
# │ ├── [Link]
# │ ├── [Link]
# │ └── energy_check.py
# ├── server/
# │ ├── fog_node.py
# │ ├── blockchain_sim.py
# │ └── [Link]
# ├── model/
# │ └── ecg_cnn.py
# ├── data/
# │ ├── [Link]
# │ └── [Link]
# ├── utils/
# │ └── [Link]
# └── [Link]
# --- main_flower.py ---
import flwr as fl
import numpy as np
from [Link] import SOFLMClient
from [Link] import weighted_average
from server.blockchain_sim import BlockchainSimulator
blockchain = BlockchainSimulator()
def client_fn(cid: str):
return SOFLMClient(cid=cid, blockchain=blockchain)
def main():
strategy = [Link](
fraction_fit=0.6,
min_fit_clients=3,
min_available_clients=5,
on_aggregate_evaluate=None,
evaluate_metrics_aggregation_fn=weighted_average,
[Link].start_simulation(
client_fn=client_fn,
num_clients=10,
config=[Link](num_rounds=5),
strategy=strategy,
)
if __name__ == "__main__":
main()
# --- client/[Link] ---
import flwr as fl
import numpy as np
from [Link] import top_k_compress
from [Link] import add_differential_privacy
from client.energy_check import should_participate
from model.ecg_cnn import create_model
from [Link] import load_client_data
class SOFLMClient([Link]):
def __init__(self, cid, blockchain):
[Link] = cid
[Link] = create_model()
[Link] = blockchain
self.x_train, self.y_train, self.x_test, self.y_test = load_client_data(cid)
def get_parameters(self):
return [Link].get_weights()
def fit(self, parameters, config):
if not should_participate():
return [Link].get_weights(), len(self.x_train), {}
[Link].set_weights(parameters)
[Link](self.x_train, self.y_train, epochs=1, batch_size=32, verbose=0)
weights = [Link].get_weights()
compressed = top_k_compress(weights, k=0.1)
private_weights = add_differential_privacy(compressed, noise_scale=0.01)
[Link].submit_update([Link], private_weights)
return private_weights, len(self.x_train), {}
def evaluate(self, parameters, config):
[Link].set_weights(parameters)
loss, acc = [Link](self.x_test, self.y_test, verbose=0)
return loss, len(self.x_test), {"accuracy": acc}
# --- client/[Link] ---
def top_k_compress(weights, k=0.1):
flat = [Link]([[Link]() for w in weights])
threshold = [Link]([Link](flat), (1 - k) * 100)
compressed = [[Link]([Link](w) < threshold, 0, w) for w in weights]
return compressed
# --- client/[Link] ---
def add_differential_privacy(weights, noise_scale=0.01):
noisy_weights = [w + [Link](0, noise_scale, [Link]) for w in weights]
return noisy_weights
# --- client/energy_check.py ---
def should_participate():
import random
return [Link]() > 0.2
# --- model/ecg_cnn.py ---
from [Link] import Sequential
from [Link] import Conv1D, Dense, Flatten, MaxPooling1D
def create_model():
model = Sequential([
Conv1D(16, 3, activation='relu', input_shape=(187, 1)),
MaxPooling1D(2),
Flatten(),
Dense(64, activation='relu'),
Dense(5, activation='softmax')
])
[Link](optimizer='adam', loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
return model
# --- server/blockchain_sim.py ---
class BlockchainSimulator:
def __init__(self):
[Link] = []
def submit_update(self, cid, weights):
print(f"[Blockchain] Client {cid} submitted update.")
[Link]((cid, weights))
def get_valid_updates(self):
return [entry[1] for entry in [Link]]
# --- server/[Link] ---
def weighted_average(metrics):
total = sum([num_examples for _, num_examples, _ in metrics])
acc = sum([num_examples * m["accuracy"] for _, num_examples, m in metrics]) / total
return {"accuracy": acc}
# --- data/[Link] ---
from sklearn.model_selection import train_test_split
import numpy as np
def load_client_data(cid):
[Link](int(cid))
x = [Link](1000, 187, 1)
y = [Link](0, 5, 1000)
return train_test_split(x, y, test_size=0.2)
# --- [Link] ---
tensorflow
flwr
numpy
scikit-learn