B
    ӻdv                  @   s   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l
mZ dd	d
ZdddZG dd deZdd Zdd Zdd ZdS )zTraining-related utilities.    N)tensor_shape)tensor_util)generic_utils)	array_ops)nestTc                s   d}t | tsd}| g} tdd | D rd|sP fdd| D }dd |D }qp fdd| D }nt|  }|r||d	 }|S )
a  Slices batches out of provided arrays (workaround for eager tensors).

  Unfortunately eager tensors don't have the same slicing behavior as
  Numpy arrays (they follow the same slicing behavior as symbolic TF tensors),
  hence we cannot use `generic_utils.slice_arrays` directly
  and we have to implement this workaround based on `concat`. This has a
  performance cost.

  Args:
    arrays: Single array or list of arrays.
    indices: List of indices in the array that should be included in the output
      batch.
    contiguous: Boolean flag indicating whether the indices are contiguous.

  Returns:
    Slice of data (either single array or list of arrays).
  FTc             s   s   | ]}t |V  qd S )N)r   Z
is_tf_type).0x r	   _/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/engine/training_utils.py	<genexpr>0   s    zslice_arrays.<locals>.<genexpr>c                s   g | ]  fd dD qS )c                s   g | ]} ||d   qS )   r	   )r   i)r   r	   r
   
<listcomp>2   s    z+slice_arrays.<locals>.<listcomp>.<listcomp>r	   )r   )indices)r   r
   r   2   s    z slice_arrays.<locals>.<listcomp>c             S   s   g | ]}t j|d dqS )r   )Zaxis)r   concat)r   r   r	   r	   r
   r   3   s    c                s$   g | ]}| d   d d  qS )r   r   r	   )r   r   )r   r	   r
   r   5   s    r   )
isinstancelistanyr   slice_arrays)Zarraysr   
contiguousZconverted_to_listentriesZslicesr	   )r   r
   r      s    
r   Fc             C   s\  |dk	ot dd |D }|o.t dd |D }|s>d||fS |sL|||fS |rtt|tt| tt| tt|  |dk	rt|t| g }xt|D ]\}}|dkr@t| | tj}	| | }
|	r|
j	nt
	|
}|dk	o|| dk}|r|d |d fn|d f}||	r2t|nt
| q|| qW t|||fS )a  Adds 1.0 as sample weights for the outputs for which there is no weight.

  Args:
    outputs: List of model outputs.
    sample_weights: List of sample weight inputs.
    sample_weight_modes: List of sample weight modes or None.
    check_all_flat: Ensure that inputs are not nested structures. This is not
      a free check, so we may not want to run it eagerly every iteration.

  Returns:
    Tuple of sample weights, one sample weight for every output, and booleans
    describing the raw sample weights.
  Nc             s   s   | ]}|d k	V  qd S )Nr	   )r   wr	   r	   r
   r   N   s    z0handle_partial_sample_weights.<locals>.<genexpr>c             s   s   | ]}|d kV  qd S )Nr	   )r   r   r	   r	   r
   r   P   s    Ztemporalr   r   )r   r   Zassert_same_structurelist_to_tupleflatten	enumerater   npZndarrayshaper   appendZones)outputsZsample_weightsZsample_weight_modesZcheck_all_flatZany_sample_weightZpartial_sample_weightZnew_sample_weightsr   swZas_numpyoutputZoutput_shapeZis_temporalZsw_shaper	   r	   r
   handle_partial_sample_weights>   s@    



 r"   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	RespectCompiledTrainableStateat  Set and restore trainable state if it has changed since compile.

  The keras API guarantees that the value of each Layer's `trainable` property
  at `Model.compile` time will be used when training that model. In order to
  respect this requirement, it may be necessary to set the trainable value of
  layers to their compile time values before beginning a training endpoint and
  restore the values before returing from said endpoint. This scope checks if
  any layer's trainable state has changed since Model compile, and performs this
  set and un-set bookkeeping.

  However, the trainable state of a layer changes quite infrequently, if ever,
  for many kinds of workflows. Moreover, updating every layer in a model is an
  expensive operation. As a result, we will only explicitly set and unset the
  trainable state of a model if a trainable value has changed since compile.
  c             C   s   || _ d | _d | _d| _d S )NF)_model_current_trainable_state_compiled_trainable_state_should_set_trainable)selfmodelr	   r	   r
   __init__   s    z&RespectCompiledTrainableState.__init__c             C   sf   | j  | _| j j| _x6| j D ](\}}|| jkr"|| j| kr"d| _P q"W | jrb| j | j d S )NT)r$   Z_get_trainable_stater%   r&   itemsr'   _set_trainable_state)r(   layerZ	trainabler	   r	   r
   	__enter__   s    

z'RespectCompiledTrainableState.__enter__c             C   s   | j r| j| j dS )NF)r'   r$   r,   r%   )r(   Ztype_argZ	value_argZtraceback_argr	   r	   r
   __exit__   s    z&RespectCompiledTrainableState.__exit__N)__name__
__module____qualname____doc__r*   r.   r/   r	   r	   r	   r
   r#   y   s   r#   c             C   sJ   dd }x$|| r,| j s td| j d } q
W t| ddrF| j| jfS dS )aB  Retrieves input shape and input dtype of layer if applicable.

  Args:
    layer: Layer (or model) instance.

  Returns:
    Tuple (input_shape, input_dtype). Both could be None if the layer
      does not have a defined input shape.

  Raises:
    ValueError: in case an empty Sequential or Functional model is passed.
  c             S   s   t | dr| jp| jjdkS )N_is_graph_networkZ
Sequential)hasattrr4   	__class__r0   )r-   r	   r	   r
   _is_graph_model   s    z2get_input_shape_and_dtype.<locals>._is_graph_modelz)An empty Model cannot be used as a Layer.r   _batch_input_shapeN)NN)Zlayers
ValueErrorgetattrr8   Zdtype)r-   r7   r	   r	   r
   get_input_shape_and_dtype   s    
r;   c             C   s(   t | \}}|dk	r$t|d jS dS )zGets the static batch size of a Layer.

  Args:
    layer: a `Layer` instance.

  Returns:
    The static batch size of a Layer.
  Nr   )r;   r   Z	Dimensionvalue)r-   Zbatch_input_shape_r	   r	   r
   get_static_batch_size   s    	r>   c             C   s   t | trt| S | S )zADatasets will stack the list of tensor, so switch them to tuples.)r   r   tuple)Z
maybe_listr	   r	   r
   r      s    
r   )T)F)r3   numpyr   Ztensorflow.python.frameworkr   r   Ztensorflow.python.keras.utilsr   Ztensorflow.python.opsr   Ztensorflow.python.utilr   r   r"   objectr#   r;   r>   r   r	   r	   r	   r
   <module>   s   
%
:0"