a
    Sic1                     @   s   d 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 ejjd	d
dZedG dd de	ejdZdd ZdS )zEContains the base ProcessingLayer and a subclass that uses Combiners.    N)data_adapter)Layer)version_utils)context)keras_export)doc_controlsz*/tensorflow/api/keras/layers/preprocessingz keras preprocessing layers usagemethodz:keras.layers.experimental.preprocessing.PreprocessingLayerc                       s   e Zd ZdZdZ fddZedd Zej	dd Z
ej	d	d
 Zej	dd Zej	dd ZdddZdddZdd Zejjjdd Zdd Z  ZS )PreprocessingLayeraO  Base class for Preprocessing Layers.

    **Don't use this class directly: it's an abstract base class!** You may
    be looking for one of the many built-in
    [preprocessing layers](https://keras.io/guides/preprocessing_layers/)
    instead.

    Preprocessing layers are layers whose state gets computed before model
    training starts. They do not get updated during training. Most
    preprocessing layers implement an `adapt()` method for state computation.

    The `PreprocessingLayer` class is the base class you would subclass to
    implement your own preprocessing layers.
    Tc                    s8   t  jf i | d| _d| _| j| _| j| _d | _d S )NF)super__init___is_compiled_is_adaptedreset_state_reset_state_impl_reset_state_wrapper_adapt_function)selfkwargs	__class__ a/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/engine/base_preprocessing_layer.pyr   8   s    zPreprocessingLayer.__init__c                 C   s   | j S )z/Whether the layer has been fit to data already.)r   r   r   r   r   
is_adaptedC   s    zPreprocessingLayer.is_adaptedc                 C   s   t dS )zAccumulates statistics for the preprocessing layer.

        Arguments:
          data: A mini-batch of inputs to the layer.
        NNotImplementedError)r   datar   r   r   update_stateH   s    zPreprocessingLayer.update_statec                 C   s   t dS )z1Resets the statistics of the preprocessing layer.Nr   r   r   r   r   r   Q   s    zPreprocessingLayer.reset_statec                 C   s   dS )a3  Finalize the statistics for the preprocessing layer.

        This method is called at the end of `adapt` or after restoring a
        serialized preprocessing layer's state. This method handles any one-time
        operations that should occur on the layer's state before
        `Layer.__call__`.
        Nr   r   r   r   r   finalize_stateV   s    	z!PreprocessingLayer.finalize_statec                    s^   j durj S fdd j  dkr4 }n fdd}jsRt|}|_ j S )a  Creates a function to execute one step of `adapt`.

        This method can be overridden to support custom adapt logic.
        This method is called by `PreprocessingLayer.adapt`.

        Typically, this method directly controls `tf.function` settings,
        and delegates the actual state update logic to
        `PreprocessingLayer.update_state`.

        This function is cached the first time `PreprocessingLayer.adapt`
        is called. The cache is cleared whenever `PreprocessingLayer.compile`
        is called.

        Returns:
          Function. The function created by this method should accept a
          `tf.data.Iterator`, retrieve a batch, and update the state of the
          layer.
        Nc                    s    t | } |  | d S N)next_adapt_maybe_buildr   )iteratorr   r   r   r   
adapt_stepx   s    
z:PreprocessingLayer.make_adapt_function.<locals>.adapt_step   c                    s   t jD ]} |  qd S r   )tfrange_steps_per_execution)r"   _r#   r   r   r   adapt_fn   s    z8PreprocessingLayer.make_adapt_function.<locals>.adapt_fn)r   r'   numpyitem_run_eagerlyr%   function)r   r*   r   r)   r   make_adapt_functiona   s    

z&PreprocessingLayer.make_adapt_functionNc                 C   s4   |du rd}|  | |du r$| j}|| _d| _dS )a`  Configures the layer for `adapt`.

        Arguments:
          run_eagerly: Bool. Defaults to `False`. If `True`, this `Model`'s
            logic will not be wrapped in a `tf.function`. Recommended to leave
            this as `None` unless your `Model` cannot be run inside a
            `tf.function`.
          steps_per_execution: Int. Defaults to 1. The number of batches to run
            during each `tf.function` call. Running multiple batches inside a
            single `tf.function` call can greatly improve performance on TPUs or
            small models with a large Python overhead.
        Nr$   T)_configure_steps_per_executiondynamicr-   r   )r   run_eagerlysteps_per_executionr   r   r   compile   s    
zPreprocessingLayer.compilec              	   C   s   t d t std| js&|   | jr4|   tj	|||d| j
dd}|  | _| D ]V\}}| 6 | D ]}| | |jrxt  qxW d   q^1 s0    Y  q^|   d| _dS )a  Fits the state of the preprocessing layer to the data being passed.

        After calling `adapt` on a layer, a preprocessing layer's state will not
        update during training. In order to make preprocessing layers efficient
        in any distribution context, they are kept constant with respect to any
        compiled `tf.Graph`s that call the layer. This does not affect the layer
        use when adapting each layer only once, but if you adapt a layer
        multiple times you will need to take care to re-compile any compiled
        functions as follows:

         * If you are adding a preprocessing layer to a `keras.Model`, you need
           to call `model.compile` after each subsequent call to `adapt`.
         * If you are calling a preprocessing layer inside
          `tf.data.Dataset.map`, you should call `map` again on the input
          `tf.data.Dataset` after each `adapt`.
         * If you are using a `tf.function` directly which calls a preprocessing
           layer, you need to call `tf.function` again on your callable after
           each subsequent call to `adapt`.

        `tf.keras.Model` example with multiple adapts:

        >>> layer = tf.keras.layers.Normalization(
        ...     axis=None)
        >>> layer.adapt([0, 2])
        >>> model = tf.keras.Sequential(layer)
        >>> model.predict([0, 1, 2])
        array([-1.,  0.,  1.], dtype=float32)
        >>> layer.adapt([-1, 1])
        >>> model.compile() # This is needed to re-compile model.predict!
        >>> model.predict([0, 1, 2])
        array([0., 1., 2.], dtype=float32)

        `tf.data.Dataset` example with multiple adapts:

        >>> layer = tf.keras.layers.Normalization(
        ...     axis=None)
        >>> layer.adapt([0, 2])
        >>> input_ds = tf.data.Dataset.range(3)
        >>> normalized_ds = input_ds.map(layer)
        >>> list(normalized_ds.as_numpy_iterator())
        [array([-1.], dtype=float32),
         array([0.], dtype=float32),
         array([1.], dtype=float32)]
        >>> layer.adapt([-1, 1])
        >>> normalized_ds = input_ds.map(layer) # Re-map over the input dataset.
        >>> list(normalized_ds.as_numpy_iterator())
        [array([0.], dtype=float32),
         array([1.], dtype=float32),
         array([2.], dtype=float32)]

        `adapt()` is meant only as a single machine utility to compute layer
        state.  To analyze a dataset that cannot fit on a single machine, see
        [Tensorflow Transform](
        https://www.tensorflow.org/tfx/transform/get_started)
        for a multi-machine, map-reduce solution.

        Arguments:
            data: The data to train on. It can be passed either as a tf.data
              Dataset, or as a numpy array.
            batch_size: Integer or `None`.
                Number of samples per state update. If unspecified,
                `batch_size` will default to 32.  Do not specify the
                `batch_size` if your data is in the form of datasets,
                generators, or `keras.utils.Sequence` instances (since they
                generate batches).
            steps: Integer or `None`.
                Total number of steps (batches of samples)
                When training with input tensors such as
                TensorFlow data tensors, the default `None` is equal to
                the number of samples in your dataset divided by
                the batch size, or 1 if that cannot be determined. If x is a
                `tf.data` dataset, and 'steps' is None, the epoch will run until
                the input dataset is exhausted. When passing an infinitely
                repeating dataset, you must specify the `steps` argument. This
                argument is not supported with array inputs.
        adaptz+`adapt` is only supported in tensorflow v2.r$   F)
batch_sizesteps_per_epochepochsr3   
distributeNT)_disallow_inside_tf_functionr   should_use_v2RuntimeErrorr   r4   builtr   r   DataHandlerr'   r/   r   enumerate_epochscatch_stop_iterationstepsshould_syncr   
async_waitr   r   )r   r   r6   rA   data_handlerr(   r"   r   r   r   r5      s0    M


*zPreprocessingLayer.adaptc                 C   s   |    d| _dS )z2Calls `reset_state` and sets `adapted` to `False`.FN)r   r   r   r   r   r   r     s    z'PreprocessingLayer._reset_state_wrapperc                 C   s   t j|dt jjd| _d S )Nint64)dtypeaggregation)r%   VariableVariableAggregationONLY_FIRST_REPLICAr'   )r   r3   r   r   r   r0     s
    z1PreprocessingLayer._configure_steps_per_executionc                 C   sn   | j sjz|j}td gt|j }W n ty>   d }d }Y n0 t| dd }|d u rZ|| _| | d| _ d S )N_batch_input_shapeT)r=   shapetuplelenAttributeErrorgetattrrK   build)r   r   
data_shapedata_shape_nonesbatch_input_shaper   r   r   r!     s    

z%PreprocessingLayer._adapt_maybe_build)NN)NN)__name__
__module____qualname____doc___must_restore_from_configr   propertyr   r   do_not_generate_docsr   r   r   r/   r4   r5   r   r%   __internal__tracking no_automatic_dependency_trackingr0   r!   __classcell__r   r   r   r   r	   %   s&   





)

f
r	   )	metaclassc                 C   s    t  rdj| d}t|dS )z1Disallow calling a method inside a `tf.function`.a  Detected a call to `PreprocessingLayer.{method_name}` inside a `tf.function`. `PreprocessingLayer.{method_name} is a high-level endpoint that manages its own `tf.function`. Please move the call to `PreprocessingLayer.{method_name}` outside of all enclosing `tf.function`s. Note that you can call a `PreprocessingLayer` directly on `Tensor`s inside a `tf.function` like: `layer(x)`, or update its state like: `layer.update_state(x)`.)method_nameN)r%   inside_functionformatr<   )ra   	error_msgr   r   r   r:   +  s    	r:   )rX   abctensorflow.compat.v2compatv2r%   keras.enginer   keras.engine.base_layerr   keras.utilsr   tensorflow.python.eagerr    tensorflow.python.util.tf_exportr   tensorflow.tools.docsr   r\   
monitoring	BoolGaugeZkeras_kpl_gaugeABCMetar	   r:   r   r   r   r   <module>   s$     