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 Zdd Zdd ZdddZeejejdd ZdS )z4Functions to convert SavedModel to frozen GraphDefs.    )util)	Component)convert_phase)SubComponent)session)ops)
tf_logging)	constants)loaderc          	   C   s*   t jt d}t||| S Q R X dS )a'  Validate saved_model and extract MetaGraphDef.

  Args:
    saved_model_dir: saved_model path to convert.
    tag_set: Set of tag(s) of the MetaGraphDef to load.

  Returns:
    The meta_graph_def used for tflite conversion.

  Raises:
    ValueError: No valid MetaGraphDef for given tag_set.
  )graphN)r   Sessionr   Graphr
   load)saved_model_dirtag_setsess r   \/var/www/html/venv/lib/python3.7/site-packages/tensorflow/lite/python/convert_saved_model.pyget_meta_graph_def   s    r   c             C   sD   | j }t| }td| ||kr<td|d||| S )a2  Get the signature def from meta_graph with given signature_key.

  Args:
    meta_graph: meta_graph_def.
    signature_key: signature_def in the meta_graph_def.

  Returns:
    The signature_def used for tflite conversion.

  Raises:
    ValueError: Given signature_key is not valid for this meta_graph.
  zTThe given SavedModel MetaGraphDef contains SignatureDefs with the following keys: %szDNo '{}' in the SavedModel's SignatureDefs. Possible values are '{}'.,)signature_defsetkeyslogginginfo
ValueErrorformatjoin)
meta_graphsignature_keyZsignature_def_mapZsignature_def_keysr   r   r   get_signature_def-   s    r    c             C   s,   | j }| j}dd }||}||}||fS )zGet inputs and outputs from SignatureDef.

  Args:
    signature_def: SignatureDef in the meta_graph_def for conversion.

  Returns:
    The inputs and outputs in the graph for conversion.
  c                s    fdd D S )Nc                s   g | ]} | j qS r   )name).0key)tensor_infor   r   
<listcomp>S   s    z<get_inputs_outputs.<locals>.gather_names.<locals>.<listcomp>r   )r$   r   )r$   r   gather_namesR   s    z(get_inputs_outputs.<locals>.gather_names)inputsoutputs)r   Zinputs_tensor_infoZoutputs_tensor_infor&   r'   r(   r   r   r   get_inputs_outputsF   s    	r)   Nc                sF   g }|rt |}t |}n$|r: fddt |D }ntd|S )a  Gets the tensors associated with the tensor names.

  Either signature_def_tensor_names or user_tensor_names should be provided. If
  the user provides tensors, the tensors associated with the user provided
  tensor names are provided. Otherwise, the tensors associated with the names in
  the SignatureDef are provided.

  Args:
    graph: GraphDef representing graph.
    signature_def_tensor_names: Tensor names stored in either the inputs or
      outputs of a SignatureDef. (default None)
    user_tensor_names: Tensor names provided by the user. (default None)

  Returns:
    List of tensors.

  Raises:
    ValueError:
      signature_def_tensors and user_tensor_names are undefined or empty.
      user_tensor_names are not valid.
  c                s   g | ]}  |qS r   )Zget_tensor_by_name)r"   r!   )r   r   r   r%   y   s   z _get_tensors.<locals>.<listcomp>z>Specify either signature_def_tensor_names or user_tensor_names)sortedr   Zget_tensors_from_tensor_namesr   )r   Zsignature_def_tensor_namesZuser_tensor_namesZtensorsr   )r   r   _get_tensorsZ   s    
r+   c          	   C   s   t | |}t||}t|\}}	|j}
tj|
kr8tdt }t	j
|dT}t||jj|  t|||}t||	|}t|| t|||}||||jfS Q R X dS )a  Converts a SavedModel to a frozen graph.

  Args:
    saved_model_dir: SavedModel directory to convert.
    input_arrays: List of input tensors to freeze graph with. Uses input arrays
      from SignatureDef when none are provided.
    input_shapes: Dict of strings representing input tensor names to list of
      integers representing input shapes (e.g., {"foo": : [1, 16, 16, 3]}).
      Automatically determined when input shapes is None (e.g., {"foo" : None}).
    output_arrays: List of output tensors to freeze graph with. Uses output
      arrays from SignatureDef when none are provided.
    tag_set: Set of tags identifying the MetaGraphDef within the SavedModel to
      analyze. All tags in the tag set must be present.
    signature_key: Key identifying SignatureDef containing inputs and outputs.

  Returns:
    frozen_graph_def: Frozen GraphDef.
    in_tensors: List of input tensors for the graph.
    out_tensors: List of output tensors for the graph.
    graph: `Graph` object.

  Raises:
    ValueError:
      SavedModel doesn't contain a MetaGraphDef identified by tag_set.
      signature_key is not in the MetaGraphDef.
      assets/ directory is in the MetaGraphDef.
      input_shapes does not match the length of input_arrays.
      input_arrays or output_arrays are not valid.
  z5SavedModels with assets/ directory are not supported.)r   N)r   r    r)   collection_defr	   Z
ASSETS_KEYr   r   r   r   r   r
   r   Zmeta_info_deftagsr+   r   Zset_tensor_shapesZfreeze_graphr   )r   Zinput_arraysZinput_shapesZoutput_arraysr   r   r   r   r'   r(   r,   r   r   Z
in_tensorsZout_tensorsZfrozen_graph_defr   r   r   freeze_saved_model   s    !


r.   )NN)__doc__Ztensorflow.lite.pythonr   Z$tensorflow.lite.python.convert_phaser   r   r   Ztensorflow.python.clientr   Ztensorflow.python.frameworkr   Ztensorflow.python.platformr   r   Ztensorflow.python.saved_modelr	   r
   r   r    r)   r+   ZPREPARE_TF_MODELZFREEZE_SAVED_MODELr.   r   r   r   r   <module>   s    
*