B
    ӻd|?              	   @   s   d 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dlmZ ddlmZ ddlmZ dd ZedG dd dejZedddddZdS )z,Input layer code (`Input` and `InputLayer`).    )distribution_strategy_context)ops)tensor_shape)tensor_spec)backend)distributed_training_utils)
base_layer)keras_tensor)node)layer_serialization)tf_utils)keras_exportc             C   s   |d k	rt d|  d S )Nz\When `type_spec` is not None, all other args except `name` must be None, but %s is not None.)
ValueError)arg_namearg r   \/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/engine/input_layer.py_assert_other_arg_none    s    r   zkeras.layers.InputLayerc                   s6   e Zd ZdZd	 fdd	Zdd Zedd Z  ZS )

InputLayera	  Layer to be used as an entry point into a Network (a graph of layers).

  It can either wrap an existing tensor (pass an `input_tensor` argument)
  or create a placeholder tensor (pass arguments `input_shape`, and
  optionally, `dtype`).

  It is generally recommend to use the functional layer API via `Input`,
  (which creates an `InputLayer`) without directly using `InputLayer`.

  When using InputLayer with Keras Sequential model, it can be skipped by
  moving the input_shape parameter to the first layer after the InputLayer.

  This class can create placeholders for tf.Tensors, tf.SparseTensors, and
  tf.RaggedTensors by choosing 'sparse=True' or 'ragged=True'. Note that
  'sparse' and 'ragged' can't be configured to True at same time.
  Usage:

  ```python
  # With explicit InputLayer.
  model = tf.keras.Sequential([
    tf.keras.layers.InputLayer(input_shape=(4,)),
    tf.keras.layers.Dense(8)])
  model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
  model.fit(np.zeros((10, 4)),
            np.ones((10, 8)))

  # Without InputLayer and let the first layer to have the input_shape.
  # Keras will add a input for the model behind the scene.
  model = tf.keras.Sequential([
    tf.keras.layers.Dense(8, input_shape=(4,))])
  model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
  model.fit(np.zeros((10, 4)),
            np.ones((10, 8)))
  ```

  Args:
      input_shape: Shape tuple (not including the batch axis), or `TensorShape`
        instance (not including the batch axis).
      batch_size: Optional input batch size (integer or None).
      dtype: Optional datatype of the input. When not provided, the Keras
          default float type will be used.
      input_tensor: Optional tensor to use as layer input. If set, the layer
          will use the `tf.TypeSpec` of this tensor rather
          than creating a new placeholder tensor.
      sparse: Boolean, whether the placeholder created is meant to be sparse.
          Default to False.
      ragged: Boolean, whether the placeholder created is meant to be ragged.
          In this case, values of 'None' in the 'shape' argument represent
          ragged dimensions. For more information about RaggedTensors, see
          [this guide](https://www.tensorflow.org/guide/ragged_tensors).
          Default to False.
      type_spec: A `tf.TypeSpec` object to create Input from. This `tf.TypeSpec`
          represents the entire batch. When provided, all other args except
          name must be None.
      name: Optional name of the layer (string).
  Nc	          	      s  || _ || _|| _|| _|| _|| _t }
|
rl|d k	rlt	|
rl||
j
 dkrbtd||
j
||
j
 }d|	kr|	d}|r|rtd|r|d }|dd  }|	rtd|	 |r|rtd|sd}|d	 tt| }|s
|d krt }n
t|}n(|d k	r2|j|kr2td
|j|f tt| j||d d| _|rVdnd| _|rfdnd| _|| _d| _t|tjrt|  }nt|t!r|f}|d k	r~d| j fd| jfd| jfd|fd| jfd| jfg}x|D ]\}}t"|| qW t#$ stdt%&|}t|t%j'r0d| _t|t%j(rDd| _d| _)yt|j*  | _+W n tk
rz   d | _+Y nX n|d kr|d k	r|ft| }nd }t, }|-  tj.||| j/||d}W d Q R X d| _)|| _+npt#$ r
t|t%j0st%1|}nt23|stdd| _)yt|j*  | _+W n tk
rT   d | _+Y nX d |_4t5j6| |d t|t%j0st27|r|j8| _8nt9j:|j*|j| j/d| _8d S )Nr   zOThe `batch_size` argument ({}) must be divisible by the number of replicas ({})batch_input_shapezdOnly provide the input_shape OR batch_input_shape argument to InputLayer, not both at the same time.   zUnrecognized keyword arguments:z;Cannot set both sparse and ragged to True in a Keras input.input_z4`input_tensor.dtype` differs from `dtype`: %s vs. %s)dtypenameTFz(input_)shape
batch_sizer   input_tensorsparseraggedzYCreating Keras inputs from a type_spec is only supported when eager execution is enabled.)shaper   r   r   r   zYou should not pass an EagerTensor to `Input`. For example, instead of creating an InputLayer, you should instantiate your model and directly call it on your input.)layeroutputs)r   r   r   );Z_init_input_shapeZ_init_batch_sizeZ_init_dtypeZ_init_sparseZ_init_ragged_init_type_specr   Zget_strategyr   Zglobal_batch_size_supportedZnum_replicas_in_syncr   formatpopkeysstrr   Zget_uidZfloatxr   superr   __init__Zbuiltr   r   r   Zsupports_masking
isinstancer   ZTensorShapetupleas_listintr   r   Z#executing_eagerly_outside_functionsr	   Zkeras_tensor_from_type_specZSparseKerasTensorZRaggedKerasTensorZis_placeholderr   _batch_input_shapeZ	get_graphZ
as_defaultplaceholderr   ZKerasTensorZkeras_tensor_from_tensorr   Zis_symbolic_tensorZ_keras_masknode_moduleNodeZis_extension_typeZ
_type_specr   Z
TensorSpec)selfinput_shaper   r   r   r   r   r   	type_speckwargsZstrategyr   prefixZargs_that_must_be_noner   r   graph)	__class__r   r   r(   b   s    












zInputLayer.__init__c             C   s8   | j d k	r| j| j d}n| j| j| j| j| jd}|S )N)r   r3   )r   r   r   r   r   )r"   r   r-   r   r   r   )r1   configr   r   r   
get_config   s    

zInputLayer.get_configc             C   s
   t | S )N)r   ZInputLayerSavedModelSaver)r1   r   r   r   _trackable_saved_model_saver   s    z'InputLayer._trackable_saved_model_saver)NNNNNNNN)	__name__
__module____qualname____doc__r(   r9   propertyr:   __classcell__r   r   )r7   r   r   '   s   9        r   zkeras.Inputzkeras.layers.InputNc             K   s   |r|rt d||||||d}	|d|dd}
| dk	rN|
dk	rNt d|
dkrv| dkrv|dkrv|dkrvt d|rt d| |
r|
d	d } |	d|
i n|	|| d
 tf |	}|jd j}t|trt	|d	kr|d S |S dS )a  `Input()` is used to instantiate a Keras tensor.

  A Keras tensor is a symbolic tensor-like object,
  which we augment with certain attributes that allow us to build a Keras model
  just by knowing the inputs and outputs of the model.

  For instance, if `a`, `b` and `c` are Keras tensors,
  it becomes possible to do:
  `model = Model(input=[a, b], output=c)`

  Args:
      shape: A shape tuple (integers), not including the batch size.
          For instance, `shape=(32,)` indicates that the expected input
          will be batches of 32-dimensional vectors. Elements of this tuple
          can be None; 'None' elements represent dimensions where the shape is
          not known.
      batch_size: optional static batch size (integer).
      name: An optional name string for the layer.
          Should be unique in a model (do not reuse the same name twice).
          It will be autogenerated if it isn't provided.
      dtype: The data type expected by the input, as a string
          (`float32`, `float64`, `int32`...)
      sparse: A boolean specifying whether the placeholder to be created is
          sparse. Only one of 'ragged' and 'sparse' can be True. Note that,
          if `sparse` is False, sparse tensors can still be passed into the
          input - they will be densified with a default value of 0.
      tensor: Optional existing tensor to wrap into the `Input` layer.
          If set, the layer will use the `tf.TypeSpec` of this tensor rather
          than creating a new placeholder tensor.
      ragged: A boolean specifying whether the placeholder to be created is
          ragged. Only one of 'ragged' and 'sparse' can be True. In this case,
          values of 'None' in the 'shape' argument represent ragged dimensions.
          For more information about RaggedTensors, see
          [this guide](https://www.tensorflow.org/guide/ragged_tensors).
      type_spec: A `tf.TypeSpec` object to create the input placeholder from.
          When provided, all other args except name must be None.
      **kwargs: deprecated arguments support. Supports `batch_shape` and
          `batch_input_shape`.

  Returns:
    A `tensor`.

  Example:

  ```python
  # this is a logistic regression in Keras
  x = Input(shape=(32,))
  y = Dense(16, activation='softmax')(x)
  model = Model(x, y)
  ```

  Note that even if eager execution is enabled,
  `Input` produces a symbolic tensor-like object (i.e. a placeholder).
  This symbolic tensor-like object can be used with lower-level
  TensorFlow ops that take tensors as inputs, as such:

  ```python
  x = Input(shape=(32,))
  y = tf.square(x)  # This op will be treated like a layer
  model = Model(x, y)
  ```

  (This behavior does not work for higher-order TensorFlow APIs such as
  control flow and being directly watched by a `tf.GradientTape`).

  However, the resulting model will not track any variables that were
  used as inputs to TensorFlow ops. All variable usages must happen within
  Keras layers to make sure they will be tracked by the model's weights.

  The Keras Input can also create a placeholder from an arbitrary `tf.TypeSpec`,
  e.g:

  ```python
  x = Input(type_spec=tf.RaggedTensorSpec(shape=[None, None],
                                          dtype=tf.float32, ragged_rank=1))
  y = x.values
  model = Model(x, y)
  ```
  When passing an arbitrary `tf.TypeSpec`, it must represent the signature of an
  entire batch instead of just one example.

  Raises:
    ValueError: If both `sparse` and `ragged` are provided.
    ValueError: If both `shape` and (`batch_input_shape` or `batch_shape`) are
      provided.
    ValueError: If `shape`, `tensor` and `type_spec` are None.
    ValueError: If arguments besides `type_spec` are non-None while `type_spec`
                is passed.
    ValueError: if any unrecognized parameters are provided.
  z;Cannot set both sparse and ragged to True in a Keras input.)r   r   r   r   r   r3   r   Zbatch_shapeNz]Only provide the `shape` OR `batch_input_shape` argument to Input, not both at the same time.zPlease provide to Input a `shape` or a `tensor` or a `type_spec` argument. Note that `shape` does not include the batch dimension.zUnrecognized keyword arguments:r   )r   r2   r   )
r   r$   r%   updater   Z_inbound_nodesr!   r)   listlen)r   r   r   r   r   Ztensorr   r3   r4   Zinput_layer_configr   Zinput_layerr!   r   r   r   Input  s2    e
rD   )NNNNNNNN)r>   Ztensorflow.python.distributer   Ztensorflow.python.frameworkr   r   r   Ztensorflow.python.kerasr   Z"tensorflow.python.keras.distributer   Ztensorflow.python.keras.enginer   r	   r
   r/   Z*tensorflow.python.keras.saving.saved_modelr   Ztensorflow.python.keras.utilsr   Z tensorflow.python.util.tf_exportr   r   ZLayerr   rD   r   r   r   r   <module>   s2   
 Z       