B
    d                 @   st   d 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 Z	dd
dZ
dd Zdd Zdd ZdddZdS )aX  Keras functions required by TensorFlow Lite.

The functions defined in this library have been copied over from Keras in order
to remove the dependency from TensorFlow Lite to Keras. The functions which
could not be copied over are accessed using the dependency inversion principle.
(for details, refer to tensorflow/python/util/keras_deps.py).
    N)def_function)
keras_deps)nest)collections_abcc                s\   dd  dd }t | }t fdd|D oFt fdd|D  }|rXt || } | S )z5Enforces that either all specs have names or none do.c             S   s   t | do| jd k	S )Nname)hasattrr   )spec r	   Z/var/www/html/venv/lib/python3.7/site-packages/tensorflow/lite/python/tflite_keras_util.py	_has_name#   s    z-_enforce_names_consistency.<locals>._has_namec             S   s   t | } t| drd | _| S )Nr   )copydeepcopyr   _name)r   r	   r	   r
   _clear_name&   s    

z/_enforce_names_consistency.<locals>._clear_namec             3   s   | ]} |V  qd S )Nr	   ).0s)r   r	   r
   	<genexpr>.   s    z-_enforce_names_consistency.<locals>.<genexpr>c             3   s   | ]} |V  qd S )Nr	   )r   r   )r   r	   r
   r   /   s    )r   flattenanyallmap_structure)specsr   Z
flat_specsZname_inconsistencyr	   )r   r
   _enforce_names_consistency    s    
r   Fc             C   sz   t | dr2| j| d}|dkr$dS |d d }n| j| d}|dkrLdS t|}t|tjrpt|dkrp|S |gS dS )aM  Inspect model to get its input signature.

  The model's input signature is a list with a single (possibly-nested) object.
  This is due to the Keras-enforced restriction that tensor inputs must be
  passed in as the first argument.

  For example, a model with input {'feature1': <Tensor>, 'feature2': <Tensor>}
  will have input signature: [{'feature1': TensorSpec, 'feature2': TensorSpec}]

  Args:
    model: Keras Model object.
    keep_original_batch_size: A boolean indicating whether we want to keep using
      the original batch size or set it to None. Default is `False`, which means
      that the batch dim of the returned input signature will always be set to
      `None`.

  Returns:
    A list containing either a single TensorSpec or an object with nested
    TensorSpecs. This list does not contain the `training` argument.
  	save_spec)Zdynamic_batchNr      )r   r   Z_get_save_specr   
isinstancer   Sequencelen)modelZkeep_original_batch_sizeZinput_specsr	   r	   r
   model_input_signature6   s    

r   c             C   s   t d| d S )NzModel {} cannot be saved because the input shapes have not been set. Usually, input shapes are automatically determined from calling `.fit()` or `.predict()`. To manually set the shapes, call `model.build(input_shape)`.)
ValueErrorformat)r   r	   r	   r
   raise_model_input_errorc   s    r"   c             C   sz   dd }t t| }t||}g }xN|D ]F}|s>|d }n*ddd |D }t|d trh|| }|| q,W |S )a%  Creates pseudo {input | output} names for subclassed Models.

  Warning: this function should only be used to define default
  names for `Metics` and `SavedModel`. No other use cases should
  rely on a `Model`'s input or output names.

  Example with dict:

  `{'a': [x1, x2], 'b': x3}` becomes:
  `['a_1', 'a_2', 'b']`

  Example with list:

  `[x, y]` becomes:
  `['output_1', 'output_2']`

  Args:
    tensors: `Model`'s outputs or inputs.
    prefix: 'output_' for outputs, 'input_' for inputs.

  Returns:
    Flattened list of pseudo names.
  c             S   s   t | tr| d S | S )Nr   )r   int)Zeler	   r	   r
   	one_index   s    
z'_create_pseudo_names.<locals>.one_index1_c             s   s   | ]}t |V  qd S )N)str)r   pr	   r	   r
   r      s    z'_create_pseudo_names.<locals>.<genexpr>r   )listr   Zyield_flat_pathsr   joinr   r#   append)Ztensorsprefixr$   Z
flat_pathsnamespathr   r	   r	   r
   _create_pseudo_namesk   s    

r/   c             C   s   t | ddS )z2Create pseudo output names for a subclassed Model.Zoutput_)r,   )r/   )outputsr	   r	   r
   create_pseudo_output_names   s    r1   c                s^    dkrt jtjrjj  dkr.t  dkr>t tj dd fdd}|S )a  Trace the model call to create a tf.function for exporting a Keras model.

  Args:
    model: A Keras model.
    input_signature: optional, a list of tf.TensorSpec objects specifying the
      inputs to the model.

  Returns:
    A tf.function wrapping the model's call function with input signatures set.

  Raises:
    ValueError: if input signature cannot be inferred from the model.
  NF)input_signatureZ	autographc           	      sR   t  dkr| d nt| }t  j|dddd |dd}W dQ R X |S )z<A concrete tf.function that wraps the model's call function.r   r   FT)inputsZbuild_graphtrainingZsaving)r4   N)r   r)   r   Zget_call_context_functionZenter)argsr3   r0   )r2   r   r	   r
   _wrapped_model   s
    
z(trace_model_call.<locals>._wrapped_model)r   callr   Functionr2   r   r"   function)r   r2   r6   r	   )r2   r   r
   trace_model_call   s    r:   )F)N)__doc__r   Ztensorflow.python.eagerr   Ztensorflow.python.utilr   r   Ztensorflow.python.util.compatr   r   r   r"   r/   r1   r:   r	   r	   r	   r
   <module>   s   
--