a
    Sic*h                     @   s>  d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlm  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 ddlmZ ddlmZ ddlmZ daedgdedgdejdd Zedgdedgddd Z dd Z!edgdedgdG dd dej"Z"dd  Z#dS )!z=Contains the base Layer class, from which all layers inherit.    )absolute_import)division)print_functionN)backend)base_layer_utils)base_layer_v1)variable_scope_shim)policy)tf_contextlib)variable_scope)keras_export)	tf_exportFz?keras.__internal__.legacy.layers.experimental.keras_style_scope)v1z%layers.experimental.keras_style_scopec                  c   s"   t } da zdV  W | a n| a 0 dS )aU  Use Keras-style variable management.

    All tf.layers and tf RNN cells created in this scope use Keras-style
    variable management.  Creating such layers with a scope= argument is
    disallowed, and reuse=True is disallowed.

    The purpose of this scope is to allow users of existing layers to
    slowly transition to a Keras layers API without breaking existing
    functionality.

    One example of this is when using TensorFlow's RNN classes with Keras
    Models or Networks.  Because Keras models do not properly set variable
    scopes, users of RNNs may either accidentally share scopes between two
    different models, or get errors about variables that already exist.

    Example:

    ```python
    class RNNModel(tf.keras.Model):

      def __init__(self, name):
        super(RNNModel, self).__init__(name=name)
        self.rnn = tf.compat.v1.nn.rnn_cell.MultiRNNCell(
          [tf.compat.v1.nn.rnn_cell.LSTMCell(64) for _ in range(2)])

      def call(self, input, state):
        return self.rnn(input, state)

    model_1 = RNNModel("model_1")
    model_2 = RNNModel("model_2")

    # OK
    output_1, next_state_1 = model_1(input, state)
    # Raises an error about trying to create an already existing variable.
    output_2, next_state_2 = model_2(input, state)
    ```

    The solution is to wrap the model construction and execution in a
    keras-style scope:

    ```python
    with keras_style_scope():
      model_1 = RNNModel("model_1")
      model_2 = RNNModel("model_2")

      # model_1 and model_2 are guaranteed to create their own variables.
      output_1, next_state_1 = model_1(input, state)
      output_2, next_state_2 = model_2(input, state)

      assert len(model_1.weights) > 0
      assert len(model_2.weights) > 0
      assert(model_1.weights != model_2.weights)
    ```

    Yields:
      A keras layer style scope.
    TN_KERAS_STYLE_SCOPE)stack r   W/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/legacy_tf_layers/base.pykeras_style_scope)   s
    @r   z=keras.__internal__.legacy.layers.experimental.set_keras_stylez#layers.experimental.set_keras_stylec                   C   s   da dS )a  Use Keras-style variable management.

    All tf.layers and tf RNN cells created after keras style ha been enabled
    use Keras-style variable management.  Creating such layers with a
    scope= argument is disallowed, and reuse=True is disallowed.

    The purpose of this function is to allow users of existing layers to
    slowly transition to Keras layers API without breaking existing
    functionality.

    For more details, see the documentation for `keras_style_scope`.

    Note, once keras style has been set, it is set globally for the entire
    program and cannot be unset.

    Example:

    ```python
    set_keras_style()

    model_1 = RNNModel(name="model_1")
    model_2 = RNNModel(name="model_2")

    # model_1 and model_2 are guaranteed to create their own variables.
    output_1, next_state_1 = model_1(input, state)
    output_2, next_state_2 = model_2(input, state)

    assert len(model_1.weights) > 0
    assert len(model_2.weights) > 0
    assert(model_1.weights != model_2.weights)
    ```
    TNr   r   r   r   r   set_keras_styleq   s    &r   c                   C   s   t S Nr   r   r   r   r   _is_in_keras_style_scope   s    r   z&keras.__internal__.legacy.layers.Layerzlayers.Layerc                	       s   e Zd ZdZd" fdd	Zdd Zedd	 Zd
d Zd#ddZ	edd Z
d$ fdd	Z fddZd%ddZddddddejjejjjjdf	 fdd	Z fddZdd Z fddZed d! Z  ZS )&LayeraX  Base layer class.

    It is considered legacy, and we recommend the use of `tf.keras.layers.Layer`
    instead.

    Args:
      trainable: Boolean, whether the layer's variables should be trainable.
      name: String name of the layer.
      dtype: Default dtype of the layer's weights (default of `None` means use
        the type of the first input).

    Read-only properties:
      name: The name of the layer (string).
      dtype: Default dtype of the layer's weights (default of `None` means use
        the type of the first input).
      trainable_variables: List of trainable variables.
      non_trainable_variables: List of non-trainable variables.
      variables: List of all variables of this layer, trainable and
        non-trainable.
      updates: List of update ops of this layer.
      losses: List of losses added by this layer.
      trainable_weights: List of variables to be included in backprop.
      non_trainable_weights: List of variables that should not be
        included in backprop.
      weights: The concatenation of the lists trainable_weights and
        non_trainable_weights (in this order).

    Mutable properties:
      trainable: Whether the layer should be trained (boolean).
      input_spec: Optional (list of) `InputSpec` object(s) specifying the
        constraints on inputs that can be accepted by the layer.
    TNc                    s
  d| _ |dd }|dd | _g | _d| _|d u r>td}d|vrNd|d< d| _t j	f |||d| t
 r|d urtd|| jd urtd	| jd| _nd| _d
| jjv | _|rtjj|}|| _W d    n1 s0    Y  nd | _d | _d S )NF_scope_reuse_inferautocastT)	trainablenamedtypeKscope argument not allowed when keras style layers are enabled, but saw: {}zKreuse argument not allowed when keras style layers are enabled, but saw: {}scope)_use_resource_variablespopr   _trainable_weightsbuiltr	   Policy_disable_keras_instrumentationsuper__init__r   
ValueErrorformat_keras_style
_call_spec	arg_names_call_has_scope_argtfcompatr   r   r   _current_scope)selfr   r   r   kwargsr!   captured_scope	__class__r   r   r)      s@    

&zLayer.__init__c                 O   s   | |i |S r   r   )r3   argsr4   r   r   r   apply   s    zLayer.applyc                 C   s"   t jddd t rtdd S )Nz`Layer.graph` is deprecated and will be removed in a future version. Please stop using this property because tf.layers layers no longer track their graph.   )
stacklevelz1Layer.graph not supported when executing eagerly.)warningswarnr0   executing_eagerlyRuntimeErrorr3   r   r   r   graph   s    zLayer.graphc                 C   sL   t |tjjjr&|j}|  \| _}n
|}|| _|sB|  \| _}|| _d S r   )	
isinstancer0   r1   r   VariableScoper   _make_unique_name_name
_base_name)r3   r   	base_name_r   r   r   _init_set_name  s    zLayer._init_set_name Fc                 C   s*   t | jj}tj|||||d}||fS )N)name_uid_mapavoid_names	namespace
zero_based)
base_layerto_snake_caser7   __name__r   unique_object_name)r3   rK   rL   rM   rN   rG   r   r   r   r   rD     s    zLayer._make_unique_namec                 C   s,   | j s$td| j d d d d | j jS )Nz5No name available for layer scope because the layer "z(" has not been used yet. The scope name z4 is determined the first time the layer instance is z1called. You must therefore call the layer before zquerying `scope_name`.)r   r*   rE   r   r@   r   r   r   
scope_name$  s    zLayer.scope_namec           	         s   t | j}t | j}t j||d t s|| j|d  }| j|d  }|D ]}| }|d urL|| qLt|tj	j
jj d S )N)inputs)len_losses_callable_lossesr(   add_lossr0   r>   append_add_elements_to_collectionr1   r   	GraphKeysREGULARIZATION_LOSSES)	r3   lossesrT   previous_losses_lengthprevious_callable_losses_length
new_lossesnew_callable_lossesregularizerloss_tensorr6   r   r   rX   1  s    

zLayer.add_lossc                    s   | j rt  S | jjS )z#Determines op naming for the Layer.)r,   r(   _name_scoper2   original_name_scoper@   r6   r   r   rd   C  s    
zLayer._name_scopec                 C   s   | j d u r| jrTtjj|d ur$|n| j}|| _ W d    q1 sH0    Y  n:tjjj|| jd}|| _ W d    n1 s0    Y  d S )N)default_name)r   r   r0   r1   r   r   rF   )r3   r!   r5   r   r   r   
_set_scopeI  s    
&zLayer._set_scopec                    s  |D ]}|dkrt d|q| jr^t jf ||||||o<| j||tjjtjj	j
j|d|S |	tjjkr~|rxtdqd}n|du rd}dd	 }d}t stjj	 }|jrt 4 t stjj	 }ttjj	 }W d   n1 s0    Y  n|}ttjj	 }|du r.| jp,tj}| d | jpD| j}t| j}tjj	j| j|dd
|}|| _t|   D |p| j!p|j"}|du r|j#}t j||ft$|||o| j||||	|
tjj	j%d	|}|r2tjj	& s|||r2| '||| t() }t*|dr2|+|| |dur|,  tjj	- }W d   n1 sh0    Y  |r| jr||vr| j|d }| jd| | _|  j.|7  _.W d   n1 s0    Y  W d   n1 s0    Y  |S )an
  Adds a new variable to the layer, or gets an existing one; returns it

        Args:
          name: variable name.
          shape: variable shape.
          dtype: The type of the variable. Defaults to `self.dtype` or
            `float32`.
          initializer: initializer instance (callable).
          regularizer: regularizer instance (callable).
          trainable: whether the variable should be part of the layer's
            "trainable_variables" (e.g. variables, biases)
            or "non_trainable_variables" (e.g. BatchNorm mean, stddev).
            Note, if the current variable scope is marked as non-trainable
            then this parameter is ignored and any added variables are also
            marked as non-trainable. `trainable` defaults to `True` unless
            `synchronization` is set to `ON_READ`.
          constraint: constraint instance (callable).
          use_resource: Whether to use `ResourceVariable`.
          synchronization: Indicates when a distributed a variable will be
            aggregated. Accepted values are constants defined in the class
            `tf.VariableSynchronization`. By default the synchronization is set
            to `AUTO` and the current `DistributionStrategy` chooses when to
            synchronize. If `synchronization` is set to `ON_READ`, `trainable`
            must not be set to `True`.
          aggregation: Indicates how a distributed variable will be aggregated.
            Accepted values are constants defined in the class
            `tf.VariableAggregation`.
          partitioner: (optional) partitioner instance (callable).  If
            provided, when the requested variable is created it will be split
            into multiple partitions according to `partitioner`.  In this case,
            an instance of `PartitionedVariable` is returned.  Available
            partitioners include `tf.compat.v1.fixed_size_partitioner` and
            `tf.compat.v1.variable_axis_size_partitioner`.  For more details,
            see the documentation of `tf.compat.v1.get_variable` and the
            "Variable Partitioners and Sharding" section of the API guide.
          **kwargs: Additional keyword arguments.

        Returns:
          The created variable.  Usually either a `Variable` or
          `ResourceVariable` instance.  If `partitioner` is not `None`, a
          `PartitionedVariable` instance is returned.

        Raises:
          RuntimeError: If called with partitioned variable regularization and
            eager execution is enabled.
          ValueError: When trainable has been set to True with synchronization
            set as `ON_READ`.
        experimental_autocastzUnknown keyword argument:)r   shaper   initializerrb   r   
constraintuse_resourcesynchronizationaggregationpartitionerzSynchronization value can be set to VariableSynchronization.ON_READ only for non-trainable variables. You have specified trainable=True and synchronization=VariableSynchronization.ON_READ.FNTc                 S   s2   t | r&| D ]}||v r dS qdS | |vS d S )NFT)r   is_split_variable)variableexisting_variable_setvarr   r   r   _should_add_regularizer  s    
z1Layer.add_weight.<locals>._should_add_regularizerreuseauxiliary_name_scope)	r   rj   r   rk   ro   rl   rm   rn   getteradd_regularizer)/	TypeErrorr,   r(   
add_weightr   r0   VariableSynchronizationAUTOr1   r   VariableAggregationNONEON_READr*   r>   get_default_graphbuilding_function
init_scopesetglobal_variablesr   float32rg   r%   r   rU   r$   r   r   r2   r   
name_scoperd   r"   rl   rj   as_dtypeget_variable#executing_eagerly_outside_functions_handle_weight_regularizationvs_get_default_variable_storehasattrry   
as_defaulttrainable_variables_non_trainable_weights)r3   r   ri   r   rj   rb   r   rk   rl   rm   rn   ro   r4   kwargrt   
init_graphdefault_graphexisting_variablesrv   prev_len_trainabler!   rq   	var_storer   extra_trainable_varsr6   r   r   r{   W  s    ?
		


$







,NzLayer.add_weightc              	      sx  | dd}| jrB|dur(td|t j|g|R i |S | | | jrz
| j}W n t	yr   d}Y n0 |du rt
jjj| jddd}t
jj s|| _nt
jjj| j| jdd}|}|| _z
| j}W n8 t	y   t| j| j_d| jjv | _| j}Y n0 |r||d< t j|g|R i |}W d   n1 sL0    Y  t
 stt| jt
jjjj |S )a  Wraps `call`, applying pre- and post-processing steps.

        Args:
          inputs: input tensor(s).
          *args: additional positional arguments to be passed to `self.call`.
          **kwargs: additional keyword arguments to be passed to `self.call`.
            **Note**: kwarg `scope` is reserved for use by the layer.

        Returns:
          Output tensor(s).

        Note:
          - If the layer's `call` method takes a `scope` keyword argument, this
            argument will be automatically set to the current variable scope.
          - If the layer's `call` method takes a `mask` argument (as some Keras
            layers do), its default value will be set to the mask generated
            for `inputs` by the previous layer (if `input` did come from
            a layer that generated a corresponding mask, i.e. if it came from
            a Keras layer with masking support.

        Raises:
          ValueError: if the layer's `call` method returns None (an invalid
            value).
        r!   Nr    TFru   )r#   r,   r*   r+   r(   __call__rg   r%   _always_reuse_variable_scopeAttributeErrorr0   r1   r   r   r   r   r   r2   r/   r   fn_argscallr-   r.   r>   rZ   updatesr[   
UPDATE_OPS)r3   rT   r8   r4   r!   scope_context_managercall_has_scope_argoutputsr6   r   r   r     sT    




:
zLayer.__call__c                 C   s   t g d}t ddg}| j}||}||t| < | j D ]f\}}||v r\t||| q>||v rxt||t| q>t	|rt||| q>t||t
|| q>|S )N)_graph_thread_local_metrics_lockr   r   )r   r7   __new__id__dict__itemssetattrcopyrO   is_tensor_or_tensor_listdeepcopy)r3   memono_copyshallow_copyclsresultkvr   r   r   __deepcopy__w  s    

zLayer.__deepcopy__c                    s   t tjjj| || d S r   )r(   r0   __internal__tracking	Trackable__setattr__)r3   valuer   r6   r   r   r     s    zLayer.__setattr__c                 C   s   dS )zLUsed by keras to check compatibility. This should not be
        overridden.Tr   r@   r   r   r   _is_legacy_layer  s    zLayer._is_legacy_layer)TNN)NNrJ   F)N)N)rQ   
__module____qualname____doc__r)   r9   propertyrA   rI   rD   rS   rX   rd   rg   r0   r|   r}   r1   r   r~   r   r{   r   r   r   r   __classcell__r   r   r6   r   r      s@   !0
    



 HYr   c                 C   sz   t  rtd| |f t j| } t j|}|D ]@}t jj|}dd |D }| D ]}t||vrX|	| qXq4d S )NzPUsing collections from Layers not supported in Eager mode. Tried to add %s to %sc                 S   s   h | ]}t |qS r   )r   ).0er   r   r   	<setcomp>      z._add_elements_to_collection.<locals>.<setcomp>)
r0   r>   r?   nestflattenr1   r   get_collection_refr   rY   )elementscollection_listr   
collectioncollection_setelementr   r   r   rZ     s    rZ   )$r   
__future__r   r   r   r   r<   Ztensorflow.compat.v2r1   v2r0   kerasr   keras.enginer   r   rO   Zkeras.legacy_tf_layersr   keras.mixed_precisionr	   keras.utilsr
   tensorflow.python.opsr   r    tensorflow.python.util.tf_exportr   r   r   contextmanagerr   r   r   r   rZ   r   r   r   r   <module>   sF   
C
%

   v