<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_param_summary(*summary_lists, **kwargs):
 """ Add summary ops for all trainable variables matching the regex, under a reused 'param-summary' name scope. This function is a no-op if not calling from main training tower. Args: summary_lists (list):
 each is (regex, [list of summary type]). Summary type is defined in :func:`add_tensor_summary`. collections (list[str]):
 collections of the summary ops. Example: .. code-block:: python add_param_summary( ('.*/W', ['histogram', 'rms']), ('.*/gamma', ['scalar']), ) """

    collections = kwargs.pop('collections', None)
    assert len(kwargs) == 0, "Unknown kwargs: " + str(kwargs)
    ctx = get_current_tower_context()
    if ctx is not None and not ctx.is_main_training_tower:
        return

    params = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES)
    with cached_name_scope('param-summary'):
        for p in params:
            name = p.op.name
            for rgx, actions in summary_lists:
                if not rgx.endswith('$'):
                    rgx = rgx + '$'
                if re.match(rgx, name):
                    add_tensor_summary(p, actions, name=name, collections=collections)