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