def add_moving_summary(*args, **kwargs):
    """
    Summarize the moving average for scalar tensors.
    This function is a no-op if not calling from main training tower.
    See tutorial at https://tensorpack.readthedocs.io/tutorial/summary.html

    Args:
        args: scalar tensors to summarize
        decay (float): the decay rate. Defaults to 0.95.
        collection (str or None): the name of the collection to add EMA-maintaining ops.
            The default will work together with the default
            :class:`MovingAverageSummary` callback.
        summary_collections ([str]): the names of collections to add the
            summary op. Default is TF's default (`tf.GraphKeys.SUMMARIES`).

    Returns:
        [tf.Tensor]:
            list of tensors returned by assign_moving_average,
            which can be used to maintain the EMA.
    """
    decay = kwargs.pop('decay', 0.95)
    coll = kwargs.pop('collection', MOVING_SUMMARY_OPS_KEY)
    summ_coll = kwargs.pop('summary_collections', None)
    assert len(kwargs) == 0, "Unknown arguments: " + str(kwargs)

    ctx = get_current_tower_context()
    # allow ctx to be none
    if ctx is not None and not ctx.is_main_training_tower:
        return []

    graph = tf.get_default_graph()
    try:
        control_flow_ctx = graph._get_control_flow_context()
        # XLA does not support summaries anyway
        # However, this function will generate unnecessary dependency edges,
        # which makes the tower function harder to compile under XLA, so we skip it
        if control_flow_ctx is not None and control_flow_ctx.IsXLAContext():
            return
    except Exception:
        pass

    if tf.get_variable_scope().reuse is True:
        logger.warn("add_moving_summary() called under reuse=True scope, ignored.")
        return []

    for x in args:
        assert isinstance(x, (tf.Tensor, tf.Variable)), x
        assert x.get_shape().ndims == 0, \
            "add_moving_summary() only accepts scalar tensor! Got one with {}".format(x.get_shape())

    from ..graph_builder.utils import override_to_local_variable
    ema_ops = []
    for c in args:
        name = re.sub('tower[0-9]+/', '', c.op.name)
        with tf.name_scope(None), override_to_local_variable(True):
            if not c.dtype.is_floating:
                c = tf.cast(c, tf.float32)
            # assign_moving_average creates variables with op names, therefore clear ns first.
            with _enter_vs_reuse_ns('EMA') as vs:
                ema_var = tf.get_variable(name, shape=c.shape, dtype=c.dtype,
                                          initializer=tf.constant_initializer(),
                                          trainable=False)
                ns = vs.original_name_scope
            with tf.name_scope(ns):     # reuse VS&NS so that EMA_1 won't appear
                ema_op = moving_averages.assign_moving_average(
                    ema_var, c, decay,
                    zero_debias=True, name=name + '_EMA_apply')
            ema_ops.append(ema_op)
        with tf.name_scope(None):
            tf.summary.scalar(
                name + '-summary', ema_op,
                collections=summ_coll)    # write the EMA value as a summary
    if coll is not None:
        for op in ema_ops:
            tf.add_to_collection(coll, op)
    return ema_ops

    Summarize the moving average for scalar tensors.
    This function is a no-op if not calling from main training tower.
    See tutorial at https://tensorpack.readthedocs.io/tutorial/summary.html

    Args:
        args: scalar tensors to summarize
        decay (float): the decay rate. Defaults to 0.95.
        collection (str or None): the name of the collection to add EMA-maintaining ops.
            The default will work together with the default
            :class:`MovingAverageSummary` callback.
        summary_collections ([str]): the names of collections to add the
            summary op. Default is TF's default (`tf.GraphKeys.SUMMARIES`).

    Returns:
        [tf.Tensor]:
            list of tensors returned by assign_moving_average,
            which can be used to maintain the EMA.
    
tensorpack/tfutils/summary.py