<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def freeze_variables(stop_gradient=True, skip_collection=False):
 """ Return a context to freeze variables, by wrapping ``tf.get_variable`` with a custom getter. It works by either applying ``tf.stop_gradient`` on the variables, or by keeping them out of the ``TRAINABLE_VARIABLES`` collection, or both. Example: .. code-block:: python with varreplace.freeze_variable(stop_gradient=False, skip_collection=True):
 x = FullyConnected('fc', x, 1000) # fc/* will not be trained Args: stop_gradient (bool):
 if True, variables returned from `get_variable` will be wrapped with `tf.stop_gradient` and therefore has no gradient when used later. Note that the created variables may still have gradient when accessed by other approaches (e.g. by name, or by collection). Also note that this makes `tf.get_variable` returns a Tensor instead of a Variable, which may break existing code. Therefore, it's recommended to use the `skip_collection` option instead. skip_collection (bool):
 if True, do not add the variable to ``TRAINABLE_VARIABLES`` collection, but to ``MODEL_VARIABLES`` collection. As a result they will not be trained by default. """

    def custom_getter(getter, *args, **kwargs):
        trainable = kwargs.get('trainable', True)
        name = args[0] if len(args) else kwargs.get('name')
        if skip_collection:
            kwargs['trainable'] = False
        v = getter(*args, **kwargs)
        if skip_collection:
            tf.add_to_collection(tf.GraphKeys.MODEL_VARIABLES, v)
        if trainable and stop_gradient:
            v = tf.stop_gradient(v, name='freezed_' + name)
        return v
    return custom_getter_scope(custom_getter)