Search code examples
tensorflowedward

where is the location of class Normal in edward's source code?


When using edward, we always use from edward.models import Normal , but i didn't find the declaration of Normal in github

anybody who can tell me where is it


Solution

  • They are defined in edward/models/random_variables.py.

    You import the Normal class like this:

    from edward.models import Normal
    

    This suggests looking in edward/models/__init__.py, which has this line:

    from edward.models.random_variables import *
    

    Looking in edward/models/random_variables.py we find this code:

    from edward.models.random_variable import RandomVariable as _RandomVariable
    from tensorflow.contrib import distributions as _distributions
    
    # Automatically generate random variable classes from classes in
    # tf.contrib.distributions.
    _globals = globals()
    for _name in sorted(dir(_distributions)):
      _candidate = getattr(_distributions, _name)
      if (_inspect.isclass(_candidate) and
              _candidate != _distributions.Distribution and
              issubclass(_candidate, _distributions.Distribution)):
    
        # to use _candidate's docstring, must write a new __init__ method
        def __init__(self, *args, **kwargs):
          _RandomVariable.__init__(self, *args, **kwargs)
        __init__.__doc__ = _candidate.__init__.__doc__
        _params = {'__doc__': _candidate.__doc__,
                   '__init__': __init__}
        _globals[_name] = type(_name, (_RandomVariable, _candidate), _params)
    
    del _candidate
    

    This goes through the tensorflow.contrib.distributions module looking for classes derived from tensorflow.contrib.distributions.Distribution (ignoring other attributes like e.g. the __file__ member of the module, or the base Distribution class itself). For each one, it does a bit of hacking (which only affects the generated documentation) then executes this key line:

    _globals[_name] = type(_name, (_RandomVariable, _candidate), _params)
    

    The type() built-in function creates a new type i.e. declares a new class. The second parameter is the list of base classes, which here is edward's RandomVariable class and the TensorFlow random variable class. Earlier it defined _globals to be globals(), which is a built-in function returning the dictionary of the module's variables. Therefore, in the case you're interested in, the line above is equivalent to the following:

    from edward.models.random_variable import RandomVariable as EdRandVar
    from tensorflow.contrib.distributions import Normal as TfNormal
    Normal = type("Normal", (EdRandVar, TfNormal), {...})
    

    Which in turn is equivalent to this (if you ignore the docstring stuff):

    from edward.models.random_variable import RandomVariable as EdRandVar
    from tensorflow.contrib.distributions import Normal as TfNormal
    class Normal(EdRandVar, TfNormal):
        pass