human
Complete this python program:
def get_batch_normalization_updates(training_graph, allow_duplicates=False):
assistant
#Here is the Python code you requested.

    """Extract correspondences for learning BN population statistics.
    Parameters
    training_graph : :class:`~blocks.graph.ComputationGraph`
    A graph of expressions wherein "training mode" batch normalization
    is taking place.
    allow_duplicates : bool, optional
    If `True`, allow multiple training-mode application calls from the
    same :class:`~blocks.bricks.BatchNormalization` instance, and
    return pairs corresponding to all of them. It\s then the user\s
    responsibility to do something sensible to resolve the duplicates.
    Returns
    update_pairs : list of tuples
    A list of 2-tuples where the first element of each tuple is the
    shared variable containing a "population" mean or standard
    deviation, and the second is a Theano variable for the
    corresponding statistics on a minibatch. Note that multiple
    applications of a single :class:`blocks.bricks.BatchNormalization`
    may appear in the graph, and therefore (if `allow_duplicates` is
    True) a single population variable may map to several different
    minibatch variables, and appear multiple times in this mapping.
    This can happen in recurrent models, siamese networks or other
    models that reuse pathways.
    Notes
    Used in their raw form, these updates will simply overwrite the
    population statistics with the minibatch statistics at every gradient
    step. You will probably want to transform these pairs into something
    more sensible, such as keeping a moving average of minibatch values,
    or accumulating an average over the entire training set once every few
    epochs.
    """
    from ..bricks import BatchNormalization
    from ..filter import VariableFilter, get_application_call
    var_filter = VariableFilter(bricks=[BatchNormalization], roles=[OUTPUT])
    all_app_calls = map(get_application_call, var_filter(training_graph))
    train_app_calls = _training_mode_application_calls(all_app_calls)
    if (len(train_app_calls) == 0):
        raise ValueError('no    training    mode    BatchNormalization    applications    found    in    graph')
    bricks = [c.application.brick for c in train_app_calls]
    if ((not allow_duplicates) and (not isdistinct(bricks))):
        raise ValueError('multiple    applications    of    the    same    BatchNormalization    brick;    pass    allow_duplicates    =    True    to    override    this    check')
    def extract_pair(brick_attribute, metadata_key, app_call):
        return (getattr(app_call.application.brick, brick_attribute), app_call.metadata[metadata_key])
    mean_pair = partial(extract_pair, 'population_mean', 'offset')
    stdev_pair = partial(extract_pair, 'population_stdev', 'divisor')
    return sum([([mean_pair(a), stdev_pair(a)] if (not a.application.brick.mean_only) else [mean_pair(a)]) for a in train_app_calls], [])