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"""
20from __future__ import absolute_import
21from __future__ import division
22from __future__ import print_function
23
24import collections
25import json
26import os
27
28import numpy as np
29
30from tensorflow.core.protobuf import config_pb2
31from tensorflow.python.client import session as session_module
32from tensorflow.python.eager import context
33from tensorflow.python.framework import constant_op
34from tensorflow.python.framework import dtypes as dtypes_module
35from tensorflow.python.framework import ops
36from tensorflow.python.framework import sparse_tensor
37from tensorflow.python.layers import base as tf_base_layers
38from tensorflow.python.ops import array_ops
39from tensorflow.python.ops import clip_ops
40from tensorflow.python.ops import control_flow_ops
41from tensorflow.python.ops import ctc_ops as ctc
42from tensorflow.python.ops import functional_ops
43from tensorflow.python.ops import gradients as gradients_module
44from tensorflow.python.ops import image_ops
45from tensorflow.python.ops import init_ops
46from tensorflow.python.ops import linalg_ops
47from tensorflow.python.ops import logging_ops
48from tensorflow.python.ops import math_ops
49from tensorflow.python.ops import nn
50from tensorflow.python.ops import random_ops
51from tensorflow.python.ops import resource_variable_ops
52from tensorflow.python.ops import sparse_ops
53from tensorflow.python.ops import state_ops
54from tensorflow.python.ops import tensor_array_grad  # pylint: disable=unused-import
55from tensorflow.python.ops import tensor_array_ops
56from tensorflow.python.ops import variables as variables_module
57from tensorflow.python.training import moving_averages
58from tensorflow.python.util import tf_inspect
59from tensorflow.python.util.tf_export import tf_export
60
61
62py_all = all
63py_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')
103def 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')
115def 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')
131def 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')
152def 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')
170def 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')
196def 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')
224def 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')
240def 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')
266def 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')
294def 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')
302def 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')
319def 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')
336def 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')
361def 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')
380def 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')
416def 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
429class _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
440def _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
454def _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
474def _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
486def _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
505def _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')
519def 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')
543def 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
569name_scope = ops.name_scope
570
571
572@tf_export('keras.backend.variable')
573def 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
624def _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')
646def 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
663def 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')
715def 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
752def 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')
768def 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')
801def 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')
829def 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')
857def 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')
888def 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')
910def 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')
943def 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')
976def 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')
1005def 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')
1031def 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
1056def 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')
1070def 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')
1107def 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')
1145def 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')
1168def 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')
1204def update(x, new_x):
1205  return state_ops.assign(x, new_x)
1206
1207
1208@tf_export('keras.backend.update_add')
1209def 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')
1223def 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')
1237def 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')
1256def 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')
1328def 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')
1421def 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')
1457def 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')
1474def 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')
1492def 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')
1510def 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')
1528def 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
1545def 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
1558def 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')
1572def 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')
1595def 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')
1613def 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')
1633def 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')
1649def 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')
1665def 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')
1679def 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')
1693def 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')
1706def 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')
1719def 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')
1735def 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')
1748def 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
1760def 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')
1782def 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')
1797def 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')
1810def 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')
1824def 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')
1845def 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')
1859def 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')
1873def 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')
1887def 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')
1901def 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')
1915def 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')
1929def 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')
1943def 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')
1957def 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')
1970def 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
1982def _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
2005def _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
2048def _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')
2085def 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')
2115def 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')
2139def 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')
2163def 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')
2177def 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')
2192def 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')
2237def 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')
2269def 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')
2322def 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')
2342def 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
2371def 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')
2388def 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')
2401def 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')
2417def 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')
2431def 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')
2445def 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')
2462def 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')
2493def 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')
2537def 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')
2551def 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')
2570def 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')
2590def 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')
2605def 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')
2623def 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')
2648def 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')
2680def 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
2706class 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')
2778def 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')
2804def 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')
2819def 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')
2840def 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')
3095def 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')
3159def 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')
3203def 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')
3227def 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')
3254def 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')
3272def 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')
3285def 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')
3298def 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')
3311def 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')
3342def 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')
3376def 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')
3400def 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')
3413def 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')
3434def 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')
3447def 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')
3470def 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')
3484def 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
3503def _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
3522def _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
3541def _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
3560def _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')
3582def 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')
3632def 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')
3677def 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
3738def 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')
3801def 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
3854def 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')
3903def 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
3947def 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')
4009def 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')
4062def 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
4114def 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
4155def 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')
4226def 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')
4300def 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')
4323def 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')
4347def 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')
4369def 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')
4403def 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')
4448def 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')
4478def 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')
4530def 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')
4546def 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')
4563def 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'))
4583if 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.
4599if 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
4607if 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