Home | History | Annotate | Download | only in keras
      1 # Copyright 2015 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 # ==============================================================================
     15 # pylint: disable=protected-access
     16 # pylint: disable=redefined-outer-name
     17 # pylint: disable=redefined-builtin
     18 """Keras backend API.
     19 """
     20 from __future__ import absolute_import
     21 from __future__ import division
     22 from __future__ import print_function
     23 
     24 import collections
     25 import json
     26 import os
     27 
     28 import numpy as np
     29 
     30 from tensorflow.core.protobuf import config_pb2
     31 from tensorflow.python.client import session as session_module
     32 from tensorflow.python.eager import context
     33 from tensorflow.python.framework import constant_op
     34 from tensorflow.python.framework import dtypes as dtypes_module
     35 from tensorflow.python.framework import ops
     36 from tensorflow.python.framework import sparse_tensor
     37 from tensorflow.python.layers import base as tf_base_layers
     38 from tensorflow.python.ops import array_ops
     39 from tensorflow.python.ops import clip_ops
     40 from tensorflow.python.ops import control_flow_ops
     41 from tensorflow.python.ops import ctc_ops as ctc
     42 from tensorflow.python.ops import functional_ops
     43 from tensorflow.python.ops import gradients as gradients_module
     44 from tensorflow.python.ops import image_ops
     45 from tensorflow.python.ops import init_ops
     46 from tensorflow.python.ops import linalg_ops
     47 from tensorflow.python.ops import logging_ops
     48 from tensorflow.python.ops import math_ops
     49 from tensorflow.python.ops import nn
     50 from tensorflow.python.ops import random_ops
     51 from tensorflow.python.ops import resource_variable_ops
     52 from tensorflow.python.ops import sparse_ops
     53 from tensorflow.python.ops import state_ops
     54 from tensorflow.python.ops import tensor_array_grad  # pylint: disable=unused-import
     55 from tensorflow.python.ops import tensor_array_ops
     56 from tensorflow.python.ops import variables as variables_module
     57 from tensorflow.python.training import moving_averages
     58 from tensorflow.python.util import tf_inspect
     59 from tensorflow.python.util.tf_export import tf_export
     60 
     61 
     62 py_all = all
     63 py_sum = sum
     64 
     65 # INTERNAL UTILS
     66 
     67 # This is the default internal TF session used by Keras.
     68 # It can be set manually via `set_session(sess)`.
     69 _SESSION = None
     70 
     71 # This dictionary holds a mapping {graph: learning_phase}.
     72 # A learning phase is a bool tensor used to run Keras models in
     73 # either train mode (learning_phase == 1) or test mode (learning_phase == 0).
     74 _GRAPH_LEARNING_PHASES = {}
     75 
     76 # This dictionary holds a mapping {graph: UID_DICT}.
     77 # each UID_DICT is a dictionary mapping name prefixes to a current index,
     78 # used for generating graph-specific string UIDs
     79 # for various names (e.g. layer names).
     80 _GRAPH_UID_DICTS = {}
     81 
     82 # This boolean flag can be set to True to leave variable initialization
     83 # up to the user.
     84 # Change its value via `manual_variable_initialization(value)`.
     85 _MANUAL_VAR_INIT = False
     86 
     87 # The type of float to use throughout a session.
     88 _FLOATX = 'float32'
     89 
     90 # Epsilon fuzz factor used throughout the codebase.
     91 _EPSILON = 1e-7
     92 
     93 # Default image data format, one of "channels_last", "channels_first".
     94 _IMAGE_DATA_FORMAT = 'channels_last'
     95 
     96 # This list holds the available devices.
     97 # It is populated when `_get_available_gpus()` is called for the first time.
     98 # We assume our devices don't change henceforth.
     99 _LOCAL_DEVICES = None
    100 
    101 
    102 @tf_export('keras.backend.backend')
    103 def backend():
    104   """Publicly accessible method for determining the current backend.
    105 
    106   Only exists for API compatibility with multi-backend Keras.
    107 
    108   Returns:
    109       The string "tensorflow".
    110   """
    111   return 'tensorflow'
    112 
    113 
    114 @tf_export('keras.backend.epsilon')
    115 def epsilon():
    116   """Returns the value of the fuzz factor used in numeric expressions.
    117 
    118   Returns:
    119       A float.
    120 
    121   Example:
    122   ```python
    123       >>> keras.backend.epsilon()
    124       1e-07
    125   ```
    126   """
    127   return _EPSILON
    128 
    129 
    130 @tf_export('keras.backend.set_epsilon')
    131 def set_epsilon(value):
    132   """Sets the value of the fuzz factor used in numeric expressions.
    133 
    134   Arguments:
    135       value: float. New value of epsilon.
    136 
    137   Example:
    138   ```python
    139       >>> from keras import backend as K
    140       >>> K.epsilon()
    141       1e-07
    142       >>> K.set_epsilon(1e-05)
    143       >>> K.epsilon()
    144       1e-05
    145   ```
    146   """
    147   global _EPSILON
    148   _EPSILON = value
    149 
    150 
    151 @tf_export('keras.backend.floatx')
    152 def floatx():
    153   """Returns the default float type, as a string.
    154 
    155   E.g. 'float16', 'float32', 'float64'.
    156 
    157   Returns:
    158       String, the current default float type.
    159 
    160   Example:
    161   ```python
    162       >>> keras.backend.floatx()
    163       'float32'
    164   ```
    165   """
    166   return _FLOATX
    167 
    168 
    169 @tf_export('keras.backend.set_floatx')
    170 def set_floatx(value):
    171   """Sets the default float type.
    172 
    173   Arguments:
    174       value: String; 'float16', 'float32', or 'float64'.
    175 
    176   Example:
    177   ```python
    178       >>> from keras import backend as K
    179       >>> K.floatx()
    180       'float32'
    181       >>> K.set_floatx('float16')
    182       >>> K.floatx()
    183       'float16'
    184   ```
    185 
    186   Raises:
    187       ValueError: In case of invalid value.
    188   """
    189   global _FLOATX
    190   if value not in {'float16', 'float32', 'float64'}:
    191     raise ValueError('Unknown floatx type: ' + str(value))
    192   _FLOATX = str(value)
    193 
    194 
    195 @tf_export('keras.backend.cast_to_floatx')
    196 def cast_to_floatx(x):
    197   """Cast a Numpy array to the default Keras float type.
    198 
    199   Arguments:
    200       x: Numpy array.
    201 
    202   Returns:
    203       The same Numpy array, cast to its new type.
    204 
    205   Example:
    206   ```python
    207       >>> from keras import backend as K
    208       >>> K.floatx()
    209       'float32'
    210       >>> arr = numpy.array([1.0, 2.0], dtype='float64')
    211       >>> arr.dtype
    212       dtype('float64')
    213       >>> new_arr = K.cast_to_floatx(arr)
    214       >>> new_arr
    215       array([ 1.,  2.], dtype=float32)
    216       >>> new_arr.dtype
    217       dtype('float32')
    218   ```
    219   """
    220   return np.asarray(x, dtype=_FLOATX)
    221 
    222 
    223 @tf_export('keras.backend.image_data_format')
    224 def image_data_format():
    225   """Returns the default image data format convention.
    226 
    227   Returns:
    228       A string, either `'channels_first'` or `'channels_last'`
    229 
    230   Example:
    231   ```python
    232       >>> keras.backend.image_data_format()
    233       'channels_first'
    234   ```
    235   """
    236   return _IMAGE_DATA_FORMAT
    237 
    238 
    239 @tf_export('keras.backend.set_image_data_format')
    240 def set_image_data_format(data_format):
    241   """Sets the value of the image data format convention.
    242 
    243   Arguments:
    244       data_format: string. `'channels_first'` or `'channels_last'`.
    245 
    246   Example:
    247   ```python
    248       >>> from keras import backend as K
    249       >>> K.image_data_format()
    250       'channels_first'
    251       >>> K.set_image_data_format('channels_last')
    252       >>> K.image_data_format()
    253       'channels_last'
    254   ```
    255 
    256   Raises:
    257       ValueError: In case of invalid `data_format` value.
    258   """
    259   global _IMAGE_DATA_FORMAT
    260   if data_format not in {'channels_last', 'channels_first'}:
    261     raise ValueError('Unknown data_format: ' + str(data_format))
    262   _IMAGE_DATA_FORMAT = str(data_format)
    263 
    264 
    265 @tf_export('keras.backend.get_uid')
    266 def get_uid(prefix=''):
    267   """Associates a string prefix with an integer counter in a TensorFlow graph.
    268 
    269   Arguments:
    270     prefix: String prefix to index.
    271 
    272   Returns:
    273     Unique integer ID.
    274 
    275   Example:
    276 
    277   ```
    278     >>> get_uid('dense')
    279     1
    280     >>> get_uid('dense')
    281     2
    282   ```
    283   """
    284   graph = ops.get_default_graph()
    285   if graph not in tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS:
    286     tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS[graph] = collections.defaultdict(
    287         int)
    288   layer_name_uids = tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS[graph]
    289   layer_name_uids[prefix] += 1
    290   return layer_name_uids[prefix]
    291 
    292 
    293 @tf_export('keras.backend.reset_uids')
    294 def reset_uids():
    295   per_graph_layer_name_uids = tf_base_layers.PER_GRAPH_LAYER_NAME_UIDS
    296   keys = list(per_graph_layer_name_uids.keys())
    297   for key in keys:
    298     del per_graph_layer_name_uids[key]
    299 
    300 
    301 @tf_export('keras.backend.clear_session')
    302 def clear_session():
    303   """Destroys the current TF graph and creates a new one.
    304 
    305   Useful to avoid clutter from old models / layers.
    306   """
    307   global _SESSION
    308   global _GRAPH_LEARNING_PHASES  # pylint: disable=global-variable-not-assigned
    309   ops.reset_default_graph()
    310   reset_uids()
    311   _SESSION = None
    312   phase = array_ops.placeholder_with_default(
    313       False, shape=(), name='keras_learning_phase')
    314   _GRAPH_LEARNING_PHASES = {}
    315   _GRAPH_LEARNING_PHASES[ops.get_default_graph()] = phase
    316 
    317 
    318 @tf_export('keras.backend.manual_variable_initialization')
    319 def manual_variable_initialization(value):
    320   """Sets the manual variable initialization flag.
    321 
    322   This boolean flag determines whether
    323   variables should be initialized
    324   as they are instantiated (default), or if
    325   the user should handle the initialization
    326   (e.g. via `tf.initialize_all_variables()`).
    327 
    328   Arguments:
    329       value: Python boolean.
    330   """
    331   global _MANUAL_VAR_INIT
    332   _MANUAL_VAR_INIT = value
    333 
    334 
    335 @tf_export('keras.backend.learning_phase')
    336 def learning_phase():
    337   """Returns the learning phase flag.
    338 
    339   The learning phase flag is a bool tensor (0 = test, 1 = train)
    340   to be passed as input to any Keras function
    341   that uses a different behavior at train time and test time.
    342 
    343   Returns:
    344       Learning phase (scalar integer tensor or Python integer).
    345   """
    346   if context.in_eager_mode():
    347     if 'eager' not in _GRAPH_LEARNING_PHASES:
    348       # Fallback to inference mode as default.
    349       return 0
    350     return _GRAPH_LEARNING_PHASES['eager']
    351 
    352   graph = ops.get_default_graph()
    353   if graph not in _GRAPH_LEARNING_PHASES:
    354     phase = array_ops.placeholder_with_default(
    355         False, shape=(), name='keras_learning_phase')
    356     _GRAPH_LEARNING_PHASES[graph] = phase
    357   return _GRAPH_LEARNING_PHASES[graph]
    358 
    359 
    360 @tf_export('keras.backend.set_learning_phase')
    361 def set_learning_phase(value):
    362   """Sets the learning phase to a fixed value.
    363 
    364   Arguments:
    365       value: Learning phase value, either 0 or 1 (integers).
    366 
    367   Raises:
    368       ValueError: if `value` is neither `0` nor `1`.
    369   """
    370   global _GRAPH_LEARNING_PHASES  # pylint: disable=global-variable-not-assigned
    371   if value not in {0, 1}:
    372     raise ValueError('Expected learning phase to be ' '0 or 1.')
    373   if context.in_eager_mode():
    374     _GRAPH_LEARNING_PHASES['eager'] = value
    375   else:
    376     _GRAPH_LEARNING_PHASES[ops.get_default_graph()] = value
    377 
    378 
    379 @tf_export('keras.backend.get_session')
    380 def get_session():
    381   """Returns the TF session to be used by the backend.
    382 
    383   If a default TensorFlow session is available, we will return it.
    384 
    385   Else, we will return the global Keras session.
    386 
    387   If no global Keras session exists at this point:
    388   we will create a new global session.
    389 
    390   Note that you can manually set the global session
    391   via `K.set_session(sess)`.
    392 
    393   Returns:
    394       A TensorFlow session.
    395   """
    396   global _SESSION
    397   if ops.get_default_session() is not None:
    398     session = ops.get_default_session()
    399   else:
    400     if _SESSION is None:
    401       if not os.environ.get('OMP_NUM_THREADS'):
    402         config = config_pb2.ConfigProto(allow_soft_placement=True)
    403       else:
    404         num_thread = int(os.environ.get('OMP_NUM_THREADS'))
    405         config = config_pb2.ConfigProto(
    406             intra_op_parallelism_threads=num_thread, allow_soft_placement=True)
    407       _SESSION = session_module.Session(config=config)
    408     session = _SESSION
    409   if not _MANUAL_VAR_INIT:
    410     with session.graph.as_default():
    411       _initialize_variables(session)
    412   return session
    413 
    414 
    415 @tf_export('keras.backend.set_session')
    416 def set_session(session):
    417   """Sets the global TensorFlow session.
    418 
    419   Arguments:
    420       session: A TF Session.
    421   """
    422   global _SESSION
    423   _SESSION = session
    424 
    425 
    426 # DEVICE MANIPULATION
    427 
    428 
    429 class _TfDeviceCaptureOp(object):
    430   """Class for capturing the TF device scope."""
    431 
    432   def __init__(self):
    433     self.device = None
    434 
    435   def _set_device(self, device):
    436     """This method captures TF's explicit device scope setting."""
    437     self.device = device
    438 
    439 
    440 def _get_current_tf_device():
    441   """Return explicit device of current context, otherwise returns `None`.
    442 
    443   Returns:
    444       If the current device scope is explicitly set, it returns a string with
    445       the device (`CPU` or `GPU`). If the scope is not explicitly set, it will
    446       return `None`.
    447   """
    448   g = ops.get_default_graph()
    449   op = _TfDeviceCaptureOp()
    450   g._apply_device_functions(op)
    451   return op.device
    452 
    453 
    454 def _is_current_explicit_device(device_type):
    455   """Check if the current device is explicitly set on the device type specified.
    456 
    457   Arguments:
    458       device_type: A string containing `GPU` or `CPU` (case-insensitive).
    459 
    460   Returns:
    461       A boolean indicating if the current device scope is explicitly set on the
    462       device type.
    463 
    464   Raises:
    465       ValueError: If the `device_type` string indicates an unsupported device.
    466   """
    467   device_type = device_type.upper()
    468   if device_type not in ['CPU', 'GPU']:
    469     raise ValueError('device_type should be either "CPU" or "GPU".')
    470   device = _get_current_tf_device()
    471   return device is not None and device.device_type == device_type.upper()
    472 
    473 
    474 def _get_available_gpus():
    475   """Get a list of available gpu devices (formatted as strings).
    476 
    477   Returns:
    478       A list of available GPU devices.
    479   """
    480   global _LOCAL_DEVICES
    481   if _LOCAL_DEVICES is None:
    482     _LOCAL_DEVICES = get_session().list_devices()
    483   return [x.name for x in _LOCAL_DEVICES if x.device_type == 'GPU']
    484 
    485 
    486 def _has_nchw_support():
    487   """Check whether the current scope supports NCHW ops.
    488 
    489   TensorFlow does not support NCHW on CPU. Therefore we check if we are not
    490   explicitly put on
    491   CPU, and have GPUs available. In this case there will be soft-placing on the
    492   GPU device.
    493 
    494   Returns:
    495       bool: if the current scope device placement would support nchw
    496   """
    497   explicitly_on_cpu = _is_current_explicit_device('CPU')
    498   gpus_available = bool(_get_available_gpus())
    499   return not explicitly_on_cpu and gpus_available
    500 
    501 
    502 # VARIABLE MANIPULATION
    503 
    504 
    505 def _to_tensor(x, dtype):
    506   """Convert the input `x` to a tensor of type `dtype`.
    507 
    508   Arguments:
    509       x: An object to be converted (numpy array, list, tensors).
    510       dtype: The destination type.
    511 
    512   Returns:
    513       A tensor.
    514   """
    515   return ops.convert_to_tensor(x, dtype=dtype)
    516 
    517 
    518 @tf_export('keras.backend.is_sparse')
    519 def is_sparse(tensor):
    520   """Returns whether a tensor is a sparse tensor.
    521 
    522   Arguments:
    523       tensor: A tensor instance.
    524 
    525   Returns:
    526       A boolean.
    527 
    528   Example:
    529   ```python
    530       >>> from keras import backend as K
    531       >>> a = K.placeholder((2, 2), sparse=False)
    532       >>> print(K.is_sparse(a))
    533       False
    534       >>> b = K.placeholder((2, 2), sparse=True)
    535       >>> print(K.is_sparse(b))
    536       True
    537   ```
    538   """
    539   return isinstance(tensor, sparse_tensor.SparseTensor)
    540 
    541 
    542 @tf_export('keras.backend.to_dense')
    543 def to_dense(tensor):
    544   """Converts a sparse tensor into a dense tensor and returns it.
    545 
    546   Arguments:
    547       tensor: A tensor instance (potentially sparse).
    548 
    549   Returns:
    550       A dense tensor.
    551 
    552   Examples:
    553   ```python
    554       >>> from keras import backend as K
    555       >>> b = K.placeholder((2, 2), sparse=True)
    556       >>> print(K.is_sparse(b))
    557       True
    558       >>> c = K.to_dense(b)
    559       >>> print(K.is_sparse(c))
    560       False
    561   ```
    562   """
    563   if is_sparse(tensor):
    564     return sparse_ops.sparse_tensor_to_dense(tensor)
    565   else:
    566     return tensor
    567 
    568 
    569 name_scope = ops.name_scope
    570 
    571 
    572 @tf_export('keras.backend.variable')
    573 def variable(value, dtype=None, name=None, constraint=None):
    574   """Instantiates a variable and returns it.
    575 
    576   Arguments:
    577       value: Numpy array, initial value of the tensor.
    578       dtype: Tensor type.
    579       name: Optional name string for the tensor.
    580       constraint: Optional projection function to be
    581           applied to the variable after an optimizer update.
    582 
    583   Returns:
    584       A variable instance (with Keras metadata included).
    585 
    586   Examples:
    587   ```python
    588       >>> from keras import backend as K
    589       >>> val = np.array([[1, 2], [3, 4]])
    590       >>> kvar = K.variable(value=val, dtype='float64', name='example_var')
    591       >>> K.dtype(kvar)
    592       'float64'
    593       >>> print(kvar)
    594       example_var
    595       >>> kvar.eval()
    596       array([[ 1.,  2.],
    597              [ 3.,  4.]])
    598   ```
    599   """
    600   if dtype is None:
    601     dtype = floatx()
    602   if hasattr(value, 'tocoo'):
    603     sparse_coo = value.tocoo()
    604     indices = np.concatenate((np.expand_dims(sparse_coo.row, 1), np.expand_dims(
    605         sparse_coo.col, 1)), 1)
    606     v = sparse_tensor.SparseTensor(
    607         indices=indices, values=sparse_coo.data, dense_shape=sparse_coo.shape)
    608     v._keras_shape = sparse_coo.shape
    609     v._uses_learning_phase = False
    610     return v
    611   v = resource_variable_ops.ResourceVariable(
    612       value,
    613       dtype=dtypes_module.as_dtype(dtype),
    614       name=name,
    615       constraint=constraint)
    616   if isinstance(value, np.ndarray):
    617     v._keras_shape = value.shape
    618   elif hasattr(value, 'get_shape'):
    619     v._keras_shape = int_shape(value)
    620   v._uses_learning_phase = False
    621   return v
    622 
    623 
    624 def _initialize_variables(session):
    625   """Utility to initialize uninitialized variables on the fly."""
    626   variables = variables_module.global_variables()
    627   candidate_vars = []
    628   for v in variables:
    629     if not getattr(v, '_keras_initialized', False):
    630       candidate_vars.append(v)
    631   if candidate_vars:
    632     # This step is expensive, so we only run it on variables not already
    633     # marked as initialized.
    634     is_initialized = session.run(
    635         [variables_module.is_variable_initialized(v) for v in candidate_vars])
    636     uninitialized_vars = []
    637     for flag, v in zip(is_initialized, candidate_vars):
    638       if not flag:
    639         uninitialized_vars.append(v)
    640       v._keras_initialized = True
    641     if uninitialized_vars:
    642       session.run(variables_module.variables_initializer(uninitialized_vars))
    643 
    644 
    645 @tf_export('keras.backend.constant')
    646 def constant(value, dtype=None, shape=None, name=None):
    647   """Creates a constant tensor.
    648 
    649   Arguments:
    650       value: A constant value (or list)
    651       dtype: The type of the elements of the resulting tensor.
    652       shape: Optional dimensions of resulting tensor.
    653       name: Optional name for the tensor.
    654 
    655   Returns:
    656       A Constant Tensor.
    657   """
    658   if dtype is None:
    659     dtype = floatx()
    660   return constant_op.constant(value, dtype=dtype, shape=shape, name=name)
    661 
    662 
    663 def is_keras_tensor(x):
    664   """Returns whether `x` is a Keras tensor.
    665 
    666   A "Keras tensor" is a tensor that was returned by a Keras layer,
    667   (`Layer` class) or by `Input`.
    668 
    669   Arguments:
    670       x: A candidate tensor.
    671 
    672   Returns:
    673       A boolean: Whether the argument is a Keras tensor.
    674 
    675   Raises:
    676       ValueError: In case `x` is not a symbolic tensor.
    677 
    678   Examples:
    679   ```python
    680       >>> from keras import backend as K
    681       >>> from keras.layers import Input, Dense
    682       >>> np_var = numpy.array([1, 2])
    683       >>> K.is_keras_tensor(np_var) # A numpy array is not a symbolic tensor.
    684       ValueError
    685       >>> k_var = tf.placeholder('float32', shape=(1,1))
    686       >>> K.is_keras_tensor(k_var) # A variable indirectly created outside of
    687       keras is not a Keras tensor.
    688       False
    689       >>> keras_var = K.variable(np_var)
    690       >>> K.is_keras_tensor(keras_var)  # A variable created with the keras
    691       backend is not a Keras tensor.
    692       False
    693       >>> keras_placeholder = K.placeholder(shape=(2, 4, 5))
    694       >>> K.is_keras_tensor(keras_placeholder)  # A placeholder is not a Keras
    695       tensor.
    696       False
    697       >>> keras_input = Input([10])
    698       >>> K.is_keras_tensor(keras_input) # An Input is a Keras tensor.
    699       True
    700       >>> keras_layer_output = Dense(10)(keras_input)
    701       >>> K.is_keras_tensor(keras_layer_output) # Any Keras layer output is a
    702       Keras tensor.
    703       True
    704   ```
    705   """
    706   if not isinstance(x, (ops.Tensor,
    707                         variables_module.Variable,
    708                         sparse_tensor.SparseTensor)):
    709     raise ValueError('Unexpectedly found an instance of type `' + str(type(x)) +
    710                      '`. Expected a symbolic tensor instance.')
    711   return hasattr(x, '_keras_history')
    712 
    713 
    714 @tf_export('keras.backend.placeholder')
    715 def placeholder(shape=None, ndim=None, dtype=None, sparse=False, name=None):
    716   """Instantiates a placeholder tensor and returns it.
    717 
    718   Arguments:
    719       shape: Shape of the placeholder
    720           (integer tuple, may include `None` entries).
    721       ndim: Number of axes of the tensor.
    722           At least one of {`shape`, `ndim`} must be specified.
    723           If both are specified, `shape` is used.
    724       dtype: Placeholder type.
    725       sparse: Boolean, whether the placeholder should have a sparse type.
    726       name: Optional name string for the placeholder.
    727 
    728   Returns:
    729       Tensor instance (with Keras metadata included).
    730 
    731   Examples:
    732   ```python
    733       >>> from keras import backend as K
    734       >>> input_ph = K.placeholder(shape=(2, 4, 5))
    735       >>> input_ph
    736       <tf.Tensor 'Placeholder_4:0' shape=(2, 4, 5) dtype=float32>
    737   ```
    738   """
    739   if dtype is None:
    740     dtype = floatx()
    741   if not shape:
    742     if ndim:
    743       shape = tuple([None for _ in range(ndim)])
    744   if sparse:
    745     x = array_ops.sparse_placeholder(dtype, shape=shape, name=name)
    746   else:
    747     x = array_ops.placeholder(dtype, shape=shape, name=name)
    748   x._uses_learning_phase = False
    749   return x
    750 
    751 
    752 def is_placeholder(x):
    753   """Returns whether `x` is a placeholder.
    754 
    755   Arguments:
    756       x: A candidate placeholder.
    757 
    758   Returns:
    759       Boolean.
    760   """
    761   try:
    762     return x.op.type == 'Placeholder'
    763   except AttributeError:
    764     return False
    765 
    766 
    767 @tf_export('keras.backend.shape')
    768 def shape(x):
    769   """Returns the symbolic shape of a tensor or variable.
    770 
    771   Arguments:
    772       x: A tensor or variable.
    773 
    774   Returns:
    775       A symbolic shape (which is itself a tensor).
    776 
    777   Examples:
    778 
    779   ```python
    780       # TensorFlow example
    781       >>> from keras import backend as K
    782       >>> tf_session = K.get_session()
    783       >>> val = np.array([[1, 2], [3, 4]])
    784       >>> kvar = K.variable(value=val)
    785       >>> input = keras.backend.placeholder(shape=(2, 4, 5))
    786       >>> K.shape(kvar)
    787       <tf.Tensor 'Shape_8:0' shape=(2,) dtype=int32>
    788       >>> K.shape(input)
    789       <tf.Tensor 'Shape_9:0' shape=(3,) dtype=int32>
    790       # To get integer shape (Instead, you can use K.int_shape(x))
    791       >>> K.shape(kvar).eval(session=tf_session)
    792       array([2, 2], dtype=int32)
    793       >>> K.shape(input).eval(session=tf_session)
    794       array([2, 4, 5], dtype=int32)
    795   ```
    796   """
    797   return array_ops.shape(x)
    798 
    799 
    800 @tf_export('keras.backend.int_shape')
    801 def int_shape(x):
    802   """Returns the shape of tensor or variable as a tuple of int or None entries.
    803 
    804   Arguments:
    805       x: Tensor or variable.
    806 
    807   Returns:
    808       A tuple of integers (or None entries).
    809 
    810   Examples:
    811   ```python
    812       >>> from keras import backend as K
    813       >>> input = K.placeholder(shape=(2, 4, 5))
    814       >>> K.int_shape(input)
    815       (2, 4, 5)
    816       >>> val = np.array([[1, 2], [3, 4]])
    817       >>> kvar = K.variable(value=val)
    818       >>> K.int_shape(kvar)
    819       (2, 2)
    820   ```
    821   """
    822   try:
    823     return tuple(x.get_shape().as_list())
    824   except ValueError:
    825     return None
    826 
    827 
    828 @tf_export('keras.backend.ndim')
    829 def ndim(x):
    830   """Returns the number of axes in a tensor, as an integer.
    831 
    832   Arguments:
    833       x: Tensor or variable.
    834 
    835   Returns:
    836       Integer (scalar), number of axes.
    837 
    838   Examples:
    839   ```python
    840       >>> from keras import backend as K
    841       >>> input = K.placeholder(shape=(2, 4, 5))
    842       >>> val = np.array([[1, 2], [3, 4]])
    843       >>> kvar = K.variable(value=val)
    844       >>> K.ndim(input)
    845       3
    846       >>> K.ndim(kvar)
    847       2
    848   ```
    849   """
    850   dims = x.get_shape()._dims
    851   if dims is not None:
    852     return len(dims)
    853   return None
    854 
    855 
    856 @tf_export('keras.backend.dtype')
    857 def dtype(x):
    858   """Returns the dtype of a Keras tensor or variable, as a string.
    859 
    860   Arguments:
    861       x: Tensor or variable.
    862 
    863   Returns:
    864       String, dtype of `x`.
    865 
    866   Examples:
    867   ```python
    868       >>> from keras import backend as K
    869       >>> K.dtype(K.placeholder(shape=(2,4,5)))
    870       'float32'
    871       >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float32'))
    872       'float32'
    873       >>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float64'))
    874       'float64'
    875       # Keras variable
    876       >>> kvar = K.variable(np.array([[1, 2], [3, 4]]))
    877       >>> K.dtype(kvar)
    878       'float32_ref'
    879       >>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
    880       >>> K.dtype(kvar)
    881       'float32_ref'
    882   ```
    883   """
    884   return x.dtype.base_dtype.name
    885 
    886 
    887 @tf_export('keras.backend.eval')
    888 def eval(x):
    889   """Evaluates the value of a variable.
    890 
    891   Arguments:
    892       x: A variable.
    893 
    894   Returns:
    895       A Numpy array.
    896 
    897   Examples:
    898   ```python
    899       >>> from keras import backend as K
    900       >>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
    901       >>> K.eval(kvar)
    902       array([[ 1.,  2.],
    903              [ 3.,  4.]], dtype=float32)
    904   ```
    905   """
    906   return to_dense(x).eval(session=get_session())
    907 
    908 
    909 @tf_export('keras.backend.zeros')
    910 def zeros(shape, dtype=None, name=None):
    911   """Instantiates an all-zeros variable and returns it.
    912 
    913   Arguments:
    914       shape: Tuple of integers, shape of returned Keras variable
    915       dtype: String, data type of returned Keras variable
    916       name: String, name of returned Keras variable
    917 
    918   Returns:
    919       A variable (including Keras metadata), filled with `0.0`.
    920       Note that if `shape` was symbolic, we cannot return a variable,
    921       and will return a dynamically-shaped tensor instead.
    922 
    923   Example:
    924   ```python
    925       >>> from keras import backend as K
    926       >>> kvar = K.zeros((3,4))
    927       >>> K.eval(kvar)
    928       array([[ 0.,  0.,  0.,  0.],
    929              [ 0.,  0.,  0.,  0.],
    930              [ 0.,  0.,  0.,  0.]], dtype=float32)
    931   ```
    932   """
    933   if dtype is None:
    934     dtype = floatx()
    935   tf_dtype = dtypes_module.as_dtype(dtype)
    936   v = array_ops.zeros(shape=shape, dtype=tf_dtype, name=name)
    937   if py_all(v.get_shape().as_list()):
    938     return variable(v, dtype=dtype, name=name)
    939   return v
    940 
    941 
    942 @tf_export('keras.backend.ones')
    943 def ones(shape, dtype=None, name=None):
    944   """Instantiates an all-ones variable and returns it.
    945 
    946   Arguments:
    947       shape: Tuple of integers, shape of returned Keras variable.
    948       dtype: String, data type of returned Keras variable.
    949       name: String, name of returned Keras variable.
    950 
    951   Returns:
    952       A Keras variable, filled with `1.0`.
    953       Note that if `shape` was symbolic, we cannot return a variable,
    954       and will return a dynamically-shaped tensor instead.
    955 
    956   Example:
    957   ```python
    958       >>> from keras import backend as K
    959       >>> kvar = K.ones((3,4))
    960       >>> K.eval(kvar)
    961       array([[ 1.,  1.,  1.,  1.],
    962              [ 1.,  1.,  1.,  1.],
    963              [ 1.,  1.,  1.,  1.]], dtype=float32)
    964   ```
    965   """
    966   if dtype is None:
    967     dtype = floatx()
    968   tf_dtype = dtypes_module.as_dtype(dtype)
    969   v = array_ops.ones(shape=shape, dtype=tf_dtype, name=name)
    970   if py_all(v.get_shape().as_list()):
    971     return variable(v, dtype=dtype, name=name)
    972   return v
    973 
    974 
    975 @tf_export('keras.backend.eye')
    976 def eye(size, dtype=None, name=None):
    977   """Instantiate an identity matrix and returns it.
    978 
    979   Arguments:
    980       size: Integer, number of rows/columns.
    981       dtype: String, data type of returned Keras variable.
    982       name: String, name of returned Keras variable.
    983 
    984   Returns:
    985       A Keras variable, an identity matrix.
    986 
    987   Example:
    988   ```python
    989       >>> from keras import backend as K
    990       >>> kvar = K.eye(3)
    991       >>> K.eval(kvar)
    992       array([[ 1.,  0.,  0.],
    993              [ 0.,  1.,  0.],
    994              [ 0.,  0.,  1.]], dtype=float32)
    995   ```
    996 
    997   """
    998   if dtype is None:
    999     dtype = floatx()
   1000   tf_dtype = dtypes_module.as_dtype(dtype)
   1001   return variable(linalg_ops.eye(size, dtype=tf_dtype), dtype, name)
   1002 
   1003 
   1004 @tf_export('keras.backend.zeros_like')
   1005 def zeros_like(x, dtype=None, name=None):
   1006   """Instantiates an all-zeros variable of the same shape as another tensor.
   1007 
   1008   Arguments:
   1009       x: Keras variable or Keras tensor.
   1010       dtype: String, dtype of returned Keras variable.
   1011            None uses the dtype of x.
   1012       name: String, name for the variable to create.
   1013 
   1014   Returns:
   1015       A Keras variable with the shape of x filled with zeros.
   1016 
   1017   Example:
   1018   ```python
   1019       >>> from keras import backend as K
   1020       >>> kvar = K.variable(np.random.random((2,3)))
   1021       >>> kvar_zeros = K.zeros_like(kvar)
   1022       >>> K.eval(kvar_zeros)
   1023       array([[ 0.,  0.,  0.],
   1024              [ 0.,  0.,  0.]], dtype=float32)
   1025   ```
   1026   """
   1027   return array_ops.zeros_like(x, dtype=dtype, name=name)
   1028 
   1029 
   1030 @tf_export('keras.backend.ones_like')
   1031 def ones_like(x, dtype=None, name=None):
   1032   """Instantiates an all-ones variable of the same shape as another tensor.
   1033 
   1034   Arguments:
   1035       x: Keras variable or tensor.
   1036       dtype: String, dtype of returned Keras variable.
   1037            None uses the dtype of x.
   1038       name: String, name for the variable to create.
   1039 
   1040   Returns:
   1041       A Keras variable with the shape of x filled with ones.
   1042 
   1043   Example:
   1044   ```python
   1045       >>> from keras import backend as K
   1046       >>> kvar = K.variable(np.random.random((2,3)))
   1047       >>> kvar_ones = K.ones_like(kvar)
   1048       >>> K.eval(kvar_ones)
   1049       array([[ 1.,  1.,  1.],
   1050              [ 1.,  1.,  1.]], dtype=float32)
   1051   ```
   1052   """
   1053   return array_ops.ones_like(x, dtype=dtype, name=name)
   1054 
   1055 
   1056 def identity(x, name=None):
   1057   """Returns a tensor with the same content as the input tensor.
   1058 
   1059   Arguments:
   1060       x: The input tensor.
   1061       name: String, name for the variable to create.
   1062 
   1063   Returns:
   1064       A tensor of the same shape, type and content.
   1065   """
   1066   return array_ops.identity(x, name=name)
   1067 
   1068 
   1069 @tf_export('keras.backend.random_uniform_variable')
   1070 def random_uniform_variable(shape, low, high, dtype=None, name=None, seed=None):
   1071   """Instantiates a variable with values drawn from a uniform distribution.
   1072 
   1073   Arguments:
   1074       shape: Tuple of integers, shape of returned Keras variable.
   1075       low: Float, lower boundary of the output interval.
   1076       high: Float, upper boundary of the output interval.
   1077       dtype: String, dtype of returned Keras variable.
   1078       name: String, name of returned Keras variable.
   1079       seed: Integer, random seed.
   1080 
   1081   Returns:
   1082       A Keras variable, filled with drawn samples.
   1083 
   1084   Example:
   1085   ```python
   1086       # TensorFlow example
   1087       >>> kvar = K.random_uniform_variable((2,3), 0, 1)
   1088       >>> kvar
   1089       <tensorflow.python.ops.variables.Variable object at 0x10ab40b10>
   1090       >>> K.eval(kvar)
   1091       array([[ 0.10940075,  0.10047495,  0.476143  ],
   1092              [ 0.66137183,  0.00869417,  0.89220798]], dtype=float32)
   1093   ```
   1094   """
   1095   if dtype is None:
   1096     dtype = floatx()
   1097   tf_dtype = dtypes_module.as_dtype(dtype)
   1098   if seed is None:
   1099     # ensure that randomness is conditioned by the Numpy RNG
   1100     seed = np.random.randint(10e8)
   1101   value = init_ops.random_uniform_initializer(
   1102       low, high, dtype=tf_dtype, seed=seed)(shape)
   1103   return variable(value, dtype=dtype, name=name)
   1104 
   1105 
   1106 @tf_export('keras.backend.random_normal_variable')
   1107 def random_normal_variable(shape, mean, scale, dtype=None, name=None,
   1108                            seed=None):
   1109   """Instantiates a variable with values drawn from a normal distribution.
   1110 
   1111   Arguments:
   1112       shape: Tuple of integers, shape of returned Keras variable.
   1113       mean: Float, mean of the normal distribution.
   1114       scale: Float, standard deviation of the normal distribution.
   1115       dtype: String, dtype of returned Keras variable.
   1116       name: String, name of returned Keras variable.
   1117       seed: Integer, random seed.
   1118 
   1119   Returns:
   1120       A Keras variable, filled with drawn samples.
   1121 
   1122   Example:
   1123   ```python
   1124       # TensorFlow example
   1125       >>> kvar = K.random_normal_variable((2,3), 0, 1)
   1126       >>> kvar
   1127       <tensorflow.python.ops.variables.Variable object at 0x10ab12dd0>
   1128       >>> K.eval(kvar)
   1129       array([[ 1.19591331,  0.68685907, -0.63814116],
   1130              [ 0.92629528,  0.28055015,  1.70484698]], dtype=float32)
   1131   ```
   1132   """
   1133   if dtype is None:
   1134     dtype = floatx()
   1135   tf_dtype = dtypes_module.as_dtype(dtype)
   1136   if seed is None:
   1137     # ensure that randomness is conditioned by the Numpy RNG
   1138     seed = np.random.randint(10e8)
   1139   value = init_ops.random_normal_initializer(
   1140       mean, scale, dtype=tf_dtype, seed=seed)(shape)
   1141   return variable(value, dtype=dtype, name=name)
   1142 
   1143 
   1144 @tf_export('keras.backend.count_params')
   1145 def count_params(x):
   1146   """Returns the static number of elements in a variable or tensor.
   1147 
   1148   Arguments:
   1149       x: Variable or tensor.
   1150 
   1151   Returns:
   1152       Integer, the number of scalars in `x`.
   1153 
   1154   Example:
   1155   ```python
   1156       >>> kvar = K.zeros((2,3))
   1157       >>> K.count_params(kvar)
   1158       6
   1159       >>> K.eval(kvar)
   1160       array([[ 0.,  0.,  0.],
   1161              [ 0.,  0.,  0.]], dtype=float32)
   1162   ```
   1163   """
   1164   return np.prod(x.get_shape().as_list())
   1165 
   1166 
   1167 @tf_export('keras.backend.cast')
   1168 def cast(x, dtype):
   1169   """Casts a tensor to a different dtype and returns it.
   1170 
   1171   You can cast a Keras variable but it still returns a Keras tensor.
   1172 
   1173   Arguments:
   1174       x: Keras tensor (or variable).
   1175       dtype: String, either (`'float16'`, `'float32'`, or `'float64'`).
   1176 
   1177   Returns:
   1178       Keras tensor with dtype `dtype`.
   1179 
   1180   Example:
   1181   ```python
   1182       >>> from keras import backend as K
   1183       >>> input = K.placeholder((2, 3), dtype='float32')
   1184       >>> input
   1185       <tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
   1186       # It doesn't work in-place as below.
   1187       >>> K.cast(input, dtype='float16')
   1188       <tf.Tensor 'Cast_1:0' shape=(2, 3) dtype=float16>
   1189       >>> input
   1190       <tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
   1191       # you need to assign it.
   1192       >>> input = K.cast(input, dtype='float16')
   1193       >>> input
   1194       <tf.Tensor 'Cast_2:0' shape=(2, 3) dtype=float16>
   1195   ```
   1196   """
   1197   return math_ops.cast(x, dtype)
   1198 
   1199 
   1200 # UPDATES OPS
   1201 
   1202 
   1203 @tf_export('keras.backend.update')
   1204 def update(x, new_x):
   1205   return state_ops.assign(x, new_x)
   1206 
   1207 
   1208 @tf_export('keras.backend.update_add')
   1209 def update_add(x, increment):
   1210   """Update the value of `x` by adding `increment`.
   1211 
   1212   Arguments:
   1213       x: A Variable.
   1214       increment: A tensor of same shape as `x`.
   1215 
   1216   Returns:
   1217       The variable `x` updated.
   1218   """
   1219   return state_ops.assign_add(x, increment)
   1220 
   1221 
   1222 @tf_export('keras.backend.update_sub')
   1223 def update_sub(x, decrement):
   1224   """Update the value of `x` by subtracting `decrement`.
   1225 
   1226   Arguments:
   1227       x: A Variable.
   1228       decrement: A tensor of same shape as `x`.
   1229 
   1230   Returns:
   1231       The variable `x` updated.
   1232   """
   1233   return state_ops.assign_sub(x, decrement)
   1234 
   1235 
   1236 @tf_export('keras.backend.moving_average_update')
   1237 def moving_average_update(x, value, momentum):
   1238   """Compute the moving average of a variable.
   1239 
   1240   Arguments:
   1241       x: A Variable.
   1242       value: A tensor with the same shape as `variable`.
   1243       momentum: The moving average momentum.
   1244 
   1245   Returns:
   1246       An Operation to update the variable.
   1247   """
   1248   return moving_averages.assign_moving_average(
   1249       x, value, momentum, zero_debias=True)
   1250 
   1251 
   1252 # LINEAR ALGEBRA
   1253 
   1254 
   1255 @tf_export('keras.backend.dot')
   1256 def dot(x, y):
   1257   """Multiplies 2 tensors (and/or variables) and returns a *tensor*.
   1258 
   1259   When attempting to multiply a nD tensor
   1260   with a nD tensor, it reproduces the Theano behavior.
   1261   (e.g. `(2, 3) * (4, 3, 5) -> (2, 4, 5)`)
   1262 
   1263   Arguments:
   1264       x: Tensor or variable.
   1265       y: Tensor or variable.
   1266 
   1267   Returns:
   1268       A tensor, dot product of `x` and `y`.
   1269 
   1270   Examples:
   1271   ```python
   1272       # dot product between tensors
   1273       >>> x = K.placeholder(shape=(2, 3))
   1274       >>> y = K.placeholder(shape=(3, 4))
   1275       >>> xy = K.dot(x, y)
   1276       >>> xy
   1277       <tf.Tensor 'MatMul_9:0' shape=(2, 4) dtype=float32>
   1278   ```
   1279 
   1280   ```python
   1281       # dot product between tensors
   1282       >>> x = K.placeholder(shape=(32, 28, 3))
   1283       >>> y = K.placeholder(shape=(3, 4))
   1284       >>> xy = K.dot(x, y)
   1285       >>> xy
   1286       <tf.Tensor 'MatMul_9:0' shape=(32, 28, 4) dtype=float32>
   1287   ```
   1288 
   1289   ```python
   1290       # Theano-like behavior example
   1291       >>> x = K.random_uniform_variable(shape=(2, 3), low=0, high=1)
   1292       >>> y = K.ones((4, 3, 5))
   1293       >>> xy = K.dot(x, y)
   1294       >>> K.int_shape(xy)
   1295       (2, 4, 5)
   1296   ```
   1297   """
   1298   if ndim(x) is not None and (ndim(x) > 2 or ndim(y) > 2):
   1299     x_shape = []
   1300     for i, s in zip(int_shape(x), array_ops.unstack(array_ops.shape(x))):
   1301       if i is not None:
   1302         x_shape.append(i)
   1303       else:
   1304         x_shape.append(s)
   1305     x_shape = tuple(x_shape)
   1306     y_shape = []
   1307     for i, s in zip(int_shape(y), array_ops.unstack(array_ops.shape(y))):
   1308       if i is not None:
   1309         y_shape.append(i)
   1310       else:
   1311         y_shape.append(s)
   1312     y_shape = tuple(y_shape)
   1313     y_permute_dim = list(range(ndim(y)))
   1314     y_permute_dim = [y_permute_dim.pop(-2)] + y_permute_dim
   1315     xt = array_ops.reshape(x, [-1, x_shape[-1]])
   1316     yt = array_ops.reshape(
   1317         array_ops.transpose(y, perm=y_permute_dim), [y_shape[-2], -1])
   1318     return array_ops.reshape(
   1319         math_ops.matmul(xt, yt), x_shape[:-1] + y_shape[:-2] + y_shape[-1:])
   1320   if is_sparse(x):
   1321     out = sparse_ops.sparse_tensor_dense_matmul(x, y)
   1322   else:
   1323     out = math_ops.matmul(x, y)
   1324   return out
   1325 
   1326 
   1327 @tf_export('keras.backend.batch_dot')
   1328 def batch_dot(x, y, axes=None):
   1329   """Batchwise dot product.
   1330 
   1331   `batch_dot` is used to compute dot product of `x` and `y` when
   1332   `x` and `y` are data in batch, i.e. in a shape of
   1333   `(batch_size, :)`.
   1334   `batch_dot` results in a tensor or variable with less dimensions
   1335   than the input. If the number of dimensions is reduced to 1,
   1336   we use `expand_dims` to make sure that ndim is at least 2.
   1337 
   1338   Arguments:
   1339       x: Keras tensor or variable with `ndim >= 2`.
   1340       y: Keras tensor or variable with `ndim >= 2`.
   1341       axes: list of (or single) int with target dimensions.
   1342           The lengths of `axes[0]` and `axes[1]` should be the same.
   1343 
   1344   Returns:
   1345       A tensor with shape equal to the concatenation of `x`'s shape
   1346       (less the dimension that was summed over) and `y`'s shape
   1347       (less the batch dimension and the dimension that was summed over).
   1348       If the final rank is 1, we reshape it to `(batch_size, 1)`.
   1349 
   1350   Examples:
   1351       Assume `x = [[1, 2], [3, 4]]` and `y = [[5, 6], [7, 8]]`
   1352       `batch_dot(x, y, axes=1) = [[17, 53]]` which is the main diagonal
   1353       of `x.dot(y.T)`, although we never have to calculate the off-diagonal
   1354       elements.
   1355 
   1356       Shape inference:
   1357       Let `x`'s shape be `(100, 20)` and `y`'s shape be `(100, 30, 20)`.
   1358       If `axes` is (1, 2), to find the output shape of resultant tensor,
   1359           loop through each dimension in `x`'s shape and `y`'s shape:
   1360 
   1361       * `x.shape[0]` : 100 : append to output shape
   1362       * `x.shape[1]` : 20 : do not append to output shape,
   1363           dimension 1 of `x` has been summed over. (`dot_axes[0]` = 1)
   1364       * `y.shape[0]` : 100 : do not append to output shape,
   1365           always ignore first dimension of `y`
   1366       * `y.shape[1]` : 30 : append to output shape
   1367       * `y.shape[2]` : 20 : do not append to output shape,
   1368           dimension 2 of `y` has been summed over. (`dot_axes[1]` = 2)
   1369       `output_shape` = `(100, 30)`
   1370 
   1371   ```python
   1372       >>> x_batch = K.ones(shape=(32, 20, 1))
   1373       >>> y_batch = K.ones(shape=(32, 30, 20))
   1374       >>> xy_batch_dot = K.batch_dot(x_batch, y_batch, axes=[1, 2])
   1375       >>> K.int_shape(xy_batch_dot)
   1376       (32, 1, 30)
   1377   ```
   1378   """
   1379   if isinstance(axes, int):
   1380     axes = (axes, axes)
   1381   x_ndim = ndim(x)
   1382   y_ndim = ndim(y)
   1383   if x_ndim > y_ndim:
   1384     diff = x_ndim - y_ndim
   1385     y = array_ops.reshape(y,
   1386                           array_ops.concat(
   1387                               [array_ops.shape(y), [1] * (diff)], axis=0))
   1388   elif y_ndim > x_ndim:
   1389     diff = y_ndim - x_ndim
   1390     x = array_ops.reshape(x,
   1391                           array_ops.concat(
   1392                               [array_ops.shape(x), [1] * (diff)], axis=0))
   1393   else:
   1394     diff = 0
   1395   if ndim(x) == 2 and ndim(y) == 2:
   1396     if axes[0] == axes[1]:
   1397       out = math_ops.reduce_sum(math_ops.multiply(x, y), axes[0])
   1398     else:
   1399       out = math_ops.reduce_sum(
   1400           math_ops.multiply(array_ops.transpose(x, [1, 0]), y), axes[1])
   1401   else:
   1402     if axes is not None:
   1403       adj_x = None if axes[0] == ndim(x) - 1 else True
   1404       adj_y = True if axes[1] == ndim(y) - 1 else None
   1405     else:
   1406       adj_x = None
   1407       adj_y = None
   1408     out = math_ops.matmul(x, y, adjoint_a=adj_x, adjoint_b=adj_y)
   1409   if diff:
   1410     if x_ndim > y_ndim:
   1411       idx = x_ndim + y_ndim - 3
   1412     else:
   1413       idx = x_ndim - 1
   1414     out = array_ops.squeeze(out, list(range(idx, idx + diff)))
   1415   if ndim(out) == 1:
   1416     out = expand_dims(out, 1)
   1417   return out
   1418 
   1419 
   1420 @tf_export('keras.backend.transpose')
   1421 def transpose(x):
   1422   """Transposes a tensor and returns it.
   1423 
   1424   Arguments:
   1425       x: Tensor or variable.
   1426 
   1427   Returns:
   1428       A tensor.
   1429 
   1430   Examples:
   1431   ```python
   1432       >>> var = K.variable([[1, 2, 3], [4, 5, 6]])
   1433       >>> K.eval(var)
   1434       array([[ 1.,  2.,  3.],
   1435              [ 4.,  5.,  6.]], dtype=float32)
   1436       >>> var_transposed = K.transpose(var)
   1437       >>> K.eval(var_transposed)
   1438       array([[ 1.,  4.],
   1439              [ 2.,  5.],
   1440              [ 3.,  6.]], dtype=float32)
   1441   ```
   1442 
   1443   ```python
   1444       >>> input = K.placeholder((2, 3))
   1445       >>> input
   1446       <tf.Tensor 'Placeholder_11:0' shape=(2, 3) dtype=float32>
   1447       >>> input_transposed = K.transpose(input)
   1448       >>> input_transposed
   1449       <tf.Tensor 'transpose_4:0' shape=(3, 2) dtype=float32>
   1450 
   1451   ```
   1452   """
   1453   return array_ops.transpose(x)
   1454 
   1455 
   1456 @tf_export('keras.backend.gather')
   1457 def gather(reference, indices):
   1458   """Retrieves the elements of indices `indices` in the tensor `reference`.
   1459 
   1460   Arguments:
   1461       reference: A tensor.
   1462       indices: An integer tensor of indices.
   1463 
   1464   Returns:
   1465       A tensor of same type as `reference`.
   1466   """
   1467   return array_ops.gather(reference, indices)
   1468 
   1469 
   1470 # ELEMENT-WISE OPERATIONS
   1471 
   1472 
   1473 @tf_export('keras.backend.max')
   1474 def max(x, axis=None, keepdims=False):
   1475   """Maximum value in a tensor.
   1476 
   1477   Arguments:
   1478       x: A tensor or variable.
   1479       axis: An integer, the axis to find maximum values.
   1480       keepdims: A boolean, whether to keep the dimensions or not.
   1481           If `keepdims` is `False`, the rank of the tensor is reduced
   1482           by 1. If `keepdims` is `True`,
   1483           the reduced dimension is retained with length 1.
   1484 
   1485   Returns:
   1486       A tensor with maximum values of `x`.
   1487   """
   1488   return math_ops.reduce_max(x, axis, keepdims)
   1489 
   1490 
   1491 @tf_export('keras.backend.min')
   1492 def min(x, axis=None, keepdims=False):
   1493   """Minimum value in a tensor.
   1494 
   1495   Arguments:
   1496       x: A tensor or variable.
   1497       axis: An integer, the axis to find minimum values.
   1498       keepdims: A boolean, whether to keep the dimensions or not.
   1499           If `keepdims` is `False`, the rank of the tensor is reduced
   1500           by 1. If `keepdims` is `True`,
   1501           the reduced dimension is retained with length 1.
   1502 
   1503   Returns:
   1504       A tensor with miminum values of `x`.
   1505   """
   1506   return math_ops.reduce_min(x, axis, keepdims)
   1507 
   1508 
   1509 @tf_export('keras.backend.sum')
   1510 def sum(x, axis=None, keepdims=False):
   1511   """Sum of the values in a tensor, alongside the specified axis.
   1512 
   1513   Arguments:
   1514       x: A tensor or variable.
   1515       axis: An integer, the axis to sum over.
   1516       keepdims: A boolean, whether to keep the dimensions or not.
   1517           If `keepdims` is `False`, the rank of the tensor is reduced
   1518           by 1. If `keepdims` is `True`,
   1519           the reduced dimension is retained with length 1.
   1520 
   1521   Returns:
   1522       A tensor with sum of `x`.
   1523   """
   1524   return math_ops.reduce_sum(x, axis, keepdims)
   1525 
   1526 
   1527 @tf_export('keras.backend.prod')
   1528 def prod(x, axis=None, keepdims=False):
   1529   """Multiplies the values in a tensor, alongside the specified axis.
   1530 
   1531   Arguments:
   1532       x: A tensor or variable.
   1533       axis: An integer, the axis to compute the product.
   1534       keepdims: A boolean, whether to keep the dimensions or not.
   1535           If `keepdims` is `False`, the rank of the tensor is reduced
   1536           by 1. If `keepdims` is `True`,
   1537           the reduced dimension is retained with length 1.
   1538 
   1539   Returns:
   1540       A tensor with the product of elements of `x`.
   1541   """
   1542   return math_ops.reduce_prod(x, axis, keepdims)
   1543 
   1544 
   1545 def cumsum(x, axis=0):
   1546   """Cumulative sum of the values in a tensor, alongside the specified axis.
   1547 
   1548   Arguments:
   1549       x: A tensor or variable.
   1550       axis: An integer, the axis to compute the sum.
   1551 
   1552   Returns:
   1553       A tensor of the cumulative sum of values of `x` along `axis`.
   1554   """
   1555   return math_ops.cumsum(x, axis=axis)
   1556 
   1557 
   1558 def cumprod(x, axis=0):
   1559   """Cumulative product of the values in a tensor, alongside the specified axis.
   1560 
   1561   Arguments:
   1562       x: A tensor or variable.
   1563       axis: An integer, the axis to compute the product.
   1564 
   1565   Returns:
   1566       A tensor of the cumulative product of values of `x` along `axis`.
   1567   """
   1568   return math_ops.cumprod(x, axis=axis)
   1569 
   1570 
   1571 @tf_export('keras.backend.var')
   1572 def var(x, axis=None, keepdims=False):
   1573   """Variance of a tensor, alongside the specified axis.
   1574 
   1575   Arguments:
   1576       x: A tensor or variable.
   1577       axis: An integer, the axis to compute the variance.
   1578       keepdims: A boolean, whether to keep the dimensions or not.
   1579           If `keepdims` is `False`, the rank of the tensor is reduced
   1580           by 1. If `keepdims` is `True`,
   1581           the reduced dimension is retained with length 1.
   1582 
   1583   Returns:
   1584       A tensor with the variance of elements of `x`.
   1585   """
   1586   if x.dtype.base_dtype == dtypes_module.bool:
   1587     x = math_ops.cast(x, floatx())
   1588   m = math_ops.reduce_mean(x, axis, True)
   1589   devs_squared = math_ops.square(x - m)
   1590   return math_ops.reduce_mean(
   1591       devs_squared, axis, keepdims)
   1592 
   1593 
   1594 @tf_export('keras.backend.std')
   1595 def std(x, axis=None, keepdims=False):
   1596   """Standard deviation of a tensor, alongside the specified axis.
   1597 
   1598   Arguments:
   1599       x: A tensor or variable.
   1600       axis: An integer, the axis to compute the standard deviation.
   1601       keepdims: A boolean, whether to keep the dimensions or not.
   1602           If `keepdims` is `False`, the rank of the tensor is reduced
   1603           by 1. If `keepdims` is `True`,
   1604           the reduced dimension is retained with length 1.
   1605 
   1606   Returns:
   1607       A tensor with the standard deviation of elements of `x`.
   1608   """
   1609   return math_ops.sqrt(var(x, axis=axis, keepdims=keepdims))
   1610 
   1611 
   1612 @tf_export('keras.backend.mean')
   1613 def mean(x, axis=None, keepdims=False):
   1614   """Mean of a tensor, alongside the specified axis.
   1615 
   1616   Arguments:
   1617       x: A tensor or variable.
   1618       axis: A list of integer. Axes to compute the mean.
   1619       keepdims: A boolean, whether to keep the dimensions or not.
   1620           If `keepdims` is `False`, the rank of the tensor is reduced
   1621           by 1 for each entry in `axis`. If `keepdims` is `True`,
   1622           the reduced dimensions are retained with length 1.
   1623 
   1624   Returns:
   1625       A tensor with the mean of elements of `x`.
   1626   """
   1627   if x.dtype.base_dtype == dtypes_module.bool:
   1628     x = math_ops.cast(x, floatx())
   1629   return math_ops.reduce_mean(x, axis, keepdims)
   1630 
   1631 
   1632 @tf_export('keras.backend.any')
   1633 def any(x, axis=None, keepdims=False):
   1634   """Bitwise reduction (logical OR).
   1635 
   1636   Arguments:
   1637       x: Tensor or variable.
   1638       axis: axis along which to perform the reduction.
   1639       keepdims: whether the drop or broadcast the reduction axes.
   1640 
   1641   Returns:
   1642       A uint8 tensor (0s and 1s).
   1643   """
   1644   x = math_ops.cast(x, dtypes_module.bool)
   1645   return math_ops.reduce_any(x, axis, keepdims)
   1646 
   1647 
   1648 @tf_export('keras.backend.all')
   1649 def all(x, axis=None, keepdims=False):
   1650   """Bitwise reduction (logical AND).
   1651 
   1652   Arguments:
   1653       x: Tensor or variable.
   1654       axis: axis along which to perform the reduction.
   1655       keepdims: whether the drop or broadcast the reduction axes.
   1656 
   1657   Returns:
   1658       A uint8 tensor (0s and 1s).
   1659   """
   1660   x = math_ops.cast(x, dtypes_module.bool)
   1661   return math_ops.reduce_all(x, axis, keepdims)
   1662 
   1663 
   1664 @tf_export('keras.backend.argmax')
   1665 def argmax(x, axis=-1):
   1666   """Returns the index of the maximum value along an axis.
   1667 
   1668   Arguments:
   1669       x: Tensor or variable.
   1670       axis: axis along which to perform the reduction.
   1671 
   1672   Returns:
   1673       A tensor.
   1674   """
   1675   return math_ops.argmax(x, axis)
   1676 
   1677 
   1678 @tf_export('keras.backend.argmin')
   1679 def argmin(x, axis=-1):
   1680   """Returns the index of the minimum value along an axis.
   1681 
   1682   Arguments:
   1683       x: Tensor or variable.
   1684       axis: axis along which to perform the reduction.
   1685 
   1686   Returns:
   1687       A tensor.
   1688   """
   1689   return math_ops.argmin(x, axis)
   1690 
   1691 
   1692 @tf_export('keras.backend.square')
   1693 def square(x):
   1694   """Element-wise square.
   1695 
   1696   Arguments:
   1697       x: Tensor or variable.
   1698 
   1699   Returns:
   1700       A tensor.
   1701   """
   1702   return math_ops.square(x)
   1703 
   1704 
   1705 @tf_export('keras.backend.abs')
   1706 def abs(x):
   1707   """Element-wise absolute value.
   1708 
   1709   Arguments:
   1710       x: Tensor or variable.
   1711 
   1712   Returns:
   1713       A tensor.
   1714   """
   1715   return math_ops.abs(x)
   1716 
   1717 
   1718 @tf_export('keras.backend.sqrt')
   1719 def sqrt(x):
   1720   """Element-wise square root.
   1721 
   1722   Arguments:
   1723       x: Tensor or variable.
   1724 
   1725   Returns:
   1726       A tensor.
   1727   """
   1728   zero = _to_tensor(0., x.dtype.base_dtype)
   1729   inf = _to_tensor(np.inf, x.dtype.base_dtype)
   1730   x = clip_ops.clip_by_value(x, zero, inf)
   1731   return math_ops.sqrt(x)
   1732 
   1733 
   1734 @tf_export('keras.backend.exp')
   1735 def exp(x):
   1736   """Element-wise exponential.
   1737 
   1738   Arguments:
   1739       x: Tensor or variable.
   1740 
   1741   Returns:
   1742       A tensor.
   1743   """
   1744   return math_ops.exp(x)
   1745 
   1746 
   1747 @tf_export('keras.backend.log')
   1748 def log(x):
   1749   """Element-wise log.
   1750 
   1751   Arguments:
   1752       x: Tensor or variable.
   1753 
   1754   Returns:
   1755       A tensor.
   1756   """
   1757   return math_ops.log(x)
   1758 
   1759 
   1760 def logsumexp(x, axis=None, keepdims=False):
   1761   """Computes log(sum(exp(elements across dimensions of a tensor))).
   1762 
   1763   This function is more numerically stable than log(sum(exp(x))).
   1764   It avoids overflows caused by taking the exp of large inputs and
   1765   underflows caused by taking the log of small inputs.
   1766 
   1767   Arguments:
   1768       x: A tensor or variable.
   1769       axis: An integer, the axis to reduce over.
   1770       keepdims: A boolean, whether to keep the dimensions or not.
   1771           If `keepdims` is `False`, the rank of the tensor is reduced
   1772           by 1. If `keepdims` is `True`, the reduced dimension is
   1773           retained with length 1.
   1774 
   1775   Returns:
   1776       The reduced tensor.
   1777   """
   1778   return math_ops.reduce_logsumexp(x, axis, keepdims)
   1779 
   1780 
   1781 @tf_export('keras.backend.round')
   1782 def round(x):
   1783   """Element-wise rounding to the closest integer.
   1784 
   1785   In case of tie, the rounding mode used is "half to even".
   1786 
   1787   Arguments:
   1788       x: Tensor or variable.
   1789 
   1790   Returns:
   1791       A tensor.
   1792   """
   1793   return math_ops.round(x)
   1794 
   1795 
   1796 @tf_export('keras.backend.sign')
   1797 def sign(x):
   1798   """Element-wise sign.
   1799 
   1800   Arguments:
   1801       x: Tensor or variable.
   1802 
   1803   Returns:
   1804       A tensor.
   1805   """
   1806   return math_ops.sign(x)
   1807 
   1808 
   1809 @tf_export('keras.backend.pow')
   1810 def pow(x, a):
   1811   """Element-wise exponentiation.
   1812 
   1813   Arguments:
   1814       x: Tensor or variable.
   1815       a: Python integer.
   1816 
   1817   Returns:
   1818       A tensor.
   1819   """
   1820   return math_ops.pow(x, a)
   1821 
   1822 
   1823 @tf_export('keras.backend.clip')
   1824 def clip(x, min_value, max_value):
   1825   """Element-wise value clipping.
   1826 
   1827   Arguments:
   1828       x: Tensor or variable.
   1829       min_value: Python float or integer.
   1830       max_value: Python float or integer.
   1831 
   1832   Returns:
   1833       A tensor.
   1834   """
   1835   if max_value is not None and max_value < min_value:
   1836     max_value = min_value
   1837   if max_value is None:
   1838     max_value = np.inf
   1839   min_value = _to_tensor(min_value, x.dtype.base_dtype)
   1840   max_value = _to_tensor(max_value, x.dtype.base_dtype)
   1841   return clip_ops.clip_by_value(x, min_value, max_value)
   1842 
   1843 
   1844 @tf_export('keras.backend.equal')
   1845 def equal(x, y):
   1846   """Element-wise equality between two tensors.
   1847 
   1848   Arguments:
   1849       x: Tensor or variable.
   1850       y: Tensor or variable.
   1851 
   1852   Returns:
   1853       A bool tensor.
   1854   """
   1855   return math_ops.equal(x, y)
   1856 
   1857 
   1858 @tf_export('keras.backend.not_equal')
   1859 def not_equal(x, y):
   1860   """Element-wise inequality between two tensors.
   1861 
   1862   Arguments:
   1863       x: Tensor or variable.
   1864       y: Tensor or variable.
   1865 
   1866   Returns:
   1867       A bool tensor.
   1868   """
   1869   return math_ops.not_equal(x, y)
   1870 
   1871 
   1872 @tf_export('keras.backend.greater')
   1873 def greater(x, y):
   1874   """Element-wise truth value of (x > y).
   1875 
   1876   Arguments:
   1877       x: Tensor or variable.
   1878       y: Tensor or variable.
   1879 
   1880   Returns:
   1881       A bool tensor.
   1882   """
   1883   return math_ops.greater(x, y)
   1884 
   1885 
   1886 @tf_export('keras.backend.greater_equal')
   1887 def greater_equal(x, y):
   1888   """Element-wise truth value of (x >= y).
   1889 
   1890   Arguments:
   1891       x: Tensor or variable.
   1892       y: Tensor or variable.
   1893 
   1894   Returns:
   1895       A bool tensor.
   1896   """
   1897   return math_ops.greater_equal(x, y)
   1898 
   1899 
   1900 @tf_export('keras.backend.less')
   1901 def less(x, y):
   1902   """Element-wise truth value of (x < y).
   1903 
   1904   Arguments:
   1905       x: Tensor or variable.
   1906       y: Tensor or variable.
   1907 
   1908   Returns:
   1909       A bool tensor.
   1910   """
   1911   return math_ops.less(x, y)
   1912 
   1913 
   1914 @tf_export('keras.backend.less_equal')
   1915 def less_equal(x, y):
   1916   """Element-wise truth value of (x <= y).
   1917 
   1918   Arguments:
   1919       x: Tensor or variable.
   1920       y: Tensor or variable.
   1921 
   1922   Returns:
   1923       A bool tensor.
   1924   """
   1925   return math_ops.less_equal(x, y)
   1926 
   1927 
   1928 @tf_export('keras.backend.maximum')
   1929 def maximum(x, y):
   1930   """Element-wise maximum of two tensors.
   1931 
   1932   Arguments:
   1933       x: Tensor or variable.
   1934       y: Tensor or variable.
   1935 
   1936   Returns:
   1937       A tensor.
   1938   """
   1939   return math_ops.maximum(x, y)
   1940 
   1941 
   1942 @tf_export('keras.backend.minimum')
   1943 def minimum(x, y):
   1944   """Element-wise minimum of two tensors.
   1945 
   1946   Arguments:
   1947       x: Tensor or variable.
   1948       y: Tensor or variable.
   1949 
   1950   Returns:
   1951       A tensor.
   1952   """
   1953   return math_ops.minimum(x, y)
   1954 
   1955 
   1956 @tf_export('keras.backend.sin')
   1957 def sin(x):
   1958   """Computes sin of x element-wise.
   1959 
   1960   Arguments:
   1961       x: Tensor or variable.
   1962 
   1963   Returns:
   1964       A tensor.
   1965   """
   1966   return math_ops.sin(x)
   1967 
   1968 
   1969 @tf_export('keras.backend.cos')
   1970 def cos(x):
   1971   """Computes cos of x element-wise.
   1972 
   1973   Arguments:
   1974       x: Tensor or variable.
   1975 
   1976   Returns:
   1977       A tensor.
   1978   """
   1979   return math_ops.cos(x)
   1980 
   1981 
   1982 def _regular_normalize_batch_in_training(x,
   1983                                          gamma,
   1984                                          beta,
   1985                                          reduction_axes,
   1986                                          epsilon=1e-3):
   1987   """Non-fused version of `normalize_batch_in_training`.
   1988 
   1989   Arguments:
   1990       x: Input tensor or variable.
   1991       gamma: Tensor by which to scale the input.
   1992       beta: Tensor with which to center the input.
   1993       reduction_axes: iterable of integers,
   1994           axes over which to normalize.
   1995       epsilon: Fuzz factor.
   1996 
   1997   Returns:
   1998       A tuple length of 3, `(normalized_tensor, mean, variance)`.
   1999   """
   2000   mean, var = nn.moments(x, reduction_axes, None, None, False)
   2001   normed = nn.batch_normalization(x, mean, var, beta, gamma, epsilon)
   2002   return normed, mean, var
   2003 
   2004 
   2005 def _broadcast_normalize_batch_in_training(x,
   2006                                            gamma,
   2007                                            beta,
   2008                                            reduction_axes,
   2009                                            epsilon=1e-3):
   2010   """Non-fused, broadcast version of `normalize_batch_in_training`.
   2011 
   2012   Arguments:
   2013       x: Input tensor or variable.
   2014       gamma: Tensor by which to scale the input.
   2015       beta: Tensor with which to center the input.
   2016       reduction_axes: iterable of integers,
   2017           axes over which to normalize.
   2018       epsilon: Fuzz factor.
   2019 
   2020   Returns:
   2021       A tuple length of 3, `(normalized_tensor, mean, variance)`.
   2022   """
   2023   mean, var = nn.moments(x, reduction_axes, None, None, False)
   2024   target_shape = []
   2025   for axis in range(ndim(x)):
   2026     if axis in reduction_axes:
   2027       target_shape.append(1)
   2028     else:
   2029       target_shape.append(array_ops.shape(x)[axis])
   2030   target_shape = array_ops.stack(target_shape)
   2031 
   2032   broadcast_mean = array_ops.reshape(mean, target_shape)
   2033   broadcast_var = array_ops.reshape(var, target_shape)
   2034   if gamma is None:
   2035     broadcast_gamma = None
   2036   else:
   2037     broadcast_gamma = array_ops.reshape(gamma, target_shape)
   2038   if beta is None:
   2039     broadcast_beta = None
   2040   else:
   2041     broadcast_beta = array_ops.reshape(beta, target_shape)
   2042 
   2043   normed = nn.batch_normalization(x, broadcast_mean, broadcast_var,
   2044                                   broadcast_beta, broadcast_gamma, epsilon)
   2045   return normed, mean, var
   2046 
   2047 
   2048 def _fused_normalize_batch_in_training(x,
   2049                                        gamma,
   2050                                        beta,
   2051                                        reduction_axes,
   2052                                        epsilon=1e-3):
   2053   """Fused version of `normalize_batch_in_training`.
   2054 
   2055   Arguments:
   2056       x: Input tensor or variable.
   2057       gamma: Tensor by which to scale the input.
   2058       beta: Tensor with which to center the input.
   2059       reduction_axes: iterable of integers,
   2060           axes over which to normalize.
   2061       epsilon: Fuzz factor.
   2062 
   2063   Returns:
   2064       A tuple length of 3, `(normalized_tensor, mean, variance)`.
   2065   """
   2066   if list(reduction_axes) == [0, 1, 2]:
   2067     normalization_axis = 3
   2068     tf_data_format = 'NHWC'
   2069   else:
   2070     normalization_axis = 1
   2071     tf_data_format = 'NCHW'
   2072 
   2073   if gamma is None:
   2074     gamma = constant_op.constant(
   2075         1.0, dtype=x.dtype, shape=[x.get_shape()[normalization_axis]])
   2076   if beta is None:
   2077     beta = constant_op.constant(
   2078         0.0, dtype=x.dtype, shape=[x.get_shape()[normalization_axis]])
   2079 
   2080   return nn.fused_batch_norm(
   2081       x, gamma, beta, epsilon=epsilon, data_format=tf_data_format)
   2082 
   2083 
   2084 @tf_export('keras.backend.normalize_batch_in_training')
   2085 def normalize_batch_in_training(x, gamma, beta, reduction_axes, epsilon=1e-3):
   2086   """Computes mean and std for batch then apply batch_normalization on batch.
   2087 
   2088   Arguments:
   2089       x: Input tensor or variable.
   2090       gamma: Tensor by which to scale the input.
   2091       beta: Tensor with which to center the input.
   2092       reduction_axes: iterable of integers,
   2093           axes over which to normalize.
   2094       epsilon: Fuzz factor.
   2095 
   2096   Returns:
   2097       A tuple length of 3, `(normalized_tensor, mean, variance)`.
   2098   """
   2099   if ndim(x) == 4 and list(reduction_axes) in [[0, 1, 2], [0, 2, 3]]:
   2100     if not _has_nchw_support() and list(reduction_axes) == [0, 2, 3]:
   2101       return _broadcast_normalize_batch_in_training(
   2102           x, gamma, beta, reduction_axes, epsilon=epsilon)
   2103     return _fused_normalize_batch_in_training(
   2104         x, gamma, beta, reduction_axes, epsilon=epsilon)
   2105   else:
   2106     if sorted(reduction_axes) == list(range(ndim(x)))[:-1]:
   2107       return _regular_normalize_batch_in_training(
   2108           x, gamma, beta, reduction_axes, epsilon=epsilon)
   2109     else:
   2110       return _broadcast_normalize_batch_in_training(
   2111           x, gamma, beta, reduction_axes, epsilon=epsilon)
   2112 
   2113 
   2114 @tf_export('keras.backend.batch_normalization')
   2115 def batch_normalization(x, mean, var, beta, gamma, epsilon=1e-3):
   2116   """Applies batch normalization on x given mean, var, beta and gamma.
   2117 
   2118   I.e. returns:
   2119   `output = (x - mean) / (sqrt(var) + epsilon) * gamma + beta`
   2120 
   2121   Arguments:
   2122       x: Input tensor or variable.
   2123       mean: Mean of batch.
   2124       var: Variance of batch.
   2125       beta: Tensor with which to center the input.
   2126       gamma: Tensor by which to scale the input.
   2127       epsilon: Fuzz factor.
   2128 
   2129   Returns:
   2130       A tensor.
   2131   """
   2132   return nn.batch_normalization(x, mean, var, beta, gamma, epsilon)
   2133 
   2134 
   2135 # SHAPE OPERATIONS
   2136 
   2137 
   2138 @tf_export('keras.backend.concatenate')
   2139 def concatenate(tensors, axis=-1):
   2140   """Concatenates a list of tensors alongside the specified axis.
   2141 
   2142   Arguments:
   2143       tensors: list of tensors to concatenate.
   2144       axis: concatenation axis.
   2145 
   2146   Returns:
   2147       A tensor.
   2148   """
   2149   if axis < 0:
   2150     rank = ndim(tensors[0])
   2151     if rank:
   2152       axis %= rank
   2153     else:
   2154       axis = 0
   2155 
   2156   if py_all([is_sparse(x) for x in tensors]):
   2157     return sparse_ops.sparse_concat(axis, tensors)
   2158   else:
   2159     return array_ops.concat([to_dense(x) for x in tensors], axis)
   2160 
   2161 
   2162 @tf_export('keras.backend.reshape')
   2163 def reshape(x, shape):
   2164   """Reshapes a tensor to the specified shape.
   2165 
   2166   Arguments:
   2167       x: Tensor or variable.
   2168       shape: Target shape tuple.
   2169 
   2170   Returns:
   2171       A tensor.
   2172   """
   2173   return array_ops.reshape(x, shape)
   2174 
   2175 
   2176 @tf_export('keras.backend.permute_dimensions')
   2177 def permute_dimensions(x, pattern):
   2178   """Permutes axes in a tensor.
   2179 
   2180   Arguments:
   2181       x: Tensor or variable.
   2182       pattern: A tuple of
   2183           dimension indices, e.g. `(0, 2, 1)`.
   2184 
   2185   Returns:
   2186       A tensor.
   2187   """
   2188   return array_ops.transpose(x, perm=pattern)
   2189 
   2190 
   2191 @tf_export('keras.backend.resize_images')
   2192 def resize_images(x, height_factor, width_factor, data_format):
   2193   """Resizes the images contained in a 4D tensor.
   2194 
   2195   Arguments:
   2196       x: Tensor or variable to resize.
   2197       height_factor: Positive integer.
   2198       width_factor: Positive integer.
   2199       data_format: One of `"channels_first"`, `"channels_last"`.
   2200 
   2201   Returns:
   2202       A tensor.
   2203 
   2204   Raises:
   2205       ValueError: if `data_format` is neither
   2206           `channels_last` or `channels_first`.
   2207   """
   2208   if data_format == 'channels_first':
   2209     original_shape = int_shape(x)
   2210     new_shape = array_ops.shape(x)[2:]
   2211     new_shape *= constant_op.constant(
   2212         np.array([height_factor, width_factor]).astype('int32'))
   2213     x = permute_dimensions(x, [0, 2, 3, 1])
   2214     x = image_ops.resize_nearest_neighbor(x, new_shape)
   2215     x = permute_dimensions(x, [0, 3, 1, 2])
   2216     x.set_shape((None, None, original_shape[2] * height_factor
   2217                  if original_shape[2] is not None else None,
   2218                  original_shape[3] * width_factor
   2219                  if original_shape[3] is not None else None))
   2220     return x
   2221   elif data_format == 'channels_last':
   2222     original_shape = int_shape(x)
   2223     new_shape = array_ops.shape(x)[1:3]
   2224     new_shape *= constant_op.constant(
   2225         np.array([height_factor, width_factor]).astype('int32'))
   2226     x = image_ops.resize_nearest_neighbor(x, new_shape)
   2227     x.set_shape((None, original_shape[1] * height_factor
   2228                  if original_shape[1] is not None else None,
   2229                  original_shape[2] * width_factor
   2230                  if original_shape[2] is not None else None, None))
   2231     return x
   2232   else:
   2233     raise ValueError('Invalid data_format: ' + str(data_format))
   2234 
   2235 
   2236 @tf_export('keras.backend.resize_volumes')
   2237 def resize_volumes(x, depth_factor, height_factor, width_factor, data_format):
   2238   """Resizes the volume contained in a 5D tensor.
   2239 
   2240   Arguments:
   2241       x: Tensor or variable to resize.
   2242       depth_factor: Positive integer.
   2243       height_factor: Positive integer.
   2244       width_factor: Positive integer.
   2245       data_format: One of `"channels_first"`, `"channels_last"`.
   2246 
   2247   Returns:
   2248       A tensor.
   2249 
   2250   Raises:
   2251       ValueError: if `data_format` is neither
   2252           `channels_last` or `channels_first`.
   2253   """
   2254   if data_format == 'channels_first':
   2255     output = repeat_elements(x, depth_factor, axis=2)
   2256     output = repeat_elements(output, height_factor, axis=3)
   2257     output = repeat_elements(output, width_factor, axis=4)
   2258     return output
   2259   elif data_format == 'channels_last':
   2260     output = repeat_elements(x, depth_factor, axis=1)
   2261     output = repeat_elements(output, height_factor, axis=2)
   2262     output = repeat_elements(output, width_factor, axis=3)
   2263     return output
   2264   else:
   2265     raise ValueError('Invalid data_format: ' + str(data_format))
   2266 
   2267 
   2268 @tf_export('keras.backend.repeat_elements')
   2269 def repeat_elements(x, rep, axis):
   2270   """Repeats the elements of a tensor along an axis, like `np.repeat`.
   2271 
   2272   If `x` has shape `(s1, s2, s3)` and `axis` is `1`, the output
   2273   will have shape `(s1, s2 * rep, s3)`.
   2274 
   2275   Arguments:
   2276       x: Tensor or variable.
   2277       rep: Python integer, number of times to repeat.
   2278       axis: Axis along which to repeat.
   2279 
   2280   Returns:
   2281       A tensor.
   2282   """
   2283   x_shape = x.get_shape().as_list()
   2284   # For static axis
   2285   if x_shape[axis] is not None:
   2286     # slices along the repeat axis
   2287     splits = array_ops.split(value=x,
   2288                              num_or_size_splits=x_shape[axis],
   2289                              axis=axis)
   2290     # repeat each slice the given number of reps
   2291     x_rep = [s for s in splits for _ in range(rep)]
   2292     return concatenate(x_rep, axis)
   2293 
   2294   # Here we use tf.tile to mimic behavior of np.repeat so that
   2295   # we can handle dynamic shapes (that include None).
   2296   # To do that, we need an auxiliary axis to repeat elements along
   2297   # it and then merge them along the desired axis.
   2298 
   2299   # Repeating
   2300   auxiliary_axis = axis + 1
   2301   x_shape = array_ops.shape(x)
   2302   x_rep = array_ops.expand_dims(x, axis=auxiliary_axis)
   2303   reps = np.ones(len(x.get_shape()) + 1)
   2304   reps[auxiliary_axis] = rep
   2305   x_rep = array_ops.tile(x_rep, reps)
   2306 
   2307   # Merging
   2308   reps = np.delete(reps, auxiliary_axis)
   2309   reps[axis] = rep
   2310   reps = array_ops.constant(reps, dtype='int32')
   2311   x_shape *= reps
   2312   x_rep = array_ops.reshape(x_rep, x_shape)
   2313 
   2314   # Fix shape representation
   2315   x_shape = x.get_shape().as_list()
   2316   x_rep.set_shape(x_shape)
   2317   x_rep._keras_shape = tuple(x_shape)
   2318   return x_rep
   2319 
   2320 
   2321 @tf_export('keras.backend.repeat')
   2322 def repeat(x, n):
   2323   """Repeats a 2D tensor.
   2324 
   2325   if `x` has shape (samples, dim) and `n` is `2`,
   2326   the output will have shape `(samples, 2, dim)`.
   2327 
   2328   Arguments:
   2329       x: Tensor or variable.
   2330       n: Python integer, number of times to repeat.
   2331 
   2332   Returns:
   2333       A tensor.
   2334   """
   2335   assert ndim(x) == 2
   2336   x = array_ops.expand_dims(x, 1)
   2337   pattern = array_ops.stack([1, n, 1])
   2338   return array_ops.tile(x, pattern)
   2339 
   2340 
   2341 @tf_export('keras.backend.arange')
   2342 def arange(start, stop=None, step=1, dtype='int32'):
   2343   """Creates a 1D tensor containing a sequence of integers.
   2344 
   2345   The function arguments use the same convention as
   2346   Theano's arange: if only one argument is provided,
   2347   it is in fact the "stop" argument and "start" is 0.
   2348 
   2349   The default type of the returned tensor is `'int32'` to
   2350   match TensorFlow's default.
   2351 
   2352   Arguments:
   2353       start: Start value.
   2354       stop: Stop value.
   2355       step: Difference between two successive values.
   2356       dtype: Integer dtype to use.
   2357 
   2358   Returns:
   2359       An integer tensor.
   2360 
   2361   """
   2362   # Match the behavior of numpy and Theano by returning an empty sequence.
   2363   if stop is None and start < 0:
   2364     start = 0
   2365   result = math_ops.range(start, limit=stop, delta=step, name='arange')
   2366   if dtype != 'int32':
   2367     result = cast(result, dtype)
   2368   return result
   2369 
   2370 
   2371 def tile(x, n):
   2372   """Creates a tensor by tiling `x` by `n`.
   2373 
   2374   Arguments:
   2375       x: A tensor or variable
   2376       n: A list of integer. The length must be the same as the number of
   2377           dimensions in `x`.
   2378 
   2379   Returns:
   2380       A tiled tensor.
   2381   """
   2382   if isinstance(n, int):
   2383     n = [n]
   2384   return array_ops.tile(x, n)
   2385 
   2386 
   2387 @tf_export('keras.backend.flatten')
   2388 def flatten(x):
   2389   """Flatten a tensor.
   2390 
   2391   Arguments:
   2392       x: A tensor or variable.
   2393 
   2394   Returns:
   2395       A tensor, reshaped into 1-D
   2396   """
   2397   return array_ops.reshape(x, [-1])
   2398 
   2399 
   2400 @tf_export('keras.backend.batch_flatten')
   2401 def batch_flatten(x):
   2402   """Turn a nD tensor into a 2D tensor with same 0th dimension.
   2403 
   2404   In other words, it flattens each data samples of a batch.
   2405 
   2406   Arguments:
   2407       x: A tensor or variable.
   2408 
   2409   Returns:
   2410       A tensor.
   2411   """
   2412   x = array_ops.reshape(x, array_ops.stack([-1, prod(shape(x)[1:])]))
   2413   return x
   2414 
   2415 
   2416 @tf_export('keras.backend.expand_dims')
   2417 def expand_dims(x, axis=-1):
   2418   """Adds a 1-sized dimension at index "axis".
   2419 
   2420   Arguments:
   2421       x: A tensor or variable.
   2422       axis: Position where to add a new axis.
   2423 
   2424   Returns:
   2425       A tensor with expanded dimensions.
   2426   """
   2427   return array_ops.expand_dims(x, axis)
   2428 
   2429 
   2430 @tf_export('keras.backend.squeeze')
   2431 def squeeze(x, axis):
   2432   """Removes a 1-dimension from the tensor at index "axis".
   2433 
   2434   Arguments:
   2435       x: A tensor or variable.
   2436       axis: Axis to drop.
   2437 
   2438   Returns:
   2439       A tensor with the same data as `x` but reduced dimensions.
   2440   """
   2441   return array_ops.squeeze(x, [axis])
   2442 
   2443 
   2444 @tf_export('keras.backend.temporal_padding')
   2445 def temporal_padding(x, padding=(1, 1)):
   2446   """Pads the middle dimension of a 3D tensor.
   2447 
   2448   Arguments:
   2449       x: Tensor or variable.
   2450       padding: Tuple of 2 integers, how many zeros to
   2451           add at the start and end of dim 1.
   2452 
   2453   Returns:
   2454       A padded 3D tensor.
   2455   """
   2456   assert len(padding) == 2
   2457   pattern = [[0, 0], [padding[0], padding[1]], [0, 0]]
   2458   return array_ops.pad(x, pattern)
   2459 
   2460 
   2461 @tf_export('keras.backend.spatial_2d_padding')
   2462 def spatial_2d_padding(x, padding=((1, 1), (1, 1)), data_format=None):
   2463   """Pads the 2nd and 3rd dimensions of a 4D tensor.
   2464 
   2465   Arguments:
   2466       x: Tensor or variable.
   2467       padding: Tuple of 2 tuples, padding pattern.
   2468       data_format: One of `channels_last` or `channels_first`.
   2469 
   2470   Returns:
   2471       A padded 4D tensor.
   2472 
   2473   Raises:
   2474       ValueError: if `data_format` is neither
   2475           `channels_last` or `channels_first`.
   2476   """
   2477   assert len(padding) == 2
   2478   assert len(padding[0]) == 2
   2479   assert len(padding[1]) == 2
   2480   if data_format is None:
   2481     data_format = image_data_format()
   2482   if data_format not in {'channels_first', 'channels_last'}:
   2483     raise ValueError('Unknown data_format: ' + str(data_format))
   2484 
   2485   if data_format == 'channels_first':
   2486     pattern = [[0, 0], [0, 0], list(padding[0]), list(padding[1])]
   2487   else:
   2488     pattern = [[0, 0], list(padding[0]), list(padding[1]), [0, 0]]
   2489   return array_ops.pad(x, pattern)
   2490 
   2491 
   2492 @tf_export('keras.backend.spatial_3d_padding')
   2493 def spatial_3d_padding(x, padding=((1, 1), (1, 1), (1, 1)), data_format=None):
   2494   """Pads 5D tensor with zeros along the depth, height, width dimensions.
   2495 
   2496   Pads these dimensions with respectively
   2497   "padding[0]", "padding[1]" and "padding[2]" zeros left and right.
   2498 
   2499   For 'channels_last' data_format,
   2500   the 2nd, 3rd and 4th dimension will be padded.
   2501   For 'channels_first' data_format,
   2502   the 3rd, 4th and 5th dimension will be padded.
   2503 
   2504   Arguments:
   2505       x: Tensor or variable.
   2506       padding: Tuple of 3 tuples, padding pattern.
   2507       data_format: One of `channels_last` or `channels_first`.
   2508 
   2509   Returns:
   2510       A padded 5D tensor.
   2511 
   2512   Raises:
   2513       ValueError: if `data_format` is neither
   2514           `channels_last` or `channels_first`.
   2515 
   2516   """
   2517   assert len(padding) == 3
   2518   assert len(padding[0]) == 2
   2519   assert len(padding[1]) == 2
   2520   assert len(padding[2]) == 2
   2521   if data_format is None:
   2522     data_format = image_data_format()
   2523   if data_format not in {'channels_first', 'channels_last'}:
   2524     raise ValueError('Unknown data_format: ' + str(data_format))
   2525 
   2526   if data_format == 'channels_first':
   2527     pattern = [[0, 0], [0, 0], [padding[0][0], padding[0][1]],
   2528                [padding[1][0], padding[1][1]], [padding[2][0], padding[2][1]]]
   2529   else:
   2530     pattern = [[0, 0], [padding[0][0], padding[0][1]],
   2531                [padding[1][0], padding[1][1]], [padding[2][0],
   2532                                                 padding[2][1]], [0, 0]]
   2533   return array_ops.pad(x, pattern)
   2534 
   2535 
   2536 @tf_export('keras.backend.stack')
   2537 def stack(x, axis=0):
   2538   """Stacks a list of rank `R` tensors into a rank `R+1` tensor.
   2539 
   2540   Arguments:
   2541       x: List of tensors.
   2542       axis: Axis along which to perform stacking.
   2543 
   2544   Returns:
   2545       A tensor.
   2546   """
   2547   return array_ops.stack(x, axis=axis)
   2548 
   2549 
   2550 @tf_export('keras.backend.one_hot')
   2551 def one_hot(indices, num_classes):
   2552   """Computes the one-hot representation of an integer tensor.
   2553 
   2554   Arguments:
   2555       indices: nD integer tensor of shape
   2556           `(batch_size, dim1, dim2, ... dim(n-1))`
   2557       num_classes: Integer, number of classes to consider.
   2558 
   2559   Returns:
   2560       (n + 1)D one hot representation of the input
   2561       with shape `(batch_size, dim1, dim2, ... dim(n-1), num_classes)`
   2562 
   2563   Returns:
   2564       The one-hot tensor.
   2565   """
   2566   return array_ops.one_hot(indices, depth=num_classes, axis=-1)
   2567 
   2568 
   2569 @tf_export('keras.backend.reverse')
   2570 def reverse(x, axes):
   2571   """Reverse a tensor along the specified axes.
   2572 
   2573   Arguments:
   2574       x: Tensor to reverse.
   2575       axes: Integer or iterable of integers.
   2576           Axes to reverse.
   2577 
   2578   Returns:
   2579       A tensor.
   2580   """
   2581   if isinstance(axes, int):
   2582     axes = [axes]
   2583   return array_ops.reverse(x, axes)
   2584 
   2585 
   2586 # VALUE MANIPULATION
   2587 
   2588 
   2589 @tf_export('keras.backend.get_value')
   2590 def get_value(x):
   2591   """Returns the value of a variable.
   2592 
   2593   Arguments:
   2594       x: input variable.
   2595 
   2596   Returns:
   2597       A Numpy array.
   2598   """
   2599   if context.in_eager_mode():
   2600     return x.numpy()
   2601   return x.eval(session=get_session())
   2602 
   2603 
   2604 @tf_export('keras.backend.batch_get_value')
   2605 def batch_get_value(tensors):
   2606   """Returns the value of more than one tensor variable.
   2607 
   2608   Arguments:
   2609       tensors: list of ops to run.
   2610 
   2611   Returns:
   2612       A list of Numpy arrays.
   2613   """
   2614   if context.in_eager_mode():
   2615     return [x.numpy() for x in tensors]
   2616   if tensors:
   2617     return get_session().run(tensors)
   2618   else:
   2619     return []
   2620 
   2621 
   2622 @tf_export('keras.backend.set_value')
   2623 def set_value(x, value):
   2624   """Sets the value of a variable, from a Numpy array.
   2625 
   2626   Arguments:
   2627       x: Tensor to set to a new value.
   2628       value: Value to set the tensor to, as a Numpy array
   2629           (of the same shape).
   2630   """
   2631   value = np.asarray(value, dtype=dtype(x))
   2632   if context.in_eager_mode():
   2633     x.assign(value)
   2634   else:
   2635     tf_dtype = dtypes_module.as_dtype(x.dtype.name.split('_')[0])
   2636     if hasattr(x, '_assign_placeholder'):
   2637       assign_placeholder = x._assign_placeholder
   2638       assign_op = x._assign_op
   2639     else:
   2640       assign_placeholder = array_ops.placeholder(tf_dtype, shape=value.shape)
   2641       assign_op = x.assign(assign_placeholder)
   2642       x._assign_placeholder = assign_placeholder
   2643       x._assign_op = assign_op
   2644     get_session().run(assign_op, feed_dict={assign_placeholder: value})
   2645 
   2646 
   2647 @tf_export('keras.backend.batch_set_value')
   2648 def batch_set_value(tuples):
   2649   """Sets the values of many tensor variables at once.
   2650 
   2651   Arguments:
   2652       tuples: a list of tuples `(tensor, value)`.
   2653           `value` should be a Numpy array.
   2654   """
   2655   if context.in_eager_mode():
   2656     for x, value in tuples:
   2657       x.assign(np.asarray(value, dtype=dtype(x)))
   2658   else:
   2659     if tuples:
   2660       assign_ops = []
   2661       feed_dict = {}
   2662       for x, value in tuples:
   2663         value = np.asarray(value, dtype=dtype(x))
   2664         tf_dtype = dtypes_module.as_dtype(x.dtype.name.split('_')[0])
   2665         if hasattr(x, '_assign_placeholder'):
   2666           assign_placeholder = x._assign_placeholder
   2667           assign_op = x._assign_op
   2668         else:
   2669           assign_placeholder = array_ops.placeholder(tf_dtype,
   2670                                                      shape=value.shape)
   2671           assign_op = x.assign(assign_placeholder)
   2672           x._assign_placeholder = assign_placeholder
   2673           x._assign_op = assign_op
   2674         assign_ops.append(assign_op)
   2675         feed_dict[assign_placeholder] = value
   2676       get_session().run(assign_ops, feed_dict=feed_dict)
   2677 
   2678 
   2679 @tf_export('keras.backend.print_tensor')
   2680 def print_tensor(x, message=''):
   2681   """Prints `message` and the tensor value when evaluated.
   2682 
   2683   Note that `print_tensor` returns a new tensor identical to `x`
   2684   which should be used in the following code. Otherwise the
   2685   print operation is not taken into account during evaluation.
   2686 
   2687   Example:
   2688 
   2689   ```python
   2690      >>> x = K.print_tensor(x, message="x is: ")
   2691   ```
   2692 
   2693   Arguments:
   2694       x: Tensor to print.
   2695       message: Message to print jointly with the tensor.
   2696 
   2697   Returns:
   2698       The same tensor `x`, unchanged.
   2699   """
   2700   return logging_ops.Print(x, [x], message)
   2701 
   2702 
   2703 # GRAPH MANIPULATION
   2704 
   2705 
   2706 class Function(object):
   2707   """Runs a computation graph.
   2708 
   2709   It's possible to pass arguments to `tf.Session.run()` via `session_kwargs`.
   2710   In particular additional operations via `fetches` argument and additional
   2711   tensor substitutions via `feed_dict` arguments. Note that given
   2712   substitutions are merged with substitutions from `inputs`. Even though
   2713   `feed_dict` is passed once in the constructor (called in `model.compile()`)
   2714   we can modify the values in the dictionary. Through this feed_dict we can
   2715   provide additional substitutions besides Keras inputs.
   2716 
   2717   Arguments:
   2718       inputs: Feed placeholders to the computation graph.
   2719       outputs: Output tensors to fetch.
   2720       updates: Additional update ops to be run at function call.
   2721       name: A name to help users identify what this function does.
   2722       session_kwargs: Arguments to `tf.Session.run()`: `fetches`, `feed_dict`,
   2723         `options`, `run_metadata`
   2724   """
   2725 
   2726   def __init__(self, inputs, outputs, updates=None, name=None,
   2727                **session_kwargs):
   2728     updates = updates or []
   2729     if not isinstance(inputs, (list, tuple)):
   2730       raise TypeError('`inputs` to a TensorFlow backend function '
   2731                       'should be a list or tuple.')
   2732     if not isinstance(outputs, (list, tuple)):
   2733       raise TypeError('`outputs` of a TensorFlow backend function '
   2734                       'should be a list or tuple.')
   2735     if not isinstance(updates, (list, tuple)):
   2736       raise TypeError('`updates` in a TensorFlow backend function '
   2737                       'should be a list or tuple.')
   2738     self.inputs = list(inputs)
   2739     self.outputs = list(outputs)
   2740     with ops.control_dependencies(self.outputs):
   2741       updates_ops = []
   2742       for update in updates:
   2743         if isinstance(update, tuple):
   2744           p, new_p = update
   2745           updates_ops.append(state_ops.assign(p, new_p))
   2746         else:
   2747           # assumed already an op
   2748           updates_ops.append(update)
   2749       self.updates_op = control_flow_ops.group(*updates_ops)
   2750     self.name = name
   2751     # additional tensor substitutions
   2752     self.feed_dict = session_kwargs.pop('feed_dict', {})
   2753     # additional operations
   2754     self.fetches = session_kwargs.pop('fetches', [])
   2755     if not isinstance(self.fetches, list):
   2756       self.fetches = [self.fetches]
   2757     self.session_kwargs = session_kwargs
   2758 
   2759   def __call__(self, inputs):
   2760     if not isinstance(inputs, (list, tuple)):
   2761       raise TypeError('`inputs` should be a list or tuple.')
   2762     feed_dict = self.feed_dict.copy()
   2763     for tensor, value in zip(self.inputs, inputs):
   2764       if is_sparse(tensor):
   2765         sparse_coo = value.tocoo()
   2766         indices = np.concatenate((np.expand_dims(sparse_coo.row, 1),
   2767                                   np.expand_dims(sparse_coo.col, 1)), 1)
   2768         value = (indices, sparse_coo.data, sparse_coo.shape)
   2769       feed_dict[tensor] = value
   2770     fetches = self.outputs + [self.updates_op] + self.fetches
   2771     session = get_session()
   2772     updated = session.run(
   2773         fetches=fetches, feed_dict=feed_dict, **self.session_kwargs)
   2774     return updated[:len(self.outputs)]
   2775 
   2776 
   2777 @tf_export('keras.backend.function')
   2778 def function(inputs, outputs, updates=None, **kwargs):
   2779   """Instantiates a Keras function.
   2780 
   2781   Arguments:
   2782       inputs: List of placeholder tensors.
   2783       outputs: List of output tensors.
   2784       updates: List of update ops.
   2785       **kwargs: Passed to `tf.Session.run`.
   2786 
   2787   Returns:
   2788       Output values as Numpy arrays.
   2789 
   2790   Raises:
   2791       ValueError: if invalid kwargs are passed in.
   2792   """
   2793   if kwargs:
   2794     for key in kwargs:
   2795       if (key not in tf_inspect.getargspec(session_module.Session.run)[0] and
   2796           key not in tf_inspect.getargspec(Function.__init__)[0]):
   2797         msg = ('Invalid argument "%s" passed to K.function with TensorFlow '
   2798                'backend') % key
   2799         raise ValueError(msg)
   2800   return Function(inputs, outputs, updates=updates, **kwargs)
   2801 
   2802 
   2803 @tf_export('keras.backend.gradients')
   2804 def gradients(loss, variables):
   2805   """Returns the gradients of `variables` w.r.t. `loss`.
   2806 
   2807   Arguments:
   2808       loss: Scalar tensor to minimize.
   2809       variables: List of variables.
   2810 
   2811   Returns:
   2812       A gradients tensor.
   2813   """
   2814   return gradients_module.gradients(
   2815       loss, variables, colocate_gradients_with_ops=True)
   2816 
   2817 
   2818 @tf_export('keras.backend.stop_gradient')
   2819 def stop_gradient(variables):
   2820   """Returns `variables` but with zero gradient w.r.t. every other variable.
   2821 
   2822   Arguments:
   2823       variables: Tensor or list of tensors to consider constant with respect
   2824         to any other variable.
   2825 
   2826 
   2827   Returns:
   2828       A single tensor or a list of tensors (depending on the passed argument)
   2829       that has no gradient with respect to any other variable.
   2830   """
   2831   if isinstance(variables, (list, tuple)):
   2832     return map(array_ops.stop_gradient, variables)
   2833   return array_ops.stop_gradient(variables)
   2834 
   2835 
   2836 # CONTROL FLOW
   2837 
   2838 
   2839 @tf_export('keras.backend.rnn')
   2840 def rnn(step_function,
   2841         inputs,
   2842         initial_states,
   2843         go_backwards=False,
   2844         mask=None,
   2845         constants=None,
   2846         unroll=False,
   2847         input_length=None):
   2848   """Iterates over the time dimension of a tensor.
   2849 
   2850   Arguments:
   2851       step_function: RNN step function.
   2852           Parameters;
   2853               input; tensor with shape `(samples, ...)` (no time dimension),
   2854                   representing input for the batch of samples at a certain
   2855                   time step.
   2856               states; list of tensors.
   2857           Returns;
   2858               output; tensor with shape `(samples, output_dim)`
   2859                   (no time dimension).
   2860               new_states; list of tensors, same length and shapes
   2861                   as 'states'. The first state in the list must be the
   2862                   output tensor at the previous timestep.
   2863       inputs: tensor of temporal data of shape `(samples, time, ...)`
   2864           (at least 3D).
   2865       initial_states: tensor with shape (samples, output_dim)
   2866           (no time dimension),
   2867           containing the initial values for the states used in
   2868           the step function.
   2869       go_backwards: boolean. If True, do the iteration over the time
   2870           dimension in reverse order and return the reversed sequence.
   2871       mask: binary tensor with shape `(samples, time, 1)`,
   2872           with a zero for every element that is masked.
   2873       constants: a list of constant values passed at each step.
   2874       unroll: whether to unroll the RNN or to use a symbolic loop
   2875           (`while_loop` or `scan` depending on backend).
   2876       input_length: Unused; exists for API compatibility.
   2877 
   2878   Returns:
   2879       A tuple, `(last_output, outputs, new_states)`.
   2880           last_output: the latest output of the rnn, of shape `(samples, ...)`
   2881           outputs: tensor with shape `(samples, time, ...)` where each
   2882               entry `outputs[s, t]` is the output of the step function
   2883               at time `t` for sample `s`.
   2884           new_states: list of tensors, latest states returned by
   2885               the step function, of shape `(samples, ...)`.
   2886 
   2887   Raises:
   2888       ValueError: if input dimension is less than 3.
   2889       ValueError: if `unroll` is `True` but input timestep is not a fixed
   2890       number.
   2891       ValueError: if `mask` is provided (not `None`) but states is not provided
   2892           (`len(states)` == 0).
   2893   """
   2894   del input_length
   2895   ndim = len(inputs.get_shape())
   2896   if ndim < 3:
   2897     raise ValueError('Input should be at least 3D.')
   2898   inputs_shape = inputs.get_shape()
   2899   axes = [1, 0] + list(range(2, ndim))
   2900   inputs = array_ops.transpose(inputs, (axes))
   2901 
   2902   if mask is not None:
   2903     if mask.dtype != dtypes_module.bool:
   2904       mask = math_ops.cast(mask, dtypes_module.bool)
   2905     if len(mask.get_shape()) == ndim - 1:
   2906       mask = expand_dims(mask)
   2907     mask = array_ops.transpose(mask, axes)
   2908 
   2909   if constants is None:
   2910     constants = []
   2911 
   2912   global uses_learning_phase  # pylint: disable=global-variable-undefined
   2913   uses_learning_phase = False
   2914 
   2915   if unroll:
   2916     if not inputs.get_shape()[0]:
   2917       raise ValueError('Unrolling requires a fixed number of timesteps.')
   2918     states = initial_states
   2919     successive_states = []
   2920     successive_outputs = []
   2921 
   2922     input_list = array_ops.unstack(inputs)
   2923     if go_backwards:
   2924       input_list.reverse()
   2925 
   2926     if mask is not None:
   2927       mask_list = array_ops.unstack(mask)
   2928       if go_backwards:
   2929         mask_list.reverse()
   2930 
   2931       for inp, mask_t in zip(input_list, mask_list):
   2932         output, new_states = step_function(inp, states + constants)
   2933         if getattr(output, '_uses_learning_phase', False):
   2934           uses_learning_phase = True
   2935 
   2936         # tf.where needs its condition tensor
   2937         # to be the same shape as its two
   2938         # result tensors, but in our case
   2939         # the condition (mask) tensor is
   2940         # (nsamples, 1), and A and B are (nsamples, ndimensions).
   2941         # So we need to
   2942         # broadcast the mask to match the shape of A and B.
   2943         # That's what the tile call does,
   2944         # it just repeats the mask along its second dimension
   2945         # n times.
   2946         tiled_mask_t = array_ops.tile(mask_t,
   2947                                       array_ops.stack(
   2948                                           [1, array_ops.shape(output)[1]]))
   2949 
   2950         if not successive_outputs:
   2951           prev_output = zeros_like(output)
   2952         else:
   2953           prev_output = successive_outputs[-1]
   2954 
   2955         output = array_ops.where(tiled_mask_t, output, prev_output)
   2956 
   2957         return_states = []
   2958         for state, new_state in zip(states, new_states):
   2959           # (see earlier comment for tile explanation)
   2960           tiled_mask_t = array_ops.tile(mask_t,
   2961                                         array_ops.stack(
   2962                                             [1,
   2963                                              array_ops.shape(new_state)[1]]))
   2964           return_states.append(array_ops.where(tiled_mask_t, new_state, state))
   2965         states = return_states
   2966         successive_outputs.append(output)
   2967         successive_states.append(states)
   2968       last_output = successive_outputs[-1]
   2969       new_states = successive_states[-1]
   2970       outputs = array_ops.stack(successive_outputs)
   2971     else:
   2972       for inp in input_list:
   2973         output, states = step_function(inp, states + constants)
   2974         if getattr(output, '_uses_learning_phase', False):
   2975           uses_learning_phase = True
   2976         successive_outputs.append(output)
   2977         successive_states.append(states)
   2978       last_output = successive_outputs[-1]
   2979       new_states = successive_states[-1]
   2980       outputs = array_ops.stack(successive_outputs)
   2981 
   2982   else:
   2983     if go_backwards:
   2984       inputs = reverse(inputs, 0)
   2985 
   2986     states = tuple(initial_states)
   2987 
   2988     time_steps = array_ops.shape(inputs)[0]
   2989     outputs, _ = step_function(inputs[0], initial_states + constants)
   2990     output_ta = tensor_array_ops.TensorArray(
   2991         dtype=outputs.dtype, size=time_steps, tensor_array_name='output_ta')
   2992     input_ta = tensor_array_ops.TensorArray(
   2993         dtype=inputs.dtype, size=time_steps, tensor_array_name='input_ta')
   2994     input_ta = input_ta.unstack(inputs)
   2995     time = constant_op.constant(0, dtype='int32', name='time')
   2996 
   2997     if mask is not None:
   2998       if not states:
   2999         raise ValueError('No initial states provided! '
   3000                          'When using masking in an RNN, you should '
   3001                          'provide initial states '
   3002                          '(and your step function should return '
   3003                          'as its first state at time `t` '
   3004                          'the output at time `t-1`).')
   3005       if go_backwards:
   3006         mask = reverse(mask, 0)
   3007 
   3008       mask_ta = tensor_array_ops.TensorArray(
   3009           dtype=dtypes_module.bool,
   3010           size=time_steps,
   3011           tensor_array_name='mask_ta')
   3012       mask_ta = mask_ta.unstack(mask)
   3013 
   3014       def _step(time, output_ta_t, *states):
   3015         """RNN step function.
   3016 
   3017         Arguments:
   3018             time: Current timestep value.
   3019             output_ta_t: TensorArray.
   3020             *states: List of states.
   3021 
   3022         Returns:
   3023             Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
   3024         """
   3025         current_input = input_ta.read(time)
   3026         mask_t = mask_ta.read(time)
   3027         output, new_states = step_function(current_input,
   3028                                            tuple(states) + tuple(constants))
   3029         if getattr(output, '_uses_learning_phase', False):
   3030           global uses_learning_phase  # pylint: disable=global-variable-undefined
   3031           uses_learning_phase = True
   3032         for state, new_state in zip(states, new_states):
   3033           new_state.set_shape(state.get_shape())
   3034         tiled_mask_t = array_ops.tile(mask_t,
   3035                                       array_ops.stack(
   3036                                           [1, array_ops.shape(output)[1]]))
   3037         output = array_ops.where(tiled_mask_t, output, states[0])
   3038         new_states = [
   3039             array_ops.where(tiled_mask_t, new_states[i], states[i])
   3040             for i in range(len(states))
   3041         ]
   3042         output_ta_t = output_ta_t.write(time, output)
   3043         return (time + 1, output_ta_t) + tuple(new_states)
   3044     else:
   3045 
   3046       def _step(time, output_ta_t, *states):
   3047         """RNN step function.
   3048 
   3049         Arguments:
   3050             time: Current timestep value.
   3051             output_ta_t: TensorArray.
   3052             *states: List of states.
   3053 
   3054         Returns:
   3055             Tuple: `(time + 1,output_ta_t) + tuple(new_states)`
   3056         """
   3057         current_input = input_ta.read(time)
   3058         output, new_states = step_function(current_input,
   3059                                            tuple(states) + tuple(constants))
   3060         if getattr(output, '_uses_learning_phase', False):
   3061           global uses_learning_phase  # pylint: disable=global-variable-undefined
   3062           uses_learning_phase = True
   3063         for state, new_state in zip(states, new_states):
   3064           new_state.set_shape(state.get_shape())
   3065         output_ta_t = output_ta_t.write(time, output)
   3066         return (time + 1, output_ta_t) + tuple(new_states)
   3067 
   3068     final_outputs = control_flow_ops.while_loop(
   3069         cond=lambda time, *_: time < time_steps,
   3070         body=_step,
   3071         loop_vars=(time, output_ta) + states,
   3072         parallel_iterations=32,
   3073         swap_memory=True)
   3074     last_time = final_outputs[0]
   3075     output_ta = final_outputs[1]
   3076     new_states = final_outputs[2:]
   3077 
   3078     outputs = output_ta.stack()
   3079     last_output = output_ta.read(last_time - 1)
   3080 
   3081   axes = [1, 0] + list(range(2, len(outputs.get_shape())))
   3082   outputs = array_ops.transpose(outputs, axes)
   3083 
   3084   # Static shape inference: (samples, time, ...)
   3085   outputs_shape = outputs.get_shape().as_list()
   3086   outputs_shape[0] = inputs_shape[0]
   3087   outputs_shape[1] = inputs_shape[1]
   3088   outputs.set_shape(outputs_shape)
   3089 
   3090   last_output._uses_learning_phase = uses_learning_phase
   3091   return last_output, outputs, new_states
   3092 
   3093 
   3094 @tf_export('keras.backend.switch')
   3095 def switch(condition, then_expression, else_expression):
   3096   """Switches between two operations depending on a scalar value.
   3097 
   3098   Note that both `then_expression` and `else_expression`
   3099   should be symbolic tensors of the *same shape*.
   3100 
   3101   Arguments:
   3102       condition: tensor (`int` or `bool`).
   3103       then_expression: either a tensor, or a callable that returns a tensor.
   3104       else_expression: either a tensor, or a callable that returns a tensor.
   3105 
   3106   Returns:
   3107       The selected tensor.
   3108 
   3109   Raises:
   3110       ValueError: If rank of `condition` is greater than rank of expressions.
   3111   """
   3112   if condition.dtype != dtypes_module.bool:
   3113     condition = math_ops.cast(condition, 'bool')
   3114   cond_ndim = ndim(condition)
   3115   if not cond_ndim:
   3116     if not callable(then_expression):
   3117 
   3118       def then_expression_fn():
   3119         return then_expression
   3120     else:
   3121       then_expression_fn = then_expression
   3122     if not callable(else_expression):
   3123 
   3124       def else_expression_fn():
   3125         return else_expression
   3126     else:
   3127       else_expression_fn = else_expression
   3128     x = control_flow_ops.cond(condition, then_expression_fn, else_expression_fn)
   3129   else:
   3130     # tf.where needs its condition tensor
   3131     # to be the same shape as its two
   3132     # result tensors
   3133     if callable(then_expression):
   3134       then_expression = then_expression()
   3135     if callable(else_expression):
   3136       else_expression = else_expression()
   3137     expr_ndim = ndim(then_expression)
   3138     if cond_ndim > expr_ndim:
   3139       raise ValueError('Rank of `condition` should be less than or'
   3140                        ' equal to rank of `then_expression` and '
   3141                        '`else_expression`. ndim(condition)=' + str(cond_ndim) +
   3142                        ', ndim(then_expression)'
   3143                        '=' + str(expr_ndim))
   3144     if cond_ndim > 1:
   3145       ndim_diff = expr_ndim - cond_ndim
   3146       cond_shape = array_ops.concat(
   3147           [array_ops.shape(condition), [1] * ndim_diff], axis=0)
   3148       condition = array_ops.reshape(condition, cond_shape)
   3149       expr_shape = array_ops.shape(then_expression)
   3150       shape_diff = expr_shape - cond_shape
   3151       tile_shape = array_ops.where(shape_diff > 0, expr_shape,
   3152                                    array_ops.ones_like(expr_shape))
   3153       condition = array_ops.tile(condition, tile_shape)
   3154     x = array_ops.where(condition, then_expression, else_expression)
   3155   return x
   3156 
   3157 
   3158 @tf_export('keras.backend.in_train_phase')
   3159 def in_train_phase(x, alt, training=None):
   3160   """Selects `x` in train phase, and `alt` otherwise.
   3161 
   3162   Note that `alt` should have the *same shape* as `x`.
   3163 
   3164   Arguments:
   3165       x: What to return in train phase
   3166           (tensor or callable that returns a tensor).
   3167       alt: What to return otherwise
   3168           (tensor or callable that returns a tensor).
   3169       training: Optional scalar tensor
   3170           (or Python boolean, or Python integer)
   3171           specifying the learning phase.
   3172 
   3173   Returns:
   3174       Either `x` or `alt` based on the `training` flag.
   3175       the `training` flag defaults to `K.learning_phase()`.
   3176   """
   3177   if training is None:
   3178     training = learning_phase()
   3179     uses_learning_phase = True
   3180   else:
   3181     uses_learning_phase = False
   3182 
   3183   if training is 1 or training is True:
   3184     if callable(x):
   3185       return x()
   3186     else:
   3187       return x
   3188 
   3189   elif training is 0 or training is False:
   3190     if callable(alt):
   3191       return alt()
   3192     else:
   3193       return alt
   3194 
   3195   # else: assume learning phase is a placeholder tensor.
   3196   x = switch(training, x, alt)
   3197   if uses_learning_phase:
   3198     x._uses_learning_phase = True
   3199   return x
   3200 
   3201 
   3202 @tf_export('keras.backend.in_test_phase')
   3203 def in_test_phase(x, alt, training=None):
   3204   """Selects `x` in test phase, and `alt` otherwise.
   3205 
   3206   Note that `alt` should have the *same shape* as `x`.
   3207 
   3208   Arguments:
   3209       x: What to return in test phase
   3210           (tensor or callable that returns a tensor).
   3211       alt: What to return otherwise
   3212           (tensor or callable that returns a tensor).
   3213       training: Optional scalar tensor
   3214           (or Python boolean, or Python integer)
   3215           specifying the learning phase.
   3216 
   3217   Returns:
   3218       Either `x` or `alt` based on `K.learning_phase`.
   3219   """
   3220   return in_train_phase(alt, x, training=training)
   3221 
   3222 
   3223 # NN OPERATIONS
   3224 
   3225 
   3226 @tf_export('keras.backend.relu')
   3227 def relu(x, alpha=0., max_value=None):
   3228   """Rectified linear unit.
   3229 
   3230   With default values, it returns element-wise `max(x, 0)`.
   3231 
   3232   Arguments:
   3233       x: A tensor or variable.
   3234       alpha: A scalar, slope of negative section (default=`0.`).
   3235       max_value: Saturation threshold.
   3236 
   3237   Returns:
   3238       A tensor.
   3239   """
   3240   if alpha != 0.:
   3241     negative_part = nn.relu(-x)
   3242   x = nn.relu(x)
   3243   if max_value is not None:
   3244     max_value = _to_tensor(max_value, x.dtype.base_dtype)
   3245     zero = _to_tensor(0., x.dtype.base_dtype)
   3246     x = clip_ops.clip_by_value(x, zero, max_value)
   3247   if alpha != 0.:
   3248     alpha = _to_tensor(alpha, x.dtype.base_dtype)
   3249     x -= alpha * negative_part
   3250   return x
   3251 
   3252 
   3253 @tf_export('keras.backend.elu')
   3254 def elu(x, alpha=1.):
   3255   """Exponential linear unit.
   3256 
   3257   Arguments:
   3258       x: A tensor or variable to compute the activation function for.
   3259       alpha: A scalar, slope of negative section.
   3260 
   3261   Returns:
   3262       A tensor.
   3263   """
   3264   res = nn.elu(x)
   3265   if alpha == 1:
   3266     return res
   3267   else:
   3268     return array_ops.where(x > 0, res, alpha * res)
   3269 
   3270 
   3271 @tf_export('keras.backend.softmax')
   3272 def softmax(x):
   3273   """Softmax of a tensor.
   3274 
   3275   Arguments:
   3276       x: A tensor or variable.
   3277 
   3278   Returns:
   3279       A tensor.
   3280   """
   3281   return nn.softmax(x)
   3282 
   3283 
   3284 @tf_export('keras.backend.softplus')
   3285 def softplus(x):
   3286   """Softplus of a tensor.
   3287 
   3288   Arguments:
   3289       x: A tensor or variable.
   3290 
   3291   Returns:
   3292       A tensor.
   3293   """
   3294   return nn.softplus(x)
   3295 
   3296 
   3297 @tf_export('keras.backend.softsign')
   3298 def softsign(x):
   3299   """Softsign of a tensor.
   3300 
   3301   Arguments:
   3302       x: A tensor or variable.
   3303 
   3304   Returns:
   3305       A tensor.
   3306   """
   3307   return nn.softsign(x)
   3308 
   3309 
   3310 @tf_export('keras.backend.categorical_crossentropy')
   3311 def categorical_crossentropy(target, output, from_logits=False):
   3312   """Categorical crossentropy between an output tensor and a target tensor.
   3313 
   3314   Arguments:
   3315       target: A tensor of the same shape as `output`.
   3316       output: A tensor resulting from a softmax
   3317           (unless `from_logits` is True, in which
   3318           case `output` is expected to be the logits).
   3319       from_logits: Boolean, whether `output` is the
   3320           result of a softmax, or is a tensor of logits.
   3321 
   3322   Returns:
   3323       Output tensor.
   3324   """
   3325   # Note: nn.softmax_cross_entropy_with_logits
   3326   # expects logits, Keras expects probabilities.
   3327   if not from_logits:
   3328     # scale preds so that the class probas of each sample sum to 1
   3329     output = output / math_ops.reduce_sum(  # pylint: disable=g-no-augmented-assignment
   3330         output, len(output.get_shape()) - 1, True)
   3331     # manual computation of crossentropy
   3332     epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
   3333     output = clip_ops.clip_by_value(output, epsilon_, 1. - epsilon_)
   3334     return -math_ops.reduce_sum(
   3335         target * math_ops.log(output),
   3336         axis=len(output.get_shape()) - 1)
   3337   else:
   3338     return nn.softmax_cross_entropy_with_logits(labels=target, logits=output)
   3339 
   3340 
   3341 @tf_export('keras.backend.sparse_categorical_crossentropy')
   3342 def sparse_categorical_crossentropy(target, output, from_logits=False):
   3343   """Categorical crossentropy with integer targets.
   3344 
   3345   Arguments:
   3346       target: An integer tensor.
   3347       output: A tensor resulting from a softmax
   3348           (unless `from_logits` is True, in which
   3349           case `output` is expected to be the logits).
   3350       from_logits: Boolean, whether `output` is the
   3351           result of a softmax, or is a tensor of logits.
   3352 
   3353   Returns:
   3354       Output tensor.
   3355   """
   3356   # Note: nn.sparse_softmax_cross_entropy_with_logits
   3357   # expects logits, Keras expects probabilities.
   3358   if not from_logits:
   3359     epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
   3360     output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
   3361     output = math_ops.log(output)
   3362 
   3363   output_shape = output.get_shape()
   3364   targets = cast(flatten(target), 'int64')
   3365   logits = array_ops.reshape(output, [-1, int(output_shape[-1])])
   3366   res = nn.sparse_softmax_cross_entropy_with_logits(
   3367       labels=targets, logits=logits)
   3368   if len(output_shape) >= 3:
   3369     # If our output includes timesteps or spatial dimensions we need to reshape
   3370     return array_ops.reshape(res, array_ops.shape(output)[:-1])
   3371   else:
   3372     return res
   3373 
   3374 
   3375 @tf_export('keras.backend.binary_crossentropy')
   3376 def binary_crossentropy(target, output, from_logits=False):
   3377   """Binary crossentropy between an output tensor and a target tensor.
   3378 
   3379   Arguments:
   3380       target: A tensor with the same shape as `output`.
   3381       output: A tensor.
   3382       from_logits: Whether `output` is expected to be a logits tensor.
   3383           By default, we consider that `output`
   3384           encodes a probability distribution.
   3385 
   3386   Returns:
   3387       A tensor.
   3388   """
   3389   # Note: nn.softmax_cross_entropy_with_logits
   3390   # expects logits, Keras expects probabilities.
   3391   if not from_logits:
   3392     # transform back to logits
   3393     epsilon_ = _to_tensor(epsilon(), output.dtype.base_dtype)
   3394     output = clip_ops.clip_by_value(output, epsilon_, 1 - epsilon_)
   3395     output = math_ops.log(output / (1 - output))
   3396   return nn.sigmoid_cross_entropy_with_logits(labels=target, logits=output)
   3397 
   3398 
   3399 @tf_export('keras.backend.sigmoid')
   3400 def sigmoid(x):
   3401   """Element-wise sigmoid.
   3402 
   3403   Arguments:
   3404       x: A tensor or variable.
   3405 
   3406   Returns:
   3407       A tensor.
   3408   """
   3409   return nn.sigmoid(x)
   3410 
   3411 
   3412 @tf_export('keras.backend.hard_sigmoid')
   3413 def hard_sigmoid(x):
   3414   """Segment-wise linear approximation of sigmoid.
   3415 
   3416   Faster than sigmoid.
   3417   Returns `0.` if `x < -2.5`, `1.` if `x > 2.5`.
   3418   In `-2.5 <= x <= 2.5`, returns `0.2 * x + 0.5`.
   3419 
   3420   Arguments:
   3421       x: A tensor or variable.
   3422 
   3423   Returns:
   3424       A tensor.
   3425   """
   3426   x = (0.2 * x) + 0.5
   3427   zero = _to_tensor(0., x.dtype.base_dtype)
   3428   one = _to_tensor(1., x.dtype.base_dtype)
   3429   x = clip_ops.clip_by_value(x, zero, one)
   3430   return x
   3431 
   3432 
   3433 @tf_export('keras.backend.tanh')
   3434 def tanh(x):
   3435   """Element-wise tanh.
   3436 
   3437   Arguments:
   3438       x: A tensor or variable.
   3439 
   3440   Returns:
   3441       A tensor.
   3442   """
   3443   return nn.tanh(x)
   3444 
   3445 
   3446 @tf_export('keras.backend.dropout')
   3447 def dropout(x, level, noise_shape=None, seed=None):
   3448   """Sets entries in `x` to zero at random, while scaling the entire tensor.
   3449 
   3450   Arguments:
   3451       x: tensor
   3452       level: fraction of the entries in the tensor
   3453           that will be set to 0.
   3454       noise_shape: shape for randomly generated keep/drop flags,
   3455           must be broadcastable to the shape of `x`
   3456       seed: random seed to ensure determinism.
   3457 
   3458   Returns:
   3459       A tensor.
   3460   """
   3461   retain_prob = 1. - level
   3462   if seed is None:
   3463     seed = np.random.randint(10e6)
   3464   # the dummy 1. works around a TF bug
   3465   # (float32_ref vs. float32 incompatibility)
   3466   return nn.dropout(x * 1., retain_prob, noise_shape, seed=seed)
   3467 
   3468 
   3469 @tf_export('keras.backend.l2_normalize')
   3470 def l2_normalize(x, axis=None):
   3471   """Normalizes a tensor wrt the L2 norm alongside the specified axis.
   3472 
   3473   Arguments:
   3474       x: Tensor or variable.
   3475       axis: axis along which to perform normalization.
   3476 
   3477   Returns:
   3478       A tensor.
   3479   """
   3480   return nn.l2_normalize(x, dim=axis)
   3481 
   3482 
   3483 @tf_export('keras.backend.in_top_k')
   3484 def in_top_k(predictions, targets, k):
   3485   """Returns whether the `targets` are in the top `k` `predictions`.
   3486 
   3487   Arguments:
   3488       predictions: A tensor of shape `(batch_size, classes)` and type `float32`.
   3489       targets: A 1D tensor of length `batch_size` and type `int32` or `int64`.
   3490       k: An `int`, number of top elements to consider.
   3491 
   3492   Returns:
   3493       A 1D tensor of length `batch_size` and type `bool`.
   3494       `output[i]` is `True` if `predictions[i, targets[i]]` is within top-`k`
   3495       values of `predictions[i]`.
   3496   """
   3497   return nn.in_top_k(predictions, targets, k)
   3498 
   3499 
   3500 # CONVOLUTIONS
   3501 
   3502 
   3503 def _preprocess_conv1d_input(x, data_format):
   3504   """Transpose and cast the input before the conv1d.
   3505 
   3506   Arguments:
   3507       x: input tensor.
   3508       data_format: string, `"channels_last"` or `"channels_first"`.
   3509 
   3510   Returns:
   3511       A tensor.
   3512   """
   3513   tf_data_format = 'NHWC'  # to pass TF Conv2dNative operations
   3514   if data_format == 'channels_first':
   3515     if not _has_nchw_support():
   3516       x = array_ops.transpose(x, (0, 2, 1))  # NCW -> NWC
   3517     else:
   3518       tf_data_format = 'NCHW'
   3519   return x, tf_data_format
   3520 
   3521 
   3522 def _preprocess_conv2d_input(x, data_format):
   3523   """Transpose and cast the input before the conv2d.
   3524 
   3525   Arguments:
   3526       x: input tensor.
   3527       data_format: string, `"channels_last"` or `"channels_first"`.
   3528 
   3529   Returns:
   3530       A tensor.
   3531   """
   3532   tf_data_format = 'NHWC'
   3533   if data_format == 'channels_first':
   3534     if not _has_nchw_support():
   3535       x = array_ops.transpose(x, (0, 2, 3, 1))  # NCHW -> NHWC
   3536     else:
   3537       tf_data_format = 'NCHW'
   3538   return x, tf_data_format
   3539 
   3540 
   3541 def _preprocess_conv3d_input(x, data_format):
   3542   """Transpose and cast the input before the conv3d.
   3543 
   3544   Arguments:
   3545       x: input tensor.
   3546       data_format: string, `"channels_last"` or `"channels_first"`.
   3547 
   3548   Returns:
   3549       A tensor.
   3550   """
   3551   tf_data_format = 'NDHWC'
   3552   if data_format == 'channels_first':
   3553     if not _has_nchw_support():
   3554       x = array_ops.transpose(x, (0, 2, 3, 4, 1))
   3555     else:
   3556       tf_data_format = 'NCDHW'
   3557   return x, tf_data_format
   3558 
   3559 
   3560 def _preprocess_padding(padding):
   3561   """Convert keras' padding to TensorFlow's padding.
   3562 
   3563   Arguments:
   3564       padding: string, one of 'same' , 'valid'
   3565 
   3566   Returns:
   3567       a string, one of 'SAME', 'VALID'.
   3568 
   3569   Raises:
   3570       ValueError: if invalid `padding'`
   3571   """
   3572   if padding == 'same':
   3573     padding = 'SAME'
   3574   elif padding == 'valid':
   3575     padding = 'VALID'
   3576   else:
   3577     raise ValueError('Invalid padding: ' + str(padding))
   3578   return padding
   3579 
   3580 
   3581 @tf_export('keras.backend.conv1d')
   3582 def conv1d(x,
   3583            kernel,
   3584            strides=1,
   3585            padding='valid',
   3586            data_format=None,
   3587            dilation_rate=1):
   3588   """1D convolution.
   3589 
   3590   Arguments:
   3591       x: Tensor or variable.
   3592       kernel: kernel tensor.
   3593       strides: stride integer.
   3594       padding: string, `"same"`, `"causal"` or `"valid"`.
   3595       data_format: string, one of "channels_last", "channels_first".
   3596       dilation_rate: integer dilate rate.
   3597 
   3598   Returns:
   3599       A tensor, result of 1D convolution.
   3600 
   3601   Raises:
   3602       ValueError: if `data_format` is neither `channels_last` or
   3603       `channels_first`.
   3604   """
   3605   if data_format is None:
   3606     data_format = image_data_format()
   3607   if data_format not in {'channels_first', 'channels_last'}:
   3608     raise ValueError('Unknown data_format: ' + str(data_format))
   3609 
   3610   kernel_shape = kernel.get_shape().as_list()
   3611   if padding == 'causal':
   3612     # causal (dilated) convolution:
   3613     left_pad = dilation_rate * (kernel_shape[0] - 1)
   3614     x = temporal_padding(x, (left_pad, 0))
   3615     padding = 'valid'
   3616   padding = _preprocess_padding(padding)
   3617   if data_format == 'channels_last':
   3618     tf_data_format = 'NWC'
   3619   else:
   3620     tf_data_format = 'NCW'
   3621   x = nn.convolution(
   3622       input=x,
   3623       filter=kernel,
   3624       dilation_rate=(dilation_rate,),
   3625       strides=(strides,),
   3626       padding=padding,
   3627       data_format=tf_data_format)
   3628   return x
   3629 
   3630 
   3631 @tf_export('keras.backend.conv2d')
   3632 def conv2d(x,
   3633            kernel,
   3634            strides=(1, 1),
   3635            padding='valid',
   3636            data_format=None,
   3637            dilation_rate=(1, 1)):
   3638   """2D convolution.
   3639 
   3640   Arguments:
   3641       x: Tensor or variable.
   3642       kernel: kernel tensor.
   3643       strides: strides tuple.
   3644       padding: string, `"same"` or `"valid"`.
   3645       data_format: `"channels_last"` or `"channels_first"`.
   3646           Whether to use Theano or TensorFlow data format
   3647           for inputs/kernels/outputs.
   3648       dilation_rate: tuple of 2 integers.
   3649 
   3650   Returns:
   3651       A tensor, result of 2D convolution.
   3652 
   3653   Raises:
   3654       ValueError: if `data_format` is neither `channels_last` or
   3655       `channels_first`.
   3656   """
   3657   if data_format is None:
   3658     data_format = image_data_format()
   3659   if data_format not in {'channels_first', 'channels_last'}:
   3660     raise ValueError('Unknown data_format: ' + str(data_format))
   3661 
   3662   x, tf_data_format = _preprocess_conv2d_input(x, data_format)
   3663   padding = _preprocess_padding(padding)
   3664   x = nn.convolution(
   3665       input=x,
   3666       filter=kernel,
   3667       dilation_rate=dilation_rate,
   3668       strides=strides,
   3669       padding=padding,
   3670       data_format=tf_data_format)
   3671   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3672     x = array_ops.transpose(x, (0, 3, 1, 2))  # NHWC -> NCHW
   3673   return x
   3674 
   3675 
   3676 @tf_export('keras.backend.conv2d_transpose')
   3677 def conv2d_transpose(x,
   3678                      kernel,
   3679                      output_shape,
   3680                      strides=(1, 1),
   3681                      padding='valid',
   3682                      data_format=None):
   3683   """2D deconvolution (i.e.
   3684 
   3685   transposed convolution).
   3686 
   3687   Arguments:
   3688       x: Tensor or variable.
   3689       kernel: kernel tensor.
   3690       output_shape: 1D int tensor for the output shape.
   3691       strides: strides tuple.
   3692       padding: string, `"same"` or `"valid"`.
   3693       data_format: string, `"channels_last"` or `"channels_first"`.
   3694           Whether to use Theano or TensorFlow/CNTK data format
   3695           for inputs/kernels/outputs.
   3696 
   3697   Returns:
   3698       A tensor, result of transposed 2D convolution.
   3699 
   3700   Raises:
   3701       ValueError: if `data_format` is neither `channels_last` or
   3702       `channels_first`.
   3703   """
   3704   if data_format is None:
   3705     data_format = image_data_format()
   3706   if data_format not in {'channels_first', 'channels_last'}:
   3707     raise ValueError('Unknown data_format: ' + str(data_format))
   3708   if isinstance(output_shape, (tuple, list)):
   3709     output_shape = array_ops.stack(output_shape)
   3710 
   3711   x, tf_data_format = _preprocess_conv2d_input(x, data_format)
   3712 
   3713   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3714     output_shape = (output_shape[0], output_shape[2], output_shape[3],
   3715                     output_shape[1])
   3716   if output_shape[0] is None:
   3717     output_shape = (array_ops.shape(x)[0],) + tuple(output_shape[1:])
   3718     output_shape = array_ops.stack(list(output_shape))
   3719 
   3720   padding = _preprocess_padding(padding)
   3721   if tf_data_format == 'NHWC':
   3722     strides = (1,) + strides + (1,)
   3723   else:
   3724     strides = (1, 1) + strides
   3725 
   3726   x = nn.conv2d_transpose(
   3727       x,
   3728       kernel,
   3729       output_shape,
   3730       strides,
   3731       padding=padding,
   3732       data_format=tf_data_format)
   3733   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3734     x = array_ops.transpose(x, (0, 3, 1, 2))  # NHWC -> NCHW
   3735   return x
   3736 
   3737 
   3738 def separable_conv1d(x,
   3739                      depthwise_kernel,
   3740                      pointwise_kernel,
   3741                      strides=1,
   3742                      padding='valid',
   3743                      data_format=None,
   3744                      dilation_rate=1):
   3745   """1D convolution with separable filters.
   3746 
   3747   Arguments:
   3748       x: input tensor
   3749       depthwise_kernel: convolution kernel for the depthwise convolution.
   3750       pointwise_kernel: kernel for the 1x1 convolution.
   3751       strides: stride integer.
   3752       padding: string, `"same"` or `"valid"`.
   3753       data_format: string, `"channels_last"` or `"channels_first"`.
   3754       dilation_rate: integer dilation rate.
   3755 
   3756   Returns:
   3757       Output tensor.
   3758 
   3759   Raises:
   3760       ValueError: if `data_format` is neither `channels_last` or
   3761       `channels_first`.
   3762   """
   3763   if data_format is None:
   3764     data_format = image_data_format()
   3765   if data_format not in {'channels_first', 'channels_last'}:
   3766     raise ValueError('Unknown data_format: ' + str(data_format))
   3767 
   3768   x, tf_data_format = _preprocess_conv1d_input(x, data_format)
   3769   padding = _preprocess_padding(padding)
   3770   if not isinstance(strides, tuple):
   3771     strides = tuple(strides)
   3772   if tf_data_format == 'NHWC':
   3773     spatial_start_dim = 1
   3774     strides = (1,) + strides * 2 + (1,)
   3775   else:
   3776     spatial_start_dim = 2
   3777     strides = (1, 1) + strides * 2
   3778   x = array_ops.expand_dims(x, spatial_start_dim)
   3779   depthwise_kernel = array_ops.expand_dims(depthwise_kernel, 0)
   3780   pointwise_kernel = array_ops.expand_dims(pointwise_kernel, 0)
   3781   dilation_rate = (1,) + dilation_rate
   3782 
   3783   x = nn.separable_conv2d(
   3784       x,
   3785       depthwise_kernel,
   3786       pointwise_kernel,
   3787       strides=strides,
   3788       padding=padding,
   3789       rate=dilation_rate,
   3790       data_format=tf_data_format)
   3791 
   3792   x = array_ops.squeeze(x, [spatial_start_dim])
   3793 
   3794   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3795     x = array_ops.transpose(x, (0, 2, 1))  # NWC -> NCW
   3796 
   3797   return x
   3798 
   3799 
   3800 @tf_export('keras.backend.separable_conv2d')
   3801 def separable_conv2d(x,
   3802                      depthwise_kernel,
   3803                      pointwise_kernel,
   3804                      strides=(1, 1),
   3805                      padding='valid',
   3806                      data_format=None,
   3807                      dilation_rate=(1, 1)):
   3808   """2D convolution with separable filters.
   3809 
   3810   Arguments:
   3811       x: input tensor
   3812       depthwise_kernel: convolution kernel for the depthwise convolution.
   3813       pointwise_kernel: kernel for the 1x1 convolution.
   3814       strides: strides tuple (length 2).
   3815       padding: string, `"same"` or `"valid"`.
   3816       data_format: string, `"channels_last"` or `"channels_first"`.
   3817       dilation_rate: tuple of integers,
   3818           dilation rates for the separable convolution.
   3819 
   3820   Returns:
   3821       Output tensor.
   3822 
   3823   Raises:
   3824       ValueError: if `data_format` is neither `channels_last` or
   3825       `channels_first`.
   3826   """
   3827   if data_format is None:
   3828     data_format = image_data_format()
   3829   if data_format not in {'channels_first', 'channels_last'}:
   3830     raise ValueError('Unknown data_format: ' + str(data_format))
   3831 
   3832   x, tf_data_format = _preprocess_conv2d_input(x, data_format)
   3833   padding = _preprocess_padding(padding)
   3834   if not isinstance(strides, tuple):
   3835     strides = tuple(strides)
   3836   if tf_data_format == 'NHWC':
   3837     strides = (1,) + strides + (1,)
   3838   else:
   3839     strides = (1, 1) + strides
   3840 
   3841   x = nn.separable_conv2d(
   3842       x,
   3843       depthwise_kernel,
   3844       pointwise_kernel,
   3845       strides=strides,
   3846       padding=padding,
   3847       rate=dilation_rate,
   3848       data_format=tf_data_format)
   3849   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3850     x = array_ops.transpose(x, (0, 3, 1, 2))  # NHWC -> NCHW
   3851   return x
   3852 
   3853 
   3854 def depthwise_conv2d(x,
   3855                      depthwise_kernel,
   3856                      strides=(1, 1),
   3857                      padding='valid',
   3858                      data_format=None,
   3859                      dilation_rate=(1, 1)):
   3860   """2D convolution with separable filters.
   3861 
   3862   Arguments:
   3863       x: input tensor
   3864       depthwise_kernel: convolution kernel for the depthwise convolution.
   3865       strides: strides tuple (length 2).
   3866       padding: string, `"same"` or `"valid"`.
   3867       data_format: string, `"channels_last"` or `"channels_first"`.
   3868       dilation_rate: tuple of integers,
   3869           dilation rates for the separable convolution.
   3870 
   3871   Returns:
   3872       Output tensor.
   3873 
   3874   Raises:
   3875       ValueError: if `data_format` is neither `channels_last` or
   3876       `channels_first`.
   3877   """
   3878   if data_format is None:
   3879     data_format = image_data_format()
   3880   if data_format not in {'channels_first', 'channels_last'}:
   3881     raise ValueError('Unknown data_format: ' + str(data_format))
   3882 
   3883   x, tf_data_format = _preprocess_conv2d_input(x, data_format)
   3884   padding = _preprocess_padding(padding)
   3885   if tf_data_format == 'NHWC':
   3886     strides = (1,) + strides + (1,)
   3887   else:
   3888     strides = (1, 1) + strides
   3889 
   3890   x = nn.depthwise_conv2d(
   3891       x,
   3892       depthwise_kernel,
   3893       strides=strides,
   3894       padding=padding,
   3895       rate=dilation_rate,
   3896       data_format=tf_data_format)
   3897   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   3898     x = array_ops.transpose(x, (0, 3, 1, 2))  # NHWC -> NCHW
   3899   return x
   3900 
   3901 
   3902 @tf_export('keras.backend.conv3d')
   3903 def conv3d(x,
   3904            kernel,
   3905            strides=(1, 1, 1),
   3906            padding='valid',
   3907            data_format=None,
   3908            dilation_rate=(1, 1, 1)):
   3909   """3D convolution.
   3910 
   3911   Arguments:
   3912       x: Tensor or variable.
   3913       kernel: kernel tensor.
   3914       strides: strides tuple.
   3915       padding: string, `"same"` or `"valid"`.
   3916       data_format: string, `"channels_last"` or `"channels_first"`.
   3917           Whether to use Theano or TensorFlow/CNTK data format
   3918           for inputs/kernels/outputs.
   3919       dilation_rate: tuple of 3 integers.
   3920 
   3921   Returns:
   3922       A tensor, result of 3D convolution.
   3923 
   3924   Raises:
   3925       ValueError: if `data_format` is neither `channels_last` or
   3926       `channels_first`.
   3927   """
   3928   if data_format is None:
   3929     data_format = image_data_format()
   3930   if data_format not in {'channels_first', 'channels_last'}:
   3931     raise ValueError('Unknown data_format: ' + str(data_format))
   3932 
   3933   x, tf_data_format = _preprocess_conv3d_input(x, data_format)
   3934   padding = _preprocess_padding(padding)
   3935   x = nn.convolution(
   3936       input=x,
   3937       filter=kernel,
   3938       dilation_rate=dilation_rate,
   3939       strides=strides,
   3940       padding=padding,
   3941       data_format=tf_data_format)
   3942   if data_format == 'channels_first' and tf_data_format == 'NDHWC':
   3943     x = array_ops.transpose(x, (0, 4, 1, 2, 3))
   3944   return x
   3945 
   3946 
   3947 def conv3d_transpose(x,
   3948                      kernel,
   3949                      output_shape,
   3950                      strides=(1, 1, 1),
   3951                      padding='valid',
   3952                      data_format=None):
   3953   """3D deconvolution (i.e.
   3954 
   3955   transposed convolution).
   3956 
   3957   Arguments:
   3958       x: input tensor.
   3959       kernel: kernel tensor.
   3960       output_shape: 1D int tensor for the output shape.
   3961       strides: strides tuple.
   3962       padding: string, "same" or "valid".
   3963       data_format: string, `"channels_last"` or `"channels_first"`.
   3964           Whether to use Theano or TensorFlow/CNTK data format
   3965           for inputs/kernels/outputs.
   3966 
   3967   Returns:
   3968       A tensor, result of transposed 3D convolution.
   3969 
   3970   Raises:
   3971       ValueError: if `data_format` is neither `channels_last` or
   3972       `channels_first`.
   3973   """
   3974   if data_format is None:
   3975     data_format = image_data_format()
   3976   if data_format not in {'channels_first', 'channels_last'}:
   3977     raise ValueError('Unknown data_format: ' + str(data_format))
   3978   if isinstance(output_shape, (tuple, list)):
   3979     output_shape = array_ops.stack(output_shape)
   3980 
   3981   x, tf_data_format = _preprocess_conv3d_input(x, data_format)
   3982 
   3983   if data_format == 'channels_first' and tf_data_format == 'NDHWC':
   3984     output_shape = (output_shape[0], output_shape[2], output_shape[3],
   3985                     output_shape[4], output_shape[1])
   3986   if output_shape[0] is None:
   3987     output_shape = (array_ops.shape(x)[0],) + tuple(output_shape[1:])
   3988     output_shape = array_ops.stack(list(output_shape))
   3989 
   3990   padding = _preprocess_padding(padding)
   3991   if tf_data_format == 'NDHWC':
   3992     strides = (1,) + strides + (1,)
   3993   else:
   3994     strides = (1, 1) + strides
   3995 
   3996   x = nn.conv3d_transpose(
   3997       x,
   3998       kernel,
   3999       output_shape,
   4000       strides,
   4001       padding=padding,
   4002       data_format=tf_data_format)
   4003   if data_format == 'channels_first' and tf_data_format == 'NDHWC':
   4004     x = array_ops.transpose(x, (0, 4, 1, 2, 3))
   4005   return x
   4006 
   4007 
   4008 @tf_export('keras.backend.pool2d')
   4009 def pool2d(x,
   4010            pool_size,
   4011            strides=(1, 1),
   4012            padding='valid',
   4013            data_format=None,
   4014            pool_mode='max'):
   4015   """2D Pooling.
   4016 
   4017   Arguments:
   4018       x: Tensor or variable.
   4019       pool_size: tuple of 2 integers.
   4020       strides: tuple of 2 integers.
   4021       padding: string, `"same"` or `"valid"`.
   4022       data_format: string, `"channels_last"` or `"channels_first"`.
   4023       pool_mode: string, `"max"` or `"avg"`.
   4024 
   4025   Returns:
   4026       A tensor, result of 2D pooling.
   4027 
   4028   Raises:
   4029       ValueError: if `data_format` is neither `"channels_last"` or
   4030       `"channels_first"`.
   4031       ValueError: if `pool_mode` is neither `"max"` or `"avg"`.
   4032   """
   4033   if data_format is None:
   4034     data_format = image_data_format()
   4035   if data_format not in {'channels_first', 'channels_last'}:
   4036     raise ValueError('Unknown data_format: ' + str(data_format))
   4037 
   4038   x, tf_data_format = _preprocess_conv2d_input(x, data_format)
   4039   padding = _preprocess_padding(padding)
   4040   if tf_data_format == 'NHWC':
   4041     strides = (1,) + strides + (1,)
   4042     pool_size = (1,) + pool_size + (1,)
   4043   else:
   4044     strides = (1, 1) + strides
   4045     pool_size = (1, 1) + pool_size
   4046 
   4047   if pool_mode == 'max':
   4048     x = nn.max_pool(
   4049         x, pool_size, strides, padding=padding, data_format=tf_data_format)
   4050   elif pool_mode == 'avg':
   4051     x = nn.avg_pool(
   4052         x, pool_size, strides, padding=padding, data_format=tf_data_format)
   4053   else:
   4054     raise ValueError('Invalid pooling mode: ' + str(pool_mode))
   4055 
   4056   if data_format == 'channels_first' and tf_data_format == 'NHWC':
   4057     x = array_ops.transpose(x, (0, 3, 1, 2))  # NHWC -> NCHW
   4058   return x
   4059 
   4060 
   4061 @tf_export('keras.backend.pool3d')
   4062 def pool3d(x,
   4063            pool_size,
   4064            strides=(1, 1, 1),
   4065            padding='valid',
   4066            data_format=None,
   4067            pool_mode='max'):
   4068   """3D Pooling.
   4069 
   4070   Arguments:
   4071       x: Tensor or variable.
   4072       pool_size: tuple of 3 integers.
   4073       strides: tuple of 3 integers.
   4074       padding: string, `"same"` or `"valid"`.
   4075       data_format: string, `"channels_last"` or `"channels_first"`.
   4076       pool_mode: string, `"max"` or `"avg"`.
   4077 
   4078   Returns:
   4079       A tensor, result of 3D pooling.
   4080 
   4081   Raises:
   4082       ValueError: if `data_format` is neither `"channels_last"` or
   4083       `"channels_first"`.
   4084       ValueError: if `pool_mode` is neither `"max"` or `"avg"`.
   4085   """
   4086   if data_format is None:
   4087     data_format = image_data_format()
   4088   if data_format not in {'channels_first', 'channels_last'}:
   4089     raise ValueError('Unknown data_format: ' + str(data_format))
   4090 
   4091   x, tf_data_format = _preprocess_conv3d_input(x, data_format)
   4092   padding = _preprocess_padding(padding)
   4093   if tf_data_format == 'NDHWC':
   4094     strides = (1,) + strides + (1,)
   4095     pool_size = (1,) + pool_size + (1,)
   4096   else:
   4097     strides = (1, 1) + strides
   4098     pool_size = (1, 1) + pool_size
   4099 
   4100   if pool_mode == 'max':
   4101     x = nn.max_pool3d(
   4102         x, pool_size, strides, padding=padding, data_format=tf_data_format)
   4103   elif pool_mode == 'avg':
   4104     x = nn.avg_pool3d(
   4105         x, pool_size, strides, padding=padding, data_format=tf_data_format)
   4106   else:
   4107     raise ValueError('Invalid pooling mode: ' + str(pool_mode))
   4108 
   4109   if data_format == 'channels_first' and tf_data_format == 'NDHWC':
   4110     x = array_ops.transpose(x, (0, 4, 1, 2, 3))
   4111   return x
   4112 
   4113 
   4114 def local_conv1d(inputs, kernel, kernel_size, strides, data_format=None):
   4115   """Apply 1D conv with un-shared weights.
   4116 
   4117   Arguments:
   4118       inputs: 3D tensor with shape: (batch_size, steps, input_dim)
   4119       kernel: the unshared weight for convolution,
   4120               with shape (output_length, feature_dim, filters)
   4121       kernel_size: a tuple of a single integer,
   4122                    specifying the length of the 1D convolution window
   4123       strides: a tuple of a single integer,
   4124                specifying the stride length of the convolution
   4125       data_format: the data format, channels_first or channels_last
   4126 
   4127   Returns:
   4128       the tensor after 1d conv with un-shared weights, with shape (batch_size,
   4129       output_length, filters)
   4130 
   4131   Raises:
   4132       ValueError: if `data_format` is neither `channels_last` or
   4133       `channels_first`.
   4134   """
   4135   if data_format is None:
   4136     data_format = image_data_format()
   4137   if data_format not in {'channels_first', 'channels_last'}:
   4138     raise ValueError('Unknown data_format: ' + str(data_format))
   4139 
   4140   stride = strides[0]
   4141   kernel_shape = int_shape(kernel)
   4142   output_length = kernel_shape[0]
   4143   feature_dim = kernel_shape[1]
   4144 
   4145   xs = []
   4146   for i in range(output_length):
   4147     slice_length = slice(i * stride, i * stride + kernel_size[0])
   4148     xs.append(reshape(inputs[:, slice_length, :], (1, -1, feature_dim)))
   4149   x_aggregate = concatenate(xs, axis=0)
   4150   # Shape: `(output_length, batch_size, filters)`.
   4151   output = batch_dot(x_aggregate, kernel)
   4152   return permute_dimensions(output, (1, 0, 2))
   4153 
   4154 
   4155 def local_conv2d(inputs,
   4156                  kernel,
   4157                  kernel_size,
   4158                  strides,
   4159                  output_shape,
   4160                  data_format=None):
   4161   """Apply 2D conv with un-shared weights.
   4162 
   4163   Arguments:
   4164       inputs: 4D tensor with shape:
   4165               (batch_size, filters, new_rows, new_cols)
   4166               if data_format='channels_first'
   4167               or 4D tensor with shape:
   4168               (batch_size, new_rows, new_cols, filters)
   4169               if data_format='channels_last'.
   4170       kernel: the unshared weight for convolution,
   4171               with shape (output_items, feature_dim, filters)
   4172       kernel_size: a tuple of 2 integers, specifying the
   4173                    width and height of the 2D convolution window.
   4174       strides: a tuple of 2 integers, specifying the strides
   4175                of the convolution along the width and height.
   4176       output_shape: a tuple with (output_row, output_col)
   4177       data_format: the data format, channels_first or channels_last
   4178 
   4179   Returns:
   4180       A 4d tensor with shape:
   4181       (batch_size, filters, new_rows, new_cols)
   4182       if data_format='channels_first'
   4183       or 4D tensor with shape:
   4184       (batch_size, new_rows, new_cols, filters)
   4185       if data_format='channels_last'.
   4186 
   4187   Raises:
   4188       ValueError: if `data_format` is neither
   4189                   `channels_last` or `channels_first`.
   4190   """
   4191   if data_format is None:
   4192     data_format = image_data_format()
   4193   if data_format not in {'channels_first', 'channels_last'}:
   4194     raise ValueError('Unknown data_format: ' + str(data_format))
   4195 
   4196   stride_row, stride_col = strides
   4197   output_row, output_col = output_shape
   4198   kernel_shape = int_shape(kernel)
   4199   feature_dim = kernel_shape[1]
   4200   filters = kernel_shape[2]
   4201 
   4202   xs = []
   4203   for i in range(output_row):
   4204     for j in range(output_col):
   4205       slice_row = slice(i * stride_row, i * stride_row + kernel_size[0])
   4206       slice_col = slice(j * stride_col, j * stride_col + kernel_size[1])
   4207       if data_format == 'channels_first':
   4208         xs.append(
   4209             reshape(inputs[:, :, slice_row, slice_col], (1, -1, feature_dim)))
   4210       else:
   4211         xs.append(
   4212             reshape(inputs[:, slice_row, slice_col, :], (1, -1, feature_dim)))
   4213 
   4214   x_aggregate = concatenate(xs, axis=0)
   4215   output = batch_dot(x_aggregate, kernel)
   4216   output = reshape(output, (output_row, output_col, -1, filters))
   4217 
   4218   if data_format == 'channels_first':
   4219     output = permute_dimensions(output, (2, 3, 0, 1))
   4220   else:
   4221     output = permute_dimensions(output, (2, 0, 1, 3))
   4222   return output
   4223 
   4224 
   4225 @tf_export('keras.backend.bias_add')
   4226 def bias_add(x, bias, data_format=None):
   4227   """Adds a bias vector to a tensor.
   4228 
   4229   Arguments:
   4230       x: Tensor or variable.
   4231       bias: Bias tensor to add.
   4232       data_format: string, `"channels_last"` or `"channels_first"`.
   4233 
   4234   Returns:
   4235       Output tensor.
   4236 
   4237   Raises:
   4238       ValueError: In one of the two cases below:
   4239                   1. invalid `data_format` argument.
   4240                   2. invalid bias shape.
   4241                      the bias should be either a vector or
   4242                      a tensor with ndim(x) - 1 dimension
   4243   """
   4244   if data_format is None:
   4245     data_format = image_data_format()
   4246   if data_format not in {'channels_first', 'channels_last'}:
   4247     raise ValueError('Unknown data_format: ' + str(data_format))
   4248   bias_shape = int_shape(bias)
   4249   if len(bias_shape) != 1 and len(bias_shape) != ndim(x) - 1:
   4250     raise ValueError(
   4251         'Unexpected bias dimensions %d, expect to be 1 or %d dimensions' %
   4252         (len(bias_shape), ndim(x)))
   4253   # pylint: disable=g-no-augmented-assignment
   4254   if ndim(x) == 5:
   4255     if data_format == 'channels_first':
   4256       if len(bias_shape) == 1:
   4257         x = x + reshape(bias, (1, bias_shape[0], 1, 1, 1))
   4258       else:
   4259         x = x + reshape(bias, (1, bias_shape[3]) + bias_shape[:3])
   4260     elif data_format == 'channels_last':
   4261       if len(bias_shape) == 1:
   4262         x = x + reshape(bias, (1, 1, 1, bias_shape[0]))
   4263       else:
   4264         x = x + reshape(bias, (1,) + bias_shape)
   4265   elif ndim(x) == 4:
   4266     if data_format == 'channels_first':
   4267       if len(bias_shape) == 1:
   4268         if _has_nchw_support():
   4269           x = nn.bias_add(x, bias, data_format='NCHW')
   4270         else:
   4271           x = x + reshape(bias, (1, bias_shape[0], 1, 1))
   4272       else:
   4273         x = x + reshape(bias, (1, bias_shape[2]) + bias_shape[:2])
   4274     elif data_format == 'channels_last':
   4275       if len(bias_shape) == 1:
   4276         x = nn.bias_add(x, bias, data_format='NHWC')
   4277       else:
   4278         x = x + reshape(bias, (1,) + bias_shape)
   4279   elif ndim(x) == 3:
   4280     if data_format == 'channels_first':
   4281       if len(bias_shape) == 1:
   4282         x = x + reshape(bias, (1, bias_shape[0], 1))
   4283       else:
   4284         x = x + reshape(bias, (1, bias_shape[1], bias_shape[0]))
   4285     elif data_format == 'channels_last':
   4286       if len(bias_shape) == 1:
   4287         x = x + reshape(bias, (1, 1, bias_shape[0]))
   4288       else:
   4289         x = x + reshape(bias, (1,) + bias_shape)
   4290   else:
   4291     x = nn.bias_add(x, bias)
   4292   # pylint: enable=g-no-augmented-assignment
   4293   return x
   4294 
   4295 
   4296 # RANDOMNESS
   4297 
   4298 
   4299 @tf_export('keras.backend.random_normal')
   4300 def random_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None):
   4301   """Returns a tensor with normal distribution of values.
   4302 
   4303   Arguments:
   4304       shape: A tuple of integers, the shape of tensor to create.
   4305       mean: A float, mean of the normal distribution to draw samples.
   4306       stddev: A float, standard deviation of the normal distribution
   4307           to draw samples.
   4308       dtype: String, dtype of returned tensor.
   4309       seed: Integer, random seed.
   4310 
   4311   Returns:
   4312       A tensor.
   4313   """
   4314   if dtype is None:
   4315     dtype = floatx()
   4316   if seed is None:
   4317     seed = np.random.randint(10e6)
   4318   return random_ops.random_normal(
   4319       shape, mean=mean, stddev=stddev, dtype=dtype, seed=seed)
   4320 
   4321 
   4322 @tf_export('keras.backend.random_uniform')
   4323 def random_uniform(shape, minval=0.0, maxval=1.0, dtype=None, seed=None):
   4324   """Returns a tensor with uniform distribution of values.
   4325 
   4326   Arguments:
   4327       shape: A tuple of integers, the shape of tensor to create.
   4328       minval: A float, lower boundary of the uniform distribution
   4329           to draw samples.
   4330       maxval: A float, upper boundary of the uniform distribution
   4331           to draw samples.
   4332       dtype: String, dtype of returned tensor.
   4333       seed: Integer, random seed.
   4334 
   4335   Returns:
   4336       A tensor.
   4337   """
   4338   if dtype is None:
   4339     dtype = floatx()
   4340   if seed is None:
   4341     seed = np.random.randint(10e6)
   4342   return random_ops.random_uniform(
   4343       shape, minval=minval, maxval=maxval, dtype=dtype, seed=seed)
   4344 
   4345 
   4346 @tf_export('keras.backend.random_binomial')
   4347 def random_binomial(shape, p=0.0, dtype=None, seed=None):
   4348   """Returns a tensor with random binomial distribution of values.
   4349 
   4350   Arguments:
   4351       shape: A tuple of integers, the shape of tensor to create.
   4352       p: A float, `0. <= p <= 1`, probability of binomial distribution.
   4353       dtype: String, dtype of returned tensor.
   4354       seed: Integer, random seed.
   4355 
   4356   Returns:
   4357       A tensor.
   4358   """
   4359   if dtype is None:
   4360     dtype = floatx()
   4361   if seed is None:
   4362     seed = np.random.randint(10e6)
   4363   return array_ops.where(
   4364       random_ops.random_uniform(shape, dtype=dtype, seed=seed) <= p,
   4365       array_ops.ones(shape, dtype=dtype), array_ops.zeros(shape, dtype=dtype))
   4366 
   4367 
   4368 @tf_export('keras.backend.truncated_normal')
   4369 def truncated_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None):
   4370   """Returns a tensor with truncated random normal distribution of values.
   4371 
   4372   The generated values follow a normal distribution
   4373   with specified mean and standard deviation,
   4374   except that values whose magnitude is more than
   4375   two standard deviations from the mean are dropped and re-picked.
   4376 
   4377   Arguments:
   4378       shape: A tuple of integers, the shape of tensor to create.
   4379       mean: Mean of the values.
   4380       stddev: Standard deviation of the values.
   4381       dtype: String, dtype of returned tensor.
   4382       seed: Integer, random seed.
   4383 
   4384   Returns:
   4385       A tensor.
   4386   """
   4387   if dtype is None:
   4388     dtype = floatx()
   4389   if seed is None:
   4390     seed = np.random.randint(10e6)
   4391   return random_ops.truncated_normal(
   4392       shape, mean, stddev, dtype=dtype, seed=seed)
   4393 
   4394 
   4395 # CTC
   4396 # TensorFlow has a native implementation, but it uses sparse tensors
   4397 # and therefore requires a wrapper for Keras. The functions below convert
   4398 # dense to sparse tensors and also wraps up the beam search code that is
   4399 # in TensorFlow's CTC implementation
   4400 
   4401 
   4402 @tf_export('keras.backend.ctc_label_dense_to_sparse')
   4403 def ctc_label_dense_to_sparse(labels, label_lengths):
   4404   """Converts CTC labels from dense to sparse.
   4405 
   4406   Arguments:
   4407       labels: dense CTC labels.
   4408       label_lengths: length of the labels.
   4409 
   4410   Returns:
   4411       A sparse tensor representation of the labels.
   4412   """
   4413   label_shape = array_ops.shape(labels)
   4414   num_batches_tns = array_ops.stack([label_shape[0]])
   4415   max_num_labels_tns = array_ops.stack([label_shape[1]])
   4416 
   4417   def range_less_than(_, current_input):
   4418     return array_ops.expand_dims(
   4419         math_ops.range(label_shape[1]), 0) < array_ops.fill(
   4420             max_num_labels_tns, current_input)
   4421 
   4422   init = math_ops.cast(
   4423       array_ops.fill([1, label_shape[1]], 0), dtypes_module.bool)
   4424   dense_mask = functional_ops.scan(
   4425       range_less_than, label_lengths, initializer=init, parallel_iterations=1)
   4426   dense_mask = dense_mask[:, 0, :]
   4427 
   4428   label_array = array_ops.reshape(
   4429       array_ops.tile(math_ops.range(0, label_shape[1]), num_batches_tns),
   4430       label_shape)
   4431   label_ind = array_ops.boolean_mask(label_array, dense_mask)
   4432 
   4433   batch_array = array_ops.transpose(
   4434       array_ops.reshape(
   4435           array_ops.tile(math_ops.range(0, label_shape[0]), max_num_labels_tns),
   4436           reverse(label_shape, 0)))
   4437   batch_ind = array_ops.boolean_mask(batch_array, dense_mask)
   4438   indices = array_ops.transpose(
   4439       array_ops.reshape(concatenate([batch_ind, label_ind], axis=0), [2, -1]))
   4440 
   4441   vals_sparse = array_ops.gather_nd(labels, indices)
   4442 
   4443   return sparse_tensor.SparseTensor(
   4444       math_ops.to_int64(indices), vals_sparse, math_ops.to_int64(label_shape))
   4445 
   4446 
   4447 @tf_export('keras.backend.ctc_batch_cost')
   4448 def ctc_batch_cost(y_true, y_pred, input_length, label_length):
   4449   """Runs CTC loss algorithm on each batch element.
   4450 
   4451   Arguments:
   4452       y_true: tensor `(samples, max_string_length)`
   4453           containing the truth labels.
   4454       y_pred: tensor `(samples, time_steps, num_categories)`
   4455           containing the prediction, or output of the softmax.
   4456       input_length: tensor `(samples, 1)` containing the sequence length for
   4457           each batch item in `y_pred`.
   4458       label_length: tensor `(samples, 1)` containing the sequence length for
   4459           each batch item in `y_true`.
   4460 
   4461   Returns:
   4462       Tensor with shape (samples,1) containing the
   4463           CTC loss of each element.
   4464   """
   4465   label_length = math_ops.to_int32(array_ops.squeeze(label_length))
   4466   input_length = math_ops.to_int32(array_ops.squeeze(input_length))
   4467   sparse_labels = math_ops.to_int32(
   4468       ctc_label_dense_to_sparse(y_true, label_length))
   4469 
   4470   y_pred = math_ops.log(array_ops.transpose(y_pred, perm=[1, 0, 2]) + epsilon())
   4471 
   4472   return array_ops.expand_dims(
   4473       ctc.ctc_loss(
   4474           inputs=y_pred, labels=sparse_labels, sequence_length=input_length), 1)
   4475 
   4476 
   4477 @tf_export('keras.backend.ctc_decode')
   4478 def ctc_decode(y_pred, input_length, greedy=True, beam_width=100, top_paths=1):
   4479   """Decodes the output of a softmax.
   4480 
   4481   Can use either greedy search (also known as best path)
   4482   or a constrained dictionary search.
   4483 
   4484   Arguments:
   4485       y_pred: tensor `(samples, time_steps, num_categories)`
   4486           containing the prediction, or output of the softmax.
   4487       input_length: tensor `(samples, )` containing the sequence length for
   4488           each batch item in `y_pred`.
   4489       greedy: perform much faster best-path search if `true`.
   4490           This does not use a dictionary.
   4491       beam_width: if `greedy` is `false`: a beam search decoder will be used
   4492           with a beam of this width.
   4493       top_paths: if `greedy` is `false`,
   4494           how many of the most probable paths will be returned.
   4495 
   4496   Returns:
   4497       Tuple:
   4498           List: if `greedy` is `true`, returns a list of one element that
   4499               contains the decoded sequence.
   4500               If `false`, returns the `top_paths` most probable
   4501               decoded sequences.
   4502               Important: blank labels are returned as `-1`.
   4503           Tensor `(top_paths, )` that contains
   4504               the log probability of each decoded sequence.
   4505   """
   4506   y_pred = math_ops.log(array_ops.transpose(y_pred, perm=[1, 0, 2]) + epsilon())
   4507   input_length = math_ops.to_int32(input_length)
   4508 
   4509   if greedy:
   4510     (decoded, log_prob) = ctc.ctc_greedy_decoder(
   4511         inputs=y_pred, sequence_length=input_length)
   4512   else:
   4513     (decoded, log_prob) = ctc.ctc_beam_search_decoder(
   4514         inputs=y_pred,
   4515         sequence_length=input_length,
   4516         beam_width=beam_width,
   4517         top_paths=top_paths)
   4518   decoded_dense = [
   4519       sparse_ops.sparse_to_dense(
   4520           st.indices, st.dense_shape, st.values, default_value=-1)
   4521       for st in decoded
   4522   ]
   4523   return (decoded_dense, log_prob)
   4524 
   4525 
   4526 # HIGH ORDER FUNCTIONS
   4527 
   4528 
   4529 @tf_export('keras.backend.map_fn')
   4530 def map_fn(fn, elems, name=None, dtype=None):
   4531   """Map the function fn over the elements elems and return the outputs.
   4532 
   4533   Arguments:
   4534       fn: Callable that will be called upon each element in elems
   4535       elems: tensor
   4536       name: A string name for the map node in the graph
   4537       dtype: Output data type.
   4538 
   4539   Returns:
   4540       Tensor with dtype `dtype`.
   4541   """
   4542   return functional_ops.map_fn(fn, elems, name=name, dtype=dtype)
   4543 
   4544 
   4545 @tf_export('keras.backend.foldl')
   4546 def foldl(fn, elems, initializer=None, name=None):
   4547   """Reduce elems using fn to combine them from left to right.
   4548 
   4549   Arguments:
   4550       fn: Callable that will be called upon each element in elems and an
   4551           accumulator, for instance `lambda acc, x: acc + x`
   4552       elems: tensor
   4553       initializer: The first value used (`elems[0]` in case of None)
   4554       name: A string name for the foldl node in the graph
   4555 
   4556   Returns:
   4557       Tensor with same type and shape as `initializer`.
   4558   """
   4559   return functional_ops.foldl(fn, elems, initializer=initializer, name=name)
   4560 
   4561 
   4562 @tf_export('keras.backend.foldr')
   4563 def foldr(fn, elems, initializer=None, name=None):
   4564   """Reduce elems using fn to combine them from right to left.
   4565 
   4566   Arguments:
   4567       fn: Callable that will be called upon each element in elems and an
   4568           accumulator, for instance `lambda acc, x: acc + x`
   4569       elems: tensor
   4570       initializer: The first value used (`elems[-1]` in case of None)
   4571       name: A string name for the foldr node in the graph
   4572 
   4573   Returns:
   4574       Same type and shape as initializer
   4575   """
   4576   return functional_ops.foldr(fn, elems, initializer=initializer, name=name)
   4577 
   4578 
   4579 # Load Keras default configuration from config file if present.
   4580 _keras_base_dir = os.path.expanduser('~')
   4581 _keras_dir = os.path.join(_keras_base_dir, '.keras')
   4582 _config_path = os.path.expanduser(os.path.join(_keras_dir, 'keras.json'))
   4583 if os.path.exists(_config_path):
   4584   try:
   4585     _config = json.load(open(_config_path))
   4586   except ValueError:
   4587     _config = {}
   4588   _floatx = _config.get('floatx', floatx())
   4589   assert _floatx in {'float16', 'float32', 'float64'}
   4590   _epsilon = _config.get('epsilon', epsilon())
   4591   assert isinstance(_epsilon, float)
   4592   _image_data_format = _config.get('image_data_format', image_data_format())
   4593   assert _image_data_format in {'channels_last', 'channels_first'}
   4594   set_floatx(_floatx)
   4595   set_epsilon(_epsilon)
   4596   set_image_data_format(_image_data_format)
   4597 
   4598 # Save config file.
   4599 if not os.path.exists(_keras_dir):
   4600   try:
   4601     os.makedirs(_keras_dir)
   4602   except OSError:
   4603     # Except permission denied and potential race conditions
   4604     # in multi-threaded environments.
   4605     pass
   4606 
   4607 if not os.path.exists(_config_path):
   4608   _config = {
   4609       'floatx': floatx(),
   4610       'epsilon': epsilon(),
   4611       'backend': 'tensorflow',
   4612       'image_data_format': image_data_format()
   4613   }
   4614   try:
   4615     with open(_config_path, 'w') as f:
   4616       f.write(json.dumps(_config, indent=4))
   4617   except IOError:
   4618     # Except permission denied.
   4619     pass
   4620