<p>I think the problem might be with the training step rather than the &quot;averaging&quot; algorithm.</p>
<p>According to the paper that proposes the FedAvg algorithm (<a href="https://arxiv.org/pdf/1602.05629.pdf" rel="nofollow noreferrer">https://arxiv.org/pdf/1602.05629.pdf</a>), the local models apply stochastic gradient descent to the global model rather than training new local models from scratch.</p>
<p>Here you have a tutorial from TensorFlow that applies Federated Averaging: <a href="https://www.tensorflow.org/federated/tutorials/custom_federated_algorithms_2#gradient_descent_on_a_single_batch" rel="nofollow noreferrer">https://www.tensorflow.org/federated/tutorials/custom_federated_algorithms_2#gradient_descent_on_a_single_batch</a></p>
Federated averaging implementation in python
<p>I am working with federated learning. I am using a global server where I defined a cnn based classifier. The global server compiles the model with hyper-parameters and send it to the edge(clients), currently I am using two clients. Each client uses its local data (for now I am using same data, and model on each client). After training model, each client has above 95 percent accuracy, precision and recall in their local models. clients sends their trained  local model to the server. The server gets the model and and gets the weights from each received model and computes average according to <a href="https://i.stack.imgur.com/iZxZr.png." rel="nofollow noreferrer">this formula</a>. Below is the code I wrote to implement this formula in python. when I set the average weights to  models and try to predict, the accuracy, recall and precision fall below 20%.</p>
<p>Am I doing something wrong in implementation?</p>
<pre><code># initial weights of global model, set to zer0.  
  ave_weights=model.get_weights()
  ave_weights=[i * 0 for i in ave_weights]
  count=0
# Multithreaded Python server : TCP Server Socket Thread Pool
def ClientThread_send(conn,address,weights):
    # send model to client
    conn.send(model)

    print(&quot;Model Sent to :&quot;,address)
    print(&quot;waiting for weights&quot;)
    model_recv=conn.recv(1024)
    print(&quot;weights received from:&quot;,address)
    global count
    global ave_weights

    
    #receive weights from clients
    rec_weight=model.get_weights()
    #multiply the client weights by number of local data samples in client local data
    rec_weight=  [i * 100000 for i in rec_weight]
    # divide the weights by total number of samples of all participants
    rec_weight=  [i / 200000 for i in rec_weight]

    #sum the weights of all clients
    ave_weights=[x + y for x, y in zip(ave_weights,rec_weight)]
  
    count=count+1
    conn.close()
if count==2:
    # set the global model weights if the count(number of clients is two)
    model.set_weights(ave_weights)


 while True:
     conn, address = s.accept()
     start_new_thread(ClientThread_send,(conn,address,ave_weights))   
     
</code></pre>