B
    ӻdO:             	   @   sn  d Z ddlZddlZddlZddlZddlZddlZddlZddl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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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,m0Z0 ddl1m2Z2 ddl1m3Z3 ddl1m4Z4 ddl1m5Z6 ddl1m7Z7 dd l1m8Z9 dd!l1m:Z: dd"l1m;Z; dd#l1m<Z< dd$l1m=Z= dd%l1m>Z? dd&l1m@Z@ dd'l1mAZA dd(l1mBZB dd)l1mCZC dd*l1mDZD dd+l1mEZE dd,l1mFZF dd-l1mGZH dd.lImJZJ dd/lKmLZM dd0lNmOZO dd1lPmQZQ dd2lPmRZR dd3lSmTZT dd4lUmVZV eWZXeYZZe[Z\e] a^e] a_e] a`ea Zbec ZdG d5d6 d6ej]Zeee Zfd7agdahe&jiZie&jjZje&jkZke&jlZle&jmZme&jnZneTd8eVjod9d: ZpeTd;eQjqeVjod<d= ZreTd>did@dAZseTdBdCdD ZteTdEdFdG ZueTdHeVjodIdJ ZveTdKeVjodLdM ZwdNdO ZxdPdQ ZydRdS ZzdTdU Z{eTdVeVjodWdX Z|dYdZ Z}eTd[e/j~eVjod\d] Ze/j~d^d_ Ze/j~d`da Zdbdc Zddde ZdjdfdgZdkdidjZeTdkgdldldmdnZdodp Ze/j~dmdqdrZeTdsgdldtdu Zdvdw Zdxdy ZG dzd{ d{Zd|d} Zd~d Zdd Zdd Zdd Zdd ZeTdeVjodd ZeTdeQjqeVjodd ZeTdg dleVjodd Ze jZeTdgdle eTdeVjodnddZdd ZeTdg dldd Zdd ZdoddZdpddZeTdg dldd ZeTdeQjqeVjodqddZeTddd ZeTdeVjodrddZdd ZeTdeQjqeVjodd ZeTdeVjodd ZeTdeVjodd ZeTdeQjqeVjodd ZeVjodd ZeTdeVjodd ZeTdeVjodsddZeTdeQjqeVjodtddÄZeTdăeQjqeVjoduddƄZeTdǃeVjodvddɄZeTdʃeQjqeVjodwdd̄Zdxdd΄ZeTdσeVjodyddфZeTd҃eVjodzddԄZeTdՃeVjoddׄ ZeTd؃eQjqeVjoddڄ ZeTdۃeVjodd݄ ZeTdރeVjodd ZeTdeVjodd ZeTdeVjodd ZeTdeQjqeVjodd ZeTdeQjqeVjod{ddZeTdeQjqeVjodd ZeTdeQjqeVjodd ZeTdeQjqeVjod|ddZeTdeQjqeVjod}ddZeTdeQjqeVjod~ddZYeTdeQjqeVjodddZeTdeQjqeVjodd dZeTdeQjqeVjodddZeTdeVjodddZeTdeQjqeVjodd	d
ZeTdeQjqeVjodddZeTdeQjqeVjodddZ[eTdeQjqeVjodddZWeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodd ZeTdeQjqeVjodd  ZeTd!eQjqeVjod"d# ZeTd$eQjqeVjod%d& ZeTd'eQjqeVjod(d) Zɐdd*d+ZeTd,eQjqeVjod-d. ZeTd/eQjqeVjod0d1 ZeTd2eQjqeVjod3d4 ZeTd5eQjqeVjod6d7 ZeTd8eQjqeVjod9d: ZeTd;eQjqeVjod<d= ZeTd>eQjqeVjod?d@ ZeTdAeQjqeVjodBdC ZeTdDeQjqeVjodEdF ZeTdGeQjqeVjodHdI ZeTdJeQjqeVjodKdL ZeTdMeQjqeVjodNdO ZeTdPeQjqeVjodQdR ZeTdSeQjqeVjodTdU ZؐddWdXZِddYdZZڐdd[d\ZeTd]eVjodd^d_ZeTd`eQjqeVjoddadbZeTdceQjqeVjoddddeZeTdfeQjqeVjodgdh ZeTdieQjqeVjodjdk ZeTdleQjqeVjoddndoZeTdpeQjqeVjodqdr ZeTdseQjqeVjodtdu ZeTdveQjqeVjodwdx ZeTdyeQjqeVjodd|d}ZeTd~eQjqeVjodd ZeTdeQjqeVjodd ZeTdeQjqeVjodd ZeTdeQjqeVjodddZeTdeQjqeVjodd ZeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodd ZeTdeQjqeVjodd Zddd ZeTdeVjodd ZeTdeQjqeVjodd ZeTdeVjodd ZeTdeQjqeVjodd Zej jede_ ej jede_ eTdeQjqeVjodddZG dd dZeTdeVjodddZeTdeVjodd Z8eTdeQjqeVjodd ZeTdeQjqdddZeTdeQjqeVjodÐdĄ ZeTdŃeVjoddƐdǄZeTdȃeVjoddɐdʄZeTd˃eQjqeVjodd͐d΄ZeTdσeQjqeVjoddѐd҄Z eTdӃeQjqeVjoddԐdՄZeTdփeQjqeVjodאd؄ ZeTdكeQjqeVjodڐdۄ ZeTd܃eQjqeVjoddݐdބZeTd߃eQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodd ZeTdeQjqeVjodd ZeTdeQjqeVjodd Z	eTdeQjqeVjodddZ
eTdeQjqeVjodddZeTdeQjqeVjodd Zdd ZdddZdd Zdd ZeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodddZdd	d
ZeTdeQjqeVjodddZeTdeQjqeVjodddZeTdeQjqeVjodddZdddZeTdeQjqeVjodddZeTdeQjqeVjodddZdddZeTdeQjqeVjodd d!ZeTd"eQjqeVjodd#d$ZeTd%eQjqeVjodd&d'ZeTd(eQjqeVjodd)d*ZeTd+eQjqeVjodd,d-Z eTd.eQjqeVjodd/d0Z!eTd1eQjqeVjodd2d3Z"eTd4eQjqeVjodd5d6Z#eTd7eQjqeVjod8d9 Z$eTd:eQjqeVjod;d< Z%eTd=eQjqeVjodd@dAZ&eTdBeVjoddCdDZ>eTdEeVjoddFdGZ'eTdHeVjoddIdJZ(dKej)krej)*dKZ+n,ej,-dLZ.ej,/e.dMZ+ej,-ej,/e+dNZ0ej,1e0ry.e2e0Z3e4e3Z5W dQ R X W n e6k
rR   i Z5Y nX e5*dOej Z7e7dPks~t8e5*dQei Z9e:e9e;st8e5*dRek Z<e<dSks֐t8eme7 ele9 ene< ej,1e+s4ye=e+ W n e>k
r2   Y nX ej,1e0sej ei dTek dUZ5yBe2e0dV(Z?e?@ejAe5dWdX W dQ R X W n eBk
r   Y nX dYdZ ZCd[d\ ZDd]d^ ZEd_d` ZFdadb ZGdcdd ZHddedfZIG dgdh dhejaZJeJe{aKeJe.jLaMeJe.jLaNdS (  zKeras backend API.    N)
config_pb2)tf2)session)distribution_strategy_context)context)
get_config)composite_tensor)config)constant_op)device_spec)dtypes)
func_graph)ops)sparse_tensor)tensor_shape)tensor_spec)tensor_util)backend_config)distribute_coordinator_utils)keras_tensor)control_flow_util)object_identity)tf_contextlib)
tf_inspect)	array_ops)clip_ops)control_flow_ops)ctc_ops)functional_ops)	gradients)	image_ops)init_ops)
linalg_ops)logging_ops)map_fn)math_ops)nn)
random_ops)
sparse_ops)	state_ops)tensor_array_grad)tensor_array_ops)	variables)ragged_tensor)
tf_logging)moving_averages)dispatch)nest)keras_export)doc_controlsc                   s.   e Zd ZdZG dd dZ fddZ  ZS )_DummyEagerGraphz_DummyEagerGraph provides a thread local `key` attribute.

  We can't use threading.local directly, i.e. without subclassing, because
  gevent monkey patches threading.local and its version does not support
  weak references.
  c               @   s   e Zd ZdZdS )z'_DummyEagerGraph._WeakReferencableClassaq  This dummy class is needed for two reasons.

    - We need something that supports weak references. Basic types like string
    and ints don't.
    - We need something whose hash and equality are based on object identity
    to make sure they are treated as different keys to _GRAPH_LEARNING_PHASES.

    An empty Python class satisfies both of these requirements.
    N)__name__
__module____qualname____doc__ r9   r9   Q/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/keras/backend.py_WeakReferencableClass   s   	r;   c                s"   t t|   t | _d| _d S )NF)superr4   __init__r;   keylearning_phase_is_set)self)	__class__r9   r:   r=      s    
z_DummyEagerGraph.__init__)r5   r6   r7   r8   r;   r=   __classcell__r9   r9   )rA   r:   r4   y   s   r4   Fzkeras.backend.backendc               C   s   dS )zPublicly accessible method for determining the current backend.

  Only exists for API compatibility with multi-backend Keras.

  Returns:
      The string "tensorflow".
  
tensorflowr9   r9   r9   r9   r:   backend   s    
rD   zkeras.backend.cast_to_floatxc             C   s6   t | tjtjtjfr&tj| t	 dS t
j| t	 dS )a  Cast a Numpy array to the default Keras float type.

  Args:
      x: Numpy array or TensorFlow tensor.

  Returns:
      The same array (Numpy array if `x` was a Numpy array, or TensorFlow tensor
      if `x` was a tensor), cast to its new type.

  Example:

  >>> tf.keras.backend.floatx()
  'float32'
  >>> arr = np.array([1.0, 2.0], dtype='float64')
  >>> arr.dtype
  dtype('float64')
  >>> new_arr = cast_to_floatx(arr)
  >>> new_arr
  array([1.,  2.], dtype=float32)
  >>> new_arr.dtype
  dtype('float32')

  )dtype)
isinstancer   Tensorvariables_moduleVariabler   SparseTensorr%   castfloatxnpasarray)xr9   r9   r:   cast_to_floatx   s
    
rP   zkeras.backend.get_uid c             C   s<   t  }|tkrttt|< t| }||   d7  < ||  S )zAssociates a string prefix with an integer counter in a TensorFlow graph.

  Args:
    prefix: String prefix to index.

  Returns:
    Unique integer ID.

  Example:

  >>> get_uid('dense')
  1
  >>> get_uid('dense')
  2

     )	get_graphPER_GRAPH_OBJECT_NAME_UIDScollectionsdefaultdictint)prefixgraphZlayer_name_uidsr9   r9   r:   get_uid   s    rZ   zkeras.backend.reset_uidsc               C   s   t   t  dS )zResets graph identifiers.
  N)rT   clearOBSERVED_NAMESr9   r9   r9   r:   
reset_uids   s    r]   zkeras.backend.clear_sessionc           	   C   s|   dt _t  t  dt_t } |  6 dt	_
t  t|  t| d t| d W dQ R X t rxt   dS )a  Resets all state generated by Keras.

  Keras manages a global state, which it uses to implement the Functional
  model-building API and to uniquify autogenerated layer names.

  If you are creating many models in a loop, this global state will consume
  an increasing amount of memory over time, and you may want to clear it.
  Calling `clear_session()` releases the global state: this helps avoid clutter
  from old models and layers, especially when memory is limited.

  Example 1: calling `clear_session()` when creating models in a loop

  ```python
  for _ in range(100):
    # Without `clear_session()`, each iteration of this loop will
    # slightly increase the size of the global state managed by Keras
    model = tf.keras.Sequential([tf.keras.layers.Dense(10) for _ in range(10)])

  for _ in range(100):
    # With `clear_session()` called at the beginning,
    # Keras starts with a blank state at each iteration
    # and memory consumption is constant over time.
    tf.keras.backend.clear_session()
    model = tf.keras.Sequential([tf.keras.layers.Dense(10) for _ in range(10)])
  ```

  Example 2: resetting the layer name generation counter

  >>> import tensorflow as tf
  >>> layers = [tf.keras.layers.Dense(10) for _ in range(10)]
  >>> new_layer = tf.keras.layers.Dense(10)
  >>> print(new_layer.name)
  dense_10
  >>> tf.keras.backend.set_learning_phase(1)
  >>> print(tf.keras.backend.learning_phase())
  1
  >>> tf.keras.backend.clear_session()
  >>> new_layer = tf.keras.layers.Dense(10)
  >>> print(new_layer.name)
  dense
  NF)_GRAPHrY   r   Zreset_default_graphr]   _SESSIONr   rS   
as_default_DUMMY_EAGER_GRAPHr?   _GRAPH_LEARNING_PHASESr[   
setdefault_GRAPH_VARIABLESpop_GRAPH_TF_OPTIMIZERSr   executing_eagerlyZclear_kernel_cache)rY   r9   r9   r:   clear_session   s    0

rh   z,keras.backend.manual_variable_initializationc             C   s   | a dS )a0  Sets the manual variable initialization flag.

  This boolean flag determines whether
  variables should be initialized
  as they are instantiated (default), or if
  the user should handle the initialization
  (e.g. via `tf.compat.v1.initialize_all_variables()`).

  Args:
      value: Python boolean.
  N)_MANUAL_VAR_INIT)valuer9   r9   r:   manual_variable_initialization>  s    rk   zkeras.backend.learning_phasec           	   C   sJ   t  } | ttddkr t }nt   td }W dQ R X t| | |S )a  Returns the learning phase flag.

  The learning phase flag is a bool tensor (0 = test, 1 = train)
  to be passed as input to any Keras function
  that uses a different behavior at train time and test time.

  Returns:
      Learning phase (scalar integer tensor or Python integer).
  rY   N)r   get_default_graphgetattrr^   symbolic_learning_phase
init_scoperb   _mark_func_graph_as_unsaveable)rY   learning_phaser9   r9   r:   rq   P  s    

rq   c               C   s   t jS )N)ra   r?   r9   r9   r9   r:   global_learning_phase_is_seto  s    rr   c             C   s   | j rt|r| d dS )ay  Mark func graph as unsaveable due to use of symbolic keras learning phase.

  Functions that capture the symbolic learning phase cannot be exported to
  SavedModel. Mark the funcgraph as unsaveable, so that an error will be raised
  if it is exported.

  Args:
    graph: Graph or FuncGraph object.
    learning_phase: Learning phase placeholder or int defined in the graph.
  zThe keras learning phase placeholder was used inside a function. Exporting placeholders is not supported when saving out a SavedModel. Please call `tf.keras.backend.set_learning_phase(0)` in the function to set the learning phase to a constant value.N)building_functionis_placeholderZmark_as_unsaveable)rY   rq   r9   r9   r:   rp   s  s    rp   c           	   C   s"   t  } |  
 t|  S Q R X d S )N)rS   r`   rb   )rY   r9   r9   r:   rn     s    
rn   c            	   C   s0   t  rdS td tjddddS Q R X d S )Nr   rQ   Fr9   Zkeras_learning_phase)shapename)r   rg   
name_scoper   Zplaceholder_with_defaultr9   r9   r9   r:   _default_learning_phase  s
    
rx   z keras.backend.set_learning_phasec             C   s   t d t|  dS )a  Sets the learning phase to a fixed value.

  The backend learning phase affects any code that calls
  `backend.learning_phase()`
  In particular, all Keras built-in layers use the learning phase as the default
  for the `training` arg to `Layer.__call__`.

  User-written layers and models can achieve the same behavior with code that
  looks like:

  ```python
    def call(self, inputs, training=None):
      if training is None:
        training = backend.learning_phase()
  ```

  Args:
      value: Learning phase value, either 0 or 1 (integers).
             0 = test, 1 = train

  Raises:
      ValueError: if `value` is neither `0` nor `1`.
  z`tf.keras.backend.set_learning_phase` is deprecated and will be removed after 2020-10-11. To update it, simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.N)warningswarn&deprecated_internal_set_learning_phase)rj   r9   r9   r:   set_learning_phase  s    
r|   c          	   C   sJ   | dkrt dt ( t r2dt_| ttj< | tt	 < W dQ R X dS )aW  A deprecated internal implementation of set_learning_phase.

  This method is an internal-only version of `set_learning_phase` that
  does not raise a deprecation error. It is required because
  saved_model needs to keep working with user code that uses the deprecated
  learning phase methods until those APIs are fully removed from the public API.

  Specifically SavedModel saving needs to make sure the learning phase is 0
  during tracing even if users overwrote it to a different value.

  But, we don't want to raise deprecation warnings for users when savedmodel
  sets learning phase just for compatibility with code that relied on
  explicitly setting the learning phase for other values.

  Args:
      value: Learning phase value, either 0 or 1 (integers). 0 = test, 1 = train

  Raises:
      ValueError: if `value` is neither `0` nor `1`.
  >   r   rR   z%Expected learning phase to be 0 or 1.TN)

ValueErrorr   ro   r   rg   ra   r?   rb   r>   rS   )rj   r9   r9   r:   r{     s    

r{   z"keras.backend.learning_phase_scopec          	   c   s0   t d t|  z
dV  W dX W dQ R X dS )aS  Provides a scope within which the learning phase is equal to `value`.

  The learning phase gets restored to its original value upon exiting the scope.

  Args:
     value: Learning phase value, either 0 or 1 (integers).
            0 = test, 1 = train

  Yields:
    None.

  Raises:
     ValueError: if `value` is neither `0` nor `1`.
  z`tf.keras.backend.learning_phase_scope` is deprecated and will be removed after 2020-10-11. To update it, simply pass a True/False value to the `training` argument of the `__call__` method of your layer or model.N)ry   rz   (deprecated_internal_learning_phase_scope)rj   r9   r9   r:   learning_phase_scope  s
    


r   c             c   s   | dkrt dt * t r0ttjd}tt	 d}W dQ R X tj
}zt|  dV  W d|sldt_
t Z t r|dk	r|ttj< ntjtkrttj= t	 }|dk	r|t|< n|tkrt|= W dQ R X X dS )a^  An internal-only version of `learning_phase_scope`.

  Unlike the public method, this method does not raise a deprecation warning.
  This is needed because saved model saving needs to set learning phase
  to maintain compatibility
  with code that sets/gets the learning phase, but saved model
  saving itself shouldn't raise a deprecation warning.

  We can get rid of this method and its usages when the public API is
  removed.

  Args:
     value: Learning phase value, either 0 or 1 (integers). 0 = test, 1 = train

  Yields:
    None.

  Raises:
     ValueError: if `value` is neither `0` nor `1`.
  >   r   rR   z%Expected learning phase to be 0 or 1.NF)r}   r   ro   r   rg   rb   getra   r>   rS   r?   r{   )rj   Zprevious_eager_valueZprevious_graph_valueZlearning_phase_previously_setrY   r9   r9   r:   r~     s0    





r~   c          	   c   s\   | dkst t st t }|r(t }z| ttj< dV  W d|rN|ttj< nttj= X dS )a  Internal scope that sets the learning phase in eager / tf.function only.

  Args:
      value: Learning phase value, either 0 or 1 (integers).
             0 = test, 1 = train

  Yields:
    None.

  Raises:
     ValueError: if `value` is neither `0` nor `1`.
  >   r   rR   N)AssertionErrorr   #executing_eagerly_outside_functionsrr   rq   rb   ra   r>   )rj   Zglobal_learning_phase_was_setprevious_valuer9   r9   r:   eager_learning_phase_scope*  s    

r   c             C   s"   t | dd}|rt|r| S dS )zConvert `obj` to a graph element if possible, otherwise return `None`.

  Args:
    obj: Object to convert.

  Returns:
    The result of `obj._as_graph_element()` if that method is available;
        otherwise `None`.
  _as_graph_elementN)rm   callable)objZconv_fnr9   r9   r:   r   I  s    
r   c             C   s@   t | dd}t |dd}|r<|r<||k	r<td|| ||f dS )zFail if the 2 items are from different graphs.

  Args:
    original_item: Original item to check against.
    item: Item to check.

  Raises:
    ValueError: if graphs do not match.
  rY   Nz<%s must be from the same graph as %s (graphs are %s and %s).)rm   r}   )Zoriginal_itemitemZoriginal_graphrY   r9   r9   r:   _assert_same_graphY  s    
r   c             C   s   t  }|jr|S t| } |r8t|t js8td|f d}x| D ]}t|t jt jt	j
fr|t|t jrvt|t jkr||}nt|}|dk	rB|s|}t|dd}qB|dk	rt|| qB|j|k	rBtd| qBW |p|S )a&  Returns the appropriate graph to use for the given inputs.

  This library method provides a consistent algorithm for choosing the graph
  in which an Operation should be constructed:

  1. If the default graph is being used to construct a function, we
     use the default graph.
  2. If the "graph" is specified explicitly, we validate that all of the inputs
     in "op_input_list" are compatible with that graph.
  3. Otherwise, we attempt to select a graph from the first Operation-
     or Tensor-valued input in "op_input_list", and validate that all other
     such inputs are in the same graph.
  4. If the graph was not specified and it could not be inferred from
     "op_input_list", we attempt to use the default graph.

  Args:
    op_input_list: A list of inputs to an operation, which may include `Tensor`,
      `Operation`, and other objects that may be converted to a graph element.
    graph: (Optional) The explicit graph to use.

  Raises:
    TypeError: If op_input_list is not a list or tuple, or if graph is not a
      Graph.
    ValueError: If a graph is explicitly passed and not all inputs are from it,
      or if the inputs are from multiple graphs, or we could not find a graph
      and there was no default graph.

  Returns:
    The appropriate graph to use for the given inputs.

  z#Input graph needs to be a Graph: %sNrY   z#%s is not from the passed-in graph.)r   rl   rs   tuplerF   ZGraph	TypeErrorZ	OperationrG   r   ZCompositeTensortyper   rm   r   rY   r}   )op_input_listrY   Zcurrent_default_graphZoriginal_graph_elementZop_inputZgraph_elementr9   r9   r:   _current_graphk  s.     

r   r9   c             C   sv   t  }|dk	r|}n\t  r&tdttdddksFtjjt| k	rlt	
 r\tt	  ntjt dt_tj}|S )z2Returns the session object for the current thread.Nz4Cannot get session inside Tensorflow graph function.r   )r	   )r   get_default_sessioninside_functionRuntimeErrorrm   r_   r   rY   r   r   Zhas_strategy(configure_and_create_distributed_sessionZget_strategysession_moduleSessionget_default_session_config)r   Zdefault_sessionr   r9   r9   r:   _get_session  s    r   zkeras.backend.get_session)Zv1c          	   C   s.   t | }ts*|j  t| W dQ R X |S )aX  Returns the TF session to be used by the backend.

  If a default TensorFlow session is available, we will return it.

  Else, we will return the global Keras session assuming it matches
  the current graph.

  If no global Keras session exists at this point:
  we will create a new global session.

  Note that you can manually set the global session
  via `K.set_session(sess)`.

  Args:
      op_input_list: An option sequence of tensors or ops, which will be used
        to determine the current graph. Otherwise the default graph will be
        used.

  Returns:
      A TensorFlow session.
  N)r   ri   rY   r`   _initialize_variables)r   r   r9   r9   r:   get_session  s
    r   c               C   s2   t  r&ttdd s tdt_tjS t S d S )NrY   Zkeras_graph)	r   rg   rm   r^   r   	FuncGraphrY   r   rl   r9   r9   r9   r:   rS     s
    rS   c             c   sf   t tdd}|dk	r,| dk	r,|| k	r,td|r:|V  dS | pFtd} z| t_| V  W ddt_X dS )aD  Retrieve a shared and temporary func graph.

  The eager execution path lifts a subgraph from the keras global graph into
  a scratch graph in order to create a function. DistributionStrategies, in
  turn, constructs multiple functions as well as a final combined function. In
  order for that logic to work correctly, all of the functions need to be
  created on the same scratch FuncGraph.

  Args:
    graph: A graph to be used as the current scratch graph. If not set then
      a scratch graph will either be retrieved or created:

  Yields:
    The current scratch graph.
  rY   Nz"Multiple scratch graphs specified.Zkeras_scratch_graph)rm   _CURRENT_SCRATCH_GRAPHr}   r   r   rY   )rY   Zscratch_graphr9   r9   r:   _scratch_graph  s    
r   zkeras.backend.set_sessionc             C   s
   | t _dS )zLSets the global TensorFlow session.

  Args:
      session: A TF Session.
  N)r_   r   )r   r9   r9   r:   set_session  s    r   c              C   s&   t jdrtd t } d| _| S )NZOMP_NUM_THREADSzOMP_NUM_THREADS is no longer used by the default Keras config. To configure the number of threads, use tf.config.threading APIs.T)osenvironr   loggingwarningr   Zallow_soft_placement)r	   r9   r9   r:   r   "  s    r   c              C   s2   t  } t| d }|d kr.tt}|t| < |S )N)r   rl   rT   r   rU   rV   rW   )rY   name_uid_mapr9   r9   r:   get_default_graph_uid_map.  s    
r   c               @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_TfDeviceCaptureOpz(Class for capturing the TF device scope.c             C   s
   d | _ d S )N)device)r@   r9   r9   r:   r=   =  s    z_TfDeviceCaptureOp.__init__c             C   s   t |tjr| }|| _dS )z8This method captures TF's explicit device scope setting.N)rF   r   DeviceSpecV2Z	to_stringr   )r@   r   r9   r9   r:   _set_device@  s    z_TfDeviceCaptureOp._set_devicec             C   s
   || _ d S )N)r   )r@   Z
device_strr9   r9   r:   _set_device_from_stringF  s    z*_TfDeviceCaptureOp._set_device_from_stringN)r5   r6   r7   r8   r=   r   r   r9   r9   r9   r:   r   :  s   r   c              C   s>   t  } t }| | t r,tj|jS tj	|jS dS )a  Return explicit device of current context, otherwise returns `None`.

  Returns:
      If the current device scope is explicitly set, it returns a string with
      the device (`CPU` or `GPU`). If the scope is not explicitly set, it will
      return `None`.
  N)
rS   r   Z_apply_device_functionsr   enabledr   r   Zfrom_stringr   ZDeviceSpecV1)rY   opr9   r9   r:   _get_current_tf_deviceJ  s    
r   c             C   s4   |   } | dkrtdt }|dk	o2|j|   kS )aj  Check if the current device is explicitly set on the device type specified.

  Args:
      device_type: A string containing `GPU` or `CPU` (case-insensitive).

  Returns:
      A boolean indicating if the current device scope is explicitly set on the
      device type.

  Raises:
      ValueError: If the `device_type` string indicates an unsupported device.
  )CPUGPUz.`device_type` should be either "CPU" or "GPU".N)upperr}   r   device_type)r   r   r9   r9   r:   _is_current_explicit_device[  s
    r   c               C   s<   t  rdd tdD S tdkr.t  add tD S )zqGet a list of available GPU devices (formatted as strings).

  Returns:
      A list of available GPU devices.
  c             S   s   g | ]
}|j qS r9   )rv   ).0dr9   r9   r:   
<listcomp>w  s    z'_get_available_gpus.<locals>.<listcomp>r   Nc             S   s   g | ]}|j d kr|jqS )r   )r   rv   )r   rO   r9   r9   r:   r   |  s    )r   r   r	   Zlist_logical_devices_LOCAL_DEVICESr   Zlist_devicesr9   r9   r9   r:   _get_available_gpuso  s
    
r   c              C   s   t d} tt }|  o|S )aD  Check whether the current scope supports NCHW ops.

  TensorFlow does not support NCHW on CPU. Therefore we check if we are not
  explicitly put on
  CPU, and have GPUs available. In this case there will be soft-placing on the
  GPU device.

  Returns:
      bool: if the current scope device placement would support nchw
  r   )r   boolr   )Zexplicitly_on_cpuZgpus_availabler9   r9   r:   _has_nchw_support  s    
r   c             C   s   t j| |dS )a8  Convert the input `x` to a tensor of type `dtype`.

  This is slightly faster than the _to_tensor function, at the cost of
  handling fewer cases.

  Args:
      x: An object to be converted (numpy arrays, floats, ints and lists of
        them).
      dtype: The destination type.

  Returns:
      A tensor.
  )rE   )r
   constant)rO   rE   r9   r9   r:   _constant_to_tensor  s    r   c             C   s   t j| |dS )zConvert the input `x` to a tensor of type `dtype`.

  Args:
      x: An object to be converted (numpy array, list, tensors).
      dtype: The destination type.

  Returns:
      A tensor.
  )rE   )r   "convert_to_tensor_v2_with_dispatch)rO   rE   r9   r9   r:   
_to_tensor  s    
r   zkeras.backend.is_sparsec             C   s,   t | dd}|dk	r t|tjS t| tjS )ac  Returns whether a tensor is a sparse tensor.

  Args:
      tensor: A tensor instance.

  Returns:
      A boolean.

  Example:


  >>> a = tf.keras.backend.placeholder((2, 2), sparse=False)
  >>> print(tf.keras.backend.is_sparse(a))
  False
  >>> b = tf.keras.backend.placeholder((2, 2), sparse=True)
  >>> print(tf.keras.backend.is_sparse(b))
  True

  Z
_type_specN)rm   rF   r   SparseTensorSpecrJ   )tensorspecr9   r9   r:   	is_sparse  s    r   zkeras.backend.to_densec             C   s   t | rt| S | S dS )ax  Converts a sparse tensor into a dense tensor and returns it.

  Args:
      tensor: A tensor instance (potentially sparse).

  Returns:
      A dense tensor.

  Examples:


  >>> b = tf.keras.backend.placeholder((2, 2), sparse=True)
  >>> print(tf.keras.backend.is_sparse(b))
  True
  >>> c = tf.keras.backend.to_dense(b)
  >>> print(tf.keras.backend.is_sparse(c))
  False

  N)r   r(   sparse_tensor_to_dense)r   r9   r9   r:   to_dense  s    
r   zkeras.backend.name_scopec             C   s
   t | S )aa  A context manager for use when defining a Python op.

  This context manager pushes a name scope, which will make the name of all
  operations added within it have a prefix.

  For example, to define a new Python op called `my_op`:


  def my_op(a):
    with tf.name_scope("MyOp") as scope:
      a = tf.convert_to_tensor(a, name="a")
      # Define some computation that uses `a`.
      return foo_op(..., name=scope)


  When executed, the Tensor `a` will have the name `MyOp/a`.

  Args:
    name: The prefix to use on all names created within the name scope.

  Returns:
    Name scope context manager.
  )r   Zname_scope_v2)rv   r9   r9   r:   rw     s    rw   zkeras.backend.variablec             C   s   |dkrt  }t| drd|  }tt|jdt|jdfd}tj	||j
|jd}|j|_|S tj| t|||d}t| tjr| j|_nt| drt| |_t| |S )a  Instantiates a variable and returns it.

  Args:
      value: Numpy array, initial value of the tensor.
      dtype: Tensor type.
      name: Optional name string for the tensor.
      constraint: Optional projection function to be
          applied to the variable after an optimizer update.

  Returns:
      A variable instance (with Keras metadata included).

  Examples:

  >>> val = np.array([[1, 2], [3, 4]])
  >>> kvar = tf.keras.backend.variable(value=val, dtype='float64',
  ...                                  name='example_var')
  >>> tf.keras.backend.dtype(kvar)
  'float64'
  >>> print(kvar)
  <tf.Variable 'example_var:...' shape=(2, 2) dtype=float64, numpy=
    array([[1., 2.],
           [3., 4.]])>

  NtocoorR   )indicesvaluesZdense_shape)rE   rv   
constraintru   )rL   hasattrr   rM   concatenateexpand_dimsrowcolr   rJ   dataru   _keras_shaperH   rI   dtypes_moduleas_dtyperF   Zndarray	int_shapetrack_variable)rj   rE   rv   r   Z
sparse_coor   vr9   r9   r:   variable
  s*    



r   c             C   s"   t  rdS td }||  dS )zBTracks the given TF optimizer for initialization of its variables.N)r   rg   rf   add)Ztf_optimizerZ
optimizersr9   r9   r:   track_tf_optimizer=  s    r   z)keras.__internal__.backend.track_variablec             C   s4   t  rdS t| dr| jnt }t| |  dS )z-Tracks the given variable for initialization.NrY   )r   rg   r   rY   rS   rd   r   )r   rY   r9   r9   r:   r   E  s    r   c             C   s   t |  dS )zFObserve a name and make sure it won't be used by `unique_object_name`.N)r\   r   )rv   r9   r9   r:   observe_object_nameN  s    r   c       	      C   s   |dkrt  }|dkr&|r t}nt }d}xx|dks<||kr|| f}|r||| }|rf| d t| }n| }||  d7  < q,||  d7  < | d t||  }q,W |S )a  Makes a object name (or arbitrary string) unique within a TensorFlow graph.

  Args:
    name: String name to make unique.
    name_uid_map: An optional defaultdict(int) to use when creating unique
      names. If None (default), uses a per-Graph dictionary.
    avoid_names: An optional set or dict with names which should not be used. If
      None (default), don't avoid any names unless `avoid_observed_names` is
      True.
    namespace: Gets a name which is unique within the (graph, namespace). Layers
      which are not Networks use a blank namespace and so get graph-global
      names.
    zero_based: If True, name sequences start with no suffix (e.g. "dense",
      "dense_1"). If False, naming is one-based ("dense_1", "dense_2").
    avoid_observed_names: If True, avoid any names that have been observed by
      `backend.observe_object_name`.

  Returns:
    Unique string name.

  Example:


  unique_object_name('dense')  # dense_1
  unique_object_name('dense')  # dense_2

  N_rR   )r   r\   setstr)	rv   r   Zavoid_names	namespaceZ
zero_basedZavoid_observed_namesZproposed_nameZname_keynumberr9   r9   r:   unique_object_nameS  s$    !r   c             C   s:   t  rtt|  }x t|  D ]}||j  qW |S )zFReturns variables corresponding to the given graph for initialization.)r   rg   r   rd   rf   updateZ	optimizerr,   )rY   r,   optr9   r9   r:   _get_variables  s
    r   z/keras.__internal__.backend.initialize_variablesc                s   t t }g }x"|D ]}t|dds|| qW |r| dd |D   fddt|D }g }x*t||D ]\}}|r|| d|_qpW |r| t	| dS )z9Utility to initialize uninitialized variables on the fly._keras_initializedFc             S   s   g | ]}t |qS r9   )rH   Zis_variable_initialized)r   r   r9   r9   r:   r     s    z)_initialize_variables.<locals>.<listcomp>c                s$   g | ]\}} |  o|j d k	qS )N)initializer)r   nr   )is_initializedr9   r:   r     s   TN)
r   rS   rm   appendrun	enumeratezipr   rH   Zvariables_initializer)r   r,   Zcandidate_varsr   Zshould_be_initializedZuninitialized_varsflagr9   )r   r:   r     s"    




r   zkeras.backend.constantc             C   s    |dkrt  }tj| |||dS )a  Creates a constant tensor.

  Args:
      value: A constant value (or list)
      dtype: The type of the elements of the resulting tensor.
      shape: Optional dimensions of resulting tensor.
      name: Optional name for the tensor.

  Returns:
      A Constant Tensor.
  N)rE   ru   rv   )rL   r
   r   )rj   rE   ru   rv   r9   r9   r:   r     s    r   zkeras.backend.is_keras_tensorc             C   sT   t | tjtjtjtjt	j
fs6tdtt|  d t rJt | t	j
S t| dS )a  Returns whether `x` is a Keras tensor.

  A "Keras tensor" is a tensor that was returned by a Keras layer,
  (`Layer` class) or by `Input`.

  Args:
      x: A candidate tensor.

  Returns:
      A boolean: Whether the argument is a Keras tensor.

  Raises:
      ValueError: In case `x` is not a symbolic tensor.

  Examples:

  >>> np_var = np.array([1, 2])
  >>> # A numpy array is not a symbolic tensor.
  >>> tf.keras.backend.is_keras_tensor(np_var)
  Traceback (most recent call last):
  ...
  ValueError: Unexpectedly found an instance of type `<class 'numpy.ndarray'>`.
  Expected a symbolic tensor instance.
  >>> keras_var = tf.keras.backend.variable(np_var)
  >>> # A variable created with the keras backend is not a Keras tensor.
  >>> tf.keras.backend.is_keras_tensor(keras_var)
  False
  >>> keras_placeholder = tf.keras.backend.placeholder(shape=(2, 4, 5))
  >>> # A placeholder is a Keras tensor.
  >>> tf.keras.backend.is_keras_tensor(keras_placeholder)
  True
  >>> keras_input = tf.keras.layers.Input([10])
  >>> # An Input is a Keras tensor.
  >>> tf.keras.backend.is_keras_tensor(keras_input)
  True
  >>> keras_layer_output = tf.keras.layers.Dense(10)(keras_input)
  >>> # Any Keras layer output is a Keras tensor.
  >>> tf.keras.backend.is_keras_tensor(keras_layer_output)
  True

  z(Unexpectedly found an instance of type `z'`. Expected a symbolic tensor instance._keras_history)rF   r   rG   rH   rI   r   rJ   r-   RaggedTensorr   ZKerasTensorr}   r   r   r   r   )rO   r9   r9   r:   is_keras_tensor  s    +
r   zkeras.backend.placeholderc          	   C   s  |r|rt d|dkrt }| s.|r.d| } t r|rJtj| |d}nn|rd}xBtdt| D ]0}| | dkst| | drb| | j	dkrb|}qbW t
j| ||d}ntj| ||d	}tj||d
}	nt   |rtj|| |d}	np|rJd}x*tdt| D ]}| | dkr|}qW t
j| ||d}
dd }tj||
dd}	ntj|| |d}	W dQ R X t rddlm} |j|	d}	d|	_|	S )a0  Instantiates a placeholder tensor and returns it.

  Args:
      shape: Shape of the placeholder
          (integer tuple, may include `None` entries).
      ndim: Number of axes of the tensor.
          At least one of {`shape`, `ndim`} must be specified.
          If both are specified, `shape` is used.
      dtype: Placeholder type.
      sparse: Boolean, whether the placeholder should have a sparse type.
      name: Optional name string for the placeholder.
      ragged: Boolean, whether the placeholder should have a ragged type.
          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).

  Raises:
      ValueError: If called with sparse = True and ragged = True.

  Returns:
      Tensor instance (with Keras metadata included).

  Examples:


  >>> input_ph = tf.keras.backend.placeholder(shape=(2, 4, 5))
  >>> input_ph
  <KerasTensor: shape=(2, 4, 5) dtype=float32 (created by layer ...)>

  zFCannot set both sparse and ragged to True when creating a placeholder.N)N)ru   rE   r   rR   rj   )ru   rE   ragged_rank)ru   rE   rv   )rv   )ru   rv   c             S   s   t | j| jS )N)r   placeholderrE   ru   )Z
tensorspecr9   r9   r:   tensor_spec_to_placeholderG  s    z/placeholder.<locals>.tensor_spec_to_placeholderT)expand_composites)input_layer)r   )r}   rL   r   r   r   r   rangelenr   rj   r-   ZRaggedTensorSpecr   Z
TensorSpecr   Zkeras_tensor_from_type_specrS   r`   r   Zsparse_placeholderr1   map_structurer   r   rg   tensorflow.python.keras.enginer   ZInput_is_backend_placeholder)ru   ndimrE   sparserv   raggedr   r   irO   Z	type_specr   r   r9   r9   r:   r     sV    &


r   c             C   sr   yXt  rt| dS ddlm} || rJtj| dd}tdd |D S | j	j
dkS W n tk
rl   d	S X d
S )znReturns whether `x` is a placeholder.

  Args:
      x: A candidate placeholder.

  Returns:
      Boolean.
  r   r   )tf_utilsT)r   c             s   s   | ]}t |V  qd S )N)rt   )r   cr9   r9   r:   	<genexpr>h  s    z!is_placeholder.<locals>.<genexpr>ZPlaceholderFN)r   r   r   tensorflow.python.keras.utilsr   is_extension_typer1   flattenpy_anyr   r   AttributeError)rO   r   Zflat_componentsr9   r9   r:   rt   Y  s    	

rt   zkeras.backend.shapec             C   s
   t | S )a  Returns the symbolic shape of a tensor or variable.

  Args:
      x: A tensor or variable.

  Returns:
      A symbolic shape (which is itself a tensor).

  Examples:

  >>> val = np.array([[1, 2], [3, 4]])
  >>> kvar = tf.keras.backend.variable(value=val)
  >>> tf.keras.backend.shape(kvar)
  <tf.Tensor: shape=(2,), dtype=int32, numpy=array([2, 2], dtype=int32)>
  >>> input = tf.keras.backend.placeholder(shape=(2, 4, 5))
  >>> tf.keras.backend.shape(input)
  <KerasTensor: shape=(3,) dtype=int32 inferred_value=[2, 4, 5] ...>

  )r   ru   )rO   r9   r9   r:   ru   o  s    ru   zkeras.backend.int_shapec             C   s:   y | j }t|tst| }|S  tk
r4   dS X dS )a  Returns the shape of tensor or variable as a tuple of int or None entries.

  Args:
      x: Tensor or variable.

  Returns:
      A tuple of integers (or None entries).

  Examples:

  >>> input = tf.keras.backend.placeholder(shape=(2, 4, 5))
  >>> tf.keras.backend.int_shape(input)
  (2, 4, 5)
  >>> val = np.array([[1, 2], [3, 4]])
  >>> kvar = tf.keras.backend.variable(value=val)
  >>> tf.keras.backend.int_shape(kvar)
  (2, 2)

  N)ru   rF   r   as_listr}   )rO   ru   r9   r9   r:   r     s    
r   zkeras.backend.ndimc             C   s   | j jS )a  Returns the number of axes in a tensor, as an integer.

  Args:
      x: Tensor or variable.

  Returns:
      Integer (scalar), number of axes.

  Examples:


  >>> input = tf.keras.backend.placeholder(shape=(2, 4, 5))
  >>> val = np.array([[1, 2], [3, 4]])
  >>> kvar = tf.keras.backend.variable(value=val)
  >>> tf.keras.backend.ndim(input)
  3
  >>> tf.keras.backend.ndim(kvar)
  2

  )ru   rank)rO   r9   r9   r:   r     s    r   zkeras.backend.dtypec             C   s
   | j jjS )aQ  Returns the dtype of a Keras tensor or variable, as a string.

  Args:
      x: Tensor or variable.

  Returns:
      String, dtype of `x`.

  Examples:

  >>> tf.keras.backend.dtype(tf.keras.backend.placeholder(shape=(2,4,5)))
  'float32'
  >>> tf.keras.backend.dtype(tf.keras.backend.placeholder(shape=(2,4,5),
  ...                                                     dtype='float32'))
  'float32'
  >>> tf.keras.backend.dtype(tf.keras.backend.placeholder(shape=(2,4,5),
  ...                                                     dtype='float64'))
  'float64'
  >>> kvar = tf.keras.backend.variable(np.array([[1, 2], [3, 4]]))
  >>> tf.keras.backend.dtype(kvar)
  'float32'
  >>> kvar = tf.keras.backend.variable(np.array([[1, 2], [3, 4]]),
  ...                                  dtype='float32')
  >>> tf.keras.backend.dtype(kvar)
  'float32'

  )rE   
base_dtyperv   )rO   r9   r9   r:   rE     s    rE   c             C   s   t | jjS )zReturns the numpy dtype of a Keras tensor or variable.

  Args:
      x: Tensor or variable.

  Returns:
      numpy.dtype, dtype of `x`.
  )r   r   rE   as_numpy_dtype)rO   r9   r9   r:   dtype_numpy  s    
r  zkeras.backend.evalc             C   s   t t| S )aH  Evaluates the value of a variable.

  Args:
      x: A variable.

  Returns:
      A Numpy array.

  Examples:

  >>> kvar = tf.keras.backend.variable(np.array([[1, 2], [3, 4]]),
  ...                                  dtype='float32')
  >>> tf.keras.backend.eval(kvar)
  array([[1.,  2.],
         [3.,  4.]], dtype=float32)

  )	get_valuer   )rO   r9   r9   r:   eval  s    r  zkeras.backend.zerosc          	   C   s\   t  J |dkrt }t|}tj| ||d}t|j	 rNt
|||dS |S Q R X dS )a(  Instantiates an all-zeros variable and returns it.

  Args:
      shape: Tuple or list of integers, shape of returned Keras variable
      dtype: data type of returned Keras variable
      name: name of returned Keras variable

  Returns:
      A variable (including Keras metadata), filled with `0.0`.
      Note that if `shape` was symbolic, we cannot return a variable,
      and will return a dynamically-shaped tensor instead.

  Example:

  >>> kvar = tf.keras.backend.zeros((3,4))
  >>> tf.keras.backend.eval(kvar)
  array([[0.,  0.,  0.,  0.],
         [0.,  0.,  0.,  0.],
         [0.,  0.,  0.,  0.]], dtype=float32)
  >>> A = tf.constant([1,2,3])
  >>> kvar2 = tf.keras.backend.zeros(A.shape) # [0., 0., 0.]
  >>> tf.keras.backend.eval(kvar2)
  array([0., 0., 0.], dtype=float32)
  >>> kvar3 = tf.keras.backend.zeros(A.shape,dtype=tf.int32)
  >>> tf.keras.backend.eval(kvar3)
  array([0, 0, 0], dtype=int32)
  >>> kvar4 = tf.keras.backend.zeros([2,3])
  >>> tf.keras.backend.eval(kvar4)
  array([[0., 0., 0.],
         [0., 0., 0.]], dtype=float32)

  N)ru   rE   rv   )rE   rv   )r   ro   rL   r   r   r   zerospy_allru   r   r   )ru   rE   rv   tf_dtyper   r9   r9   r:   r    s    #

r  zkeras.backend.onesc          	   C   s\   t  J |dkrt }t|}tj| ||d}t|j	 rNt
|||dS |S Q R X dS )al  Instantiates an all-ones variable and returns it.

  Args:
      shape: Tuple of integers, shape of returned Keras variable.
      dtype: String, data type of returned Keras variable.
      name: String, name of returned Keras variable.

  Returns:
      A Keras variable, filled with `1.0`.
      Note that if `shape` was symbolic, we cannot return a variable,
      and will return a dynamically-shaped tensor instead.

  Example:


  >>> kvar = tf.keras.backend.ones((3,4))
  >>> tf.keras.backend.eval(kvar)
  array([[1.,  1.,  1.,  1.],
         [1.,  1.,  1.,  1.],
         [1.,  1.,  1.,  1.]], dtype=float32)

  N)ru   rE   rv   )rE   rv   )r   ro   rL   r   r   r   onesr  ru   r   r   )ru   rE   rv   r	  r   r9   r9   r:   r
  5  s    

r
  zkeras.backend.eyec             C   s.   |dkrt  }t|}ttj| |d||S )a  Instantiate an identity matrix and returns it.

  Args:
      size: Integer, number of rows/columns.
      dtype: String, data type of returned Keras variable.
      name: String, name of returned Keras variable.

  Returns:
      A Keras variable, an identity matrix.

  Example:


  >>> kvar = tf.keras.backend.eye(3)
  >>> tf.keras.backend.eval(kvar)
  array([[1.,  0.,  0.],
         [0.,  1.,  0.],
         [0.,  0.,  1.]], dtype=float32)


  N)rE   )rL   r   r   r   r"   eye)sizerE   rv   r	  r9   r9   r:   r  Y  s    
r  zkeras.backend.zeros_likec             C   s   t j| ||dS )a;  Instantiates an all-zeros variable of the same shape as another tensor.

  Args:
      x: Keras variable or Keras tensor.
      dtype: dtype of returned Keras variable.
             `None` uses the dtype of `x`.
      name: name for the variable to create.

  Returns:
      A Keras variable with the shape of `x` filled with zeros.

  Example:

  ```python
  from tensorflow.keras import backend as K
  kvar = K.variable(np.random.random((2,3)))
  kvar_zeros = K.zeros_like(kvar)
  K.eval(kvar_zeros)
  # array([[ 0.,  0.,  0.], [ 0.,  0.,  0.]], dtype=float32)
  ```
  )rE   rv   )r   
zeros_like)rO   rE   rv   r9   r9   r:   r  x  s    r  zkeras.backend.ones_likec             C   s   t j| ||dS )a9  Instantiates an all-ones variable of the same shape as another tensor.

  Args:
      x: Keras variable or tensor.
      dtype: String, dtype of returned Keras variable.
           None uses the dtype of x.
      name: String, name for the variable to create.

  Returns:
      A Keras variable with the shape of x filled with ones.

  Example:

  >>> kvar = tf.keras.backend.variable(np.random.random((2,3)))
  >>> kvar_ones = tf.keras.backend.ones_like(kvar)
  >>> tf.keras.backend.eval(kvar_ones)
  array([[1.,  1.,  1.],
         [1.,  1.,  1.]], dtype=float32)

  )rE   rv   )r   	ones_like)rO   rE   rv   r9   r9   r:   r    s    r  c             C   s   t j| |dS )zReturns a tensor with the same content as the input tensor.

  Args:
      x: The input tensor.
      name: String, name for the variable to create.

  Returns:
      A tensor of the same shape, type and content.
  )rv   )r   identity)rO   rv   r9   r9   r:   r    s    
r  z%keras.backend.random_uniform_variablec             C   sP   |dkrt  }t|}|dkr,tjd}tj||||d| }t|||dS )a  Instantiates a variable with values drawn from a uniform distribution.

  Args:
      shape: Tuple of integers, shape of returned Keras variable.
      low: Float, lower boundary of the output interval.
      high: Float, upper boundary of the output interval.
      dtype: String, dtype of returned Keras variable.
      name: String, name of returned Keras variable.
      seed: Integer, random seed.

  Returns:
      A Keras variable, filled with drawn samples.

  Example:

  >>> kvar = tf.keras.backend.random_uniform_variable(shape=(2,3),
  ... low=0.0, high=1.0)
  >>> kvar
  <tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=...,
  dtype=float32)>
  Ng    eA)rE   seed)rE   rv   )	rL   r   r   rM   randomrandintr!   Zrandom_uniform_initializerr   )ru   lowhighrE   rv   r  r	  rj   r9   r9   r:   random_uniform_variable  s    
r  z$keras.backend.random_normal_variablec             C   sP   |dkrt  }t|}|dkr,tjd}tj||||d| }t|||dS )a  Instantiates a variable with values drawn from a normal distribution.

  Args:
      shape: Tuple of integers, shape of returned Keras variable.
      mean: Float, mean of the normal distribution.
      scale: Float, standard deviation of the normal distribution.
      dtype: String, dtype of returned Keras variable.
      name: String, name of returned Keras variable.
      seed: Integer, random seed.

  Returns:
      A Keras variable, filled with drawn samples.

  Example:

  >>> kvar = tf.keras.backend.random_normal_variable(shape=(2,3),
  ... mean=0.0, scale=1.0)
  >>> kvar
  <tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=...,
  dtype=float32)>
  Ng    eA)rE   r  )rE   rv   )	rL   r   r   rM   r  r  r!   Zrandom_normal_initializerr   )ru   meanscalerE   rv   r  r	  rj   r9   r9   r:   random_normal_variable  s    
r  zkeras.backend.count_paramsc             C   s   t | j S )ak  Returns the static number of elements in a variable or tensor.

  Args:
      x: Variable or tensor.

  Returns:
      Integer, the number of scalars in `x`.

  Example:

  >>> kvar = tf.keras.backend.zeros((2,3))
  >>> tf.keras.backend.count_params(kvar)
  6
  >>> tf.keras.backend.eval(kvar)
  array([[0.,  0.,  0.],
         [0.,  0.,  0.]], dtype=float32)

  )rM   prodru   r   )rO   r9   r9   r:   count_params  s    r  zkeras.backend.castc             C   s   t | |S )a  Casts a tensor to a different dtype and returns it.

  You can cast a Keras variable but it still returns a Keras tensor.

  Args:
      x: Keras tensor (or variable).
      dtype: String, either (`'float16'`, `'float32'`, or `'float64'`).

  Returns:
      Keras tensor with dtype `dtype`.

  Examples:
      Cast a float32 variable to a float64 tensor

  >>> input = tf.keras.backend.ones(shape=(1,3))
  >>> print(input)
  <tf.Variable 'Variable:0' shape=(1, 3) dtype=float32,
  numpy=array([[1., 1., 1.]], dtype=float32)>
  >>> cast_input = tf.keras.backend.cast(input, dtype='float64')
  >>> print(cast_input)
  tf.Tensor([[1. 1. 1.]], shape=(1, 3), dtype=float64)

  )r%   rK   )rO   rE   r9   r9   r:   rK     s    rK   zkeras.backend.updatec             C   s   t | |S )N)r)   assign)rO   Znew_xr9   r9   r:   r   ;  s    r   zkeras.backend.update_addc             C   s   t | |S )zUpdate the value of `x` by adding `increment`.

  Args:
      x: A Variable.
      increment: A tensor of same shape as `x`.

  Returns:
      The variable `x` updated.
  )r)   Z
assign_add)rO   	incrementr9   r9   r:   
update_addA  s    r  zkeras.backend.update_subc             C   s   t | |S )zUpdate the value of `x` by subtracting `decrement`.

  Args:
      x: A Variable.
      decrement: A tensor of same shape as `x`.

  Returns:
      The variable `x` updated.
  )r)   Z
assign_sub)rO   Z	decrementr9   r9   r:   
update_subP  s    r  z#keras.backend.moving_average_updatec             C   sT   t  r>t|| j}t|| j}| | | |d|   S tj| ||ddS dS )a  Compute the exponential moving average of a value.

  The moving average 'x' is updated with 'value' following:

  ```
  x = x * momentum + value * (1 - momentum)
  ```

  For example:

  >>> x = tf.Variable(0.0)
  >>> momentum=0.9
  >>> moving_average_update(x, value = 2.0, momentum=momentum).numpy()
  >>> x.numpy()
  0.2

  The result will be biased towards the initial value of the variable.

  If the variable was initialized to zero, you can divide by
  `1 - momentum ** num_updates` to debias it (Section 3 of
  [Kingma et al., 2015](https://arxiv.org/abs/1412.6980)):

  >>> num_updates = 1.0
  >>> x_zdb = x/(1 - momentum**num_updates)
  >>> x_zdb.numpy()
  2.0

  Args:
      x: A Variable, the moving average.
      value: A tensor with the same shape as `x`, the new value to be
        averaged in.
      momentum: The moving average momentum.

  Returns:
      The updated variable.
  rR   T)Zzero_debiasN)r   r   r%   rK   rE   r  r/   Zassign_moving_average)rO   rj   Zmomentumr9   r9   r:   moving_average_update_  s    'r  zkeras.backend.dotc       
      C   sz  t | dk	rRt | dks(t |dkrRg }xDtt| tt| D ]&\}}|dk	rd|| qH|| qHW t|}g }xDtt|tt|D ]&\}}|dk	r|| q|| qW t|}tt	t |}|
dg| }t| d|d g}ttj||d|d dg}tt|||dd |dd  |dd  S t| rjt| |}	nt| |}	|	S )aX  Multiplies 2 tensors (and/or variables) and returns a tensor.

  This operation corresponds to `numpy.dot(a, b, out=None)`.

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A tensor, dot product of `x` and `y`.

  Examples:

  If inputs `x` and `y` are 2-D arrays, then it is equivalent to `tf.matmul`.
  >>> x = tf.keras.backend.placeholder(shape=(2, 3))
  >>> y = tf.keras.backend.placeholder(shape=(3, 4))
  >>> xy = tf.keras.backend.dot(x, y)
  >>> xy
  <KerasTensor: shape=(2, 4) dtype=float32 ...>

  >>> x = tf.keras.backend.placeholder(shape=(32, 28, 3))
  >>> y = tf.keras.backend.placeholder(shape=(3, 4))
  >>> xy = tf.keras.backend.dot(x, y)
  >>> xy
  <KerasTensor: shape=(32, 28, 4) dtype=float32 ...>

  If `x` is an N-D array and `y` is an M-D array (where M>=2), it is a sum
  product over the last axis of `x` and the second-to-last axis of `y`.
  >>> x = tf.keras.backend.random_uniform_variable(shape=(2, 3), low=0, high=1)
  >>> y = tf.keras.backend.ones((4, 3, 5))
  >>> xy = tf.keras.backend.dot(x, y)
  >>> tf.keras.backend.int_shape(xy)
  (2, 4, 5)
  N   )perm)r   r   r   r   unstackru   r   r   listr   re   reshape	transposer%   matmulr   r(   Zsparse_tensor_dense_matmul)
rO   yx_shaper   sy_shapeZy_permute_dimZxtZytoutr9   r9   r:   dot  s0    &($$0
r.  zkeras.backend.batch_dotc             C   s  t | }t |}t|}t|}|dk s0|dk rPtdt| d t| d |d }|d }|dk	r|dk	r||krtdt| d t| d t|tr||g}|dkr|dkr|d |d g}n|d |d g}td	d
 |D rtdt| t|}|d dk r$|d  |7  < |d dk rB|d  |7  < d|krTtd|\}	}
||	 }||
 }|dk	r|dk	r||krtdt| d t| d t| d|d |d ||f  |}|}|dkrt	| d} |	d7 }	|d7 }|dkrt	|d}|d7 }|	|d krntt
|}x(t
|	|d D ]}||d  ||< q@W |	|d< t| |} |
dkrtt
|}x&t
|
ddD ]}||d  ||< qW |
|d< t||}|dkrt| }|dd }t|d d|d g}t| |} d}nd}|dkrTt|}|dd }t|d |d dg}t||}d}nd}t| |}t|}d}|rt|dd ||dd gd}d}|rt|dd |gd}d}|rt||}|dkrt|d}n|dkr t|d}|S )aZ  Batchwise dot product.

  `batch_dot` is used to compute dot product of `x` and `y` when
  `x` and `y` are data in batch, i.e. in a shape of
  `(batch_size, :)`.
  `batch_dot` results in a tensor or variable with less dimensions
  than the input. If the number of dimensions is reduced to 1,
  we use `expand_dims` to make sure that ndim is at least 2.

  Args:
    x: Keras tensor or variable with `ndim >= 2`.
    y: Keras tensor or variable with `ndim >= 2`.
    axes: Tuple or list of integers with target dimensions, or single integer.
      The sizes of `x.shape[axes[0]]` and `y.shape[axes[1]]` should be equal.

  Returns:
    A tensor with shape equal to the concatenation of `x`'s shape
    (less the dimension that was summed over) and `y`'s shape
    (less the batch dimension and the dimension that was summed over).
    If the final rank is 1, we reshape it to `(batch_size, 1)`.

  Examples:

  >>> x_batch = tf.keras.backend.ones(shape=(32, 20, 1))
  >>> y_batch = tf.keras.backend.ones(shape=(32, 30, 20))
  >>> xy_batch_dot = tf.keras.backend.batch_dot(x_batch, y_batch, axes=(1, 2))
  >>> tf.keras.backend.int_shape(xy_batch_dot)
  (32, 1, 30)

  Shape inference:
    Let `x`'s shape be `(100, 20)` and `y`'s shape be `(100, 30, 20)`.
    If `axes` is (1, 2), to find the output shape of resultant tensor,
        loop through each dimension in `x`'s shape and `y`'s shape:
    * `x.shape[0]` : 100 : append to output shape
    * `x.shape[1]` : 20 : do not append to output shape,
        dimension 1 of `x` has been summed over. (`dot_axes[0]` = 1)
    * `y.shape[0]` : 100 : do not append to output shape,
        always ignore first dimension of `y`
    * `y.shape[1]` : 30 : append to output shape
    * `y.shape[2]` : 20 : do not append to output shape,
        dimension 2 of `y` has been summed over. (`dot_axes[1]` = 2)
    `output_shape` = `(100, 30)`
  r   zICannot do batch_dot on inputs with rank < 2. Received inputs with shapes z and .r   NzVCannot do batch_dot on inputs with different batch sizes. Received inputs with shapes rR   c             s   s   | ]}t |ttfV  qd S )N)rF   r%  r   )r   ar9   r9   r:   r   $  s    zbatch_dot.<locals>.<genexpr>zYMultiple target dimensions are not supported. Expected: None, int, (int, int), Provided: zCannot perform batch_dot over axis 0. If your inputs are not batched, add a dummy batch dimension to your inputs using K.expand_dims(x, 0)z*Cannot do batch_dot on inputs with shapes z with axes=z(. x.shape[%d] != y.shape[%d] (%d != %d).r"     TF)r   r   r}   r   rF   rW   r   r%  r   r   r   r'  ru   stackr&  r%   r(  concatsqueeze)rO   r)  axesr*  r,  Zx_ndimZy_ndimZx_batch_sizeZy_batch_sizeZa0Za1Zd1Zd2Zorig_x_ndimZorig_y_ndimpatternr   Z
x_mid_dimsZx_squashed_shapeZ
x_squashedZy_trail_dimsZy_squashed_shapeZ
y_squashedresultoutput_shapeZ
do_reshaper9   r9   r:   	batch_dot  s    /

$








r9  zkeras.backend.transposec             C   s
   t | S )a  Transposes a tensor and returns it.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.

  Examples:

  >>> var = tf.keras.backend.variable([[1, 2, 3], [4, 5, 6]])
  >>> tf.keras.backend.eval(var)
  array([[1.,  2.,  3.],
         [4.,  5.,  6.]], dtype=float32)
  >>> var_transposed = tf.keras.backend.transpose(var)
  >>> tf.keras.backend.eval(var_transposed)
  array([[1.,  4.],
         [2.,  5.],
         [3.,  6.]], dtype=float32)
  >>> input = tf.keras.backend.placeholder((2, 3))
  >>> input
  <KerasTensor: shape=(2, 3) dtype=float32 ...>
  >>> input_transposed = tf.keras.backend.transpose(input)
  >>> input_transposed
  <KerasTensor: shape=(3, 2) dtype=float32 ...>
  )r   r'  )rO   r9   r9   r:   r'    s    r'  zkeras.backend.gatherc             C   s   t | |S )aG  Retrieves the elements of indices `indices` in the tensor `reference`.

  Args:
      reference: A tensor.
      indices: An integer tensor of indices.

  Returns:
      A tensor of same type as `reference`.

  Examples:

  >>> var = tf.keras.backend.variable([[1, 2, 3], [4, 5, 6]])
  >>> tf.keras.backend.eval(var)
  array([[1., 2., 3.],
         [4., 5., 6.]], dtype=float32)
  >>> var_gathered = tf.keras.backend.gather(var, [0])
  >>> tf.keras.backend.eval(var_gathered)
  array([[1., 2., 3.]], dtype=float32)
  >>> var_gathered = tf.keras.backend.gather(var, [1])
  >>> tf.keras.backend.eval(var_gathered)
  array([[4., 5., 6.]], dtype=float32)
  >>> var_gathered = tf.keras.backend.gather(var, [0,1,0])
  >>> tf.keras.backend.eval(var_gathered)
  array([[1., 2., 3.],
         [4., 5., 6.],
         [1., 2., 3.]], dtype=float32)
  )r   gather)	referencer   r9   r9   r:   r:    s    r:  zkeras.backend.maxc             C   s   t | ||S )a  Maximum value in a tensor.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to find maximum values.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`,
          the reduced dimension is retained with length 1.

  Returns:
      A tensor with maximum values of `x`.
  )r%   
reduce_max)rO   axiskeepdimsr9   r9   r:   max  s    r?  zkeras.backend.minc             C   s   t | ||S )a  Minimum value in a tensor.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to find minimum values.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`,
          the reduced dimension is retained with length 1.

  Returns:
      A tensor with minimum values of `x`.
  )r%   Z
reduce_min)rO   r=  r>  r9   r9   r:   min  s    r@  zkeras.backend.sumc             C   s   t | ||S )a  Sum of the values in a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to sum over.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`,
          the reduced dimension is retained with length 1.

  Returns:
      A tensor with sum of `x`.
  )r%   
reduce_sum)rO   r=  r>  r9   r9   r:   sum	  s    rB  zkeras.backend.prodc             C   s   t | ||S )a  Multiplies the values in a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to compute the product.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`,
          the reduced dimension is retained with length 1.

  Returns:
      A tensor with the product of elements of `x`.
  )r%   Zreduce_prod)rO   r=  r>  r9   r9   r:   r  	  s    r  zkeras.backend.cumsumc             C   s   t j| |dS )zCumulative sum of the values in a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to compute the sum.

  Returns:
      A tensor of the cumulative sum of values of `x` along `axis`.
  )r=  )r%   cumsum)rO   r=  r9   r9   r:   rC  )	  s    rC  zkeras.backend.cumprodc             C   s   t j| |dS )a  Cumulative product of the values in a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to compute the product.

  Returns:
      A tensor of the cumulative product of values of `x` along `axis`.
  )r=  )r%   cumprod)rO   r=  r9   r9   r:   rD  9	  s    rD  zkeras.backend.varc             C   s,   | j jtjkrt| t } tj| ||dS )a  Variance of a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to compute the variance.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`,
          the reduced dimension is retained with length 1.

  Returns:
      A tensor with the variance of elements of `x`.
  )r=  r>  )rE   r  r   r   r%   rK   rL   Zreduce_variance)rO   r=  r>  r9   r9   r:   varI	  s    rE  zkeras.backend.stdc             C   s,   | j jtjkrt| t } tj| ||dS )a  Standard deviation of a tensor, alongside the specified axis.

  It is an alias to `tf.math.reduce_std`.

  Args:
      x: A tensor or variable. It should have numerical dtypes. Boolean type
        inputs will be converted to float.
      axis: An integer, the axis to compute the standard deviation. If `None`
        (the default), reduces all dimensions. Must be in the range
        `[-rank(x), rank(x))`.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`, the reduced dimension is retained with
          length 1.

  Returns:
      A tensor with the standard deviation of elements of `x` with same dtype.
      Boolean type input will be converted to float.
  )r=  r>  )rE   r  r   r   r%   rK   rL   Z
reduce_std)rO   r=  r>  r9   r9   r:   std^	  s    rF  zkeras.backend.meanc             C   s*   | j jtjkrt| t } t| ||S )a  Mean of a tensor, alongside the specified axis.

  Args:
      x: A tensor or variable.
      axis: A list of integer. Axes to compute the mean.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1 for each entry in `axis`. If `keepdims` is `True`,
          the reduced dimensions are retained with length 1.

  Returns:
      A tensor with the mean of elements of `x`.
  )rE   r  r   r   r%   rK   rL   Zreduce_mean)rO   r=  r>  r9   r9   r:   r  z	  s    r  zkeras.backend.anyc             C   s   t | tj} t | ||S )zBitwise reduction (logical OR).

  Args:
      x: Tensor or variable.
      axis: axis along which to perform the reduction.
      keepdims: whether the drop or broadcast the reduction axes.

  Returns:
      A uint8 tensor (0s and 1s).
  )r%   rK   r   r   Z
reduce_any)rO   r=  r>  r9   r9   r:   any	  s    rG  zkeras.backend.allc             C   s   t | tj} t | ||S )zBitwise reduction (logical AND).

  Args:
      x: Tensor or variable.
      axis: axis along which to perform the reduction.
      keepdims: whether the drop or broadcast the reduction axes.

  Returns:
      A uint8 tensor (0s and 1s).
  )r%   rK   r   r   Z
reduce_all)rO   r=  r>  r9   r9   r:   all	  s    rH  zkeras.backend.argmaxr"  c             C   s   t | |S )zReturns the index of the maximum value along an axis.

  Args:
      x: Tensor or variable.
      axis: axis along which to perform the reduction.

  Returns:
      A tensor.
  )r%   argmax)rO   r=  r9   r9   r:   rI  	  s    rI  zkeras.backend.argminc             C   s   t | |S )zReturns the index of the minimum value along an axis.

  Args:
      x: Tensor or variable.
      axis: axis along which to perform the reduction.

  Returns:
      A tensor.
  )r%   argmin)rO   r=  r9   r9   r:   rJ  	  s    rJ  zkeras.backend.squarec             C   s
   t | S )zYElement-wise square.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   square)rO   r9   r9   r:   rK  	  s    rK  zkeras.backend.absc             C   s
   t | S )zaElement-wise absolute value.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   abs)rO   r9   r9   r:   rL  	  s    rL  zkeras.backend.sqrtc             C   s$   t d| jj}t| |} t| S )zElement-wise square root.

     This function clips negative tensor values to 0 before computing the
     square root.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  g        )r   rE   r  r%   maximumsqrt)rO   zeror9   r9   r:   rN  	  s    rN  zkeras.backend.expc             C   s
   t | S )z^Element-wise exponential.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   exp)rO   r9   r9   r:   rP  
  s    rP  zkeras.backend.logc             C   s
   t | S )zVElement-wise log.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   log)rO   r9   r9   r:   rQ  
  s    rQ  c             C   s   t | ||S )aj  Computes log(sum(exp(elements across dimensions of a tensor))).

  This function is more numerically stable than log(sum(exp(x))).
  It avoids overflows caused by taking the exp of large inputs and
  underflows caused by taking the log of small inputs.

  Args:
      x: A tensor or variable.
      axis: An integer, the axis to reduce over.
      keepdims: A boolean, whether to keep the dimensions or not.
          If `keepdims` is `False`, the rank of the tensor is reduced
          by 1. If `keepdims` is `True`, the reduced dimension is
          retained with length 1.

  Returns:
      The reduced tensor.
  )r%   Zreduce_logsumexp)rO   r=  r>  r9   r9   r:   	logsumexp$
  s    rR  zkeras.backend.roundc             C   s
   t | S )zElement-wise rounding to the closest integer.

  In case of tie, the rounding mode used is "half to even".

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   round)rO   r9   r9   r:   rS  9
  s    rS  zkeras.backend.signc             C   s
   t | S )zWElement-wise sign.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   sign)rO   r9   r9   r:   rT  J
  s    rT  zkeras.backend.powc             C   s   t | |S )zzElement-wise exponentiation.

  Args:
      x: Tensor or variable.
      a: Python integer.

  Returns:
      A tensor.
  )r%   pow)rO   r0  r9   r9   r:   rU  Y
  s    rU  zkeras.backend.clipc             C   sT   t |ttfr(t |ttfr(||k r(|}|dkr8tj }|dkrFtj}t| ||S )zElement-wise value clipping.

  Args:
      x: Tensor or variable.
      min_value: Python float, integer, or tensor.
      max_value: Python float, integer, or tensor.

  Returns:
      A tensor.
  N)rF   rW   floatrM   infr   clip_by_value)rO   Z	min_value	max_valuer9   r9   r:   clipi
  s    rZ  zkeras.backend.equalc             C   s   t | |S )zElement-wise equality between two tensors.

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   equal)rO   r)  r9   r9   r:   r[  
  s    r[  zkeras.backend.not_equalc             C   s   t | |S )zElement-wise inequality between two tensors.

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   	not_equal)rO   r)  r9   r9   r:   r\  
  s    r\  zkeras.backend.greaterc             C   s   t | |S )zElement-wise truth value of (x > y).

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   greater)rO   r)  r9   r9   r:   r]  
  s    r]  zkeras.backend.greater_equalc             C   s   t | |S )zElement-wise truth value of (x >= y).

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   greater_equal)rO   r)  r9   r9   r:   r^  
  s    r^  zkeras.backend.lessc             C   s   t | |S )zElement-wise truth value of (x < y).

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   less)rO   r)  r9   r9   r:   r_  
  s    r_  zkeras.backend.less_equalc             C   s   t | |S )zElement-wise truth value of (x <= y).

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A bool tensor.
  )r%   
less_equal)rO   r)  r9   r9   r:   r`  
  s    r`  zkeras.backend.maximumc             C   s   t | |S )a  Element-wise maximum of two tensors.

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A tensor with the element wise maximum value(s) of `x` and `y`.

  Examples:

  >>> x = tf.Variable([[1, 2], [3, 4]])
  >>> y = tf.Variable([[2, 1], [0, -1]])
  >>> m = tf.keras.backend.maximum(x, y)
  >>> m
  <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
  array([[2, 2],
         [3, 4]], dtype=int32)>
  )r%   rM  )rO   r)  r9   r9   r:   rM  
  s    rM  zkeras.backend.minimumc             C   s   t | |S )zElement-wise minimum of two tensors.

  Args:
      x: Tensor or variable.
      y: Tensor or variable.

  Returns:
      A tensor.
  )r%   minimum)rO   r)  r9   r9   r:   ra  
  s    ra  zkeras.backend.sinc             C   s
   t | S )zdComputes sin of x element-wise.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   sin)rO   r9   r9   r:   rb    s    rb  zkeras.backend.cosc             C   s
   t | S )zdComputes cos of x element-wise.

  Args:
      x: Tensor or variable.

  Returns:
      A tensor.
  )r%   cos)rO   r9   r9   r:   rc    s    rc  MbP?c             C   s4   t | |ddd\}}t | |||||}|||fS )a  Non-fused version of `normalize_batch_in_training`.

  Args:
      x: Input tensor or variable.
      gamma: Tensor by which to scale the input.
      beta: Tensor with which to center the input.
      reduction_axes: iterable of integers,
          axes over which to normalize.
      epsilon: Fuzz factor.

  Returns:
      A tuple length of 3, `(normalized_tensor, mean, variance)`.
  NF)r&   momentsbatch_normalization)rO   gammabetareduction_axesepsilonr  rE  normedr9   r9   r:   $_regular_normalize_batch_in_training*  s    rl  c             C   s   t | |ddd\}}g }x<tt| D ],}||kr@|d q(|t| |  q(W t|}t||}	t||}
|dkrd}nt||}|dkrd}nt||}t 	| |	|
|||}|||fS )a  Non-fused, broadcast version of `normalize_batch_in_training`.

  Args:
      x: Input tensor or variable.
      gamma: Tensor by which to scale the input.
      beta: Tensor with which to center the input.
      reduction_axes: iterable of integers,
          axes over which to normalize.
      epsilon: Fuzz factor.

  Returns:
      A tuple length of 3, `(normalized_tensor, mean, variance)`.
  NFrR   )
r&   re  r   r   r   r   ru   r2  r&  rf  )rO   rg  rh  ri  rj  r  rE  Ztarget_shaper=  Zbroadcast_meanZbroadcast_varZbroadcast_gammaZbroadcast_betark  r9   r9   r:   &_broadcast_normalize_batch_in_trainingA  s$    


rm  c             C   s|   t |dddgkrd}d}nd}d}|dkrFtjd| j| j| gd	}|dkrhtjd
| j| j| gd	}tj| ||||dS )a  Fused version of `normalize_batch_in_training`.

  Args:
      x: Input tensor or variable.
      gamma: Tensor by which to scale the input.
      beta: Tensor with which to center the input.
      reduction_axes: iterable of integers,
          axes over which to normalize.
      epsilon: Fuzz factor.

  Returns:
      A tuple length of 3, `(normalized_tensor, mean, variance)`.
  r   rR   r   r1  NHWCNCHWNg      ?)rE   ru   g        )rj  data_format)r%  r
   r   rE   ru   r&   fused_batch_norm)rO   rg  rh  ri  rj  Znormalization_axistf_data_formatr9   r9   r:   "_fused_normalize_batch_in_trainingl  s    rs  z)keras.backend.normalize_batch_in_trainingc             C   s   t | dkrdt|dddgdddggkrdt sRt|dddgkrRt| ||||dS t| ||||dS t|ttt | dd krt| ||||dS t| ||||dS dS )	a  Computes mean and std for batch then apply batch_normalization on batch.

  Args:
      x: Input tensor or variable.
      gamma: Tensor by which to scale the input.
      beta: Tensor with which to center the input.
      reduction_axes: iterable of integers,
          axes over which to normalize.
      epsilon: Fuzz factor.

  Returns:
      A tuple length of 3, `(normalized_tensor, mean, variance)`.
     r   rR   r   r1  )rj  Nr"  )r   r%  r   rm  rs  sortedr   rl  )rO   rg  rh  ri  rj  r9   r9   r:   normalize_batch_in_training  s    ( rv  z!keras.backend.batch_normalizationc       
   
   C   s  t | dkr|dks|dkr$d}n|dks4|dkr:d}nd}|dksT|dkrt rt |dkrnt|dg}t |dkrt|dg}|dkrt|}nt |dkrt|dg}|dkrt|}nt |dkrt|dg}tj| ||||||d	d
\}}	}	|S t| |||||S )a  Applies batch normalization on x given mean, var, beta and gamma.

  I.e. returns:
  `output = (x - mean) / (sqrt(var) + epsilon) * gamma + beta`

  Args:
      x: Input tensor or variable.
      mean: Mean of batch.
      var: Variance of batch.
      beta: Tensor with which to center the input.
      gamma: Tensor by which to scale the input.
      axis: Integer, the axis that should be normalized.
          (typically the features axis).
      epsilon: Fuzz factor.

  Returns:
      A tensor.
  rt  rR   ro  r1  r"  rn  NF)rj  r  Zvariancerp  Zis_training)	r   r   r   r&  r  r  r&   rq  rf  )
rO   r  rE  rh  rg  r=  rj  rr  r)  r   r9   r9   r:   rf    s>    

rf  zkeras.backend.concatenatec             C   s|   |dk r&t | d }|r"||; }nd}tdd | D rDt|| S tdd | D rbt| |S tdd | D |S dS )a4  Concatenates a list of tensors alongside the specified axis.

  Args:
      tensors: list of tensors to concatenate.
      axis: concatenation axis.

  Returns:
      A tensor.

  Example:

      >>> a = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
      >>> b = tf.constant([[10, 20, 30], [40, 50, 60], [70, 80, 90]])
      >>> tf.keras.backend.concatenate((a, b), axis=-1)
      <tf.Tensor: shape=(3, 6), dtype=int32, numpy=
      array([[ 1,  2,  3, 10, 20, 30],
             [ 4,  5,  6, 40, 50, 60],
             [ 7,  8,  9, 70, 80, 90]], dtype=int32)>

  r   c             s   s   | ]}t |V  qd S )N)r   )r   rO   r9   r9   r:   r     s    zconcatenate.<locals>.<genexpr>c             s   s   | ]}t |tjV  qd S )N)rF   r-   r   )r   rO   r9   r9   r:   r     s    c             S   s   g | ]}t |qS r9   )r   )r   rO   r9   r9   r:   r     s    zconcatenate.<locals>.<listcomp>N)r   r  r(   Zsparse_concatr   r3  )tensorsr=  r  r9   r9   r:   r     s    
r   zkeras.backend.reshapec             C   s   t | |S )aR  Reshapes a tensor to the specified shape.

  Args:
      x: Tensor or variable.
      shape: Target shape tuple.

  Returns:
      A tensor.

  Example:

    >>> a = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
    >>> a
    <tf.Tensor: shape=(4, 3), dtype=int32, numpy=
    array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]], dtype=int32)>
    >>> tf.keras.backend.reshape(a, shape=(2, 6))
    <tf.Tensor: shape=(2, 6), dtype=int32, numpy=
    array([[ 1,  2,  3,  4,  5,  6],
           [ 7,  8,  9, 10, 11, 12]], dtype=int32)>

  )r   r&  )rO   ru   r9   r9   r:   r&    s    r&  z keras.backend.permute_dimensionsc             C   s   t j| |dS )a  Permutes axes in a tensor.

  Args:
      x: Tensor or variable.
      pattern: A tuple of
          dimension indices, e.g. `(0, 2, 1)`.

  Returns:
      A tensor.

  Example:

    >>> a = tf.constant([[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]])
    >>> a
    <tf.Tensor: shape=(4, 3), dtype=int32, numpy=
    array([[ 1,  2,  3],
           [ 4,  5,  6],
           [ 7,  8,  9],
           [10, 11, 12]], dtype=int32)>
    >>> tf.keras.backend.permute_dimensions(a, pattern=(1, 0))
    <tf.Tensor: shape=(3, 4), dtype=int32, numpy=
    array([[ 1,  4,  7, 10],
           [ 2,  5,  8, 11],
           [ 3,  6,  9, 12]], dtype=int32)>

  )r#  )r   r'  )rO   r6  r9   r9   r:   permute_dimensions5  s    ry  zkeras.backend.resize_imagesnearestc             C   s  |dkrd\}}n |dkr$d\}}nt d|f | j||d  }| r`tj| dd}nt| ||d  }|ttj	||gdd9 }|dkrt
| d	d
ddg} |dkrtj| |tjjd} n&|dkrtj| |tjjd} nt d|dkrt
| d	ddd
g} | S )a  Resizes the images contained in a 4D tensor.

  Args:
      x: Tensor or variable to resize.
      height_factor: Positive integer.
      width_factor: Positive integer.
      data_format: One of `"channels_first"`, `"channels_last"`.
      interpolation: A string, one of `nearest` or `bilinear`.

  Returns:
      A tensor.

  Raises:
      ValueError: in case of incorrect value for
        `data_format` or `interpolation`.
  channels_first)r   r1  channels_last)rR   r   z"Invalid `data_format` argument: %srR   int32)rE   r   r   r1  rz  )methodZbilinearz7interpolation should be one of "nearest" or "bilinear".)r}   ru   Zis_fully_definedr
   r   r   r   shape_v2rM   arrayry  r    Zresize_images_v2ZResizeMethodZNEAREST_NEIGHBORZBILINEAR)rO   height_factorwidth_factorrp  interpolationrowscolsZ	new_shaper9   r9   r:   resize_imagesV  s.    


r  zkeras.backend.resize_volumesc             C   s   |dkr6t | |dd}t ||dd}t ||dd}|S |dkrlt | |dd}t ||dd}t ||dd}|S tdt| d	S )
a  Resizes the volume contained in a 5D tensor.

  Args:
      x: Tensor or variable to resize.
      depth_factor: Positive integer.
      height_factor: Positive integer.
      width_factor: Positive integer.
      data_format: One of `"channels_first"`, `"channels_last"`.

  Returns:
      A tensor.

  Raises:
      ValueError: if `data_format` is neither
          `channels_last` or `channels_first`.
  r{  r   )r=  r1  rt  r|  rR   zInvalid data_format: N)repeat_elementsr}   r   )rO   Zdepth_factorr  r  rp  outputr9   r9   r:   resize_volumes  s    r  zkeras.backend.repeat_elementsc                s   | j  }|| dk	rFtj| || |d} fdd|D }t||S |d }t | }tj| |d}tt| j d } ||< t	||}t
||} ||< tj|dd}||9 }t||}| j  }|| t||_|S )	a   Repeats the elements of a tensor along an axis, like `np.repeat`.

  If `x` has shape `(s1, s2, s3)` and `axis` is `1`, the output
  will have shape `(s1, s2 * rep, s3)`.

  Args:
      x: Tensor or variable.
      rep: Python integer, number of times to repeat.
      axis: Axis along which to repeat.

  Returns:
      A tensor.

  Example:

      >>> b = tf.constant([1, 2, 3])
      >>> tf.keras.backend.repeat_elements(b, rep=2, axis=0)
      <tf.Tensor: shape=(6,), dtype=int32,
          numpy=array([1, 1, 2, 2, 3, 3], dtype=int32)>

  N)rj   Znum_or_size_splitsr=  c                s   g | ]}t  D ]}|qqS r9   )r   )r   r+  r   )repr9   r:   r     s    z#repeat_elements.<locals>.<listcomp>rR   )r=  r}  )rE   )ru   r   r   splitr   r   rM   r
  r   tiledeleter   r&  	set_shaper   r   )rO   r  r=  r*  ZsplitsZx_repZauxiliary_axisZrepsr9   )r  r:   r    s,    





r  zkeras.backend.repeatc             C   s8   t | dkstt| d} td|dg}t| |S )ao  Repeats a 2D tensor.

  if `x` has shape (samples, dim) and `n` is `2`,
  the output will have shape `(samples, 2, dim)`.

  Args:
      x: Tensor or variable.
      n: Python integer, number of times to repeat.

  Returns:
      A tensor.

  Example:

      >>> b = tf.constant([[1, 2], [3, 4]])
      >>> b
      <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
      array([[1, 2],
             [3, 4]], dtype=int32)>
      >>> tf.keras.backend.repeat(b, n=2)
      <tf.Tensor: shape=(2, 2, 2), dtype=int32, numpy=
      array([[[1, 2],
              [1, 2]],
             [[3, 4],
              [3, 4]]], dtype=int32)>

  r   rR   )r   r   r   r   r2  r  )rO   r   r6  r9   r9   r:   repeat  s    r  zkeras.backend.arangerR   r}  c             C   s<   |dkr| dk rd} t j| ||dd}|dkr8t||}|S )a  Creates a 1D tensor containing a sequence of integers.

  The function arguments use the same convention as
  Theano's arange: if only one argument is provided,
  it is in fact the "stop" argument and "start" is 0.

  The default type of the returned tensor is `'int32'` to
  match TensorFlow's default.

  Args:
      start: Start value.
      stop: Stop value.
      step: Difference between two successive values.
      dtype: Integer dtype to use.

  Returns:
      An integer tensor.

  Example:

      >>> tf.keras.backend.arange(start=0, stop=10, step=1.5)
      <tf.Tensor: shape=(7,), dtype=float32,
          numpy=array([0. , 1.5, 3. , 4.5, 6. , 7.5, 9. ], dtype=float32)>



  Nr   arange)limitdeltarv   r}  )r%   r   rK   )startstopsteprE   r7  r9   r9   r:   r    s     
r  zkeras.backend.tilec             C   s   t |tr|g}t| |S )zCreates a tensor by tiling `x` by `n`.

  Args:
      x: A tensor or variable
      n: A list of integer. The length must be the same as the number of
          dimensions in `x`.

  Returns:
      A tiled tensor.
  )rF   rW   r   r  )rO   r   r9   r9   r:   r  9  s    
r  zkeras.backend.flattenc             C   s   t | dgS )a  Flatten a tensor.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor, reshaped into 1-D

  Example:

      >>> b = tf.constant([[1, 2], [3, 4]])
      >>> b
      <tf.Tensor: shape=(2, 2), dtype=int32, numpy=
      array([[1, 2],
             [3, 4]], dtype=int32)>
      >>> tf.keras.backend.flatten(b)
      <tf.Tensor: shape=(4,), dtype=int32,
          numpy=array([1, 2, 3, 4], dtype=int32)>

  r"  )r   r&  )rO   r9   r9   r:   r   L  s    r   zkeras.backend.batch_flattenc          
   C   s*   t | t dtt| dd g} | S )a  Turn a nD tensor into a 2D tensor with same 0th dimension.

  In other words, it flattens each data samples of a batch.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.

  Examples:
    Flattening a 3D tensor to 2D by collapsing the last dimension.

  >>> x_batch = tf.keras.backend.ones(shape=(2, 3, 4, 5))
  >>> x_batch_flatten = batch_flatten(x_batch)
  >>> tf.keras.backend.int_shape(x_batch_flatten)
  (2, 60)

  r"  rR   N)r   r&  r2  r  ru   )rO   r9   r9   r:   batch_flatteng  s    &r  zkeras.backend.expand_dimsc             C   s   t | |S )zAdds a 1-sized dimension at index "axis".

  Args:
      x: A tensor or variable.
      axis: Position where to add a new axis.

  Returns:
      A tensor with expanded dimensions.
  )r   r   )rO   r=  r9   r9   r:   r     s    r   zkeras.backend.squeezec             C   s   t | |gS )zRemoves a 1-dimension from the tensor at index "axis".

  Args:
      x: A tensor or variable.
      axis: Axis to drop.

  Returns:
      A tensor with the same data as `x` but reduced dimensions.
  )r   r4  )rO   r=  r9   r9   r:   r4    s    r4  zkeras.backend.temporal_paddingrR   rR   c             C   s:   t |dkstddg|d |d gddgg}t| |S )zPads the middle dimension of a 3D tensor.

  Args:
      x: Tensor or variable.
      padding: Tuple of 2 integers, how many zeros to
          add at the start and end of dim 1.

  Returns:
      A padded 3D tensor.
  r   r   rR   )r   r   r   pad)rO   paddingr6  r9   r9   r:   temporal_padding  s    r  z keras.backend.spatial_2d_padding)rR   rR   )rR   rR   c             C   s   t |dkstt |d dks$tt |d dks8t|dkrFt }|dkr^tdt| |dkrddgddgt|d t|d g}n$ddgt|d t|d ddgg}t| |S )aX  Pads the 2nd and 3rd dimensions of a 4D tensor.

  Args:
      x: Tensor or variable.
      padding: Tuple of 2 tuples, padding pattern.
      data_format: One of `channels_last` or `channels_first`.

  Returns:
      A padded 4D tensor.

  Raises:
      ValueError: if `data_format` is neither
          `channels_last` or `channels_first`.
  r   r   rR   N>   r{  r|  zUnknown data_format: r{  )r   r   image_data_formatr}   r   r%  r   r  )rO   r  rp  r6  r9   r9   r:   spatial_2d_padding  s    &$r  z keras.backend.spatial_3d_padding)rR   rR   )rR   rR   )rR   rR   c             C   s,  t |dkstt |d dks$tt |d dks8tt |d dksLt|dkrZt }|dkrrtdt| |dkrddgddg|d d |d d g|d d |d d g|d d |d d gg}nRddg|d d |d d g|d d |d d g|d d |d d gddgg}t| |S )	a  Pads 5D tensor with zeros along the depth, height, width dimensions.

  Pads these dimensions with respectively
  "padding[0]", "padding[1]" and "padding[2]" zeros left and right.

  For 'channels_last' data_format,
  the 2nd, 3rd and 4th dimension will be padded.
  For 'channels_first' data_format,
  the 3rd, 4th and 5th dimension will be padded.

  Args:
      x: Tensor or variable.
      padding: Tuple of 3 tuples, padding pattern.
      data_format: One of `channels_last` or `channels_first`.

  Returns:
      A padded 5D tensor.

  Raises:
      ValueError: if `data_format` is neither
          `channels_last` or `channels_first`.

  r1  r   r   rR   N>   r{  r|  zUnknown data_format: r{  )r   r   r  r}   r   r   r  )rO   r  rp  r6  r9   r9   r:   spatial_3d_padding  s    "2 r  zkeras.backend.stackc             C   s   t j| |dS )a  Stacks a list of rank `R` tensors into a rank `R+1` tensor.

  Args:
      x: List of tensors.
      axis: Axis along which to perform stacking.

  Returns:
      A tensor.

  Example:

      >>> a = tf.constant([[1, 2],[3, 4]])
      >>> b = tf.constant([[10, 20],[30, 40]])
      >>> tf.keras.backend.stack((a, b))
      <tf.Tensor: shape=(2, 2, 2), dtype=int32, numpy=
      array([[[ 1,  2],
              [ 3,  4]],
             [[10, 20],
              [30, 40]]], dtype=int32)>

  )r=  )r   r2  )rO   r=  r9   r9   r:   r2    s    r2  zkeras.backend.one_hotc             C   s   t j| |ddS )a  Computes the one-hot representation of an integer tensor.

  Args:
      indices: nD integer tensor of shape
          `(batch_size, dim1, dim2, ... dim(n-1))`
      num_classes: Integer, number of classes to consider.

  Returns:
      (n + 1)D one hot representation of the input
      with shape `(batch_size, dim1, dim2, ... dim(n-1), num_classes)`

  Returns:
      The one-hot tensor.
  r"  )depthr=  )r   one_hot)r   Znum_classesr9   r9   r:   r     s    r  zkeras.backend.reversec             C   s   t |tr|g}t| |S )zReverse a tensor along the specified axes.

  Args:
      x: Tensor to reverse.
      axes: Integer or iterable of integers.
          Axes to reverse.

  Returns:
      A tensor.
  )rF   rW   r   reverse)rO   r5  r9   r9   r:   r  5  s    
r  a  
  >>> K = tf.keras.backend  # Common keras convention
  >>> v = K.variable(1.)

  >>> # reassign
  >>> K.set_value(v, 2.)
  >>> print(K.get_value(v))
  2.0

  >>> # increment
  >>> K.set_value(v, K.get_value(v) + 1)
  >>> print(K.get_value(v))
  3.0

  Variable semantics in TensorFlow 2 are eager execution friendly. The above
  code is roughly equivalent to:

  >>> v = tf.Variable(1.)

  >>> v.assign(2.)
  >>> print(v.numpy())
  2.0

  >>> v.assign_add(1.)
  >>> print(v.numpy())
  3.0r1  zkeras.backend.get_valuec          	   C   s   t | s| S t s"t| tjr*|  S t| ddsNt	 
 |  S Q R X t
 rnt 
 |  S Q R X | j  | jt| fdS Q R X dS )aE  Returns the value of a variable.

  `backend.get_value` is the complement of `backend.set_value`, and provides
  a generic interface for reading from variables while abstracting away the
  differences between TensorFlow 1.x and 2.x semantics.

  {snippet}

  Args:
      x: input variable.

  Returns:
      A Numpy array.
  Z_in_graph_modeTN)r   )r   
is_tf_typer   rg   rF   r   EagerTensornumpyrm   Z
eager_moder   ro   rY   r`   r  r   )rO   r9   r9   r:   r  e  s    


r  zkeras.backend.batch_get_valuec             C   s@   t  rdd | D S t r&td| r8t| | S g S dS )zReturns the value of more than one tensor variable.

  Args:
      tensors: list of ops to run.

  Returns:
      A list of Numpy arrays.

  Raises:
      RuntimeError: If this method is called inside defun.
  c             S   s   g | ]}|  qS r9   )r  )r   rO   r9   r9   r:   r     s    z#batch_get_value.<locals>.<listcomp>z2Cannot get value inside Tensorflow graph function.N)r   rg   r   r   r   r   r   )rx  r9   r9   r:   batch_get_value  s    r  zkeras.backend.set_valuec          	   C   s   t j|t| d}t r&| | nt   t	| j
jdd }t| drb| j}| j}n6tdg|j }tj||d}| |}|| _|| _t j|||id W dQ R X dS )a  Sets the value of a variable, from a Numpy array.

  `backend.set_value` is the complement of `backend.get_value`, and provides
  a generic interface for assigning to variables while abstracting away the
  differences between TensorFlow 1.x and 2.x semantics.

  {snippet}

  Args:
      x: Variable to set to a new value.
      value: Value to set the tensor to, as a Numpy array
          (of the same shape).
  )rE   r   r   _assign_placeholderN)ru   )	feed_dict)rM   rN   r  r   r   r  rS   r`   r   r   rE   rv   r  r   r  
_assign_opr   TensorShaper   r   r   r   r   )rO   rj   r	  assign_placeholder	assign_opplaceholder_shaper9   r9   r:   	set_value  s    


r  zkeras.backend.batch_set_valuec       	   	   C   s  t  st r<x| D ] \}}|tj|t|d qW nt 	  | rg }i }x| D ]\}}tj|t|d}t
|jjdd }t|dr|j}|j}n6tdg|j }tj||d}||}||_||_|| |||< q\W t j||d W dQ R X dS )zSets the values of many tensor variables at once.

  Args:
      tuples: a list of tuples `(tensor, value)`.
          `value` should be a Numpy array.
  )rE   r   r   r  N)ru   )r  )r   rg   r   r   r  rM   rN   r  rS   r`   r   r   rE   rv   r  r   r  r  r   r  r   r   r   r   r   r   )	ZtuplesrO   rj   Z
assign_opsr  r	  r  r  r  r9   r9   r:   batch_set_value  s,    




r  )Zsnippetzkeras.backend.print_tensorc          
   C   s|   t | tjr`t| dr`t  8 tj|| tj	|d}t
|g t| S Q R X W dQ R X ntj|| tj	|d | S dS )a&  Prints `message` and the tensor value when evaluated.

  Note that `print_tensor` returns a new tensor identical to `x`
  which should be used in the following code. Otherwise the
  print operation is not taken into account during evaluation.

  Example:

  >>> x = tf.constant([[1.0, 2.0], [3.0, 4.0]])
  >>> _ = tf.keras.backend.print_tensor(x)
  [[1 2]
   [3 4]]

  Args:
      x: Tensor to print.
      message: Message to print jointly with the tensor.
      summarize: The first and last `summarize` elements within each dimension
          are recursively printed per Tensor. If None, then the first 3 and last
          3 elements of each dimension are printed for each tensor. If set to
          -1, it will print all elements of every tensor.

  Returns:
      The same tensor `x`, unchanged.
  rY   )Zoutput_stream	summarizeN)rF   r   rG   r   rS   r`   r#   Zprint_v2sysstdoutcontrol_dependenciesr   r  )rO   messager  r   r9   r9   r:   print_tensor  s    r  c               @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )GraphExecutionFunctiona  Runs a computation graph.

  It's possible to pass arguments to `tf.Session.run()` via `session_kwargs`.
  In particular additional operations via `fetches` argument and additional
  tensor substitutions via `feed_dict` arguments. Note that given
  substitutions are merged with substitutions from `inputs`. Even though
  `feed_dict` is passed once in the constructor (called in `model.compile()`)
  we can modify the values in the dictionary. Through this feed_dict we can
  provide additional substitutions besides Keras inputs.

  Args:
      inputs: Feed placeholders to the computation graph.
      outputs: Output tensors to fetch.
      updates: Additional update ops to be run at function call.
      name: A name to help users identify what this function does.
      session_kwargs: Arguments to `tf.Session.run()`:
                      `fetches`, `feed_dict`, `options`, `run_metadata`.
  Nc       
   	   K   sl  |pg }t |ttfstd|| _tj|dd| _|| _t	tj|dd| _
t| j
d gT g }x<|D ]4}t |tr|\}}	|t||	 ql|| qlW tj| | _W d Q R X || _|dd | _|dg | _t | jts| jg| _|dd | _|dd | _d	d
 | jD | _|| _i | _|rDtd| f d | _d | _d | _d | _ d | _!d | _"d S )Nz@`updates` in a Keras backend function should be a list or tuple.T)r   r   r  fetchesoptionsrun_metadatac             S   s   g | ]}t |qS r9   )r   r  )r   rO   r9   r9   r:   r   X  s    z3GraphExecutionFunction.__init__.<locals>.<listcomp>z>Some keys in session_kwargs are not supported at this time: %s)#rF   r%  r   r   Z_inputs_structurer1   r   inputs_outputs_structurecast_variables_to_tensoroutputsr   r  r   r)   r  r   group
updates_oprv   re   r  r  run_optionsr  session_kwargsfetch_callbacksr}   keys_callable_fn_feed_arrays_feed_symbols_symbol_vals_fetches_session)
r@   r  r  updatesrv   r  Zupdates_opsr   pZnew_pr9   r9   r:   r=   3  sF    


zGraphExecutionFunction.__init__c             C   s2  t  }x|D ]}|j|j qW | jrPx$t| j D ]}|j|j q:W x`t||D ]R\}}|j	
 }	|j|jkrtj||jd}t|}
|
dkr|}
|
j|	_|j|	_q\W x"| j| j D ]}|j|j qW |j| jj | jr|j| j ||}|| _|| _|| _|| _t| j| _|| _dS )a  Generates a callable that runs the graph.

    Args:
      feed_arrays: List of input tensors to be fed Numpy arrays at runtime.
      feed_symbols: List of input tensors to be fed symbolic tensors at runtime.
      symbol_vals: List of symbolic tensors to be fed to `feed_symbols`.
      session: Session to use to generate the callable.

    Returns:
      Function that runs the graph according to the above options.
    )rE   N) r   ZCallableOptionsfeedr   rv   r  ru  r  r   Ztensor_connectionr   rE   r%   rK   r   from_tensor	to_tensorr  r  fetchtargetr  r  ZCopyFromZ_make_callable_from_optionsr  r  r  r  r%  r  r  )r@   feed_arraysfeed_symbolssymbol_valsr   Zcallable_optsrO   r>   r)  
connectionr  Zcallable_fnr9   r9   r:   _make_callablek  s6    


z%GraphExecutionFunction._make_callablec             C   s6   x0t | j|D ] \}}|| jkr| j| | qW d S )N)r   r  r  )r@   Zfetches_outputr  r  r9   r9   r:   _call_fetch_callbacks  s    
z,GraphExecutionFunction._call_fetch_callbacksc             C   s*   ddl m} ||r"| j|S |S dS )z@Helper method which evaluates any CompositeTensors passed to it.r   )r   N)r   r   r   r  r   )r@   r   r   r9   r9   r:   _eval_if_composite  s    
z)GraphExecutionFunction._eval_if_compositec             C   s  t j|dd}t|}g }g }g }g }xnt| j|D ]^\}}|d krFq4t|rf|| || q4|| t	|j
}	|tj||	jd q4W | jrx4t| j D ]"}
|tj| j|
 |
j
jd qW | jd ks|| jks|| jks|| jks| j| jks|| jkr,| |||| | j|d| ji}| |t| j d   t j| j|d t| j dd}t | j |S )NT)r   )rE   r  )!r1   r   r   r   r  r   r  r   r   r   rE   rM   rN   r  r  ru  r  r  r  r  r  r  r  r  r  r  r  r   pack_sequence_asr  r  r   r  )r@   r  r   r  Z
array_valsr  r  r   rj   Ztensor_typer>   ZfetchedZoutput_structurer9   r9   r:   __call__  sB    




zGraphExecutionFunction.__call__)NN)	r5   r6   r7   r8   r=   r  r  r  r  r9   r9   r9   r:   r    s   
81r  zkeras.backend.functionc       	         s   t  r||rtd|f |r,td|f ddlm} ddlm |j| |d t|t	oft
|dk fdd	}|S |rx:|D ]2}|ttjjd kr|d
krd| }t|qW t| |f||d|S )ay  Instantiates a Keras function.

  Args:
      inputs: List of placeholder tensors.
      outputs: List of output tensors.
      updates: List of update ops.
      name: String, name of function.
      **kwargs: Passed to `tf.Session.run`.

  Returns:
      Output values as Numpy arrays.

  Raises:
      ValueError: if invalid kwargs are passed in or if in eager execution.
  zRSession keyword arguments are not supported during eager execution. You passed: %szJ`updates` argument is not supported during eager execution. You passed: %sr   )models)r   )r  r  rR   c                s    | }r|g} |S )N)Zsync_to_numpy_or_python_type)Zmodel_inputsZouts)modelr   wrap_outputsr9   r:   func  s    zfunction.<locals>.func)r  r  r  rv   zBInvalid argument "%s" passed to K.function with TensorFlow backend)r  rv   )r   r   r}   tensorflow.python.kerasr  r   r   ZModelrF   r%  r   r   getfullargspecr   r   r   r  )	r  r  r  rv   kwargsr  r  r>   msgr9   )r  r   r  r:   function  s,    


r  zkeras.backend.gradientsc             C   s   t j| |ddS )zReturns the gradients of `loss` w.r.t. `variables`.

  Args:
      loss: Scalar tensor to minimize.
      variables: List of variables.

  Returns:
      A gradients tensor.
  T)Zcolocate_gradients_with_ops)gradients_moduler   )Zlossr,   r9   r9   r:   r     s    r   zkeras.backend.stop_gradientc             C   s$   t | ttfrttj| S t| S )aY  Returns `variables` but with zero gradient w.r.t. every other variable.

  Args:
      variables: Tensor or list of tensors to consider constant with respect
        to any other variable.


  Returns:
      A single tensor or a list of tensors (depending on the passed argument)
      that has no gradient with respect to any other variable.
  )rF   r%  r   mapr   stop_gradient)r,   r9   r9   r:   r  %  s    r  zkeras.backend.rnnc
       )         s  dd }
|st |
		t 	}|d jd |d jd t|d d x|D ]}|jd qVW |dk	r|jtjkrt	
|tj}t|jdkrt|}|s|
|}dkrg d4dd	 |r܈std
t}g }g }fdd}t 	rt |	n
|	f	fdd}|dk	rtt|}rF|  xtD ]}||}|| 
|t|t \}} 
|}|st|}n|d }t|||}t |}t |}t 
fdd|D }tdd t|||D }t ||}|| || qPW |d }|d }t|}rt |d ||t|}t ||dd|t|}ndxHtD ]<}||}|t|t \}}|| || q~W |d }|d }t|}ntt}tfddt|D tfddt|D t 	dd |D }|tt \}} tfddtt |D }!tjdddd}"t stt ! rt	"}#nd}#fdd|#ddd }$|dk	r
rt|d}t#j$tjd!d"|fd#d$ fd%d&nZt%t j&r`rJt	j"dd'}%t	'|%d fd(d$nfd)d$d*d& nddk	rtd+d t |D 	fd,d-}&t(j)f |&|"|!f| d.|$}'|'dd }n>	fd/d-}&t(j)f |&|"|!f| d.|$}'|'dd }|'d }!td0d |!D }td1d |D }t ||}t ||}fd2d3}(t |(|}|s|t |
|}|||fS )5aA  Iterates over the time dimension of a tensor.

  Args:
      step_function: RNN step function.
          Args;
              input; Tensor with shape `(samples, ...)` (no time dimension),
                  representing input for the batch of samples at a certain
                  time step.
              states; List of tensors.
          Returns;
              output; Tensor with shape `(samples, output_dim)`
                  (no time dimension).
              new_states; List of tensors, same length and shapes
                  as 'states'. The first state in the list must be the
                  output tensor at the previous timestep.
      inputs: Tensor of temporal data of shape `(samples, time, ...)`
          (at least 3D), or nested tensors, and each of which has shape
          `(samples, time, ...)`.
      initial_states: Tensor with shape `(samples, state_size)`
          (no time dimension), containing the initial values for the states used
          in the step function. In the case that state_size is in a nested
          shape, the shape of initial_states will also follow the nested
          structure.
      go_backwards: Boolean. If True, do the iteration over the time
          dimension in reverse order and return the reversed sequence.
      mask: Binary tensor with shape `(samples, time, 1)`,
          with a zero for every element that is masked.
      constants: List of constant values passed at each step.
      unroll: Whether to unroll the RNN or to use a symbolic `while_loop`.
      input_length: An integer or a 1-D Tensor, depending on whether
          the time dimension is fixed-length or not. In case of variable length
          input, it is used for masking in case there's no mask specified.
      time_major: Boolean. If true, the inputs and outputs will be in shape
          `(timesteps, batch, ...)`, whereas in the False case, it will be
          `(batch, timesteps, ...)`. Using `time_major = True` is a bit more
          efficient because it avoids transposes at the beginning and end of the
          RNN calculation. However, most TensorFlow data is batch-major, so by
          default this function accepts input and emits output in batch-major
          form.
      zero_output_for_mask: Boolean. If True, the output for masked timestep
          will be zeros, whereas in the False case, output from previous
          timestep is returned.

  Returns:
      A tuple, `(last_output, outputs, new_states)`.
          last_output: the latest output of the rnn, of shape `(samples, ...)`
          outputs: tensor with shape `(samples, time, ...)` where each
              entry `outputs[s, t]` is the output of the step function
              at time `t` for sample `s`.
          new_states: list of tensors, latest states returned by
              the step function, of shape `(samples, ...)`.

  Raises:
      ValueError: if input dimension is less than 3.
      ValueError: if `unroll` is `True` but input timestep is not a fixed
      number.
      ValueError: if `mask` is provided (not `None`) but states is not provided
          (`len(states)` == 0).
  c             S   s.   t tt| j}d\|d< |d< t| |S )N)rR   r   r   rR   )r%  r   r   ru   r   r'  )input_tr5  r9   r9   r:   swap_batch_timestep  s    z rnn.<locals>.swap_batch_timestepr   rR   r1  Nr   c             S   s   t | rtd|  t |r,td| t|jt| j }xt|D ]}t| d} qJW dg| |j |d   }t	| |S )Nz+mask_t is expected to be tensor, but got %sz,input_t is expected to be tensor, but got %sr"  rR   )
r1   	is_nestedr}   r   ru   r   r   r   r   r  )mask_tr  	fixed_dimZ	rank_diffr   Z	multiplesr9   r9   r:   _expand_mask  s    

zrnn.<locals>._expand_maskz/Unrolling requires a fixed number of timesteps.c                s   t | }  r|   | S )N)r   r$  r  )r  )go_backwardsr9   r:   _process_single_input_t  s    
z$rnn.<locals>._process_single_input_tc                s    fddD }t |S )Nc                s   g | ]}|  qS r9   r9   )r   Zt_)timer9   r:   r     s    z2rnn.<locals>._get_input_tensor.<locals>.<listcomp>)r1   r  )r  inp)r  processed_input)r  r:   _get_input_tensor  s    zrnn.<locals>._get_input_tensorr"  c             3   s   | ]} |V  qd S )Nr9   )r   r+  )r  r  r9   r:   r     s    zrnn.<locals>.<genexpr>c             s   s"   | ]\}}}t |||V  qd S )N)r   where_v2)r   mr+  Zpsr9   r9   r:   r     s   )r  c             3   s(   | ] \}}t j|j d | dV  qdS )zinput_ta_%s)rE   r  tensor_array_nameN)r+   TensorArrayrE   )r   r   r  )time_steps_tr9   r:   r     s   c             3   s0   | ](\}} s| |n| t|d V  qdS )r   N)r$  r  )r   tainput_)r  r9   r:   r     s   c             S   s   g | ]}|d  qS )r   r9   )r   r  r9   r9   r:   r     s    zrnn.<locals>.<listcomp>c             3   s,   | ]$\}}t j|j |jd | dV  qdS )zoutput_ta_%s)rE   r  Zelement_shaper  N)r+   r  rE   ru   )r   r   r-  )r  r9   r:   r     s   r}  r  )rE   rv   c                s   |  k S )Nr9   )r  r   )r  r9   r:   <lambda>,      zrnn.<locals>.<lambda>    T)condZmaximum_iterationsparallel_iterationsZswap_memorymask_ta)rE   r  r  c                s
     | S )N)read)r  )r  r9   r:   
masking_fn;  s    zrnn.<locals>.masking_fnc                s2   t  fdd|D }t dd t|||D S )Nc             3   s"   | ]} |t jd V  qdS ))r  N)r   ru   )r   o)r  r  r9   r:   r   @  s   z5rnn.<locals>.compute_masked_output.<locals>.<genexpr>c             s   s"   | ]\}}}t |||V  qd S )N)r   r  )r   r  r  fmr9   r9   r:   r   C  s   )r   r   )r  flat_out	flat_masktiled_mask_t)r  )r  r:   compute_masked_output>  s    
z"rnn.<locals>.compute_masked_output)r=  c                s   t  | S )N)r%   r_  )r  )rev_input_lengthr9   r:   r   J  s    c                s   t  | S )N)r%   r]  )r  )input_lengthr9   r:   r   N  s    c                s   t  fddt||D S )Nc             3   s    | ]\}}t  ||V  qd S )N)r   where)r   r  Zzo)r  r9   r:   r   S  s   z5rnn.<locals>.compute_masked_output.<locals>.<genexpr>)r   r   )r  r  r  r9   )r  r:   r  Q  s    
c             s   s   | ]}t |V  qd S )N)r   r  )r   r  r9   r9   r:   r   [  s   c                s   t  fddD }t|} }|t |t  \}}t|}rVnt|}	|||	}
t|}t|}x.t||D ] \}}t|tjr||j	 qW |||}t||}t  fddt||
D } d |t |
ft | S )a3  RNN step function.

        Args:
            time: Current timestep value.
            output_ta_t: TensorArray.
            prev_output: tuple of outputs from time - 1.
            *states: List of states.

        Returns:
            Tuple: `(time + 1, output_ta_t, output) + tuple(new_states)`
        c             3   s   | ]}|  V  qd S )N)r  )r   r  )r  r9   r:   r   i  s    z%rnn.<locals>._step.<locals>.<genexpr>c             3   s   | ]\}}|  |V  qd S )N)write)r   r  r-  )r  r9   r:   r     s   rR   )
r   r1   r  r   r   rF   r   rG   r  ru   )r  output_ta_tprev_outputstatescurrent_inputr  r  
new_statesflat_outputZflat_mask_outputZflat_new_output
flat_stateflat_new_statestate	new_stateZflat_final_state)r  	constantsflat_zero_outputinput_tar  r   step_functionzero_output_for_mask)r  r:   _step]  s.    




zrnn.<locals>._step)bodyZ	loop_varsc                s   t  fddD }t|}|t |t  \}}t|}t|}x.t||D ] \}}	t|	tjr\|	|j	 q\W t|}
t  fddt||
D }t|} d |ft | S )zRNN step function.

        Args:
            time: Current timestep value.
            output_ta_t: TensorArray.
            *states: List of states.

        Returns:
            Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
        c             3   s   | ]}|  V  qd S )N)r  )r   r  )r  r9   r:   r     s    z%rnn.<locals>._step.<locals>.<genexpr>c             3   s   | ]\}}|  |V  qd S )N)r
  )r   r  r-  )r  r9   r:   r     s    rR   )
r   r1   r  r   r   rF   r   rG   r  ru   )r  r  r  r  r  r  r  r  r  r  r  )r  initial_statesr  r  r  )r  r:   r    s    


c             s   s   | ]}|  V  qd S )N)r2  )r   r  r9   r9   r:   r     s    c             s   s   | ]}|d  V  qdS )r"  Nr9   )r   r  r9   r9   r:   r     s    c                s4   t | tjr0| j }|d<  |d< | | | S )Nr   rR   )rF   r   rG   ru   r   r  )Zoutput_ru   )batch
time_stepsr9   r:   r    s    

zrnn.<locals>.set_shape)rR   )*r1   r   r   ru   r   Zwith_rank_at_leastrE   r   r   r%   rK   r   r   r}   r   r  r$  r  r   r  r  r   r  r   r2  r   r
   r   r   rg   r   ZGraphOrParentsInXlaContextr   rl   r<  r+   r  rF   rG   subtractr   Z
while_loop))r  r  r  r  maskr  Zunrollr  Z
time_majorr  r  Zflatted_inputsr  r  Zsuccessive_statesZsuccessive_outputsr  r  Z	mask_listr   r  r  r  r  r  Zflat_statesZflat_new_statesZflat_final_statesZlast_outputr  Zinput_time_zeroZoutput_time_zeror   Z	output_tar  Zmax_iterationsZwhile_loop_kwargsmax_lenr  Zfinal_outputsr  r9   )r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r:   rnn<  s   H























)r"  zkeras.backend.switchc                s4  | j tjkrt| d} t| }|shts:fdd}n}t sT fdd}n }t| ||}ntrv t r   t}||krt	dt
| d t
| |dkr"|| }tjt| dg| gd	d
}	t| |	} t}
|
|	 }t|d	k|
t|
}t| |} t|  }|S )a  Switches between two operations depending on a scalar value.

  Note that both `then_expression` and `else_expression`
  should be symbolic tensors of the *same shape*.

  Args:
      condition: tensor (`int` or `bool`).
      then_expression: either a tensor, or a callable that returns a tensor.
      else_expression: either a tensor, or a callable that returns a tensor.

  Returns:
      The selected tensor.

  Raises:
      ValueError: If rank of `condition` is greater than rank of expressions.
  r   c                  s    S )Nr9   r9   )then_expressionr9   r:   then_expression_fn  s    z"switch.<locals>.then_expression_fnc                  s    S )Nr9   r9   )else_expressionr9   r:   else_expression_fn  s    z"switch.<locals>.else_expression_fnzuRank of `condition` should be less than or equal to rank of `then_expression` and `else_expression`. ndim(condition)=z, ndim(then_expression)=rR   r   )r=  )rE   r   r   r%   rK   r   r   r   r  r}   r   r   r3  ru   r&  r  r  r  )	conditionr#  r%  Z	cond_ndimr$  r&  rO   Z	expr_ndimZ	ndim_diffZ
cond_shapeZ
expr_shapeZ
shape_diffZ
tile_shaper9   )r%  r#  r:   switch  s>    

r(  zkeras.backend.in_train_phasec             C   s   ddl m} |dkr| j}|dkr,t }t|s||dksF|dkrZt| rT|  S | S n"|dksj|dkr|t|rx| S |S t|| |} | S )a,  Selects `x` in train phase, and `alt` otherwise.

  Note that `alt` should have the *same shape* as `x`.

  Args:
      x: What to return in train phase
          (tensor or callable that returns a tensor).
      alt: What to return otherwise
          (tensor or callable that returns a tensor).
      training: Optional scalar tensor
          (or Python boolean, or Python integer)
          specifying the learning phase.

  Returns:
      Either `x` or `alt` based on the `training` flag.
      the `training` flag defaults to `K.learning_phase()`.
  r   )base_layer_utilsNrR   TF)	r   r)  Zcall_contexttrainingrq   r   r  r   r(  )rO   altr*  r)  r9   r9   r:   in_train_phase	  s     

r,  zkeras.backend.in_test_phasec             C   s   t || |dS )a  Selects `x` in test phase, and `alt` otherwise.

  Note that `alt` should have the *same shape* as `x`.

  Args:
      x: What to return in test phase
          (tensor or callable that returns a tensor).
      alt: What to return otherwise
          (tensor or callable that returns a tensor).
      training: Optional scalar tensor
          (or Python boolean, or Python integer)
          specifying the learning phase.

  Returns:
      Either `x` or `alt` based on `K.learning_phase`.
  )r*  )r,  )rO   r+  r*  r9   r9   r:   in_test_phase7  s    r-  zkeras.backend.relu        c             C   s   t | dt }|dkrZ|dkr4|dkr4tj| |dS |dkrNt|  | }nt|  }|dk	}|dkr| tjt| ||d } n"|dkrt| } d}n
t| } |rt	|| j
j}t	d| j
j}t| ||} |dkrt|| j
j}| || 8 } | S )	a  Rectified linear unit.

  With default values, it returns element-wise `max(x, 0)`.

  Otherwise, it follows:
  `f(x) = max_value` for `x >= max_value`,
  `f(x) = x` for `threshold <= x < max_value`,
  `f(x) = alpha * (x - threshold)` otherwise.

  Args:
      x: A tensor or variable.
      alpha: A scalar, slope of negative section (default=`0.`).
      max_value: float. Saturation threshold.
      threshold: float. Threshold value for thresholded activation.

  Returns:
      A tensor.
  rE   g        Nr   )alpha)rE      F)rm   rL   r&   Z
leaky_relurelur%   rK   r]  Zrelu6r   rE   r  r   rX  r   )rO   r/  rY  	thresholdrE   Znegative_partZclip_maxrO  r9   r9   r:   r1  P  s,    

r1  zkeras.backend.elu      ?c             C   s0   t | }|dkr|S t| dk||| S dS )zExponential linear unit.

  Args:
      x: A tensor or variable to compute the activation function for.
      alpha: A scalar, slope of negative section.

  Returns:
      A tensor.
  rR   r   N)r&   elur   r  )rO   r/  resr9   r9   r:   r4    s    
r4  zkeras.backend.softmaxc             C   s   t j| |dS )zSoftmax of a tensor.

  Args:
      x: A tensor or variable.
      axis: The dimension softmax would be performed on.
          The default is -1 which indicates the last dimension.

  Returns:
      A tensor.
  )r=  )r&   softmax)rO   r=  r9   r9   r:   r6    s    r6  zkeras.backend.softplusc             C   s
   t | S )z\Softplus of a tensor.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.
  )r%   softplus)rO   r9   r9   r:   r7    s    r7  zkeras.backend.softsignc             C   s
   t | S )z\Softsign of a tensor.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.
  )r&   softsign)rO   r9   r9   r:   r8    s    r8  z&keras.backend.categorical_crossentropyc             C   s   t | } t |}| j|j t|drD|j}|r@td d}|rXtj	| ||dS t
|t jtjfs|jjdkrt|dst|jjdkst|jjd }tj	| ||dS |t||d }tt |jj}t||d	| }t| t| | S )
a*  Categorical crossentropy between an output tensor and a target tensor.

  Args:
      target: A tensor of the same shape as `output`.
      output: A tensor resulting from a softmax
          (unless `from_logits` is True, in which
          case `output` is expected to be the logits).
      from_logits: Boolean, whether `output` is the
          result of a softmax, or is a tensor of logits.
      axis: Int specifying the channels axis. `axis=-1` corresponds to data
          format `channels_last`, and `axis=1` corresponds to data format
          `channels_first`.

  Returns:
      Output tensor.

  Raises:
      ValueError: if `axis` is neither -1 nor one of the axes of `output`.

  Example:

  >>> a = tf.constant([1., 0., 0., 0., 1., 0., 0., 0., 1.], shape=[3,3])
  >>> print(a)
  tf.Tensor(
    [[1. 0. 0.]
     [0. 1. 0.]
     [0. 0. 1.]], shape=(3, 3), dtype=float32)
  >>> b = tf.constant([.9, .05, .05, .05, .89, .06, .05, .01, .94], shape=[3,3])
  >>> print(b)
  tf.Tensor(
    [[0.9  0.05 0.05]
     [0.05 0.89 0.06]
     [0.05 0.01 0.94]], shape=(3, 3), dtype=float32)
  >>> loss = tf.keras.backend.categorical_crossentropy(a, b)
  >>> print(np.around(loss, 5))
  [0.10536 0.11653 0.06188]
  >>> loss = tf.keras.backend.categorical_crossentropy(a, a)
  >>> print(np.around(loss, 5))
  [0. 0. 0.]

  _keras_logitsz"`categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a sigmoid or softmax activation and thus does not represent logits. Was this intended?"T)labelslogitsr=  Softmaxr   rR   r   g      ?)r   r   ru   Zassert_is_compatible_withr   r9  ry   rz   r&   Z$softmax_cross_entropy_with_logits_v2rF   r  rH   rI   r   r   r   r  r   r%   rA  r   rj  rE   r  r   rX  rQ  )r  r  from_logitsr=  epsilon_r9   r9   r:   categorical_crossentropy  s,    -


r?  z-keras.backend.sparse_categorical_crossentropyc          	   C   s  t | } t |}t|dr8|j}|r2td d}n|st|t jtj	fs|j
jdkrt|dst|j
jdksxt|j
jd }d}n0|stt |jj}t||d| }t|}t|jttfrt|j}n|jj}|dk	r0||; }||d krHttt|t|d ||g}tj||d	}n|d
krHt d!|t"| d} t#|}| jj}|dk	o|dk	o||d k}	|	rt$| } t%|d
|d
 g}t&dd | |gD rt' (  t)j*| |d}
W dQ R X nt)j*| |d}
|	r|dkrt%|
|dd
 S |
S dS )a  Categorical crossentropy with integer targets.

  Args:
      target: An integer tensor.
      output: A tensor resulting from a softmax
          (unless `from_logits` is True, in which
          case `output` is expected to be the logits).
      from_logits: Boolean, whether `output` is the
          result of a softmax, or is a tensor of logits.
      axis: Int specifying the channels axis. `axis=-1` corresponds to data
          format `channels_last`, and `axis=1` corresponds to data format
          `channels_first`.

  Returns:
      Output tensor.

  Raises:
      ValueError: if `axis` is neither -1 nor one of the axes of `output`.
  r9  z"`sparse_categorical_crossentropy` received `from_logits=True`, but the `output` argument was produced by a sigmoid or softmax activation and thus does not represent logits. Was this intended?"Tr<  r   rR   r   N)r#  r"  zcCannot compute sparse categorical crossentropy with `axis={}` on an output tensor with unknown rankint64c             s   s   | ]}t |V  qd S )N)_is_symbolic_tensor)r   r   r9   r9   r:   r   o  s    z2sparse_categorical_crossentropy.<locals>.<genexpr>)r:  r;  r1  )+r   r   r   r9  ry   rz   rF   r  rH   rI   r   r   r   r  r   r   rj  rE   r  r   rX  r%   rQ  ru   r   r%  ndims	itertoolschainr   r   r'  r}   formatrK   r  r   r&  r   rS   r`   r&   Z+sparse_softmax_cross_entropy_with_logits_v2)r  r  r=  r=  r>  Zoutput_rankpermutationr8  Ztarget_rankZupdate_shaper5  r9   r9   r:   sparse_categorical_crossentropy   s`    




 



rG  z!keras.backend.binary_crossentropyc             C   s   t | } t |}t|dr6|j}|r2td d}|rHtj| |dS t|t j	t
jfs|jjdkrt|dst|jjdkst|jjd }tj| |dS tt |jj}t||d	| }| t|t   }|d|  td| t   7 }| S )
a^  Binary crossentropy between an output tensor and a target tensor.

  Args:
      target: A tensor with the same shape as `output`.
      output: A tensor.
      from_logits: Whether `output` is expected to be a logits tensor.
          By default, we consider that `output`
          encodes a probability distribution.

  Returns:
      A tensor.
  r9  z"`binary_crossentropy` received `from_logits=True`, but the `output` argument was produced by a sigmoid or softmax activation and thus does not represent logits. Was this intended?"T)r:  r;  ZSigmoidr   rR   r   g      ?)r   r   r   r9  ry   rz   r&   Z!sigmoid_cross_entropy_with_logitsrF   r  rH   rI   r   r   r   r  r   r   rj  rE   r  r   rX  r%   rQ  )r  r  r=  r>  Zbcer9   r9   r:   binary_crossentropy~  s(    


 rH  zkeras.backend.sigmoidc             C   s
   t | S )z\Element-wise sigmoid.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.
  )r&   sigmoid)rO   r9   r9   r:   rI    s    rI  zkeras.backend.hard_sigmoidc             C   sF   t d| jj}t d| jj}t| |} t| |} t| dd} | S )zSegment-wise linear approximation of sigmoid.

  Faster than sigmoid.
  Returns `0.` if `x < -2.5`, `1.` if `x > 2.5`.
  In `-2.5 <= x <= 2.5`, returns `0.2 * x + 0.5`.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.
  g?g      ?g        g      ?)r   rE   r  r%   multiplyr   r   rX  )rO   Z	point_twoZ
point_fiver9   r9   r:   hard_sigmoid  s    rK  zkeras.backend.tanhc             C   s
   t | S )zYElement-wise tanh.

  Args:
      x: A tensor or variable.

  Returns:
      A tensor.
  )r&   tanh)rO   r9   r9   r:   rL    s    rL  zkeras.backend.dropoutc             C   s&   |dkrt jd}tj| |||dS )aw  Sets entries in `x` to zero at random, while scaling the entire tensor.

  Args:
      x: tensor
      level: fraction of the entries in the tensor
          that will be set to 0.
      noise_shape: shape for randomly generated keep/drop flags,
          must be broadcastable to the shape of `x`
      seed: random seed to ensure determinism.

  Returns:
      A tensor.
  Ng    cA)ratenoise_shaper  )rM   r  r  r&   Z
dropout_v2)rO   levelrN  r  r9   r9   r:   dropout  s    rP  zkeras.backend.l2_normalizec             C   s   t j| |dS )zNormalizes a tensor wrt the L2 norm alongside the specified axis.

  Args:
      x: Tensor or variable.
      axis: axis along which to perform normalization.

  Returns:
      A tensor.
  )r=  )r&   l2_normalize)rO   r=  r9   r9   r:   rQ    s    rQ  zkeras.backend.in_top_kc             C   s   t | ||S )a  Returns whether the `targets` are in the top `k` `predictions`.

  Args:
      predictions: A tensor of shape `(batch_size, classes)` and type `float32`.
      targets: A 1D tensor of length `batch_size` and type `int32` or `int64`.
      k: An `int`, number of top elements to consider.

  Returns:
      A 1D tensor of length `batch_size` and type `bool`.
      `output[i]` is `True` if `predictions[i, targets[i]]` is within top-`k`
      values of `predictions[i]`.
  )r&   in_top_k)Zpredictionstargetskr9   r9   r:   rR    s    rR  c             C   s,   d}|dkr$t  s t| d} nd}| |fS )zTranspose and cast the input before the conv1d.

  Args:
      x: input tensor.
      data_format: string, `"channels_last"` or `"channels_first"`.

  Returns:
      A tensor.
  NWCr{  )r   r   rR   ZNCW)r   r   r'  )rO   rp  rr  r9   r9   r:   _preprocess_conv1d_input#  s    
rV  c             C   s0   d}|dkr(t  r|r$t| d} nd}| |fS )a  Transpose and cast the input before the conv2d.

  Args:
      x: input tensor.
      data_format: string, `"channels_last"` or `"channels_first"`.
      force_transpose: Boolean. If True, the input will always be transposed
          from NCHW to NHWC if `data_format` is `"channels_first"`.
          If False, the transposition only occurs on CPU (GPU ops are
          assumed to support NCHW).

  Returns:
      A tensor.
  rn  r{  )r   r   r1  rR   ro  )r   r   r'  )rO   rp  force_transposerr  r9   r9   r:   _preprocess_conv2d_input6  s    
rX  c             C   s,   d}|dkr$t  s t| d} nd}| |fS )zTranspose and cast the input before the conv3d.

  Args:
      x: input tensor.
      data_format: string, `"channels_last"` or `"channels_first"`.

  Returns:
      A tensor.
  NDHWCr{  )r   r   r1  rt  rR   ZNCDHW)r   r   r'  )rO   rp  rr  r9   r9   r:   _preprocess_conv3d_inputM  s    
rZ  c             C   s0   | dkrd} n| dkrd} nt dt|  | S )zConvert keras' padding to TensorFlow's padding.

  Args:
      padding: string, one of 'same' , 'valid'

  Returns:
      a string, one of 'SAME', 'VALID'.

  Raises:
      ValueError: if invalid `padding'`
  ZsameZSAMEvalidZVALIDzInvalid padding: )r}   r   )r  r9   r9   r:   _preprocess_padding`  s    r\  zkeras.backend.conv1dr[  c       	      C   s   |dkrt  }|dkr&tdt| |j }|dkrZ||d d  }t| |df} d}t|}t| |\} }tj	| |||||d} |d	kr|d
krt
| d} | S )a  1D convolution.

  Args:
      x: Tensor or variable.
      kernel: kernel tensor.
      strides: stride integer.
      padding: string, `"same"`, `"causal"` or `"valid"`.
      data_format: string, one of "channels_last", "channels_first".
      dilation_rate: integer dilate rate.

  Returns:
      A tensor, result of 1D convolution.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: Zcausalr   rR   r[  )inputfilterdilation_ratestridesr  rp  r{  rU  )r   r   rR   )r  r}   r   ru   r   r  r\  rV  r&   convolutionr   r'  )	rO   kernelr`  r  rp  r_  kernel_shapeZleft_padrr  r9   r9   r:   conv1du  s*    
rd  zkeras.backend.conv2dc             C   sr   |dkrt  }|dkr&tdt| t| |\} }t|}tj| |||||d} |dkrn|dkrnt| d} | S )a  2D convolution.

  Args:
      x: Tensor or variable.
      kernel: kernel tensor.
      strides: strides tuple.
      padding: string, `"same"` or `"valid"`.
      data_format: `"channels_last"` or `"channels_first"`.
      dilation_rate: tuple of 2 integers.

  Returns:
      A tensor, result of 2D convolution.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: )r]  r^  r_  r`  r  rp  r{  rn  )r   r1  rR   r   )	r  r}   r   rX  r\  r&   ra  r   r'  )rO   rb  r`  r  rp  r_  rr  r9   r9   r:   conv2d  s     re  zkeras.backend.conv2d_transposec       	      C   s\  |dkrt  }|dkr&tdt| |dkr<|dkr<d}nd}t| ||\} }|dkr||dkr||d	 |d
 |d |d f}|d	 dkrt| d	 ft|dd  }t|ttfrt	t|}t
|}|dkrd| d }nd| }|dkr
tj| |||||d} n.|d	 |d ks ttj| |||d	 |d} |dkrX|dkrXt| d} | S )a  2D deconvolution (i.e.

  transposed convolution).

  Args:
      x: Tensor or variable.
      kernel: kernel tensor.
      output_shape: 1D int tensor for the output shape.
      strides: strides tuple.
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      dilation_rate: Tuple of 2 integers.

  Returns:
      A tensor, result of transposed 2D convolution.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: r{  )rR   rR   TFrn  r   r   r1  rR   )rR   )r  rp  )rM  r  )r   r1  rR   r   )r  r}   r   rX  ru   r   rF   r%  r   r2  r\  r&   conv2d_transposer   Zatrous_conv2d_transposer'  )	rO   rb  r8  r`  r  rp  r_  rW  rr  r9   r9   r:   rf    sB    


rf  c       	   	   C   s  |dkrt  }|dkr&tdt| t|tr6|f}t|trF|f}t| |\} }t|}t|tsnt|}|dkrd}d|d  d }nd}d|d  }t	| |} t	|d	}t	|d	}d| }t
j| ||||||d
} t| |g} |dkr|dkrt| d} | S )a  1D convolution with separable filters.

  Args:
      x: input tensor
      depthwise_kernel: convolution kernel for the depthwise convolution.
      pointwise_kernel: kernel for the 1x1 convolution.
      strides: stride integer.
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      dilation_rate: integer dilation rate.

  Returns:
      Output tensor.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: rU  rR   )rR   r   )rR   rR   r   )r`  r  rM  rp  r{  )r   r   rR   )r  r}   r   rF   rW   rV  r\  r   r   r   r&   separable_conv2dr4  r'  )	rO   depthwise_kernelpointwise_kernelr`  r  rp  r_  rr  Zspatial_start_dimr9   r9   r:   separable_conv1d!  sB    


rj  zkeras.backend.separable_conv2dc          	   C   s   |dkrt  }|dkr&tdt| t|dkr:tdt| |\} }t|}t|tsbt|}|dkrxd| d }nd| }tj	| ||||||d	} |d
kr|dkrt
| d} | S )a  2D convolution with separable filters.

  Args:
      x: input tensor
      depthwise_kernel: convolution kernel for the depthwise convolution.
      pointwise_kernel: kernel for the 1x1 convolution.
      strides: strides tuple (length 2).
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      dilation_rate: tuple of integers,
          dilation rates for the separable convolution.

  Returns:
      Output tensor.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
      ValueError: if `strides` is not a tuple of 2 integers.
  N>   r{  r|  zUnknown data_format: r   z(`strides` must be a tuple of 2 integers.rn  )rR   )rR   rR   )r`  r  rM  rp  r{  )r   r1  rR   r   )r  r}   r   r   rX  r\  rF   r   r&   rg  r   r'  )rO   rh  ri  r`  r  rp  r_  rr  r9   r9   r:   rg  d  s0    
rg  zkeras.backend.depthwise_conv2dc             C   s   |dkrt  }|dkr&tdt| t| |\} }t|}|dkrRd| d }nd| }tj| |||||d} |dkr|dkrt| d	} | S )
a  2D convolution with separable filters.

  Args:
      x: input tensor
      depthwise_kernel: convolution kernel for the depthwise convolution.
      strides: strides tuple (length 2).
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      dilation_rate: tuple of integers,
          dilation rates for the separable convolution.

  Returns:
      Output tensor.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: rn  )rR   )rR   rR   )r`  r  rM  rp  r{  )r   r1  rR   r   )	r  r}   r   rX  r\  r&   depthwise_conv2dr   r'  )rO   rh  r`  r  rp  r_  rr  r9   r9   r:   rk    s&    rk  zkeras.backend.conv3drR   rR   rR   c             C   sr   |dkrt  }|dkr&tdt| t| |\} }t|}tj| |||||d} |dkrn|dkrnt| d} | S )a  3D convolution.

  Args:
      x: Tensor or variable.
      kernel: kernel tensor.
      strides: strides tuple.
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      dilation_rate: tuple of 3 integers.

  Returns:
      A tensor, result of 3D convolution.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: )r]  r^  r_  r`  r  rp  r{  rY  )r   rt  rR   r   r1  )	r  r}   r   rZ  r\  r&   ra  r   r'  )rO   rb  r`  r  rp  r_  rr  r9   r9   r:   conv3d  s     rm  c             C   s  |dkrt  }|dkr&tdt| t|ttfr>t|}t| |\} }|dkr~|dkr~|d |d |d |d	 |d
 f}|d dkrt	| d ft|d
d  }tt|}t
|}|dkrd| d }nd| }tj| |||||d} |dkr|dkrt| d} | S )a  3D deconvolution (i.e.

  transposed convolution).

  Args:
      x: input tensor.
      kernel: kernel tensor.
      output_shape: 1D int tensor for the output shape.
      strides: strides tuple.
      padding: string, "same" or "valid".
      data_format: string, `"channels_last"` or `"channels_first"`.

  Returns:
      A tensor, result of transposed 3D convolution.

  Raises:
      ValueError: if `data_format` is neither `channels_last` or
      `channels_first`.
  N>   r{  r|  zUnknown data_format: r{  rY  r   r   r1  rt  rR   )rR   )rR   rR   )r  rp  )r   rt  rR   r   r1  )r  r}   r   rF   r   r%  r   r2  rZ  ru   r\  r&   conv3d_transposer'  )rO   rb  r8  r`  r  rp  rr  r9   r9   r:   rn    s6    
 rn  zkeras.backend.pool2dc             C   s  |dkrt  }|dkr&tdt| t|dkr:tdt|dkrNtdt| |\} }t|}|dkrd| d }d| d }nd	| }d	| }|d
krtj| ||||d} n.|dkrtj| ||||d} ntdt| |dkr|dkrt	
| d} | S )as  2D Pooling.

  Args:
      x: Tensor or variable.
      pool_size: tuple of 2 integers.
      strides: tuple of 2 integers.
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      pool_mode: string, `"max"` or `"avg"`.

  Returns:
      A tensor, result of 2D pooling.

  Raises:
      ValueError: if `data_format` is neither `"channels_last"` or
      `"channels_first"`.
      ValueError: if `pool_size` is not a tuple of 2 integers.
      ValueError: if `strides` is not a tuple of 2 integers.
      ValueError: if `pool_mode` is neither `"max"` or `"avg"`.
  N>   r{  r|  zUnknown data_format: r   z*`pool_size` must be a tuple of 2 integers.z(`strides` must be a tuple of 2 integers.rn  )rR   )rR   rR   r?  )r  rp  avgzInvalid pooling mode: r{  )r   r1  rR   r   )r  r}   r   r   rX  r\  r&   Zmax_poolZavg_poolr   r'  )rO   	pool_sizer`  r  rp  	pool_moderr  r9   r9   r:   pool2d:  s2    rr  zkeras.backend.pool3dc             C   s   |dkrt  }|dkr&tdt| t| |\} }t|}|dkr^d| d }d| d }nd| }d| }|dkrtj| ||||d} n.|d	krtj| ||||d} ntd
t| |dkr|dkrt	| d} | S )a  3D Pooling.

  Args:
      x: Tensor or variable.
      pool_size: tuple of 3 integers.
      strides: tuple of 3 integers.
      padding: string, `"same"` or `"valid"`.
      data_format: string, `"channels_last"` or `"channels_first"`.
      pool_mode: string, `"max"` or `"avg"`.

  Returns:
      A tensor, result of 3D pooling.

  Raises:
      ValueError: if `data_format` is neither `"channels_last"` or
      `"channels_first"`.
      ValueError: if `pool_mode` is neither `"max"` or `"avg"`.
  N>   r{  r|  zUnknown data_format: rY  )rR   )rR   rR   r?  )r  rp  ro  zInvalid pooling mode: r{  )r   rt  rR   r   r1  )
r  r}   r   rZ  r\  r&   Z
max_pool3dZ
avg_pool3dr   r'  )rO   rp  r`  r  rp  rq  rr  r9   r9   r:   pool3dw  s*    rs  c                sF  |dkrt  }|dkr&tdt| t|}|d }|d }t|}	tt|	}
g }dd |D }x~tj| D ]pt	dg}|dkr|
t	d | fd	d
|
D  |dkr|
t	d |
t| | dd|f qpW t|dd}t||}t||d|f }|dkr(|	|	d g|
 }n|	g|
 |	d g }t||S )a  Apply N-D convolution with un-shared weights.

  Args:
      inputs: (N+2)-D tensor with shape
          (batch_size, channels_in, d_in1, ..., d_inN)
          if data_format='channels_first', or
          (batch_size, d_in1, ..., d_inN, channels_in)
          if data_format='channels_last'.
      kernel: the unshared weight for N-D convolution,
          with shape (output_items, feature_dim, channels_out), where
          feature_dim = np.prod(kernel_size) * channels_in,
          output_items = np.prod(output_shape).
      kernel_size: a tuple of N integers, specifying the
          spatial dimensions of the N-D convolution window.
      strides: a tuple of N integers, specifying the strides
          of the convolution along the spatial dimensions.
      output_shape: a tuple of (d_out1, ..., d_outN) specifying the spatial
          dimensionality of the output.
      data_format: string, "channels_first" or "channels_last".

  Returns:
      An (N+2)-D tensor with shape:
      (batch_size, channels_out) + output_shape
      if data_format='channels_first', or:
      (batch_size,) + output_shape + (channels_out,)
      if data_format='channels_last'.

  Raises:
      ValueError: if `data_format` is neither
      `channels_last` nor `channels_first`.
  N>   r{  r|  zUnknown data_format: rR   r"  c             S   s   g | ]}t |qS r9   )r   )r   Zaxis_maxr9   r9   r:   r     s    zlocal_conv.<locals>.<listcomp>r{  c             3   s8   | ]0}t | |  | |   |  V  qd S )N)slice)r   r   )kernel_sizepositionr`  r9   r:   r     s   zlocal_conv.<locals>.<genexpr>r|  r   )r=  )r  r}   r   r   r   r%  r   rC  productrt  r   extendr&  r   r9  ry  )r  rb  ru  r`  r8  rp  rc  Zfeature_dimZchannels_outrB  Zspatial_dimensionsZxsZoutput_axes_ticksZslicesZx_aggregater  rF  r9   )ru  rv  r`  r:   
local_conv  s8    %



ry  zkeras.backend.local_conv1dc             C   s   |j d f}t| |||||S )ax  Apply 1D conv with un-shared weights.

  Args:
      inputs: 3D tensor with shape:
          (batch_size, steps, input_dim)
          if data_format is "channels_last" or
          (batch_size, input_dim, steps)
          if data_format is "channels_first".
      kernel: the unshared weight for convolution,
          with shape (output_length, feature_dim, filters).
      kernel_size: a tuple of a single integer,
          specifying the length of the 1D convolution window.
      strides: a tuple of a single integer,
          specifying the stride length of the convolution.
      data_format: the data format, channels_first or channels_last.

  Returns:
      A 3d tensor with shape:
      (batch_size, output_length, filters)
      if data_format='channels_first'
      or 3D tensor with shape:
      (batch_size, filters, output_length)
      if data_format='channels_last'.
  r   )ru   ry  )r  rb  ru  r`  rp  r8  r9   r9   r:   local_conv1d  s    rz  zkeras.backend.local_conv2dc             C   s   t | |||||S )a  Apply 2D conv with un-shared weights.

  Args:
      inputs: 4D tensor with shape:
          (batch_size, filters, new_rows, new_cols)
          if data_format='channels_first'
          or 4D tensor with shape:
          (batch_size, new_rows, new_cols, filters)
          if data_format='channels_last'.
      kernel: the unshared weight for convolution,
          with shape (output_items, feature_dim, filters).
      kernel_size: a tuple of 2 integers, specifying the
          width and height of the 2D convolution window.
      strides: a tuple of 2 integers, specifying the strides
          of the convolution along the width and height.
      output_shape: a tuple with (output_row, output_col).
      data_format: the data format, channels_first or channels_last.

  Returns:
      A 4D tensor with shape:
      (batch_size, filters, new_rows, new_cols)
      if data_format='channels_first'
      or 4D tensor with shape:
      (batch_size, new_rows, new_cols, filters)
      if data_format='channels_last'.
  )ry  )r  rb  ru  r`  r8  rp  r9   r9   r:   local_conv2d   s    #r{  zkeras.backend.bias_addc             C   s   |dkrt  }|dkr&tdt| t|}t|dkrjt|t| d krjtdt|t| d f t|dkr|dkrtj| |ddS tj| |d	dS t| d
kr|dkrd|d f|dd  }| t|| S | t|d|  S t| |S )a  Adds a bias vector to a tensor.

  Args:
      x: Tensor or variable.
      bias: Bias tensor to add.
      data_format: string, `"channels_last"` or `"channels_first"`.

  Returns:
      Output tensor.

  Raises:
      ValueError: In one of the two cases below:
                  1. invalid `data_format` argument.
                  2. invalid bias shape.
                     the bias should be either a vector or
                     a tensor with ndim(x) - 1 dimension
  N>   r{  r|  zUnknown data_format: rR   z>Unexpected bias dimensions %d, expect to be 1 or %d dimensionsr{  ro  )rp  rn  )r1  rt     r"  )rR   )	r  r}   r   r   r   r   r&   bias_addr&  )rO   Zbiasrp  Z
bias_shapeZbias_reshape_axisr9   r9   r:   r}  K  s&     r}  zkeras.backend.random_normalc             C   s6   |dkrt  }|dkr"tjd}tj| ||||dS )am  Returns a tensor with normal distribution of values.

  It is an alias to `tf.random.normal`.

  Args:
      shape: A tuple of integers, the shape of tensor to create.
      mean: A float, the mean value of the normal distribution to draw samples.
        Default to 0.0.
      stddev: A float, the standard deviation of the normal distribution
        to draw samples. Default to 1.0.
      dtype: `tf.dtypes.DType`, dtype of returned tensor. Default to use Keras
        backend dtype which is float32.
      seed: Integer, random seed. Will use a random numpy integer when not
        specified.

  Returns:
      A tensor with normal distribution of values.

  Example:

  >>> random_normal_tensor = tf.keras.backend.random_normal(shape=(2,3),
  ... mean=0.0, stddev=1.0)
  >>> random_normal_tensor
  <tf.Tensor: shape=(2, 3), dtype=float32, numpy=...,
  dtype=float32)>
  Ng    cA)r  stddevrE   r  )rL   rM   r  r  r'   random_normal)ru   r  r~  rE   r  r9   r9   r:   r  y  s    r  zkeras.backend.random_uniformc             C   s6   |dkrt  }|dkr"tjd}tj| ||||dS )a  Returns a tensor with uniform distribution of values.

  Args:
      shape: A tuple of integers, the shape of tensor to create.
      minval: A float, lower boundary of the uniform distribution
          to draw samples.
      maxval: A float, upper boundary of the uniform distribution
          to draw samples.
      dtype: String, dtype of returned tensor.
      seed: Integer, random seed.

  Returns:
      A tensor.

  Example:

  >>> random_uniform_tensor = tf.keras.backend.random_uniform(shape=(2,3),
  ... minval=0.0, maxval=1.0)
  >>> random_uniform_tensor
  <tf.Tensor: shape=(2, 3), dtype=float32, numpy=...,
  dtype=float32)>
  Ng    cA)minvalmaxvalrE   r  )rL   rM   r  r  r'   random_uniform)ru   r  r  rE   r  r9   r9   r:   r    s    r  zkeras.backend.random_binomialc             C   s   t d t| |||S )a  Returns a tensor with random binomial distribution of values.

  DEPRECATED, use `tf.keras.backend.random_bernoulli` instead.

  The binomial distribution with parameters `n` and `p` is the probability
  distribution of the number of successful Bernoulli process. Only supports
  `n` = 1 for now.

  Args:
      shape: A tuple of integers, the shape of tensor to create.
      p: A float, `0. <= p <= 1`, probability of binomial distribution.
      dtype: String, dtype of returned tensor.
      seed: Integer, random seed.

  Returns:
      A tensor.

  Example:

  >>> random_binomial_tensor = tf.keras.backend.random_binomial(shape=(2,3),
  ... p=0.5)
  >>> random_binomial_tensor
  <tf.Tensor: shape=(2, 3), dtype=float32, numpy=...,
  dtype=float32)>
  z`tf.keras.backend.random_binomial` is deprecated, and will be removed in a future version.Please use `tf.keras.backend.random_bernoulli` instead.)ry   rz   random_bernoulli)ru   r  rE   r  r9   r9   r:   random_binomial  s    
r  zkeras.backend.random_bernoullic             C   sT   |dkrt  }|dkr"tjd}ttj| ||d|ktj| |dtj	| |dS )aA  Returns a tensor with random bernoulli distribution of values.

  Args:
      shape: A tuple of integers, the shape of tensor to create.
      p: A float, `0. <= p <= 1`, probability of bernoulli distribution.
      dtype: String, dtype of returned tensor.
      seed: Integer, random seed.

  Returns:
      A tensor.
  Ng    cA)rE   r  )rE   )
rL   rM   r  r  r   r  r'   r  r
  r  )ru   r  rE   r  r9   r9   r:   r    s    r  zkeras.backend.truncated_normalc             C   s6   |dkrt  }|dkr"tjd}tj| ||||dS )a'  Returns a tensor with truncated random normal distribution of values.

  The generated values follow a normal distribution
  with specified mean and standard deviation,
  except that values whose magnitude is more than
  two standard deviations from the mean are dropped and re-picked.

  Args:
      shape: A tuple of integers, the shape of tensor to create.
      mean: Mean of the values.
      stddev: Standard deviation of the values.
      dtype: String, dtype of returned tensor.
      seed: Integer, random seed.

  Returns:
      A tensor.
  Ng    cA)rE   r  )rL   rM   r  r  r'   truncated_normal)ru   r  r~  rE   r  r9   r9   r:   r    s    r  z'keras.backend.ctc_label_dense_to_sparsec                s0  t | }t |d g}t |d g  fdd}tt d|d gdtj}tj	|||dd}|dddddf }t 
t td|d ||}t ||}t t 
t td|d  t|d}	t |	|}
t t 
t|
|gdddd	g}t | |}tt|tj|t|tjS )
zConverts CTC labels from dense to sparse.

  Args:
      labels: dense CTC labels.
      label_lengths: length of the labels.

  Returns:
      A sparse tensor representation of the labels.
  r   rR   c                s(   t tt | d dt  |k S )NrR   r   )r   r   r%   r   ru   fill)Z	old_inputr  )max_num_labels_tnsr9   r:   range_less_than1  s    z2ctc_label_dense_to_sparse.<locals>.range_less_than)r   r  N)r=  r   r"  )r   ru   r2  r%   rK   r  r   r   r   scanr&  r  r   Zboolean_maskr'  r  r   Z	gather_ndr   rJ   r@  )r:  Zlabel_lengthsZlabel_shapeZnum_batches_tnsr  initZ
dense_maskZlabel_arrayZ	label_indZbatch_arrayZ	batch_indr   Zvals_sparser9   )r  r:   ctc_label_dense_to_sparse   s0    
r  zkeras.backend.ctc_batch_costc             C   s|   t tj|ddtj}t tj|ddtj}t t| |tj}t tj|dddgdt	  }t
tj|||ddS )a\  Runs CTC loss algorithm on each batch element.

  Args:
      y_true: tensor `(samples, max_string_length)`
          containing the truth labels.
      y_pred: tensor `(samples, time_steps, num_categories)`
          containing the prediction, or output of the softmax.
      input_length: tensor `(samples, 1)` containing the sequence length for
          each batch item in `y_pred`.
      label_length: tensor `(samples, 1)` containing the sequence length for
          each batch item in `y_true`.

  Returns:
      Tensor with shape (samples,1) containing the
          CTC loss of each element.
  r"  )r=  rR   r   r   )r#  )r  r:  sequence_length)r%   rK   r   r4  r   r}  r  rQ  r'  rj  r   ctcZctc_loss)Zy_truey_predr  Zlabel_lengthZsparse_labelsr9   r9   r:   ctc_batch_costP  s     r  zkeras.backend.ctc_decodeTd   c             C   s   t | }|d |d  }}ttj| dddgdt  } t|tj}|r`t	j
| |d\}}	nt	j| |||d\}}	g }
x6|D ].}t|j|j||f}|
tj|dd qW |
|	fS )	a  Decodes the output of a softmax.

  Can use either greedy search (also known as best path)
  or a constrained dictionary search.

  Args:
      y_pred: tensor `(samples, time_steps, num_categories)`
          containing the prediction, or output of the softmax.
      input_length: tensor `(samples, )` containing the sequence length for
          each batch item in `y_pred`.
      greedy: perform much faster best-path search if `true`.
          This does not use a dictionary.
      beam_width: if `greedy` is `false`: a beam search decoder will be used
          with a beam of this width.
      top_paths: if `greedy` is `false`,
          how many of the most probable paths will be returned.

  Returns:
      Tuple:
          List: if `greedy` is `true`, returns a list of one element that
              contains the decoded sequence.
              If `false`, returns the `top_paths` most probable
              decoded sequences.
              Each decoded sequence has shape (samples, time_steps).
              Important: blank labels are returned as `-1`.
          Tensor `(top_paths, )` that contains
              the log probability of each decoded sequence.
  r   rR   r   )r#  )r  r  )r  r  
beam_width	top_pathsr"  )Zsp_inputdefault_value)ru   r%   rQ  r   r'  rj  rK   r   r}  r  Zctc_greedy_decoderZctc_beam_search_decoderr   rJ   r   r   r   r(   r   )r  r  Zgreedyr  r  Zinput_shapeZnum_samplesZ	num_stepsdecodedZlog_probZdecoded_densestr9   r9   r:   
ctc_decoder  s&      
r  zkeras.backend.map_fnc             C   s   t j| |||dS )a)  Map the function fn over the elements elems and return the outputs.

  Args:
      fn: Callable that will be called upon each element in elems
      elems: tensor
      name: A string name for the map node in the graph
      dtype: Output data type.

  Returns:
      Tensor with dtype `dtype`.
  )rv   rE   )
map_fn_libr$   )fnelemsrv   rE   r9   r9   r:   r$     s    r$   zkeras.backend.foldlc             C   s   t j| |||dS )a  Reduce elems using fn to combine them from left to right.

  Args:
      fn: Callable that will be called upon each element in elems and an
          accumulator, for instance `lambda acc, x: acc + x`
      elems: tensor
      initializer: The first value used (`elems[0]` in case of None)
      name: A string name for the foldl node in the graph

  Returns:
      Tensor with same type and shape as `initializer`.
  )r   rv   )r   foldl)r  r  r   rv   r9   r9   r:   r    s    r  zkeras.backend.foldrc             C   s   t j| |||dS )a  Reduce elems using fn to combine them from right to left.

  Args:
      fn: Callable that will be called upon each element in elems and an
          accumulator, for instance `lambda acc, x: acc + x`
      elems: tensor
      initializer: The first value used (`elems[-1]` in case of None)
      name: A string name for the foldr node in the graph

  Returns:
      Same type and shape as initializer
  )r   rv   )r   foldr)r  r  r   rv   r9   r9   r:   r    s    r  Z
KERAS_HOME~z.kerasz
keras.jsonrL   >   float32float16float64rj  r  >   r{  r|  rC   )rL   rj  rD   r  wrt  )indentc             C   s,   dd }| j  r t||  n||  dS )z6Configure session config and create a session with it.c             S   s   t  }ttddr(tjjr(|tjj t| rV| | | jj	
 }tj||d}nDt }|r|j}|| tj||jd}n| | tj|d}t| dS )z(Create the Distributed Strategy session.r   N)r	   r  )r	   )r   rm   r_   r   _configZ	MergeFromis_tpu_strategy	configureextendedZ_tpu_cluster_resolvermasterr   r   dcZget_current_worker_contextsession_configZmaster_targetr   )distribution_strategyr  r  r   Zworker_contextZdc_session_configr9   r9   r:   _create_session  s     


zAconfigure_and_create_distributed_session.<locals>._create_sessionN)r  Z_in_multi_worker_moder  Zrun_distribute_coordinator)r  r  r9   r9   r:   r     s    !
r   c             C   s$   dd }|| rdS t tt| jS )Nc             S   s   | j dS )NZTPUStrategy)r5   
startswith)rT  r9   r9   r:   r  >  r  z(_is_tpu_strategy_class.<locals>.<lambda>T)r   r  _is_tpu_strategy_class	__bases__)ZclzZis_tpu_stratr9   r9   r:   r  =  s    r  c             C   s
   t | jS )zEReturns whether input is a TPUStrategy instance or subclass instance.)r  rA   )Zstrategyr9   r9   r:   r  D  s    r  c             C   s   dd }t || S )Nc             S   s   t | tjrt| S | S )N)rF   rH   rI   r   r  )r   r9   r9   r:   _cast_variables_to_tensorK  s    
z;cast_variables_to_tensor.<locals>._cast_variables_to_tensor)r1   r   )rx  r  r9   r9   r:   r  I  s    r  c             C   s   t | ot| tj S )N)r   r  rF   r   r  )rO   r9   r9   r:   rA  S  s    rA  c             C   s\   dd }t | }tdd |D }|s0| dfS t || } t|d  d d}| |fS )z%Converts any ragged tensors to dense.c             S   s   t | tjr|  S | S )N)rF   r-   r   r  )r  r9   r9   r:   _convert_ragged_inputZ  s    z7convert_inputs_if_ragged.<locals>._convert_ragged_inputc             s   s   | ]}t |tjV  qd S )N)rF   r-   r   )r   r   r9   r9   r:   r   a  s    z+convert_inputs_if_ragged.<locals>.<genexpr>Nr   r}  )r1   r   r   r   r%   rK   nested_row_lengths)r  r  Zflat_inputsZcontains_raggedr  r9   r9   r:   convert_inputs_if_raggedW  s    
r  c             C   sD   | s|S |r2t |dg}tj||}t |dgS tj||S dS )z8Converts any ragged input back to its initial structure.rR   N)r  r-   r   r  )Zis_ragged_inputr  r  r  r   r9   r9   r:   maybe_convert_to_raggedn  s    r  c               @   sB   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdddZ	dS )ContextValueCachea  Container that caches (possibly tensor) values based on the context.

  This class is similar to defaultdict, where values may be produced by the
  default factory specified during initialization. This class also has a default
  value for the key (when key is `None`) -- the key is set to the current graph
  or eager context. The default factories for key and value are only used in
  `__getitem__` and `setdefault`. The `.get()` behavior remains the same.

  This object will return the value of the current graph or closest parent graph
  if the current graph is a function. This is to reflect the fact that if a
  tensor is created in eager/graph, child functions may capture that tensor.

  The default factory method may accept keyword arguments (unlike defaultdict,
  which only accepts callables with 0 arguments). To pass keyword arguments to
  `default_factory`, use the `setdefault` method instead of `__getitem__`.

  An example of how this class can be used in different contexts:

  ```
  cache = ContextValueCache(int)

  # Eager mode
  cache[None] += 2
  cache[None] += 4
  assert cache[None] == 6

  # Graph mode
  with tf.Graph().as_default() as g:
    cache[None] += 5
    cache[g] += 3
  assert cache[g] == 8
  ```

  Example of a default factory with arguments:

  ```
  cache = ContextValueCache(lambda x: x + 1)
  g = tf.get_default_graph()

  # Example with keyword argument.
  value = cache.setdefault(key=g, kwargs={'x': 3})
  assert cache[g] == 4
  ```
  c             C   s   || _ tj|  d S )N)default_factoryweakrefWeakKeyDictionaryr=   )r@   r  r9   r9   r:   r=     s    zContextValueCache.__init__c             C   s   t  rtjS t S d S )N)r   rg   ra   r>   r   rl   )r@   r9   r9   r:   _key  s    zContextValueCache._keyc             C   s$   |j }t|tjs t r tjS |S )z/Returns the parent graph or dummy eager object.)Zouter_graphrF   r   r   r   r   ra   r>   )r@   rY   Zparent_graphr9   r9   r:   _get_parent_graph  s
    z#ContextValueCache._get_parent_graphc             C   s6   |  |}|dk	r|S t|tjr2| | |S dS )z2Gets the value at key or the closest parent graph.N)r   rF   r   r   _get_recursiver  )r@   r>   rj   r9   r9   r:   r    s    
z ContextValueCache._get_recursivec             C   s6   |dkr|   }| |}|dkr2|   }| |< |S )zGets the value at key (or current context), or sets default value.

    Args:
      key: May be `None` or `Graph`object. When `None`, the key is set to the
        current context.

    Returns:
      Either the cached or default value.
    N)r  r  r  )r@   r>   rj   r9   r9   r:   __getitem__  s    

zContextValueCache.__getitem__Nc             C   sD   |dkr|   }|pi }|dkr4|| kr4| jf |}tj| ||S )zDSets the default value if key is not in dict, and returns the value.N)r  r  r  r  rc   )r@   r>   defaultr  r9   r9   r:   rc     s    zContextValueCache.setdefault)NNN)
r5   r6   r7   r8   r=   r  r  r  r  rc   r9   r9   r9   r:   r  ~  s   ,r  )rQ   )N)r9   )r9   )N)NNN)NNrQ   FF)N)NNN)NNNFNF)NN)NN)NN)NN)NN)N)NNN)NNN)N)NF)NF)NF)NF)r   )r   )NF)NF)NF)NF)NF)r"  )r"  )NF)rd  )rd  )rd  )rd  )r"  rd  )r"  )rz  )NrR   r}  )r"  )r  )r  N)r  N)r   )rQ   r1  )NN)FNNFNFF)N)N)r.  Nr   )r3  )r"  )Fr"  )Fr"  )F)NN)N)F)rR   r[  NrR   )r  r[  Nr  )r  r[  Nr  )rR   r[  NrR   )r  r[  Nr  )r  r[  Nr  )rl  r[  Nrl  )rl  r[  N)r  r[  Nr?  )rl  r[  Nr?  )N)N)N)N)r.  r3  NN)r.  r3  NN)r.  NN)r.  NN)r.  r3  NN)Tr  rR   )NN)NN)NN)F(O  r8   rU   rC  jsonr   r  	threadingry   r  r  rM   Ztensorflow.core.protobufr   Ztensorflow.pythonr   Ztensorflow.python.clientr   r   Ztensorflow.python.distributer   Ztensorflow.python.eagerr   Ztensorflow.python.eager.contextr   Ztensorflow.python.frameworkr   r	   r
   r   r   r   r   r   r   r   r   r   r  r   Z"tensorflow.python.keras.distributer   r  r   r   r   r   r   r   r   Ztensorflow.python.opsr   r   r   r   r  r   r   r  r    r!   r"   r#   r$   r  r%   r&   r'   r(   r)   r*   r+   r,   rH   Ztensorflow.python.ops.raggedr-   Ztensorflow.python.platformr.   r   Ztensorflow.python.trainingr/   Ztensorflow.python.utilr0   r1   Z tensorflow.python.util.tf_exportr2   Ztensorflow.tools.docsr3   rH  r  rB  Zpy_sumrG  r   localr^   r   r_   r  rT   r   r\   r4   ra   ri   r   rj  rL   r  Zset_epsilonZ
set_floatxZset_image_data_formatZdo_not_generate_docsrD   Zadd_dispatch_supportrP   rZ   r]   rh   rk   rq   rr   rp   rn   rx   r|   r{   contextmanagerr   r~   r   r   r   r   r   r   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   rw   Zname_scope_v1Z_v1_name_scoper   r   r   r   r   r   r   r   r   r   rt   ru   r   r   rE   r  r  r  r
  r  r  r  r  r  r  r  rK   r   r  r  r  r.  r9  r'  r:  r?  r@  r  rC  rD  rE  rF  r  rI  rJ  rK  rL  rN  rP  rQ  rR  rS  rT  rU  rZ  r[  r\  r]  r^  r_  r`  rM  ra  rb  rc  rl  rm  rs  rv  rf  r   r&  ry  r  r  r  r  r  r  r   r  r   r4  r  r  r  r2  r  r  Z_VALUE_SET_CODE_STRINGr  r  r  r  rE  r  r  r  r  r"  r(  r,  r-  r1  r4  r6  r7  r8  r?  rG  rH  rI  rK  rL  rP  rQ  rR  rV  rX  rZ  r\  rd  re  rf  rj  rg  rk  rm  rn  rr  rs  ry  rz  r{  r}  r  r  r  r  r  r  r  r  r  r  r   r   Z
_keras_dirpath
expanduserZ_keras_base_dirjoinZ_config_pathexistsopenfhloadr  r}   Z_floatxr   Z_epsilonrF   rV  Z_image_data_formatmakedirsOSErrorfr
  dumpsIOErrorr   r  r  r  rA  r  r  r  rb   ZObjectIdentityWeakSetrd   rf   r9   r9   r9   r:   <module>   s<  		 	A	 !6G

#
1	    3	6     X +!! !2A <#+ =$1 =#%++#&&' F/         @,7P[0   ,   %   E   =   2   +   (  6   5   4H"#+# !. 7$


.,
r