a
    /Sic?                     @   s   d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ ed
G dd
 d
e
jZdd Zdd Zdd Zdd ZedZedZdd Zdd ZdddZdS )z1Modules encapsulate building stateful components.    N)tf2)ops)	variables)autotrackable)nest)tf_decorator)	tf_exportModulec                   @   s   e Zd ZdZedZdddZedd Zedd	 Z	ed
d Z
edd Zedd Zedd ZdddZedd ZdS )r	   a
  Base neural network module class.

  A module is a named container for `tf.Variable`s, other `tf.Module`s and
  functions which apply to user input. For example a dense layer in a neural
  network might be implemented as a `tf.Module`:

  >>> class Dense(tf.Module):
  ...   def __init__(self, input_dim, output_size, name=None):
  ...     super(Dense, self).__init__(name=name)
  ...     self.w = tf.Variable(
  ...       tf.random.normal([input_dim, output_size]), name='w')
  ...     self.b = tf.Variable(tf.zeros([output_size]), name='b')
  ...   def __call__(self, x):
  ...     y = tf.matmul(x, self.w) + self.b
  ...     return tf.nn.relu(y)

  You can use the Dense layer as you would expect:

  >>> d = Dense(input_dim=3, output_size=2)
  >>> d(tf.ones([1, 3]))
  <tf.Tensor: shape=(1, 2), dtype=float32, numpy=..., dtype=float32)>


  By subclassing `tf.Module` instead of `object` any `tf.Variable` or
  `tf.Module` instances assigned to object properties can be collected using
  the `variables`, `trainable_variables` or `submodules` property:

  >>> d.variables
      (<tf.Variable 'b:0' shape=(2,) dtype=float32, numpy=...,
      dtype=float32)>,
      <tf.Variable 'w:0' shape=(3, 2) dtype=float32, numpy=..., dtype=float32)>)


  Subclasses of `tf.Module` can also take advantage of the `_flatten` method
  which can be used to implement tracking of any other types.

  All `tf.Module` classes have an associated `tf.name_scope` which can be used
  to group operations in TensorBoard and create hierarchies for variable names
  which can help with debugging. We suggest using the name scope when creating
  nested submodules/parameters or for forward methods whose graph you might want
  to inspect in TensorBoard. You can enter the name scope explicitly using
  `with self.name_scope:` or you can annotate methods (apart from `__init__`)
  with `@tf.Module.with_name_scope`.

  >>> class MLP(tf.Module):
  ...   def __init__(self, input_size, sizes, name=None):
  ...     super(MLP, self).__init__(name=name)
  ...     self.layers = []
  ...     with self.name_scope:
  ...       for size in sizes:
  ...         self.layers.append(Dense(input_dim=input_size, output_size=size))
  ...         input_size = size
  ...   @tf.Module.with_name_scope
  ...   def __call__(self, x):
  ...     for layer in self.layers:
  ...       x = layer(x)
  ...     return x

  >>> module = MLP(input_size=5, sizes=[5, 5])
  >>> module.variables
  (<tf.Variable 'mlp/b:0' shape=(5,) dtype=float32, numpy=..., dtype=float32)>,
  <tf.Variable 'mlp/w:0' shape=(5, 5) dtype=float32, numpy=...,
     dtype=float32)>,
  <tf.Variable 'mlp/b:0' shape=(5,) dtype=float32, numpy=..., dtype=float32)>,
  <tf.Variable 'mlp/w:0' shape=(5, 5) dtype=float32, numpy=...,
     dtype=float32)>)
  )+_self_unconditional_checkpoint_dependencies$_self_unconditional_dependency_namesNc                 C   s   |d u rt t| j}nt|s,td| || _t rrt	|}t	|| _
W d    q1 sf0    Y  n4tj|dd}|| _W d    n1 s0    Y  d S )Nzg%r is not a valid module name. Module names must be valid Python identifiers (e.g. a valid class name).Fskip_on_eager)camel_to_snaketype__name__valid_identifier
ValueError_namer   enabledr   name_scope_v2_name_scope
name_scope_scope_name)selfname
scope_name r   [/var/www/html/django/DPS/env/lib/python3.9/site-packages/tensorflow/python/module/module.py__init__l   s    ,zModule.__init__c                 C   s   | j S )zReturns the name of this module as passed or determined in the ctor.

    NOTE: This is not the same as the `self.name_scope.name` which includes
    parent module names.
    )r   r   r   r   r   r   }   s    zModule.namec                 C   s"   t  r| jS tj| jddS dS )z2Returns a `tf.name_scope` instance for this class.Fr   N)r   r   r   r   r   r   r   r   r   r   r      s    zModule.name_scopec                 C   s   t | jtddS )a  Sequence of variables owned by this module and its submodules.

    Note: this method uses reflection to find variables on the current instance
    and submodules. For performance reasons you may wish to cache the result
    of calling this method if you don't expect the return value to change.

    Returns:
      A sequence of variables for the current module (sorted by attribute
      name) followed by variables from all submodules recursively (breadth
      first).
    T	predicateexpand_composites)tuple_flatten_is_variabler   r   r   r   r      s    zModule.variablesc                 C   s   t | jtddS )a  Sequence of trainable variables owned by this module and its submodules.

    Note: this method uses reflection to find variables on the current instance
    and submodules. For performance reasons you may wish to cache the result
    of calling this method if you don't expect the return value to change.

    Returns:
      A sequence of variables for the current module (sorted by attribute
      name) followed by variables from all submodules recursively (breadth
      first).
    Tr    )r#   r$   _is_trainable_variabler   r   r   r   trainable_variables   s    zModule.trainable_variablesc                 C   s   t | jtdS )a  Sequence of non-trainable variables owned by this module and its submodules.

    Note: this method uses reflection to find variables on the current instance
    and submodules. For performance reasons you may wish to cache the result
    of calling this method if you don't expect the return value to change.

    Returns:
      A sequence of variables for the current module (sorted by attribute
      name) followed by variables from all submodules recursively (breadth
      first).
    r!   )r#   r$   _is_non_trainable_variabler   r   r   r   non_trainable_variables   s    zModule.non_trainable_variablesc                 C   s   t | jtdS )a  Sequence of all sub-modules.

    Submodules are modules which are properties of this module, or found as
    properties of modules which are properties of this module (and so on).

    >>> a = tf.Module()
    >>> b = tf.Module()
    >>> c = tf.Module()
    >>> a.b = b
    >>> b.c = c
    >>> list(a.submodules) == [b, c]
    True
    >>> list(b.submodules) == [c]
    True
    >>> list(c.submodules) == []
    True

    Returns:
      A sequence of all submodules.
    r(   )r#   r$   
_is_moduler   r   r   r   
submodules   s    zModule.submodulesTFc              	   C   s(   |du rdd }t | ||| j|||dS )a  Flattened attribute values in sorted order by attribute name.

    Modules are flattened by first walking their attributes in name order.
    Each attribute value is then flattened to find leaf values. If flatten is
    applied `recursive`ly and if the leaf is a `Module` it will also be
    flattened to find leaves. Finally every leaf value is optionally tested
    against the given `predicate` and finally yielded.

    ```
    class Foo(tf.Module):
      def __init__(self):
        super(Foo, self).__init__()
        self.x = [tf.constant('a'), tf.constant('b')]
        self.y = {'i': tf.constant('c'), 'j': tf.constant('d')}
        self.z = tf.constant('e')

      @property
      def tensors(self):
        return tuple(self._flatten(predicate=is_tensor, with_path=True))

    foo = Foo()
    foo.tensors
    # ==> ((('x', 0),   <tf.Tensor: ...'a'>),
    #     (('x', 1),   <tf.Tensor: ...'b'>),
    #     (('y', 'i'), <tf.Tensor: ...'c'>),
    #     (('y', 'j'), <tf.Tensor: ...'d'>),
    #     (('z',),     <tf.Tensor: ...'e'>))
    ```

    `attribute_traversal_key` controls the order object properties are visited.
    If not set objects are visited in ascending order by name.

    Args:
      recursive: Whether to recurse into child modules or not.
      predicate: (Optional) If set then only values matching predicate are
        yielded. A value of `None` (the default) means no items will be
        filtered.
      attribute_traversal_key: (Optional) Method to rekey object attributes
        before they are sorted. Contract is the same as `key` argument to
        builtin `sorted` and only applies to object properties.
      with_path: (Optional) Whether to include the path to the object as well
        as the object itself. If `with_path` is `True` then leaves will not be
        de-duplicated (e.g. if the same leaf instance is reachable via multiple
        modules then it will be yielded multiple times with different paths).
      expand_composites: If true, then composite tensors are expanded into their
        component tensors.

    Returns:
      Flat generator for leaves of the current module and optionally all
      submodules.
    Nc                 S   s   dS )NTr   )_r   r   r   <lambda>      z!Module._flatten.<locals>.<lambda>)	recursiver!   attributes_to_ignoreattribute_traversal_key	with_pathr"   )_flatten_module_TF_MODULE_IGNORED_PROPERTIES)r   r0   r!   r2   r3   r"   r   r   r   r$      s    9zModule._flattenc                    s    fdd}t  |S )a)  Decorator to automatically enter the module name scope.

    >>> class MyModule(tf.Module):
    ...   @tf.Module.with_name_scope
    ...   def __call__(self, x):
    ...     if not hasattr(self, 'w'):
    ...       self.w = tf.Variable(tf.random.normal([x.shape[1], 3]))
    ...     return tf.matmul(x, self.w)

    Using the above module would produce `tf.Variable`s and `tf.Tensor`s whose
    names included the module name:

    >>> mod = MyModule()
    >>> mod(tf.ones([1, 2]))
    <tf.Tensor: shape=(1, 3), dtype=float32, numpy=..., dtype=float32)>
    >>> mod.w
    <tf.Variable 'my_module/Variable:0' shape=(2, 3) dtype=float32,
    numpy=..., dtype=float32)>

    Args:
      method: The method to wrap.

    Returns:
      The original method wrapped such that it enters the module's name scope.
    c                    s@   | j &  | g|R i |W  d    S 1 s20    Y  d S N)r   )r   argskwargsmethodr   r   method_with_name_scope5  s    z6Module.with_name_scope.<locals>.method_with_name_scope)r   make_decorator)clsr:   r;   r   r9   r   with_name_scope  s    zModule.with_name_scope)N)TNNFF)r   
__module____qualname____doc__	frozensetr5   r   propertyr   r   r   r'   r*   r,   r$   classmethodr>   r   r   r   r   r	      s.   G






     
Ec                 C   s   t | tjS r6   )
isinstancer   Variableobjr   r   r   r%   <  s    r%   c                 C   s   t | ot| ddS N	trainableFr%   getattrrG   r   r   r   r&   @  s    r&   c                 C   s   t | ot| dd S rI   rK   rG   r   r   r   r)   D  s    r)   c                 C   s
   t | tS r6   )rE   r	   rG   r   r   r   r+   H  s    r+   z(((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))z^[a-zA-Z_]([a-zA-Z0-9_])*$c                 C   s   t t| S r6   )bool_VALID_IDENTIFIERmatch)r   r   r   r   r   O  s    r   c                 C   s   t d|  S )Nz_\1)_CAMEL_TO_SNAKE_Rsublower)valuer   r   r   r   S  s    r   r   c
                 c   s  t | }
|du rt|
g}t| }g }|	du r2g }	|
|	v r>d}t||dD ]}||v rXqJ|| }ztj||d}W n< ty } z$tt	d
||| W Y d}~n
d}~0 0 |D ]v\}}|f| }|st |}||v rq|| ||r|r|| |fV  n|V  |rt|r||| |f qqJ|	|
 |D ]:\}}t|||||j|||||	d
}|D ]}|V  qfq<|	  dS )a$  Implementation of `flatten`.

  Args:
    module: Current module to process.
    recursive: Whether to recurse into child modules or not.
    predicate: (Optional) If set then only values matching predicate are
      yielded. A value of `None` (the default) means no items will be
      filtered.
    attribute_traversal_key: (Optional) Method to rekey object attributes
      before they are sorted. Contract is the same as `key` argument to
      builtin `sorted` and only applies to object properties.
    attributes_to_ignore: object attributes to ignored.
    with_path: (Optional) Whether to include the path to the object as well
      as the object itself. If `with_path` is `True` then leaves will not be
      de-duplicated (e.g. if the same leaf instance is reachable via multiple
      modules then it will be yielded multiple times with different paths).
    expand_composites: If true, then composite tensors are expanded into their
      component tensors.
    module_path: The path to the current module as a tuple.
    seen: A set containing all leaf IDs seen so far.
    recursion_stack: A list containing all module IDs associated with the
      current call stack.

  Yields:
    Matched leaves with the optional corresponding paths of the current module
    and optionally all its submodules.
  NF)key)r"   z&Error processing property {!r} of {!r})	r0   r!   r2   r1   r3   r"   module_pathseenrecursion_stack)idsetvarssortedr   flatten_with_tuple_paths	Exceptionsix
raise_fromr   formataddr+   appendr4   r5   pop)moduler0   r!   r2   r1   r3   r"   rU   rV   rW   	module_idmodule_dictr,   rT   propleavescause	leaf_pathleafZleaf_idZsubmodule_path	submoduleZ	subvaluessubvaluer   r   r   r4   W  sl    %
	





r4   )r   NN)rA   rer^   tensorflow.pythonr   tensorflow.python.frameworkr   tensorflow.python.opsr   tensorflow.python.trackabler   tensorflow.python.utilr   r    tensorflow.python.util.tf_exportr   AutoTrackabler	   r%   r&   r)   r+   compilerP   rN   r   r   r4   r   r   r   r   <module>   s2     

   