code: def average_gradients(multi_device_gradients):
      """
      the input gradients are grouped by device,
      this function average the gradients of multiple devices
  
      :param multi_device_gradients: list of N gradients for N devices
      :return:
      """
      # print(len(multi_device_gradients),
      #   len(multi_device_gradients[0]),
      #   len(multi_device_gradients[0][0]),
      #   len(multi_device_gradients[0][0][0]))
  
      if len(multi_device_gradients) == 1:
          # only one device, so we get rid of the first level list
          # that loops over devices
          return multi_device_gradients[0]
  
      nested_grads_depth = list_depth_count(multi_device_gradients)
      if nested_grads_depth == 4:
          gradients = zip(*multi_device_gradients)
          averaged_grads = [__average_grads(g) for g in gradients]
      elif nested_grads_depth == 3:
          averaged_grads = __average_grads(multi_device_gradients)
      else:
          tf.logging.fatal(
              "The list of gradients are nested in an unusual way."
              "application's gradient is not compatible with app driver."
              "Please check the return value of gradients_collector "
              "in connect_data_and_network() of the application"
          )
          raise RuntimeError
      return averaged_grads
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import datetime
  import os
  import re
  from functools import partial
  import numpy
  import tensorflow
  from scipy import ndimage
  from six import string_types
label_desc: Use image node_id 4 for calling a global function with example usage: average_gradients(multi_device_gradients) and returns: averaged_grads, multi_device_gradients