Module keras.api.keras.layers

Public API for tf.keras.layers namespace.

Expand source code
# This file is MACHINE GENERATED! Do not edit.
# Generated by: tensorflow/python/tools/api/generator/create_python_api.py script.
"""Public API for tf.keras.layers namespace.
"""

from __future__ import print_function as _print_function

import sys as _sys

from keras.api.keras.layers import experimental
from keras.engine.base_layer import Layer
from keras.engine.base_layer_utils import disable_v2_dtype_behavior
from keras.engine.base_layer_utils import enable_v2_dtype_behavior
from keras.engine.input_layer import Input
from keras.engine.input_layer import InputLayer
from keras.engine.input_spec import InputSpec
from keras.feature_column.dense_features import DenseFeatures
from keras.layers.advanced_activations import ELU
from keras.layers.advanced_activations import LeakyReLU
from keras.layers.advanced_activations import PReLU
from keras.layers.advanced_activations import ReLU
from keras.layers.advanced_activations import Softmax
from keras.layers.advanced_activations import ThresholdedReLU
from keras.layers.convolutional import Conv1D
from keras.layers.convolutional import Conv1D as Convolution1D
from keras.layers.convolutional import Conv1DTranspose
from keras.layers.convolutional import Conv1DTranspose as Convolution1DTranspose
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import Conv2D as Convolution2D
from keras.layers.convolutional import Conv2DTranspose
from keras.layers.convolutional import Conv2DTranspose as Convolution2DTranspose
from keras.layers.convolutional import Conv3D
from keras.layers.convolutional import Conv3D as Convolution3D
from keras.layers.convolutional import Conv3DTranspose
from keras.layers.convolutional import Conv3DTranspose as Convolution3DTranspose
from keras.layers.convolutional import Cropping1D
from keras.layers.convolutional import Cropping2D
from keras.layers.convolutional import Cropping3D
from keras.layers.convolutional import DepthwiseConv2D
from keras.layers.convolutional import SeparableConv1D
from keras.layers.convolutional import SeparableConv1D as SeparableConvolution1D
from keras.layers.convolutional import SeparableConv2D
from keras.layers.convolutional import SeparableConv2D as SeparableConvolution2D
from keras.layers.convolutional import UpSampling1D
from keras.layers.convolutional import UpSampling2D
from keras.layers.convolutional import UpSampling3D
from keras.layers.convolutional import ZeroPadding1D
from keras.layers.convolutional import ZeroPadding2D
from keras.layers.convolutional import ZeroPadding3D
from keras.layers.convolutional_recurrent import ConvLSTM1D
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.convolutional_recurrent import ConvLSTM3D
from keras.layers.core import Activation
from keras.layers.core import ActivityRegularization
from keras.layers.core import Dense
from keras.layers.core import Dropout
from keras.layers.core import Flatten
from keras.layers.core import Lambda
from keras.layers.core import Masking
from keras.layers.core import Permute
from keras.layers.core import RepeatVector
from keras.layers.core import Reshape
from keras.layers.core import SpatialDropout1D
from keras.layers.core import SpatialDropout2D
from keras.layers.core import SpatialDropout3D
from keras.layers.cudnn_recurrent import CuDNNGRU
from keras.layers.cudnn_recurrent import CuDNNLSTM
from keras.layers.dense_attention import AdditiveAttention
from keras.layers.dense_attention import Attention
from keras.layers.embeddings import Embedding
from keras.layers.local import LocallyConnected1D
from keras.layers.local import LocallyConnected2D
from keras.layers.merge import Add
from keras.layers.merge import Average
from keras.layers.merge import Concatenate
from keras.layers.merge import Dot
from keras.layers.merge import Maximum
from keras.layers.merge import Minimum
from keras.layers.merge import Multiply
from keras.layers.merge import Subtract
from keras.layers.merge import add
from keras.layers.merge import average
from keras.layers.merge import concatenate
from keras.layers.merge import dot
from keras.layers.merge import maximum
from keras.layers.merge import minimum
from keras.layers.merge import multiply
from keras.layers.merge import subtract
from keras.layers.multi_head_attention import MultiHeadAttention
from keras.layers.noise import AlphaDropout
from keras.layers.noise import GaussianDropout
from keras.layers.noise import GaussianNoise
from keras.layers.normalization.batch_normalization_v1 import BatchNormalization
from keras.layers.normalization.layer_normalization import LayerNormalization
from keras.layers.pooling import AveragePooling1D
from keras.layers.pooling import AveragePooling1D as AvgPool1D
from keras.layers.pooling import AveragePooling2D
from keras.layers.pooling import AveragePooling2D as AvgPool2D
from keras.layers.pooling import AveragePooling3D
from keras.layers.pooling import AveragePooling3D as AvgPool3D
from keras.layers.pooling import GlobalAveragePooling1D
from keras.layers.pooling import GlobalAveragePooling1D as GlobalAvgPool1D
from keras.layers.pooling import GlobalAveragePooling2D
from keras.layers.pooling import GlobalAveragePooling2D as GlobalAvgPool2D
from keras.layers.pooling import GlobalAveragePooling3D
from keras.layers.pooling import GlobalAveragePooling3D as GlobalAvgPool3D
from keras.layers.pooling import GlobalMaxPooling1D
from keras.layers.pooling import GlobalMaxPooling1D as GlobalMaxPool1D
from keras.layers.pooling import GlobalMaxPooling2D
from keras.layers.pooling import GlobalMaxPooling2D as GlobalMaxPool2D
from keras.layers.pooling import GlobalMaxPooling3D
from keras.layers.pooling import GlobalMaxPooling3D as GlobalMaxPool3D
from keras.layers.pooling import MaxPooling1D
from keras.layers.pooling import MaxPooling1D as MaxPool1D
from keras.layers.pooling import MaxPooling2D
from keras.layers.pooling import MaxPooling2D as MaxPool2D
from keras.layers.pooling import MaxPooling3D
from keras.layers.pooling import MaxPooling3D as MaxPool3D
from keras.layers.preprocessing.category_encoding import CategoryEncoding
from keras.layers.preprocessing.discretization import Discretization
from keras.layers.preprocessing.hashing import Hashing
from keras.layers.preprocessing.image_preprocessing import CenterCrop
from keras.layers.preprocessing.image_preprocessing import RandomContrast
from keras.layers.preprocessing.image_preprocessing import RandomCrop
from keras.layers.preprocessing.image_preprocessing import RandomFlip
from keras.layers.preprocessing.image_preprocessing import RandomHeight
from keras.layers.preprocessing.image_preprocessing import RandomRotation
from keras.layers.preprocessing.image_preprocessing import RandomTranslation
from keras.layers.preprocessing.image_preprocessing import RandomWidth
from keras.layers.preprocessing.image_preprocessing import RandomZoom
from keras.layers.preprocessing.image_preprocessing import Rescaling
from keras.layers.preprocessing.image_preprocessing import Resizing
from keras.layers.preprocessing.normalization import Normalization
from keras.layers.recurrent import AbstractRNNCell
from keras.layers.recurrent import GRU
from keras.layers.recurrent import GRUCell
from keras.layers.recurrent import LSTM
from keras.layers.recurrent import LSTMCell
from keras.layers.recurrent import RNN
from keras.layers.recurrent import SimpleRNN
from keras.layers.recurrent import SimpleRNNCell
from keras.layers.recurrent import StackedRNNCells
from keras.layers.serialization import deserialize
from keras.layers.serialization import serialize
from keras.layers.wrappers import Bidirectional
from keras.layers.wrappers import TimeDistributed
from keras.layers.wrappers import Wrapper

del _print_function

from tensorflow.python.util import module_wrapper as _module_wrapper

if not isinstance(_sys.modules[__name__], _module_wrapper.TFModuleWrapper):
  _sys.modules[__name__] = _module_wrapper.TFModuleWrapper(
      _sys.modules[__name__], "keras.layers", public_apis=None, deprecation=True,
      has_lite=False)

Sub-modules

keras.api.keras.layers.experimental

Public API for tf.keras.layers.experimental namespace.

Functions

def Input(shape=None, batch_size=None, name=None, dtype=None, sparse=None, tensor=None, ragged=None, type_spec=None, **kwargs)

Input() is used to instantiate a Keras tensor.

A Keras tensor is a symbolic tensor-like object, which we augment with certain attributes that allow us to build a Keras model just by knowing the inputs and outputs of the model.

For instance, if a, b and c are Keras tensors, it becomes possible to do: model = Model(input=[a, b], output=c)

Args

shape
A shape tuple (integers), not including the batch size. For instance, shape=(32,) indicates that the expected input will be batches of 32-dimensional vectors. Elements of this tuple can be None; 'None' elements represent dimensions where the shape is not known.
batch_size
optional static batch size (integer).
name
An optional name string for the layer. Should be unique in a model (do not reuse the same name twice). It will be autogenerated if it isn't provided.
dtype
The data type expected by the input, as a string (float32, float64, int32…)
sparse
A boolean specifying whether the placeholder to be created is sparse. Only one of 'ragged' and 'sparse' can be True. Note that, if sparse is False, sparse tensors can still be passed into the input - they will be densified with a default value of 0.
tensor
Optional existing tensor to wrap into the Input() layer. If set, the layer will use the tf.TypeSpec of this tensor rather than creating a new placeholder tensor.
ragged
A boolean specifying whether the placeholder to be created is ragged. Only one of 'ragged' and 'sparse' can be True. In this case, values of 'None' in the 'shape' argument represent ragged dimensions. For more information about RaggedTensors, see this guide.
type_spec
A tf.TypeSpec object to create the input placeholder from. When provided, all other args except name must be None.
**kwargs
deprecated arguments support. Supports batch_shape and batch_input_shape.

Returns

A tensor. Example:

# this is a logistic regression in Keras
x = Input(shape=(32,))
y = Dense(16, activation='softmax')(x)
model = Model(x, y)

Note that even if eager execution is enabled, Input() produces a symbolic tensor-like object (i.e. a placeholder). This symbolic tensor-like object can be used with lower-level TensorFlow ops that take tensors as inputs, as such:

x = Input(shape=(32,))
y = tf.square(x)  # This op will be treated like a layer
model = Model(x, y)

(This behavior does not work for higher-order TensorFlow APIs such as control flow and being directly watched by a tf.GradientTape).

However, the resulting model will not track any variables that were used as inputs to TensorFlow ops. All variable usages must happen within Keras layers to make sure they will be tracked by the model's weights.

The Keras Input can also create a placeholder from an arbitrary tf.TypeSpec, e.g:

x = Input(type_spec=tf.RaggedTensorSpec(shape=[None, None],
                                        dtype=tf.float32, ragged_rank=1))
y = x.values
model = Model(x, y)

When passing an arbitrary tf.TypeSpec, it must represent the signature of an entire batch instead of just one example.

Raises

ValueError
If both sparse and ragged are provided.
ValueError
If both shape and (batch_input_shape or batch_shape) are provided.
ValueError
If shape, tensor and type_spec are None.
ValueError
If arguments besides type_spec are non-None while type_spec is passed.
ValueError
if any unrecognized parameters are provided.
Expand source code
@keras_export('keras.Input', 'keras.layers.Input')
def Input(  # pylint: disable=invalid-name
    shape=None,
    batch_size=None,
    name=None,
    dtype=None,
    sparse=None,
    tensor=None,
    ragged=None,
    type_spec=None,
    **kwargs):
  """`Input()` is used to instantiate a Keras tensor.

  A Keras tensor is a symbolic tensor-like object,
  which we augment with certain attributes that allow us to build a Keras model
  just by knowing the inputs and outputs of the model.

  For instance, if `a`, `b` and `c` are Keras tensors,
  it becomes possible to do:
  `model = Model(input=[a, b], output=c)`

  Args:
      shape: A shape tuple (integers), not including the batch size.
          For instance, `shape=(32,)` indicates that the expected input
          will be batches of 32-dimensional vectors. Elements of this tuple
          can be None; 'None' elements represent dimensions where the shape is
          not known.
      batch_size: optional static batch size (integer).
      name: An optional name string for the layer.
          Should be unique in a model (do not reuse the same name twice).
          It will be autogenerated if it isn't provided.
      dtype: The data type expected by the input, as a string
          (`float32`, `float64`, `int32`...)
      sparse: A boolean specifying whether the placeholder to be created is
          sparse. Only one of 'ragged' and 'sparse' can be True. Note that,
          if `sparse` is False, sparse tensors can still be passed into the
          input - they will be densified with a default value of 0.
      tensor: Optional existing tensor to wrap into the `Input` layer.
          If set, the layer will use the `tf.TypeSpec` of this tensor rather
          than creating a new placeholder tensor.
      ragged: A boolean specifying whether the placeholder to be created is
          ragged. Only one of 'ragged' and 'sparse' can be True. In this case,
          values of 'None' in the 'shape' argument represent ragged dimensions.
          For more information about RaggedTensors, see
          [this guide](https://www.tensorflow.org/guide/ragged_tensors).
      type_spec: A `tf.TypeSpec` object to create the input placeholder from.
          When provided, all other args except name must be None.
      **kwargs: deprecated arguments support. Supports `batch_shape` and
          `batch_input_shape`.

  Returns:
    A `tensor`.

  Example:

  ```python
  # this is a logistic regression in Keras
  x = Input(shape=(32,))
  y = Dense(16, activation='softmax')(x)
  model = Model(x, y)
  ```

  Note that even if eager execution is enabled,
  `Input` produces a symbolic tensor-like object (i.e. a placeholder).
  This symbolic tensor-like object can be used with lower-level
  TensorFlow ops that take tensors as inputs, as such:

  ```python
  x = Input(shape=(32,))
  y = tf.square(x)  # This op will be treated like a layer
  model = Model(x, y)
  ```

  (This behavior does not work for higher-order TensorFlow APIs such as
  control flow and being directly watched by a `tf.GradientTape`).

  However, the resulting model will not track any variables that were
  used as inputs to TensorFlow ops. All variable usages must happen within
  Keras layers to make sure they will be tracked by the model's weights.

  The Keras Input can also create a placeholder from an arbitrary `tf.TypeSpec`,
  e.g:

  ```python
  x = Input(type_spec=tf.RaggedTensorSpec(shape=[None, None],
                                          dtype=tf.float32, ragged_rank=1))
  y = x.values
  model = Model(x, y)
  ```
  When passing an arbitrary `tf.TypeSpec`, it must represent the signature of an
  entire batch instead of just one example.

  Raises:
    ValueError: If both `sparse` and `ragged` are provided.
    ValueError: If both `shape` and (`batch_input_shape` or `batch_shape`) are
      provided.
    ValueError: If `shape`, `tensor` and `type_spec` are None.
    ValueError: If arguments besides `type_spec` are non-None while `type_spec`
                is passed.
    ValueError: if any unrecognized parameters are provided.
  """
  if sparse and ragged:
    raise ValueError(
        'Cannot set both sparse and ragged to True in a Keras input.')

  input_layer_config = {'name': name, 'dtype': dtype, 'sparse': sparse,
                        'ragged': ragged, 'input_tensor': tensor,
                        'type_spec': type_spec}

  batch_input_shape = kwargs.pop('batch_input_shape',
                                 kwargs.pop('batch_shape', None))
  if shape is not None and batch_input_shape is not None:
    raise ValueError('Only provide the `shape` OR `batch_input_shape` argument '
                     'to Input, not both at the same time.')
  if (batch_input_shape is None and shape is None and tensor is None
      and type_spec is None):
    raise ValueError('Please provide to Input a `shape`'
                     ' or a `tensor` or a `type_spec` argument. Note that '
                     '`shape` does not include the batch '
                     'dimension.')
  if kwargs:
    raise ValueError('Unrecognized keyword arguments:', kwargs.keys())

  if batch_input_shape:
    shape = batch_input_shape[1:]
    input_layer_config.update({'batch_input_shape': batch_input_shape})
  else:
    input_layer_config.update(
        {'batch_size': batch_size, 'input_shape': shape})
  input_layer = InputLayer(**input_layer_config)

  # Return tensor including `_keras_history`.
  # Note that in this case train_output and test_output are the same pointer.
  outputs = input_layer._inbound_nodes[0].outputs
  if isinstance(outputs, list) and len(outputs) == 1:
    return outputs[0]
  else:
    return outputs
def add(inputs, **kwargs)

Functional interface to the tf.keras.layers.Add layer.

Args

inputs
A list of input tensors (at least 2) with the same shape.
**kwargs
Standard layer keyword arguments.

Returns

A tensor as the sum of the inputs. It has the same shape as the inputs. Examples:

>>> input_shape = (2, 3, 4)
>>> x1 = tf.random.normal(input_shape)
>>> x2 = tf.random.normal(input_shape)
>>> y = tf.keras.layers.add([x1, x2])
>>> print(y.shape)
(2, 3, 4)

Used in a functional model:

>>> input1 = tf.keras.layers.Input(shape=(16,))
>>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
>>> input2 = tf.keras.layers.Input(shape=(32,))
>>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
>>> added = tf.keras.layers.add([x1, x2])
>>> out = tf.keras.layers.Dense(4)(added)
>>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)
Expand source code
@keras_export('keras.layers.add')
def add(inputs, **kwargs):
  """Functional interface to the `tf.keras.layers.Add` layer.

  Args:
      inputs: A list of input tensors (at least 2) with the same shape.
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor as the sum of the inputs. It has the same shape as the inputs.

  Examples:

  >>> input_shape = (2, 3, 4)
  >>> x1 = tf.random.normal(input_shape)
  >>> x2 = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.add([x1, x2])
  >>> print(y.shape)
  (2, 3, 4)

  Used in a functional model:

  >>> input1 = tf.keras.layers.Input(shape=(16,))
  >>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
  >>> input2 = tf.keras.layers.Input(shape=(32,))
  >>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
  >>> added = tf.keras.layers.add([x1, x2])
  >>> out = tf.keras.layers.Dense(4)(added)
  >>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

  """
  return Add(**kwargs)(inputs)
def average(inputs, **kwargs)

Functional interface to the tf.keras.layers.Average layer.

Example:

>>> x1 = np.ones((2, 2))
>>> x2 = np.zeros((2, 2))
>>> y = tf.keras.layers.Average()([x1, x2])
>>> y.numpy().tolist()
[[0.5, 0.5], [0.5, 0.5]]

Usage in a functional model:

>>> input1 = tf.keras.layers.Input(shape=(16,))
>>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
>>> input2 = tf.keras.layers.Input(shape=(32,))
>>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
>>> avg = tf.keras.layers.Average()([x1, x2])
>>> out = tf.keras.layers.Dense(4)(avg)
>>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

Args

inputs
A list of input tensors (at least 2).
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the average of the inputs.

Raises

ValueError
If there is a shape mismatch between the inputs and the shapes cannot be broadcasted to match.
Expand source code
@keras_export('keras.layers.average')
def average(inputs, **kwargs):
  """Functional interface to the `tf.keras.layers.Average` layer.

  Example:

  >>> x1 = np.ones((2, 2))
  >>> x2 = np.zeros((2, 2))
  >>> y = tf.keras.layers.Average()([x1, x2])
  >>> y.numpy().tolist()
  [[0.5, 0.5], [0.5, 0.5]]

  Usage in a functional model:

  >>> input1 = tf.keras.layers.Input(shape=(16,))
  >>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
  >>> input2 = tf.keras.layers.Input(shape=(32,))
  >>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
  >>> avg = tf.keras.layers.Average()([x1, x2])
  >>> out = tf.keras.layers.Dense(4)(avg)
  >>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

  Args:
      inputs: A list of input tensors (at least 2).
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the average of the inputs.

  Raises:
    ValueError: If there is a shape mismatch between the inputs and the shapes
      cannot be broadcasted to match.
  """
  return Average(**kwargs)(inputs)
def concatenate(inputs, axis=-1, **kwargs)

Functional interface to the Concatenate layer.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.concatenate([x, y],
...                             axis=1)
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
      [ 5,  6,  7,  8,  9],
      [20, 21, 22, 23, 24]],
     [[10, 11, 12, 13, 14],
      [15, 16, 17, 18, 19],
      [25, 26, 27, 28, 29]]])>

Args

inputs
A list of input tensors (at least 2).
axis
Concatenation axis.
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the concatenation of the inputs alongside axis axis.

Expand source code
@keras_export('keras.layers.concatenate')
def concatenate(inputs, axis=-1, **kwargs):
  """Functional interface to the `Concatenate` layer.

  >>> x = np.arange(20).reshape(2, 2, 5)
  >>> print(x)
  [[[ 0  1  2  3  4]
    [ 5  6  7  8  9]]
   [[10 11 12 13 14]
    [15 16 17 18 19]]]
  >>> y = np.arange(20, 30).reshape(2, 1, 5)
  >>> print(y)
  [[[20 21 22 23 24]]
   [[25 26 27 28 29]]]
  >>> tf.keras.layers.concatenate([x, y],
  ...                             axis=1)
  <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
  array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [20, 21, 22, 23, 24]],
       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]])>

  Args:
      inputs: A list of input tensors (at least 2).
      axis: Concatenation axis.
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the concatenation of the inputs alongside axis `axis`.
  """
  return Concatenate(axis=axis, **kwargs)(inputs)
def deserialize(config, custom_objects=None)

Instantiates a layer from a config dictionary.

Args

config
dict of the form {'class_name': str, 'config': dict}
custom_objects
dict mapping class names (or function names) of custom (non-Keras) objects to class/functions

Returns

Layer instance (may be Model, Sequential, Network, Layer…) Example:

# Configuration of Dense(32, activation='relu')
config = {
  'class_name': 'Dense',
  'config': {
    'activation': 'relu',
    'activity_regularizer': None,
    'bias_constraint': None,
    'bias_initializer': {'class_name': 'Zeros', 'config': {}},
    'bias_regularizer': None,
    'dtype': 'float32',
    'kernel_constraint': None,
    'kernel_initializer': {'class_name': 'GlorotUniform',
                           'config': {'seed': None}},
    'kernel_regularizer': None,
    'name': 'dense',
    'trainable': True,
    'units': 32,
    'use_bias': True
  }
}
dense_layer = tf.keras.layers.deserialize(config)
Expand source code
@keras_export('keras.layers.deserialize')
def deserialize(config, custom_objects=None):
  """Instantiates a layer from a config dictionary.

  Args:
      config: dict of the form {'class_name': str, 'config': dict}
      custom_objects: dict mapping class names (or function names)
          of custom (non-Keras) objects to class/functions

  Returns:
      Layer instance (may be Model, Sequential, Network, Layer...)

  Example:

  ```python
  # Configuration of Dense(32, activation='relu')
  config = {
    'class_name': 'Dense',
    'config': {
      'activation': 'relu',
      'activity_regularizer': None,
      'bias_constraint': None,
      'bias_initializer': {'class_name': 'Zeros', 'config': {}},
      'bias_regularizer': None,
      'dtype': 'float32',
      'kernel_constraint': None,
      'kernel_initializer': {'class_name': 'GlorotUniform',
                             'config': {'seed': None}},
      'kernel_regularizer': None,
      'name': 'dense',
      'trainable': True,
      'units': 32,
      'use_bias': True
    }
  }
  dense_layer = tf.keras.layers.deserialize(config)
  ```
  """
  populate_deserializable_objects()
  return generic_utils.deserialize_keras_object(
      config,
      module_objects=LOCAL.ALL_OBJECTS,
      custom_objects=custom_objects,
      printable_module_name='layer')
def disable_v2_dtype_behavior()

Disables the V2 dtype behavior for Keras layers.

See tf.compat.v1.keras.layers.enable_v2_dtype_behavior.

Expand source code
@keras_export(v1=['keras.layers.disable_v2_dtype_behavior'])
def disable_v2_dtype_behavior():
  """Disables the V2 dtype behavior for Keras layers.

  See `tf.compat.v1.keras.layers.enable_v2_dtype_behavior`.
  """
  global V2_DTYPE_BEHAVIOR
  V2_DTYPE_BEHAVIOR = False
def dot(inputs, axes, normalize=False, **kwargs)

Functional interface to the Dot layer.

Args

inputs
A list of input tensors (at least 2).
axes
Integer or tuple of integers, axis or axes along which to take the dot product.
normalize
Whether to L2-normalize samples along the dot product axis before taking the dot product. If set to True, then the output of the dot product is the cosine proximity between the two samples.
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the dot product of the samples from the inputs.

Expand source code
@keras_export('keras.layers.dot')
def dot(inputs, axes, normalize=False, **kwargs):
  """Functional interface to the `Dot` layer.

  Args:
      inputs: A list of input tensors (at least 2).
      axes: Integer or tuple of integers,
          axis or axes along which to take the dot product.
      normalize: Whether to L2-normalize samples along the
          dot product axis before taking the dot product.
          If set to True, then the output of the dot product
          is the cosine proximity between the two samples.
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the dot product of the samples from the inputs.
  """
  return Dot(axes=axes, normalize=normalize, **kwargs)(inputs)
def enable_v2_dtype_behavior()

Enable the V2 dtype behavior for Keras layers.

By default, the V2 dtype behavior is enabled in TensorFlow 2, so this function is only useful if tf.compat.v1.disable_v2_behavior has been called. Since mixed precision requires V2 dtype behavior to be enabled, this function allows you to use mixed precision in Keras layers if disable_v2_behavior has been called.

When enabled, the dtype of Keras layers defaults to floatx (which is typically float32) instead of None. In addition, layers will automatically cast floating-point inputs to the layer's dtype.

>>> x = tf.ones((4, 4, 4, 4), dtype='float64')
>>> layer = tf.keras.layers.Conv2D(filters=4, kernel_size=2)
>>> print(layer.dtype)  # float32 since V2 dtype behavior is enabled
float32
>>> y = layer(x)  # Layer casts inputs since V2 dtype behavior is enabled
>>> print(y.dtype.name)
float32

A layer author can opt-out their layer from the automatic input casting by passing autocast=False to the base Layer's constructor. This disables the autocasting part of the V2 behavior for that layer, but not the defaulting to floatx part of the V2 behavior.

When a global tf.keras.mixed_precision.Policy is set, a Keras layer's dtype will default to the global policy instead of floatx. Layers will automatically cast inputs to the policy's compute_dtype.

Expand source code
@keras_export(v1=['keras.layers.enable_v2_dtype_behavior'])
def enable_v2_dtype_behavior():
  """Enable the V2 dtype behavior for Keras layers.

  By default, the V2 dtype behavior is enabled in TensorFlow 2, so this function
  is only useful if `tf.compat.v1.disable_v2_behavior` has been called. Since
  mixed precision requires V2 dtype behavior to be enabled, this function allows
  you to use mixed precision in Keras layers if `disable_v2_behavior` has been
  called.

  When enabled, the dtype of Keras layers defaults to floatx (which is typically
  float32) instead of None. In addition, layers will automatically cast
  floating-point inputs to the layer's dtype.

  >>> x = tf.ones((4, 4, 4, 4), dtype='float64')
  >>> layer = tf.keras.layers.Conv2D(filters=4, kernel_size=2)
  >>> print(layer.dtype)  # float32 since V2 dtype behavior is enabled
  float32
  >>> y = layer(x)  # Layer casts inputs since V2 dtype behavior is enabled
  >>> print(y.dtype.name)
  float32

  A layer author can opt-out their layer from the automatic input casting by
  passing `autocast=False` to the base Layer's constructor. This disables the
  autocasting part of the V2 behavior for that layer, but not the defaulting to
  floatx part of the V2 behavior.

  When a global `tf.keras.mixed_precision.Policy` is set, a Keras layer's dtype
  will default to the global policy instead of floatx. Layers will automatically
  cast inputs to the policy's compute_dtype.
  """
  global V2_DTYPE_BEHAVIOR
  V2_DTYPE_BEHAVIOR = True
def maximum(inputs, **kwargs)

Functional interface to compute maximum (element-wise) list of inputs.

This is equivalent to the tf.keras.layers.Maximum layer.

For example:

input1 = tf.keras.layers.Input(shape=(16,))
x1 = tf.keras.layers.Dense(8, activation='relu')(input1) #shape=(None, 8)
input2 = tf.keras.layers.Input(shape=(32,))
x2 = tf.keras.layers.Dense(8, activation='relu')(input2) #shape=(None, 8)
max_inp=tf.keras.layers.maximum([x1,x2]) #shape=(None, 8)
out = tf.keras.layers.Dense(4)(max_inp)
model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

Args

inputs
A list of input tensors (at least 2) of same shape.
**kwargs
Standard layer keyword arguments.

Returns

A tensor (of same shape as input tensor) with the element-wise maximum of the inputs.

Raises

ValueError
If input tensors are of different shape.
Expand source code
@keras_export('keras.layers.maximum')
def maximum(inputs, **kwargs):
  """Functional interface to compute maximum (element-wise) list of `inputs`.

  This is equivalent to the `tf.keras.layers.Maximum` layer.

  For example:

  ```python
  input1 = tf.keras.layers.Input(shape=(16,))
  x1 = tf.keras.layers.Dense(8, activation='relu')(input1) #shape=(None, 8)
  input2 = tf.keras.layers.Input(shape=(32,))
  x2 = tf.keras.layers.Dense(8, activation='relu')(input2) #shape=(None, 8)
  max_inp=tf.keras.layers.maximum([x1,x2]) #shape=(None, 8)
  out = tf.keras.layers.Dense(4)(max_inp)
  model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)
  ```

  Args:
      inputs: A list of input tensors (at least 2) of same shape.
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor (of same shape as input tensor) with the element-wise
      maximum of the inputs.

  Raises:
      ValueError: If input tensors are of different shape.
  """
  return Maximum(**kwargs)(inputs)
def minimum(inputs, **kwargs)

Functional interface to the Minimum layer.

Args

inputs
A list of input tensors (at least 2).
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the element-wise minimum of the inputs.

Expand source code
@keras_export('keras.layers.minimum')
def minimum(inputs, **kwargs):
  """Functional interface to the `Minimum` layer.

  Args:
      inputs: A list of input tensors (at least 2).
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the element-wise minimum of the inputs.
  """
  return Minimum(**kwargs)(inputs)
def multiply(inputs, **kwargs)

Functional interface to the Multiply layer.

Example:

>>> x1 = np.arange(3.0)
>>> x2 = np.arange(3.0)
>>> tf.keras.layers.multiply([x1, x2])
<tf.Tensor: shape=(3,), dtype=float32, numpy=array([0., 1., 4.], ...)>

Usage in a functional model:

>>> input1 = tf.keras.layers.Input(shape=(16,))
>>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1) #shape=(None, 8)
>>> input2 = tf.keras.layers.Input(shape=(32,))
>>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2) #shape=(None, 8)
>>> out = tf.keras.layers.multiply([x1,x2]) #shape=(None, 8)
>>> out = tf.keras.layers.Dense(4)(out)
>>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

Args

inputs
A list of input tensors (at least 2).
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the element-wise product of the inputs.

Expand source code
@keras_export('keras.layers.multiply')
def multiply(inputs, **kwargs):
  """Functional interface to the `Multiply` layer.

  Example:

  >>> x1 = np.arange(3.0)
  >>> x2 = np.arange(3.0)
  >>> tf.keras.layers.multiply([x1, x2])
  <tf.Tensor: shape=(3,), dtype=float32, numpy=array([0., 1., 4.], ...)>

  Usage in a functional model:

  >>> input1 = tf.keras.layers.Input(shape=(16,))
  >>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1) #shape=(None, 8)
  >>> input2 = tf.keras.layers.Input(shape=(32,))
  >>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2) #shape=(None, 8)
  >>> out = tf.keras.layers.multiply([x1,x2]) #shape=(None, 8)
  >>> out = tf.keras.layers.Dense(4)(out)
  >>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

  Args:
      inputs: A list of input tensors (at least 2).
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the element-wise product of the inputs.
  """
  return Multiply(**kwargs)(inputs)
def serialize(layer)

Serializes a Layer object into a JSON-compatible representation.

Args

layer
The Layer object to serialize.

Returns

A JSON-serializable dict representing the object's config. Example:

```python from pprint import pprint model = tf.keras.models.Sequential() model.add(tf.keras.Input(shape=(16,))) model.add(tf.keras.layers.Dense(32, activation='relu'))

pprint(tf.keras.layers.serialize(model))

prints the configuration of the model, as a dict.

Expand source code
@keras_export('keras.layers.serialize')
def serialize(layer):
  """Serializes a `Layer` object into a JSON-compatible representation.

  Args:
    layer: The `Layer` object to serialize.

  Returns:
    A JSON-serializable dict representing the object's config.

  Example:

  ```python
  from pprint import pprint
  model = tf.keras.models.Sequential()
  model.add(tf.keras.Input(shape=(16,)))
  model.add(tf.keras.layers.Dense(32, activation='relu'))

  pprint(tf.keras.layers.serialize(model))
  # prints the configuration of the model, as a dict.
  """
  return generic_utils.serialize_keras_object(layer)
def subtract(inputs, **kwargs)

Functional interface to the Subtract layer.

Args

inputs
A list of input tensors (exactly 2).
**kwargs
Standard layer keyword arguments.

Returns

A tensor, the difference of the inputs. Examples:

    import keras

    input1 = keras.layers.Input(shape=(16,))
    x1 = keras.layers.Dense(8, activation='relu')(input1)
    input2 = keras.layers.Input(shape=(32,))
    x2 = keras.layers.Dense(8, activation='relu')(input2)
    subtracted = keras.layers.subtract([x1, x2])

    out = keras.layers.Dense(4)(subtracted)
    model = keras.models.Model(inputs=[input1, input2], outputs=out)
Expand source code
@keras_export('keras.layers.subtract')
def subtract(inputs, **kwargs):
  """Functional interface to the `Subtract` layer.

  Args:
      inputs: A list of input tensors (exactly 2).
      **kwargs: Standard layer keyword arguments.

  Returns:
      A tensor, the difference of the inputs.

  Examples:

  ```python
      import keras

      input1 = keras.layers.Input(shape=(16,))
      x1 = keras.layers.Dense(8, activation='relu')(input1)
      input2 = keras.layers.Input(shape=(32,))
      x2 = keras.layers.Dense(8, activation='relu')(input2)
      subtracted = keras.layers.subtract([x1, x2])

      out = keras.layers.Dense(4)(subtracted)
      model = keras.models.Model(inputs=[input1, input2], outputs=out)
  ```
  """
  return Subtract(**kwargs)(inputs)

Classes

class AbstractRNNCell (trainable=True, name=None, dtype=None, dynamic=False, **kwargs)

Abstract object representing an RNN cell.

See the Keras RNN API guide for details about the usage of RNN API.

This is the base class for implementing RNN cells with custom behavior.

Every RNNCell must have the properties below and implement call with the signature (output, next_state) = call(input, state).

Examples:

  class MinimalRNNCell(AbstractRNNCell):

    def __init__(self, units, **kwargs):
      self.units = units
      super(MinimalRNNCell, self).__init__(**kwargs)

    @property
    def state_size(self):
      return self.units

    def build(self, input_shape):
      self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                                    initializer='uniform',
                                    name='kernel')
      self.recurrent_kernel = self.add_weight(
          shape=(self.units, self.units),
          initializer='uniform',
          name='recurrent_kernel')
      self.built = True

    def call(self, inputs, states):
      prev_output = states[0]
      h = backend.dot(inputs, self.kernel)
      output = h + backend.dot(prev_output, self.recurrent_kernel)
      return output, output

This definition of cell differs from the definition used in the literature. In the literature, 'cell' refers to an object with a single scalar output. This definition refers to a horizontal array of such units.

An RNN cell, in the most abstract setting, is anything that has a state and performs some operation that takes a matrix of inputs. This operation results in an output matrix with self.output_size columns. If self.state_size is an integer, this operation also results in a new state matrix with self.state_size columns. If self.state_size is a (possibly nested tuple of) TensorShape object(s), then it should return a matching structure of Tensors having shape [batch_size].concatenate()(s) for each s in self.batch_size.

Expand source code
class AbstractRNNCell(Layer):
  """Abstract object representing an RNN cell.

  See [the Keras RNN API guide](https://www.tensorflow.org/guide/keras/rnn)
  for details about the usage of RNN API.

  This is the base class for implementing RNN cells with custom behavior.

  Every `RNNCell` must have the properties below and implement `call` with
  the signature `(output, next_state) = call(input, state)`.

  Examples:

  ```python
    class MinimalRNNCell(AbstractRNNCell):

      def __init__(self, units, **kwargs):
        self.units = units
        super(MinimalRNNCell, self).__init__(**kwargs)

      @property
      def state_size(self):
        return self.units

      def build(self, input_shape):
        self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                                      initializer='uniform',
                                      name='kernel')
        self.recurrent_kernel = self.add_weight(
            shape=(self.units, self.units),
            initializer='uniform',
            name='recurrent_kernel')
        self.built = True

      def call(self, inputs, states):
        prev_output = states[0]
        h = backend.dot(inputs, self.kernel)
        output = h + backend.dot(prev_output, self.recurrent_kernel)
        return output, output
  ```

  This definition of cell differs from the definition used in the literature.
  In the literature, 'cell' refers to an object with a single scalar output.
  This definition refers to a horizontal array of such units.

  An RNN cell, in the most abstract setting, is anything that has
  a state and performs some operation that takes a matrix of inputs.
  This operation results in an output matrix with `self.output_size` columns.
  If `self.state_size` is an integer, this operation also results in a new
  state matrix with `self.state_size` columns.  If `self.state_size` is a
  (possibly nested tuple of) TensorShape object(s), then it should return a
  matching structure of Tensors having shape `[batch_size].concatenate(s)`
  for each `s` in `self.batch_size`.
  """

  def call(self, inputs, states):
    """The function that contains the logic for one RNN step calculation.

    Args:
      inputs: the input tensor, which is a slide from the overall RNN input by
        the time dimension (usually the second dimension).
      states: the state tensor from previous step, which has the same shape
        as `(batch, state_size)`. In the case of timestep 0, it will be the
        initial state user specified, or zero filled tensor otherwise.

    Returns:
      A tuple of two tensors:
        1. output tensor for the current timestep, with size `output_size`.
        2. state tensor for next step, which has the shape of `state_size`.
    """
    raise NotImplementedError('Abstract method')

  @property
  def state_size(self):
    """size(s) of state(s) used by this cell.

    It can be represented by an Integer, a TensorShape or a tuple of Integers
    or TensorShapes.
    """
    raise NotImplementedError('Abstract method')

  @property
  def output_size(self):
    """Integer or TensorShape: size of outputs produced by this cell."""
    raise NotImplementedError('Abstract method')

  def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
    return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

  • keras.layers.rnn_cell_wrapper_v2._RNNCellWrapperV2

Instance variables

var output_size

Integer or TensorShape: size of outputs produced by this cell.

Expand source code
@property
def output_size(self):
  """Integer or TensorShape: size of outputs produced by this cell."""
  raise NotImplementedError('Abstract method')
var state_size

size(s) of state(s) used by this cell.

It can be represented by an Integer, a TensorShape or a tuple of Integers or TensorShapes.

Expand source code
@property
def state_size(self):
  """size(s) of state(s) used by this cell.

  It can be represented by an Integer, a TensorShape or a tuple of Integers
  or TensorShapes.
  """
  raise NotImplementedError('Abstract method')

Methods

def call(self, inputs, states)

The function that contains the logic for one RNN step calculation.

Args

inputs
the input tensor, which is a slide from the overall RNN input by the time dimension (usually the second dimension).
states
the state tensor from previous step, which has the same shape as (batch, state_size). In the case of timestep 0, it will be the initial state user specified, or zero filled tensor otherwise.

Returns

A tuple of two tensors: 1. output tensor for the current timestep, with size output_size. 2. state tensor for next step, which has the shape of state_size.

Expand source code
def call(self, inputs, states):
  """The function that contains the logic for one RNN step calculation.

  Args:
    inputs: the input tensor, which is a slide from the overall RNN input by
      the time dimension (usually the second dimension).
    states: the state tensor from previous step, which has the same shape
      as `(batch, state_size)`. In the case of timestep 0, it will be the
      initial state user specified, or zero filled tensor otherwise.

  Returns:
    A tuple of two tensors:
      1. output tensor for the current timestep, with size `output_size`.
      2. state tensor for next step, which has the shape of `state_size`.
  """
  raise NotImplementedError('Abstract method')
def get_initial_state(self, inputs=None, batch_size=None, dtype=None)
Expand source code
def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
  return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

Inherited members

class Activation (activation, **kwargs)

Applies an activation function to an output.

Args

activation
Activation function, such as tf.nn.relu, or string name of built-in activation function, such as "relu".

Usage:

>>> layer = tf.keras.layers.Activation('relu')
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[0.0, 0.0, 0.0, 2.0]
>>> layer = tf.keras.layers.Activation(tf.nn.relu)
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[0.0, 0.0, 0.0, 2.0]

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the batch axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Expand source code
class Activation(Layer):
  """Applies an activation function to an output.

  Args:
    activation: Activation function, such as `tf.nn.relu`, or string name of
      built-in activation function, such as "relu".

  Usage:

  >>> layer = tf.keras.layers.Activation('relu')
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [0.0, 0.0, 0.0, 2.0]
  >>> layer = tf.keras.layers.Activation(tf.nn.relu)
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [0.0, 0.0, 0.0, 2.0]

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the batch axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as input.
  """

  def __init__(self, activation, **kwargs):
    super(Activation, self).__init__(**kwargs)
    self.supports_masking = True
    self.activation = activations.get(activation)

  def call(self, inputs):
    return self.activation(inputs)

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {'activation': activations.serialize(self.activation)}
    base_config = super(Activation, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class ActivityRegularization (l1=0.0, l2=0.0, **kwargs)

Layer that applies an update to the cost function based input activity.

Args

l1
L1 regularization factor (positive float).
l2
L2 regularization factor (positive float).

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Expand source code
class ActivityRegularization(Layer):
  """Layer that applies an update to the cost function based input activity.

  Args:
    l1: L1 regularization factor (positive float).
    l2: L2 regularization factor (positive float).

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as input.
  """

  def __init__(self, l1=0., l2=0., **kwargs):
    super(ActivityRegularization, self).__init__(
        activity_regularizer=regularizers.L1L2(l1=l1, l2=l2), **kwargs)
    self.supports_masking = True
    self.l1 = l1
    self.l2 = l2

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {'l1': self.l1, 'l2': self.l2}
    base_config = super(ActivityRegularization, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Add (**kwargs)

Layer that adds a list of inputs.

It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).

Examples:

>>> input_shape = (2, 3, 4)
>>> x1 = tf.random.normal(input_shape)
>>> x2 = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Add()([x1, x2])
>>> print(y.shape)
(2, 3, 4)

Used in a functional model:

>>> input1 = tf.keras.layers.Input(shape=(16,))
>>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
>>> input2 = tf.keras.layers.Input(shape=(32,))
>>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
>>> # equivalent to `added = tf.keras.layers.add([x1, x2])`
>>> added = tf.keras.layers.Add()([x1, x2])
>>> out = tf.keras.layers.Dense(4)(added)
>>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Add(_Merge):
  """Layer that adds a list of inputs.

  It takes as input a list of tensors,
  all of the same shape, and returns
  a single tensor (also of the same shape).

  Examples:

  >>> input_shape = (2, 3, 4)
  >>> x1 = tf.random.normal(input_shape)
  >>> x2 = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Add()([x1, x2])
  >>> print(y.shape)
  (2, 3, 4)

  Used in a functional model:

  >>> input1 = tf.keras.layers.Input(shape=(16,))
  >>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
  >>> input2 = tf.keras.layers.Input(shape=(32,))
  >>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
  >>> # equivalent to `added = tf.keras.layers.add([x1, x2])`
  >>> added = tf.keras.layers.Add()([x1, x2])
  >>> out = tf.keras.layers.Dense(4)(added)
  >>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

  """

  def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
      output += inputs[i]
    return output

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class AdditiveAttention (use_scale=True, **kwargs)

Additive attention layer, a.k.a. Bahdanau-style attention.

Inputs are query tensor of shape [batch_size, Tq, dim], value tensor of shape [batch_size, Tv, dim] and key tensor of shape [batch_size, Tv, dim]. The calculation follows the steps:

  1. Reshape query and key into shapes [batch_size, Tq, 1, dim] and [batch_size, 1, Tv, dim] respectively.
  2. Calculate scores with shape [batch_size, Tq, Tv] as a non-linear sum: scores = tf.reduce_sum(tf.tanh(query + key), axis=-1)
  3. Use scores to calculate a distribution with shape [batch_size, Tq, Tv]: distribution = tf.nn.softmax(scores).
  4. Use distribution to create a linear combination of value with shape [batch_size, Tq, dim]: return tf.matmul(distribution, value).

Args

use_scale
If True, will create a variable to scale the attention scores.
causal
Boolean. Set to True for decoder self-attention. Adds a mask such that position i cannot attend to positions j > i. This prevents the flow of information from the future towards the past.
dropout
Float between 0 and 1. Fraction of the units to drop for the attention scores.

Call Args:

inputs: List of the following tensors: * query: Query Tensor of shape [batch_size, Tq, dim]. * value: Value Tensor of shape [batch_size, Tv, dim]. * key: Optional key Tensor of shape [batch_size, Tv, dim]. If not given, will use value for both key and value, which is the most common case. mask: List of the following tensors: * query_mask: A boolean mask Tensor of shape [batch_size, Tq]. If given, the output will be zero at the positions where mask==False. * value_mask: A boolean mask Tensor of shape [batch_size, Tv]. If given, will apply the mask such that values at positions where mask==False do not contribute to the result. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (no dropout). return_attention_scores: bool, it True, returns the attention scores (after masking and softmax) as an additional output argument.

Output

Attention outputs of shape [batch_size, Tq, dim]. [Optional] Attention scores after masking and softmax with shape [batch_size, Tq, Tv].

The meaning of query, value and key depend on the application. In the case of text similarity, for example, query is the sequence embeddings of the first piece of text and value is the sequence embeddings of the second piece of text. key is usually the same tensor as value.

Here is a code example for using AdditiveAttention in a CNN+Attention network:

# Variable-length int sequences.
query_input = tf.keras.Input(shape=(None,), dtype='int32')
value_input = tf.keras.Input(shape=(None,), dtype='int32')

# Embedding lookup.
token_embedding = tf.keras.layers.Embedding(max_tokens, dimension)
# Query embeddings of shape [batch_size, Tq, dimension].
query_embeddings = token_embedding(query_input)
# Value embeddings of shape [batch_size, Tv, dimension].
value_embeddings = token_embedding(value_input)

# CNN layer.
cnn_layer = tf.keras.layers.Conv1D(
    filters=100,
    kernel_size=4,
    # Use 'same' padding so outputs have the same shape as inputs.
    padding='same')
# Query encoding of shape [batch_size, Tq, filters].
query_seq_encoding = cnn_layer(query_embeddings)
# Value encoding of shape [batch_size, Tv, filters].
value_seq_encoding = cnn_layer(value_embeddings)

# Query-value attention of shape [batch_size, Tq, filters].
query_value_attention_seq = tf.keras.layers.AdditiveAttention()(
    [query_seq_encoding, value_seq_encoding])

# Reduce over the sequence axis to produce encodings of shape
# [batch_size, filters].
query_encoding = tf.keras.layers.GlobalAveragePooling1D()(
    query_seq_encoding)
query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
    query_value_attention_seq)

# Concatenate query and document encodings to produce a DNN input layer.
input_layer = tf.keras.layers.Concatenate()(
    [query_encoding, query_value_attention])

# Add DNN layers, and create Model.
# ...
Expand source code
class AdditiveAttention(BaseDenseAttention):
  """Additive attention layer, a.k.a. Bahdanau-style attention.

  Inputs are `query` tensor of shape `[batch_size, Tq, dim]`, `value` tensor of
  shape `[batch_size, Tv, dim]` and `key` tensor of shape
  `[batch_size, Tv, dim]`. The calculation follows the steps:

  1. Reshape `query` and `key` into shapes `[batch_size, Tq, 1, dim]`
     and `[batch_size, 1, Tv, dim]` respectively.
  2. Calculate scores with shape `[batch_size, Tq, Tv]` as a non-linear
     sum: `scores = tf.reduce_sum(tf.tanh(query + key), axis=-1)`
  3. Use scores to calculate a distribution with shape
     `[batch_size, Tq, Tv]`: `distribution = tf.nn.softmax(scores)`.
  4. Use `distribution` to create a linear combination of `value` with
     shape `[batch_size, Tq, dim]`:
     `return tf.matmul(distribution, value)`.

  Args:
    use_scale: If `True`, will create a variable to scale the attention scores.
    causal: Boolean. Set to `True` for decoder self-attention. Adds a mask such
      that position `i` cannot attend to positions `j > i`. This prevents the
      flow of information from the future towards the past.
    dropout: Float between 0 and 1. Fraction of the units to drop for the
      attention scores.

  Call Args:

    inputs: List of the following tensors:
      * query: Query `Tensor` of shape `[batch_size, Tq, dim]`.
      * value: Value `Tensor` of shape `[batch_size, Tv, dim]`.
      * key: Optional key `Tensor` of shape `[batch_size, Tv, dim]`. If not
        given, will use `value` for both `key` and `value`, which is the
        most common case.
    mask: List of the following tensors:
      * query_mask: A boolean mask `Tensor` of shape `[batch_size, Tq]`.
        If given, the output will be zero at the positions where
        `mask==False`.
      * value_mask: A boolean mask `Tensor` of shape `[batch_size, Tv]`.
        If given, will apply the mask such that values at positions where
        `mask==False` do not contribute to the result.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (no dropout).
    return_attention_scores: bool, it `True`, returns the attention scores
      (after masking and softmax) as an additional output argument.

  Output:

    Attention outputs of shape `[batch_size, Tq, dim]`.
    [Optional] Attention scores after masking and softmax with shape
      `[batch_size, Tq, Tv]`.

  The meaning of `query`, `value` and `key` depend on the application. In the
  case of text similarity, for example, `query` is the sequence embeddings of
  the first piece of text and `value` is the sequence embeddings of the second
  piece of text. `key` is usually the same tensor as `value`.

  Here is a code example for using `AdditiveAttention` in a CNN+Attention
  network:

  ```python
  # Variable-length int sequences.
  query_input = tf.keras.Input(shape=(None,), dtype='int32')
  value_input = tf.keras.Input(shape=(None,), dtype='int32')

  # Embedding lookup.
  token_embedding = tf.keras.layers.Embedding(max_tokens, dimension)
  # Query embeddings of shape [batch_size, Tq, dimension].
  query_embeddings = token_embedding(query_input)
  # Value embeddings of shape [batch_size, Tv, dimension].
  value_embeddings = token_embedding(value_input)

  # CNN layer.
  cnn_layer = tf.keras.layers.Conv1D(
      filters=100,
      kernel_size=4,
      # Use 'same' padding so outputs have the same shape as inputs.
      padding='same')
  # Query encoding of shape [batch_size, Tq, filters].
  query_seq_encoding = cnn_layer(query_embeddings)
  # Value encoding of shape [batch_size, Tv, filters].
  value_seq_encoding = cnn_layer(value_embeddings)

  # Query-value attention of shape [batch_size, Tq, filters].
  query_value_attention_seq = tf.keras.layers.AdditiveAttention()(
      [query_seq_encoding, value_seq_encoding])

  # Reduce over the sequence axis to produce encodings of shape
  # [batch_size, filters].
  query_encoding = tf.keras.layers.GlobalAveragePooling1D()(
      query_seq_encoding)
  query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
      query_value_attention_seq)

  # Concatenate query and document encodings to produce a DNN input layer.
  input_layer = tf.keras.layers.Concatenate()(
      [query_encoding, query_value_attention])

  # Add DNN layers, and create Model.
  # ...
  ```
  """

  def __init__(self, use_scale=True, **kwargs):
    super(AdditiveAttention, self).__init__(**kwargs)
    self.use_scale = use_scale

  def build(self, input_shape):
    v_shape = tf.TensorShape(input_shape[1])
    dim = v_shape[-1]
    dim = tf.compat.dimension_value(dim)
    if self.use_scale:
      self.scale = self.add_weight(
          name='scale',
          shape=[dim],
          initializer='glorot_uniform',
          dtype=self.dtype,
          trainable=True)
    else:
      self.scale = None
    super(AdditiveAttention, self).build(input_shape)

  def _calculate_scores(self, query, key):
    """Calculates attention scores as a nonlinear sum of query and key.

    Args:
      query: Query tensor of shape `[batch_size, Tq, dim]`.
      key: Key tensor of shape `[batch_size, Tv, dim]`.
    Returns:
      Tensor of shape `[batch_size, Tq, Tv]`.
    """
    # Reshape tensors to enable broadcasting.
    # Reshape into [batch_size, Tq, 1, dim].
    q_reshaped = tf.expand_dims(query, axis=-2)
    # Reshape into [batch_size, 1, Tv, dim].
    k_reshaped = tf.expand_dims(key, axis=-3)
    if self.use_scale:
      scale = self.scale
    else:
      scale = 1.
    return tf.reduce_sum(
        scale * tf.tanh(q_reshaped + k_reshaped), axis=-1)

  def get_config(self):
    config = {'use_scale': self.use_scale}
    base_config = super(AdditiveAttention, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

Inherited members

class AlphaDropout (rate, noise_shape=None, seed=None, **kwargs)

Applies Alpha Dropout to the input.

Alpha Dropout is a Dropout that keeps mean and variance of inputs to their original values, in order to ensure the self-normalizing property even after this dropout. Alpha Dropout fits well to Scaled Exponential Linear Units by randomly setting activations to the negative saturation value.

Args

rate
float, drop probability (as with Dropout). The multiplicative noise will have standard deviation sqrt(rate / (1 - rate)).
seed
A Python integer to use as random seed.

Call arguments: inputs: Input tensor (of any rank). training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Expand source code
class AlphaDropout(Layer):
  """Applies Alpha Dropout to the input.

  Alpha Dropout is a `Dropout` that keeps mean and variance of inputs
  to their original values, in order to ensure the self-normalizing property
  even after this dropout.
  Alpha Dropout fits well to Scaled Exponential Linear Units
  by randomly setting activations to the negative saturation value.

  Args:
    rate: float, drop probability (as with `Dropout`).
      The multiplicative noise will have
      standard deviation `sqrt(rate / (1 - rate))`.
    seed: A Python integer to use as random seed.

  Call arguments:
    inputs: Input tensor (of any rank).
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as input.
  """

  def __init__(self, rate, noise_shape=None, seed=None, **kwargs):
    super(AlphaDropout, self).__init__(**kwargs)
    self.rate = rate
    self.noise_shape = noise_shape
    self.seed = seed
    self.supports_masking = True

  def _get_noise_shape(self, inputs):
    return self.noise_shape if self.noise_shape else tf.shape(inputs)

  def call(self, inputs, training=None):
    if 0. < self.rate < 1.:
      noise_shape = self._get_noise_shape(inputs)

      def dropped_inputs(inputs=inputs, rate=self.rate, seed=self.seed):  # pylint: disable=missing-docstring
        alpha = 1.6732632423543772848170429916717
        scale = 1.0507009873554804934193349852946
        alpha_p = -alpha * scale

        kept_idx = tf.greater_equal(
            backend.random_uniform(noise_shape, seed=seed), rate)
        kept_idx = tf.cast(kept_idx, inputs.dtype)

        # Get affine transformation params
        a = ((1 - rate) * (1 + rate * alpha_p**2))**-0.5
        b = -a * alpha_p * rate

        # Apply mask
        x = inputs * kept_idx + alpha_p * (1 - kept_idx)

        # Do affine transformation
        return a * x + b

      return backend.in_train_phase(dropped_inputs, inputs, training=training)
    return inputs

  def get_config(self):
    config = {'rate': self.rate}
    base_config = super(AlphaDropout, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Attention (use_scale=False, **kwargs)

Dot-product attention layer, a.k.a. Luong-style attention.

Inputs are query tensor of shape [batch_size, Tq, dim], value tensor of shape [batch_size, Tv, dim] and key tensor of shape [batch_size, Tv, dim]. The calculation follows the steps:

  1. Calculate scores with shape [batch_size, Tq, Tv] as a query-key dot product: scores = tf.matmul(query, key, transpose_b=True).
  2. Use scores to calculate a distribution with shape [batch_size, Tq, Tv]: distribution = tf.nn.softmax(scores).
  3. Use distribution to create a linear combination of value with shape [batch_size, Tq, dim]: return tf.matmul(distribution, value).

Args

use_scale
If True, will create a scalar variable to scale the attention scores.
causal
Boolean. Set to True for decoder self-attention. Adds a mask such that position i cannot attend to positions j > i. This prevents the flow of information from the future towards the past.
dropout
Float between 0 and 1. Fraction of the units to drop for the attention scores.

Call Args:

inputs: List of the following tensors: * query: Query Tensor of shape [batch_size, Tq, dim]. * value: Value Tensor of shape [batch_size, Tv, dim]. * key: Optional key Tensor of shape [batch_size, Tv, dim]. If not given, will use value for both key and value, which is the most common case. mask: List of the following tensors: * query_mask: A boolean mask Tensor of shape [batch_size, Tq]. If given, the output will be zero at the positions where mask==False. * value_mask: A boolean mask Tensor of shape [batch_size, Tv]. If given, will apply the mask such that values at positions where mask==False do not contribute to the result. return_attention_scores: bool, it True, returns the attention scores (after masking and softmax) as an additional output argument. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (no dropout).

Output

Attention outputs of shape [batch_size, Tq, dim]. [Optional] Attention scores after masking and softmax with shape [batch_size, Tq, Tv].

The meaning of query, value and key depend on the application. In the case of text similarity, for example, query is the sequence embeddings of the first piece of text and value is the sequence embeddings of the second piece of text. key is usually the same tensor as value.

Here is a code example for using Attention in a CNN+Attention network:

# Variable-length int sequences.
query_input = tf.keras.Input(shape=(None,), dtype='int32')
value_input = tf.keras.Input(shape=(None,), dtype='int32')

# Embedding lookup.
token_embedding = tf.keras.layers.Embedding(input_dim=1000, output_dim=64)
# Query embeddings of shape [batch_size, Tq, dimension].
query_embeddings = token_embedding(query_input)
# Value embeddings of shape [batch_size, Tv, dimension].
value_embeddings = token_embedding(value_input)

# CNN layer.
cnn_layer = tf.keras.layers.Conv1D(
    filters=100,
    kernel_size=4,
    # Use 'same' padding so outputs have the same shape as inputs.
    padding='same')
# Query encoding of shape [batch_size, Tq, filters].
query_seq_encoding = cnn_layer(query_embeddings)
# Value encoding of shape [batch_size, Tv, filters].
value_seq_encoding = cnn_layer(value_embeddings)

# Query-value attention of shape [batch_size, Tq, filters].
query_value_attention_seq = tf.keras.layers.Attention()(
    [query_seq_encoding, value_seq_encoding])

# Reduce over the sequence axis to produce encodings of shape
# [batch_size, filters].
query_encoding = tf.keras.layers.GlobalAveragePooling1D()(
    query_seq_encoding)
query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
    query_value_attention_seq)

# Concatenate query and document encodings to produce a DNN input layer.
input_layer = tf.keras.layers.Concatenate()(
    [query_encoding, query_value_attention])

# Add DNN layers, and create Model.
# ...
Expand source code
class Attention(BaseDenseAttention):
  """Dot-product attention layer, a.k.a. Luong-style attention.

  Inputs are `query` tensor of shape `[batch_size, Tq, dim]`, `value` tensor of
  shape `[batch_size, Tv, dim]` and `key` tensor of shape
  `[batch_size, Tv, dim]`. The calculation follows the steps:

  1. Calculate scores with shape `[batch_size, Tq, Tv]` as a `query`-`key` dot
     product: `scores = tf.matmul(query, key, transpose_b=True)`.
  2. Use scores to calculate a distribution with shape
     `[batch_size, Tq, Tv]`: `distribution = tf.nn.softmax(scores)`.
  3. Use `distribution` to create a linear combination of `value` with
     shape `[batch_size, Tq, dim]`:
     `return tf.matmul(distribution, value)`.

  Args:
    use_scale: If `True`, will create a scalar variable to scale the attention
      scores.
    causal: Boolean. Set to `True` for decoder self-attention. Adds a mask such
      that position `i` cannot attend to positions `j > i`. This prevents the
      flow of information from the future towards the past.
    dropout: Float between 0 and 1. Fraction of the units to drop for the
      attention scores.

  Call Args:

    inputs: List of the following tensors:
      * query: Query `Tensor` of shape `[batch_size, Tq, dim]`.
      * value: Value `Tensor` of shape `[batch_size, Tv, dim]`.
      * key: Optional key `Tensor` of shape `[batch_size, Tv, dim]`. If not
        given, will use `value` for both `key` and `value`, which is the
        most common case.
    mask: List of the following tensors:
      * query_mask: A boolean mask `Tensor` of shape `[batch_size, Tq]`.
        If given, the output will be zero at the positions where
        `mask==False`.
      * value_mask: A boolean mask `Tensor` of shape `[batch_size, Tv]`.
        If given, will apply the mask such that values at positions where
        `mask==False` do not contribute to the result.
    return_attention_scores: bool, it `True`, returns the attention scores
      (after masking and softmax) as an additional output argument.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (no dropout).

  Output:

    Attention outputs of shape `[batch_size, Tq, dim]`.
    [Optional] Attention scores after masking and softmax with shape
      `[batch_size, Tq, Tv]`.

  The meaning of `query`, `value` and `key` depend on the application. In the
  case of text similarity, for example, `query` is the sequence embeddings of
  the first piece of text and `value` is the sequence embeddings of the second
  piece of text. `key` is usually the same tensor as `value`.

  Here is a code example for using `Attention` in a CNN+Attention network:

  ```python
  # Variable-length int sequences.
  query_input = tf.keras.Input(shape=(None,), dtype='int32')
  value_input = tf.keras.Input(shape=(None,), dtype='int32')

  # Embedding lookup.
  token_embedding = tf.keras.layers.Embedding(input_dim=1000, output_dim=64)
  # Query embeddings of shape [batch_size, Tq, dimension].
  query_embeddings = token_embedding(query_input)
  # Value embeddings of shape [batch_size, Tv, dimension].
  value_embeddings = token_embedding(value_input)

  # CNN layer.
  cnn_layer = tf.keras.layers.Conv1D(
      filters=100,
      kernel_size=4,
      # Use 'same' padding so outputs have the same shape as inputs.
      padding='same')
  # Query encoding of shape [batch_size, Tq, filters].
  query_seq_encoding = cnn_layer(query_embeddings)
  # Value encoding of shape [batch_size, Tv, filters].
  value_seq_encoding = cnn_layer(value_embeddings)

  # Query-value attention of shape [batch_size, Tq, filters].
  query_value_attention_seq = tf.keras.layers.Attention()(
      [query_seq_encoding, value_seq_encoding])

  # Reduce over the sequence axis to produce encodings of shape
  # [batch_size, filters].
  query_encoding = tf.keras.layers.GlobalAveragePooling1D()(
      query_seq_encoding)
  query_value_attention = tf.keras.layers.GlobalAveragePooling1D()(
      query_value_attention_seq)

  # Concatenate query and document encodings to produce a DNN input layer.
  input_layer = tf.keras.layers.Concatenate()(
      [query_encoding, query_value_attention])

  # Add DNN layers, and create Model.
  # ...
  ```
  """

  def __init__(self, use_scale=False, **kwargs):
    super(Attention, self).__init__(**kwargs)
    self.use_scale = use_scale

  def build(self, input_shape):
    """Creates scale variable if use_scale==True."""
    if self.use_scale:
      self.scale = self.add_weight(
          name='scale',
          shape=(),
          initializer='ones',
          dtype=self.dtype,
          trainable=True)
    else:
      self.scale = None
    super(Attention, self).build(input_shape)

  def _calculate_scores(self, query, key):
    """Calculates attention scores as a query-key dot product.

    Args:
      query: Query tensor of shape `[batch_size, Tq, dim]`.
      key: Key tensor of shape `[batch_size, Tv, dim]`.
    Returns:
      Tensor of shape `[batch_size, Tq, Tv]`.
    """
    scores = tf.matmul(query, key, transpose_b=True)
    if self.scale is not None:
      scores *= self.scale
    return scores

  def get_config(self):
    config = {'use_scale': self.use_scale}
    base_config = super(Attention, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

Methods

def build(self, input_shape)

Creates scale variable if use_scale==True.

Expand source code
def build(self, input_shape):
  """Creates scale variable if use_scale==True."""
  if self.use_scale:
    self.scale = self.add_weight(
        name='scale',
        shape=(),
        initializer='ones',
        dtype=self.dtype,
        trainable=True)
  else:
    self.scale = None
  super(Attention, self).build(input_shape)

Inherited members

class Average (**kwargs)

Layer that averages a list of inputs element-wise.

It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).

Example:

>>> x1 = np.ones((2, 2))
>>> x2 = np.zeros((2, 2))
>>> y = tf.keras.layers.Average()([x1, x2])
>>> y.numpy().tolist()
[[0.5, 0.5], [0.5, 0.5]]

Usage in a functional model:

>>> input1 = tf.keras.layers.Input(shape=(16,))
>>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
>>> input2 = tf.keras.layers.Input(shape=(32,))
>>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
>>> avg = tf.keras.layers.Average()([x1, x2])
>>> out = tf.keras.layers.Dense(4)(avg)
>>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

Raises

ValueError
If there is a shape mismatch between the inputs and the shapes cannot be broadcasted to match.

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Average(_Merge):
  """Layer that averages a list of inputs element-wise.

  It takes as input a list of tensors, all of the same shape, and returns
  a single tensor (also of the same shape).

  Example:

  >>> x1 = np.ones((2, 2))
  >>> x2 = np.zeros((2, 2))
  >>> y = tf.keras.layers.Average()([x1, x2])
  >>> y.numpy().tolist()
  [[0.5, 0.5], [0.5, 0.5]]

  Usage in a functional model:

  >>> input1 = tf.keras.layers.Input(shape=(16,))
  >>> x1 = tf.keras.layers.Dense(8, activation='relu')(input1)
  >>> input2 = tf.keras.layers.Input(shape=(32,))
  >>> x2 = tf.keras.layers.Dense(8, activation='relu')(input2)
  >>> avg = tf.keras.layers.Average()([x1, x2])
  >>> out = tf.keras.layers.Dense(4)(avg)
  >>> model = tf.keras.models.Model(inputs=[input1, input2], outputs=out)

  Raises:
    ValueError: If there is a shape mismatch between the inputs and the shapes
      cannot be broadcasted to match.
  """

  def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
      output += inputs[i]
    return output / len(inputs)

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class AveragePooling1D (pool_size=2, strides=None, padding='valid', data_format='channels_last', **kwargs)

Average pooling for temporal data.

Downsamples the input representation by taking the average value over the window defined by pool_size. The window is shifted by strides. The resulting output when using "valid" padding option has a shape of: output_shape = (input_shape - pool_size + 1) / strides)

The resulting output shape when using the "same" padding option is: output_shape = input_shape / strides

For example, for strides=1 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=1, padding='valid')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
array([[[1.5],
        [2.5],
        [3.5],
        [4.5]]], dtype=float32)>

For example, for strides=2 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=2, padding='valid')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
array([[[1.5],
        [3.5]]], dtype=float32)>

For example, for strides=1 and padding="same":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=1, padding='same')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[1.5],
        [2.5],
        [3.5],
        [4.5],
        [5.]]], dtype=float32)>

Args

pool_size
Integer, size of the average pooling windows.
strides
Integer, or None. Factor by which to downscale. E.g. 2 will halve the input. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).

Input shape: - If data_format='channels_last': 3D tensor with shape (batch_size, steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, steps).

Output shape: - If data_format='channels_last': 3D tensor with shape (batch_size, downsampled_steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, downsampled_steps).

Expand source code
class AveragePooling1D(Pooling1D):
  """Average pooling for temporal data.

  Downsamples the input representation by taking the average value over the
  window defined by `pool_size`. The window is shifted by `strides`.  The
  resulting output when using "valid" padding option has a shape of:
  `output_shape = (input_shape - pool_size + 1) / strides)`

  The resulting output shape when using the "same" padding option is:
  `output_shape = input_shape / strides`

  For example, for strides=1 and padding="valid":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=1, padding='valid')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
  array([[[1.5],
          [2.5],
          [3.5],
          [4.5]]], dtype=float32)>

  For example, for strides=2 and padding="valid":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=2, padding='valid')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
  array([[[1.5],
          [3.5]]], dtype=float32)>

  For example, for strides=1 and padding="same":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=1, padding='same')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.5],
          [2.5],
          [3.5],
          [4.5],
          [5.]]], dtype=float32)>

  Args:
    pool_size: Integer, size of the average pooling windows.
    strides: Integer, or None. Factor by which to downscale.
      E.g. 2 will halve the input.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, steps)`.

  Output shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, downsampled_steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, downsampled_steps)`.
  """

  def __init__(self, pool_size=2, strides=None,
               padding='valid', data_format='channels_last', **kwargs):
    super(AveragePooling1D, self).__init__(
        functools.partial(backend.pool2d, pool_mode='avg'),
        pool_size=pool_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        **kwargs)

Ancestors

  • Pooling1D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class AvgPool1D (pool_size=2, strides=None, padding='valid', data_format='channels_last', **kwargs)

Average pooling for temporal data.

Downsamples the input representation by taking the average value over the window defined by pool_size. The window is shifted by strides. The resulting output when using "valid" padding option has a shape of: output_shape = (input_shape - pool_size + 1) / strides)

The resulting output shape when using the "same" padding option is: output_shape = input_shape / strides

For example, for strides=1 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=1, padding='valid')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
array([[[1.5],
        [2.5],
        [3.5],
        [4.5]]], dtype=float32)>

For example, for strides=2 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=2, padding='valid')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
array([[[1.5],
        [3.5]]], dtype=float32)>

For example, for strides=1 and padding="same":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> x
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.],
          [2.],
          [3.],
          [4.],
          [5.]], dtype=float32)>
>>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
...    strides=1, padding='same')
>>> avg_pool_1d(x)
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[1.5],
        [2.5],
        [3.5],
        [4.5],
        [5.]]], dtype=float32)>

Args

pool_size
Integer, size of the average pooling windows.
strides
Integer, or None. Factor by which to downscale. E.g. 2 will halve the input. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).

Input shape: - If data_format='channels_last': 3D tensor with shape (batch_size, steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, steps).

Output shape: - If data_format='channels_last': 3D tensor with shape (batch_size, downsampled_steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, downsampled_steps).

Expand source code
class AveragePooling1D(Pooling1D):
  """Average pooling for temporal data.

  Downsamples the input representation by taking the average value over the
  window defined by `pool_size`. The window is shifted by `strides`.  The
  resulting output when using "valid" padding option has a shape of:
  `output_shape = (input_shape - pool_size + 1) / strides)`

  The resulting output shape when using the "same" padding option is:
  `output_shape = input_shape / strides`

  For example, for strides=1 and padding="valid":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=1, padding='valid')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
  array([[[1.5],
          [2.5],
          [3.5],
          [4.5]]], dtype=float32)>

  For example, for strides=2 and padding="valid":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=2, padding='valid')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
  array([[[1.5],
          [3.5]]], dtype=float32)>

  For example, for strides=1 and padding="same":

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> x
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
    array([[[1.],
            [2.],
            [3.],
            [4.],
            [5.]], dtype=float32)>
  >>> avg_pool_1d = tf.keras.layers.AveragePooling1D(pool_size=2,
  ...    strides=1, padding='same')
  >>> avg_pool_1d(x)
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[1.5],
          [2.5],
          [3.5],
          [4.5],
          [5.]]], dtype=float32)>

  Args:
    pool_size: Integer, size of the average pooling windows.
    strides: Integer, or None. Factor by which to downscale.
      E.g. 2 will halve the input.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, steps)`.

  Output shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, downsampled_steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, downsampled_steps)`.
  """

  def __init__(self, pool_size=2, strides=None,
               padding='valid', data_format='channels_last', **kwargs):
    super(AveragePooling1D, self).__init__(
        functools.partial(backend.pool2d, pool_mode='avg'),
        pool_size=pool_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        **kwargs)

Ancestors

  • Pooling1D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class AveragePooling2D (pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Average pooling operation for spatial data.

Downsamples the input along its spatial dimensions (height and width) by taking the average value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

The resulting output when using "valid" padding option has a shape (number of rows or columns) of: output_shape = math.floor((input_shape - pool_size) / strides) + 1 (when input_shape >= pool_size)

The resulting output shape when using the "same" padding option is: output_shape = math.floor((input_shape - 1) / strides) + 1

For example, for strides=(1, 1) and padding="valid":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='valid')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
  array([[[[3.],
           [4.]],
          [[6.],
           [7.]]]], dtype=float32)>

For example, for stride=(2, 2) and padding="valid":

>>> x = tf.constant([[1., 2., 3., 4.],
...                  [5., 6., 7., 8.],
...                  [9., 10., 11., 12.]])
>>> x = tf.reshape(x, [1, 3, 4, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(2, 2), padding='valid')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
  array([[[[3.5],
           [5.5]]]], dtype=float32)>

For example, for strides=(1, 1) and padding="same":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='same')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
  array([[[[3.],
           [4.],
           [4.5]],
          [[6.],
           [7.],
           [7.5]],
          [[7.5],
           [8.5],
           [9.]]]], dtype=float32)>

Args

pool_size
integer or tuple of 2 integers, factors by which to downscale (vertical, horizontal). (2, 2) will halve the input in both spatial dimension. If only one integer is specified, the same window length will be used for both dimensions.
strides
Integer, tuple of 2 integers, or None. Strides values. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If data_format='channels_last': 4D tensor with shape (batch_size, pooled_rows, pooled_cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, pooled_rows, pooled_cols).

Expand source code
class AveragePooling2D(Pooling2D):
  """Average pooling operation for spatial data.

  Downsamples the input along its spatial dimensions (height and width)
  by taking the average value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  The resulting output when using `"valid"` padding option has a shape
  (number of rows or columns) of:
  `output_shape = math.floor((input_shape - pool_size) / strides) + 1`
  (when `input_shape >= pool_size`)

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = math.floor((input_shape - 1) / strides) + 1`

  For example, for `strides=(1, 1)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='valid')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
    array([[[[3.],
             [4.]],
            [[6.],
             [7.]]]], dtype=float32)>

  For example, for `stride=(2, 2)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3., 4.],
  ...                  [5., 6., 7., 8.],
  ...                  [9., 10., 11., 12.]])
  >>> x = tf.reshape(x, [1, 3, 4, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(2, 2), padding='valid')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
    array([[[[3.5],
             [5.5]]]], dtype=float32)>

  For example, for `strides=(1, 1)` and `padding="same"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='same')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
    array([[[[3.],
             [4.],
             [4.5]],
            [[6.],
             [7.],
             [7.5]],
            [[7.5],
             [8.5],
             [9.]]]], dtype=float32)>

  Args:
    pool_size: integer or tuple of 2 integers,
      factors by which to downscale (vertical, horizontal).
      `(2, 2)` will halve the input in both spatial dimension.
      If only one integer is specified, the same window length
      will be used for both dimensions.
    strides: Integer, tuple of 2 integers, or None.
      Strides values.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, pooled_rows, pooled_cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, pooled_rows, pooled_cols)`.
  """

  def __init__(self,
               pool_size=(2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(AveragePooling2D, self).__init__(
        tf.nn.avg_pool,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling2D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class AvgPool2D (pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Average pooling operation for spatial data.

Downsamples the input along its spatial dimensions (height and width) by taking the average value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

The resulting output when using "valid" padding option has a shape (number of rows or columns) of: output_shape = math.floor((input_shape - pool_size) / strides) + 1 (when input_shape >= pool_size)

The resulting output shape when using the "same" padding option is: output_shape = math.floor((input_shape - 1) / strides) + 1

For example, for strides=(1, 1) and padding="valid":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='valid')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
  array([[[[3.],
           [4.]],
          [[6.],
           [7.]]]], dtype=float32)>

For example, for stride=(2, 2) and padding="valid":

>>> x = tf.constant([[1., 2., 3., 4.],
...                  [5., 6., 7., 8.],
...                  [9., 10., 11., 12.]])
>>> x = tf.reshape(x, [1, 3, 4, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(2, 2), padding='valid')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
  array([[[[3.5],
           [5.5]]]], dtype=float32)>

For example, for strides=(1, 1) and padding="same":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='same')
>>> avg_pool_2d(x)
<tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
  array([[[[3.],
           [4.],
           [4.5]],
          [[6.],
           [7.],
           [7.5]],
          [[7.5],
           [8.5],
           [9.]]]], dtype=float32)>

Args

pool_size
integer or tuple of 2 integers, factors by which to downscale (vertical, horizontal). (2, 2) will halve the input in both spatial dimension. If only one integer is specified, the same window length will be used for both dimensions.
strides
Integer, tuple of 2 integers, or None. Strides values. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If data_format='channels_last': 4D tensor with shape (batch_size, pooled_rows, pooled_cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, pooled_rows, pooled_cols).

Expand source code
class AveragePooling2D(Pooling2D):
  """Average pooling operation for spatial data.

  Downsamples the input along its spatial dimensions (height and width)
  by taking the average value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  The resulting output when using `"valid"` padding option has a shape
  (number of rows or columns) of:
  `output_shape = math.floor((input_shape - pool_size) / strides) + 1`
  (when `input_shape >= pool_size`)

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = math.floor((input_shape - 1) / strides) + 1`

  For example, for `strides=(1, 1)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='valid')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
    array([[[[3.],
             [4.]],
            [[6.],
             [7.]]]], dtype=float32)>

  For example, for `stride=(2, 2)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3., 4.],
  ...                  [5., 6., 7., 8.],
  ...                  [9., 10., 11., 12.]])
  >>> x = tf.reshape(x, [1, 3, 4, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(2, 2), padding='valid')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
    array([[[[3.5],
             [5.5]]]], dtype=float32)>

  For example, for `strides=(1, 1)` and `padding="same"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> avg_pool_2d = tf.keras.layers.AveragePooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='same')
  >>> avg_pool_2d(x)
  <tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
    array([[[[3.],
             [4.],
             [4.5]],
            [[6.],
             [7.],
             [7.5]],
            [[7.5],
             [8.5],
             [9.]]]], dtype=float32)>

  Args:
    pool_size: integer or tuple of 2 integers,
      factors by which to downscale (vertical, horizontal).
      `(2, 2)` will halve the input in both spatial dimension.
      If only one integer is specified, the same window length
      will be used for both dimensions.
    strides: Integer, tuple of 2 integers, or None.
      Strides values.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, pooled_rows, pooled_cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, pooled_rows, pooled_cols)`.
  """

  def __init__(self,
               pool_size=(2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(AveragePooling2D, self).__init__(
        tf.nn.avg_pool,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling2D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class AveragePooling3D (pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Average pooling operation for 3D data (spatial or spatio-temporal).

Downsamples the input along its spatial dimensions (depth, height, and width) by taking the average value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

Args

pool_size
tuple of 3 integers, factors by which to downscale (dim1, dim2, dim3). (2, 2, 2) will halve the size of the 3D input in each dimension.
strides
tuple of 3 integers, or None. Strides values.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)

Example:

depth = 30
height = 30
width = 30
input_channels = 3

inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
layer = tf.keras.layers.AveragePooling3D(pool_size=3)
outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
Expand source code
class AveragePooling3D(Pooling3D):
  """Average pooling operation for 3D data (spatial or spatio-temporal).

  Downsamples the input along its spatial dimensions (depth, height, and width)
  by taking the average value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  Args:
    pool_size: tuple of 3 integers,
      factors by which to downscale (dim1, dim2, dim3).
      `(2, 2, 2)` will halve the size of the 3D input in each dimension.
    strides: tuple of 3 integers, or None. Strides values.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`

  Example:

  ```python
  depth = 30
  height = 30
  width = 30
  input_channels = 3

  inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
  layer = tf.keras.layers.AveragePooling3D(pool_size=3)
  outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
  ```
  """

  def __init__(self,
               pool_size=(2, 2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(AveragePooling3D, self).__init__(
        tf.nn.avg_pool3d,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling3D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class AvgPool3D (pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Average pooling operation for 3D data (spatial or spatio-temporal).

Downsamples the input along its spatial dimensions (depth, height, and width) by taking the average value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

Args

pool_size
tuple of 3 integers, factors by which to downscale (dim1, dim2, dim3). (2, 2, 2) will halve the size of the 3D input in each dimension.
strides
tuple of 3 integers, or None. Strides values.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)

Example:

depth = 30
height = 30
width = 30
input_channels = 3

inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
layer = tf.keras.layers.AveragePooling3D(pool_size=3)
outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
Expand source code
class AveragePooling3D(Pooling3D):
  """Average pooling operation for 3D data (spatial or spatio-temporal).

  Downsamples the input along its spatial dimensions (depth, height, and width)
  by taking the average value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  Args:
    pool_size: tuple of 3 integers,
      factors by which to downscale (dim1, dim2, dim3).
      `(2, 2, 2)` will halve the size of the 3D input in each dimension.
    strides: tuple of 3 integers, or None. Strides values.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`

  Example:

  ```python
  depth = 30
  height = 30
  width = 30
  input_channels = 3

  inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
  layer = tf.keras.layers.AveragePooling3D(pool_size=3)
  outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
  ```
  """

  def __init__(self,
               pool_size=(2, 2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(AveragePooling3D, self).__init__(
        tf.nn.avg_pool3d,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling3D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class BatchNormalization (axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initializer='zeros', moving_variance_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None, renorm=False, renorm_clipping=None, renorm_momentum=0.99, fused=None, trainable=True, virtual_batch_size=None, adjustment=None, name=None, **kwargs)

Layer that normalizes its inputs.

Batch normalization applies a transformation that maintains the mean output close to 0 and the output standard deviation close to 1.

Importantly, batch normalization works differently during training and during inference.

During training (i.e. when using fit() or when calling the layer/model with the argument training=True), the layer normalizes its output using the mean and standard deviation of the current batch of inputs. That is to say, for each channel being normalized, the layer returns gamma * (batch - mean(batch)) / sqrt(var(batch) + epsilon) + beta, where:

  • epsilon is small constant (configurable as part of the constructor arguments)
  • gamma is a learned scaling factor (initialized as 1), which can be disabled by passing scale=False to the constructor.
  • beta is a learned offset factor (initialized as 0), which can be disabled by passing center=False to the constructor.

During inference (i.e. when using evaluate() or predict()) or when calling the layer/model with the argument training=False (which is the default), the layer normalizes its output using a moving average of the mean and standard deviation of the batches it has seen during training. That is to say, it returns gamma * (batch - self.moving_mean) / sqrt(self.moving_var + epsilon) + beta.

self.moving_mean and self.moving_var are non-trainable variables that are updated each time the layer in called in training mode, as such:

  • moving_mean = moving_mean * momentum + mean(batch) * (1 - momentum)
  • moving_var = moving_var * momentum + var(batch) * (1 - momentum)

As such, the layer will only normalize its inputs during inference after having been trained on data that has similar statistics as the inference data.

Args

axis
Integer or a list of integers, the axis that should be normalized (typically the features axis). For instance, after a Conv2D layer with data_format="channels_first", set axis=1 in BatchNormalization.
momentum
Momentum for the moving average.
epsilon
Small float added to variance to avoid dividing by zero.
center
If True, add offset of beta to normalized tensor. If False, beta is ignored.
scale
If True, multiply by gamma. If False, gamma is not used. When the next layer is linear (also e.g. nn.relu), this can be disabled since the scaling will be done by the next layer.
beta_initializer
Initializer for the beta weight.
gamma_initializer
Initializer for the gamma weight.
moving_mean_initializer
Initializer for the moving mean.
moving_variance_initializer
Initializer for the moving variance.
beta_regularizer
Optional regularizer for the beta weight.
gamma_regularizer
Optional regularizer for the gamma weight.
beta_constraint
Optional constraint for the beta weight.
gamma_constraint
Optional constraint for the gamma weight.
renorm
Whether to use Batch Renormalization. This adds extra variables during training. The inference is the same for either value of this parameter.
renorm_clipping
A dictionary that may map keys 'rmax', 'rmin', 'dmax' to scalar Tensors used to clip the renorm correction. The correction (r, d)<code> is used as </code>corrected_value = normalized_value * r + d<code>, with </code>r clipped to [rmin, rmax], and d to [-dmax, dmax]. Missing rmax, rmin, dmax are set to inf, 0, inf, respectively.
renorm_momentum
Momentum used to update the moving means and standard deviations with renorm. Unlike momentum, this affects training and should be neither too small (which would add noise) nor too large (which would give stale estimates). Note that momentum is still applied to get the means and variances for inference.
fused
if True, use a faster, fused implementation, or raise a ValueError if the fused implementation cannot be used. If None, use the faster implementation if possible. If False, do not used the fused implementation. Note that in TensorFlow 1.x, the meaning of fused=True is different: if False, the layer uses the system-recommended implementation.
trainable
Boolean, if True the variables will be marked as trainable.
virtual_batch_size
An int. By default, virtual_batch_size is None, which means batch normalization is performed across the whole batch. When virtual_batch_size is not None, instead perform "Ghost Batch Normalization", which creates virtual sub-batches which are each normalized separately (with shared gamma, beta, and moving statistics). Must divide the actual batch size during execution.
adjustment
A function taking the Tensor containing the (dynamic) shape of the input tensor and returning a pair (scale, bias) to apply to the normalized values (before gamma and beta), only during training. For example, if axis=-1, adjustment = lambda shape: ( tf.random.uniform(shape[-1:], 0.93, 1.07), tf.random.uniform(shape[-1:], -0.1, 0.1)) will scale the normalized value by up to 7% up or down, then shift the result by up to 0.1 (with independent scaling and bias for each feature but shared across all examples), and finally apply gamma and/or beta. If None, no adjustment is applied. Cannot be specified if virtual_batch_size is specified.

Call arguments: inputs: Input tensor (of any rank). training: Python boolean indicating whether the layer should behave in training mode or in inference mode. - training=True: The layer will normalize its inputs using the mean and variance of the current batch of inputs. - training=False: The layer will normalize its inputs using the mean and variance of its moving statistics, learned during training.

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Reference

Expand source code
class BatchNormalization(batch_normalization.BatchNormalizationBase):
  _USE_V2_BEHAVIOR = False

Ancestors

Subclasses

Inherited members

class Bidirectional (layer, merge_mode='concat', weights=None, backward_layer=None, **kwargs)

Bidirectional wrapper for RNNs.

Args

layer
keras.layers.RNN instance, such as keras.layers.LSTM or keras.layers.GRU. It could also be a keras.layers.Layer instance that meets the following criteria: 1. Be a sequence-processing layer (accepts 3D+ inputs). 2. Have a go_backwards, return_sequences and return_state attribute (with the same semantics as for the RNN class). 3. Have an input_spec attribute. 4. Implement serialization via get_config() and from_config(). Note that the recommended way to create new RNN layers is to write a custom RNN cell and use it with keras.layers.RNN, instead of subclassing keras.layers.Layer directly. - When the returns_sequences is true, the output of the masked timestep will be zero regardless of the layer's original zero_output_for_mask value.
merge_mode
Mode by which outputs of the forward and backward RNNs will be combined. One of {'sum', 'mul', 'concat', 'ave', None}. If None, the outputs will not be combined, they will be returned as a list. Default value is 'concat'.
backward_layer
Optional keras.layers.RNN, or keras.layers.Layer instance to be used to handle backwards input processing. If backward_layer is not provided, the layer instance passed as the layer argument will be used to generate the backward layer automatically. Note that the provided backward_layer layer should have properties matching those of the layer argument, in particular it should have the same values for stateful, return_states, return_sequences, etc. In addition, backward_layer and layer should have different go_backwards argument values. A ValueError will be raised if these requirements are not met.

Call arguments: The call arguments for this layer are the same as those of the wrapped RNN layer. Beware that when passing the initial_state argument during the call of this layer, the first half in the list of elements in the initial_state list will be passed to the forward RNN call and the last half in the list of elements will be passed to the backward RNN call.

Raises

ValueError: 1. If layer or backward_layer is not a Layer instance. 2. In case of invalid merge_mode argument. 3. If backward_layer has mismatched properties compared to layer. Examples:

model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(Bidirectional(LSTM(10)))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

 # With custom backward layer
 model = Sequential()
 forward_layer = LSTM(10, return_sequences=True)
 backward_layer = LSTM(10, activation='relu', return_sequences=True,
                       go_backwards=True)
 model.add(Bidirectional(forward_layer, backward_layer=backward_layer,
                         input_shape=(5, 10)))
 model.add(Dense(5))
 model.add(Activation('softmax'))
 model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
Expand source code
class Bidirectional(Wrapper):
  """Bidirectional wrapper for RNNs.

  Args:
    layer: `keras.layers.RNN` instance, such as `keras.layers.LSTM` or
      `keras.layers.GRU`. It could also be a `keras.layers.Layer` instance
      that meets the following criteria:
      1. Be a sequence-processing layer (accepts 3D+ inputs).
      2. Have a `go_backwards`, `return_sequences` and `return_state`
        attribute (with the same semantics as for the `RNN` class).
      3. Have an `input_spec` attribute.
      4. Implement serialization via `get_config()` and `from_config()`.
      Note that the recommended way to create new RNN layers is to write a
      custom RNN cell and use it with `keras.layers.RNN`, instead of
      subclassing `keras.layers.Layer` directly.
      - When the `returns_sequences` is true, the output of the masked timestep
      will be zero regardless of the layer's original `zero_output_for_mask`
      value.
    merge_mode: Mode by which outputs of the forward and backward RNNs will be
      combined. One of {'sum', 'mul', 'concat', 'ave', None}. If None, the
      outputs will not be combined, they will be returned as a list. Default
      value is 'concat'.
    backward_layer: Optional `keras.layers.RNN`, or `keras.layers.Layer`
      instance to be used to handle backwards input processing.
      If `backward_layer` is not provided, the layer instance passed as the
      `layer` argument will be used to generate the backward layer
      automatically.
      Note that the provided `backward_layer` layer should have properties
      matching those of the `layer` argument, in particular it should have the
      same values for `stateful`, `return_states`, `return_sequences`, etc.
      In addition, `backward_layer` and `layer` should have different
      `go_backwards` argument values.
      A `ValueError` will be raised if these requirements are not met.

  Call arguments:
    The call arguments for this layer are the same as those of the wrapped RNN
      layer.
    Beware that when passing the `initial_state` argument during the call of
    this layer, the first half in the list of elements in the `initial_state`
    list will be passed to the forward RNN call and the last half in the list
    of elements will be passed to the backward RNN call.

  Raises:
    ValueError:
      1. If `layer` or `backward_layer` is not a `Layer` instance.
      2. In case of invalid `merge_mode` argument.
      3. If `backward_layer` has mismatched properties compared to `layer`.

  Examples:

  ```python
  model = Sequential()
  model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
  model.add(Bidirectional(LSTM(10)))
  model.add(Dense(5))
  model.add(Activation('softmax'))
  model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

   # With custom backward layer
   model = Sequential()
   forward_layer = LSTM(10, return_sequences=True)
   backward_layer = LSTM(10, activation='relu', return_sequences=True,
                         go_backwards=True)
   model.add(Bidirectional(forward_layer, backward_layer=backward_layer,
                           input_shape=(5, 10)))
   model.add(Dense(5))
   model.add(Activation('softmax'))
   model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
  ```
  """

  def __init__(self,
               layer,
               merge_mode='concat',
               weights=None,
               backward_layer=None,
               **kwargs):
    if not isinstance(layer, Layer):
      raise ValueError(
          'Please initialize `Bidirectional` layer with a '
          '`Layer` instance. You passed: {input}'.format(input=layer))
    if backward_layer is not None and not isinstance(backward_layer, Layer):
      raise ValueError('`backward_layer` need to be a `Layer` instance. '
                       'You passed: {input}'.format(input=backward_layer))
    if merge_mode not in ['sum', 'mul', 'ave', 'concat', None]:
      raise ValueError('Invalid merge mode. '
                       'Merge mode should be one of '
                       '{"sum", "mul", "ave", "concat", None}')
    # We don't want to track `layer` since we're already tracking the two copies
    # of it we actually run.
    self._setattr_tracking = False
    super(Bidirectional, self).__init__(layer, **kwargs)
    self._setattr_tracking = True

    # Recreate the forward layer from the original layer config, so that it will
    # not carry over any state from the layer.
    self.forward_layer = self._recreate_layer_from_config(layer)

    if backward_layer is None:
      self.backward_layer = self._recreate_layer_from_config(
          layer, go_backwards=True)
    else:
      self.backward_layer = backward_layer
      # Keep the custom backward layer config, so that we can save it later. The
      # layer's name might be updated below with prefix 'backward_', and we want
      # to preserve the original config.
      self._backward_layer_config = generic_utils.serialize_keras_object(
          backward_layer)

    self.forward_layer._name = 'forward_' + self.forward_layer.name
    self.backward_layer._name = 'backward_' + self.backward_layer.name

    self._verify_layer_config()

    def force_zero_output_for_mask(layer):
      # Force the zero_output_for_mask to be True if returning sequences.
      if getattr(layer, 'zero_output_for_mask', None) is not None:
        layer.zero_output_for_mask = layer.return_sequences

    force_zero_output_for_mask(self.forward_layer)
    force_zero_output_for_mask(self.backward_layer)

    self.merge_mode = merge_mode
    if weights:
      nw = len(weights)
      self.forward_layer.initial_weights = weights[:nw // 2]
      self.backward_layer.initial_weights = weights[nw // 2:]
    self.stateful = layer.stateful
    self.return_sequences = layer.return_sequences
    self.return_state = layer.return_state
    self.supports_masking = True
    self._trainable = True
    self._num_constants = 0
    self.input_spec = layer.input_spec

  def _verify_layer_config(self):
    """Ensure the forward and backward layers have valid common property."""
    if self.forward_layer.go_backwards == self.backward_layer.go_backwards:
      raise ValueError('Forward layer and backward layer should have different '
                       '`go_backwards` value.')

    common_attributes = ('stateful', 'return_sequences', 'return_state')
    for a in common_attributes:
      forward_value = getattr(self.forward_layer, a)
      backward_value = getattr(self.backward_layer, a)
      if forward_value != backward_value:
        raise ValueError(
            'Forward layer and backward layer are expected to have the same '
            'value for attribute {attr}, got {forward} and {backward}'.format(
                attr=a, forward=forward_value, backward=backward_value))

  def _recreate_layer_from_config(self, layer, go_backwards=False):
    # When recreating the layer from its config, it is possible that the layer
    # is a RNN layer that contains custom cells. In this case we inspect the
    # layer and pass the custom cell class as part of the `custom_objects`
    # argument when calling `from_config`.
    # See https://github.com/tensorflow/tensorflow/issues/26581 for more detail.
    config = layer.get_config()
    if go_backwards:
      config['go_backwards'] = not config['go_backwards']
    if 'custom_objects' in tf_inspect.getfullargspec(
        layer.__class__.from_config).args:
      custom_objects = {}
      cell = getattr(layer, 'cell', None)
      if cell is not None:
        custom_objects[cell.__class__.__name__] = cell.__class__
        # For StackedRNNCells
        stacked_cells = getattr(cell, 'cells', [])
        for c in stacked_cells:
          custom_objects[c.__class__.__name__] = c.__class__
      return layer.__class__.from_config(config, custom_objects=custom_objects)
    else:
      return layer.__class__.from_config(config)

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    output_shape = self.forward_layer.compute_output_shape(input_shape)
    if self.return_state:
      state_shape = tf_utils.convert_shapes(output_shape[1:], to_tuples=False)
      output_shape = tf_utils.convert_shapes(output_shape[0], to_tuples=False)
    else:
      output_shape = tf_utils.convert_shapes(output_shape, to_tuples=False)

    if self.merge_mode == 'concat':
      output_shape = output_shape.as_list()
      output_shape[-1] *= 2
      output_shape = tf.TensorShape(output_shape)
    elif self.merge_mode is None:
      output_shape = [output_shape, copy.copy(output_shape)]

    if self.return_state:
      if self.merge_mode is None:
        return output_shape + state_shape + copy.copy(state_shape)
      return [output_shape] + state_shape + copy.copy(state_shape)
    return output_shape

  def __call__(self, inputs, initial_state=None, constants=None, **kwargs):
    """`Bidirectional.__call__` implements the same API as the wrapped `RNN`."""
    inputs, initial_state, constants = _standardize_args(
        inputs, initial_state, constants, self._num_constants)

    if isinstance(inputs, list):
      if len(inputs) > 1:
        initial_state = inputs[1:]
      inputs = inputs[0]

    if initial_state is None and constants is None:
      return super(Bidirectional, self).__call__(inputs, **kwargs)

    # Applies the same workaround as in `RNN.__call__`
    additional_inputs = []
    additional_specs = []
    if initial_state is not None:
      # Check if `initial_state` can be splitted into half
      num_states = len(initial_state)
      if num_states % 2 > 0:
        raise ValueError(
            'When passing `initial_state` to a Bidirectional RNN, '
            'the state should be a list containing the states of '
            'the underlying RNNs. '
            'Found: ' + str(initial_state))

      kwargs['initial_state'] = initial_state
      additional_inputs += initial_state
      state_specs = tf.nest.map_structure(
          lambda state: InputSpec(shape=backend.int_shape(state)),
          initial_state)
      self.forward_layer.state_spec = state_specs[:num_states // 2]
      self.backward_layer.state_spec = state_specs[num_states // 2:]
      additional_specs += state_specs
    if constants is not None:
      kwargs['constants'] = constants
      additional_inputs += constants
      constants_spec = [InputSpec(shape=backend.int_shape(constant))
                        for constant in constants]
      self.forward_layer.constants_spec = constants_spec
      self.backward_layer.constants_spec = constants_spec
      additional_specs += constants_spec

      self._num_constants = len(constants)
      self.forward_layer._num_constants = self._num_constants
      self.backward_layer._num_constants = self._num_constants

    is_keras_tensor = backend.is_keras_tensor(
        tf.nest.flatten(additional_inputs)[0])
    for tensor in tf.nest.flatten(additional_inputs):
      if backend.is_keras_tensor(tensor) != is_keras_tensor:
        raise ValueError('The initial state of a Bidirectional'
                         ' layer cannot be specified with a mix of'
                         ' Keras tensors and non-Keras tensors'
                         ' (a "Keras tensor" is a tensor that was'
                         ' returned by a Keras layer, or by `Input`)')

    if is_keras_tensor:
      # Compute the full input spec, including state
      full_input = [inputs] + additional_inputs
      # The original input_spec is None since there could be a nested tensor
      # input. Update the input_spec to match the inputs.
      full_input_spec = [None for _ in range(len(tf.nest.flatten(inputs)))
                        ] + additional_specs
      # Removing kwargs since the value are passed with input list.
      kwargs['initial_state'] = None
      kwargs['constants'] = None

      # Perform the call with temporarily replaced input_spec
      original_input_spec = self.input_spec
      self.input_spec = full_input_spec
      output = super(Bidirectional, self).__call__(full_input, **kwargs)
      self.input_spec = original_input_spec
      return output
    else:
      return super(Bidirectional, self).__call__(inputs, **kwargs)

  def call(self,
           inputs,
           training=None,
           mask=None,
           initial_state=None,
           constants=None):
    """`Bidirectional.call` implements the same API as the wrapped `RNN`."""
    kwargs = {}
    if generic_utils.has_arg(self.layer.call, 'training'):
      kwargs['training'] = training
    if generic_utils.has_arg(self.layer.call, 'mask'):
      kwargs['mask'] = mask
    if generic_utils.has_arg(self.layer.call, 'constants'):
      kwargs['constants'] = constants

    if generic_utils.has_arg(self.layer.call, 'initial_state'):
      if isinstance(inputs, list) and len(inputs) > 1:
        # initial_states are keras tensors, which means they are passed in
        # together with inputs as list. The initial_states need to be split into
        # forward and backward section, and be feed to layers accordingly.
        forward_inputs = [inputs[0]]
        backward_inputs = [inputs[0]]
        pivot = (len(inputs) - self._num_constants) // 2 + 1
        # add forward initial state
        forward_inputs += inputs[1:pivot]
        if not self._num_constants:
          # add backward initial state
          backward_inputs += inputs[pivot:]
        else:
          # add backward initial state
          backward_inputs += inputs[pivot:-self._num_constants]
          # add constants for forward and backward layers
          forward_inputs += inputs[-self._num_constants:]
          backward_inputs += inputs[-self._num_constants:]
        forward_state, backward_state = None, None
        if 'constants' in kwargs:
          kwargs['constants'] = None
      elif initial_state is not None:
        # initial_states are not keras tensors, eg eager tensor from np array.
        # They are only passed in from kwarg initial_state, and should be passed
        # to forward/backward layer via kwarg initial_state as well.
        forward_inputs, backward_inputs = inputs, inputs
        half = len(initial_state) // 2
        forward_state = initial_state[:half]
        backward_state = initial_state[half:]
      else:
        forward_inputs, backward_inputs = inputs, inputs
        forward_state, backward_state = None, None

      y = self.forward_layer(forward_inputs,
                             initial_state=forward_state, **kwargs)
      y_rev = self.backward_layer(backward_inputs,
                                  initial_state=backward_state, **kwargs)
    else:
      y = self.forward_layer(inputs, **kwargs)
      y_rev = self.backward_layer(inputs, **kwargs)

    if self.return_state:
      states = y[1:] + y_rev[1:]
      y = y[0]
      y_rev = y_rev[0]

    if self.return_sequences:
      time_dim = 0 if getattr(self.forward_layer, 'time_major', False) else 1
      y_rev = backend.reverse(y_rev, time_dim)
    if self.merge_mode == 'concat':
      output = backend.concatenate([y, y_rev])
    elif self.merge_mode == 'sum':
      output = y + y_rev
    elif self.merge_mode == 'ave':
      output = (y + y_rev) / 2
    elif self.merge_mode == 'mul':
      output = y * y_rev
    elif self.merge_mode is None:
      output = [y, y_rev]
    else:
      raise ValueError(
          'Unrecognized value for `merge_mode`: %s' % (self.merge_mode))

    if self.return_state:
      if self.merge_mode is None:
        return output + states
      return [output] + states
    return output

  def reset_states(self):
    self.forward_layer.reset_states()
    self.backward_layer.reset_states()

  def build(self, input_shape):
    with backend.name_scope(self.forward_layer.name):
      self.forward_layer.build(input_shape)
    with backend.name_scope(self.backward_layer.name):
      self.backward_layer.build(input_shape)
    self.built = True

  def compute_mask(self, inputs, mask):
    if isinstance(mask, list):
      mask = mask[0]
    if self.return_sequences:
      if not self.merge_mode:
        output_mask = [mask, mask]
      else:
        output_mask = mask
    else:
      output_mask = [None, None] if not self.merge_mode else None

    if self.return_state:
      states = self.forward_layer.states
      state_mask = [None for _ in states]
      if isinstance(output_mask, list):
        return output_mask + state_mask * 2
      return [output_mask] + state_mask * 2
    return output_mask

  @property
  def constraints(self):
    constraints = {}
    if hasattr(self.forward_layer, 'constraints'):
      constraints.update(self.forward_layer.constraints)
      constraints.update(self.backward_layer.constraints)
    return constraints

  def get_config(self):
    config = {'merge_mode': self.merge_mode}
    if self._num_constants:
      config['num_constants'] = self._num_constants

    if hasattr(self, '_backward_layer_config'):
      config['backward_layer'] = self._backward_layer_config
    base_config = super(Bidirectional, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config, custom_objects=None):
    # Instead of updating the input, create a copy and use that.
    config = copy.deepcopy(config)
    num_constants = config.pop('num_constants', 0)
    # Handle forward layer instantiation (as would parent class).
    from keras.layers import deserialize as deserialize_layer  # pylint: disable=g-import-not-at-top
    config['layer'] = deserialize_layer(
        config['layer'], custom_objects=custom_objects)
    # Handle (optional) backward layer instantiation.
    backward_layer_config = config.pop('backward_layer', None)
    if backward_layer_config is not None:
      backward_layer = deserialize_layer(
          backward_layer_config, custom_objects=custom_objects)
      config['backward_layer'] = backward_layer
    # Instantiate the wrapper, adjust it and return it.
    layer = cls(**config)
    layer._num_constants = num_constants
    return layer

Ancestors

  • Wrapper
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Instance variables

var constraints
Expand source code
@property
def constraints(self):
  constraints = {}
  if hasattr(self.forward_layer, 'constraints'):
    constraints.update(self.forward_layer.constraints)
    constraints.update(self.backward_layer.constraints)
  return constraints

Methods

def call(self, inputs, training=None, mask=None, initial_state=None, constants=None)

Bidirectional.call() implements the same API as the wrapped RNN.

Expand source code
def call(self,
         inputs,
         training=None,
         mask=None,
         initial_state=None,
         constants=None):
  """`Bidirectional.call` implements the same API as the wrapped `RNN`."""
  kwargs = {}
  if generic_utils.has_arg(self.layer.call, 'training'):
    kwargs['training'] = training
  if generic_utils.has_arg(self.layer.call, 'mask'):
    kwargs['mask'] = mask
  if generic_utils.has_arg(self.layer.call, 'constants'):
    kwargs['constants'] = constants

  if generic_utils.has_arg(self.layer.call, 'initial_state'):
    if isinstance(inputs, list) and len(inputs) > 1:
      # initial_states are keras tensors, which means they are passed in
      # together with inputs as list. The initial_states need to be split into
      # forward and backward section, and be feed to layers accordingly.
      forward_inputs = [inputs[0]]
      backward_inputs = [inputs[0]]
      pivot = (len(inputs) - self._num_constants) // 2 + 1
      # add forward initial state
      forward_inputs += inputs[1:pivot]
      if not self._num_constants:
        # add backward initial state
        backward_inputs += inputs[pivot:]
      else:
        # add backward initial state
        backward_inputs += inputs[pivot:-self._num_constants]
        # add constants for forward and backward layers
        forward_inputs += inputs[-self._num_constants:]
        backward_inputs += inputs[-self._num_constants:]
      forward_state, backward_state = None, None
      if 'constants' in kwargs:
        kwargs['constants'] = None
    elif initial_state is not None:
      # initial_states are not keras tensors, eg eager tensor from np array.
      # They are only passed in from kwarg initial_state, and should be passed
      # to forward/backward layer via kwarg initial_state as well.
      forward_inputs, backward_inputs = inputs, inputs
      half = len(initial_state) // 2
      forward_state = initial_state[:half]
      backward_state = initial_state[half:]
    else:
      forward_inputs, backward_inputs = inputs, inputs
      forward_state, backward_state = None, None

    y = self.forward_layer(forward_inputs,
                           initial_state=forward_state, **kwargs)
    y_rev = self.backward_layer(backward_inputs,
                                initial_state=backward_state, **kwargs)
  else:
    y = self.forward_layer(inputs, **kwargs)
    y_rev = self.backward_layer(inputs, **kwargs)

  if self.return_state:
    states = y[1:] + y_rev[1:]
    y = y[0]
    y_rev = y_rev[0]

  if self.return_sequences:
    time_dim = 0 if getattr(self.forward_layer, 'time_major', False) else 1
    y_rev = backend.reverse(y_rev, time_dim)
  if self.merge_mode == 'concat':
    output = backend.concatenate([y, y_rev])
  elif self.merge_mode == 'sum':
    output = y + y_rev
  elif self.merge_mode == 'ave':
    output = (y + y_rev) / 2
  elif self.merge_mode == 'mul':
    output = y * y_rev
  elif self.merge_mode is None:
    output = [y, y_rev]
  else:
    raise ValueError(
        'Unrecognized value for `merge_mode`: %s' % (self.merge_mode))

  if self.return_state:
    if self.merge_mode is None:
      return output + states
    return [output] + states
  return output
def reset_states(self)
Expand source code
def reset_states(self):
  self.forward_layer.reset_states()
  self.backward_layer.reset_states()

Inherited members

class CategoryEncoding (num_tokens=None, output_mode='multi_hot', sparse=False, **kwargs)

Category encoding layer.

This layer provides options for condensing data into a categorical encoding when the total number of tokens are known in advance. It accepts integer values as inputs, and it outputs a dense representation of those inputs. For integer inputs where the total number of tokens is not known, use instead tf.keras.layers.IntegerLookup.

Examples:

One-hot encoding data

>>> layer = tf.keras.layers.CategoryEncoding(
...           num_tokens=4, output_mode="one_hot")
>>> layer([3, 2, 0, 1])
<tf.Tensor: shape=(4, 4), dtype=float32, numpy=
  array([[0., 0., 0., 1.],
         [0., 0., 1., 0.],
         [1., 0., 0., 0.],
         [0., 1., 0., 0.]], dtype=float32)>

Multi-hot encoding data

>>> layer = tf.keras.layers.CategoryEncoding(
...           num_tokens=4, output_mode="multi_hot")
>>> layer([[0, 1], [0, 0], [1, 2], [3, 1]])
<tf.Tensor: shape=(4, 4), dtype=float32, numpy=
  array([[1., 1., 0., 0.],
         [1., 0., 0., 0.],
         [0., 1., 1., 0.],
         [0., 1., 0., 1.]], dtype=float32)>

Using weighted inputs in "count" mode

>>> layer = tf.keras.layers.CategoryEncoding(
...           num_tokens=4, output_mode="count")
>>> count_weights = np.array([[.1, .2], [.1, .1], [.2, .3], [.4, .2]])
>>> layer([[0, 1], [0, 0], [1, 2], [3, 1]], count_weights=count_weights)
<tf.Tensor: shape=(4, 4), dtype=float64, numpy=
  array([[0.1, 0.2, 0. , 0. ],
         [0.2, 0. , 0. , 0. ],
         [0. , 0.2, 0.3, 0. ],
         [0. , 0.2, 0. , 0.4]])>

Args

num_tokens
The total number of tokens the layer should support. All inputs to the layer must integers in the range 0 <= value < num_tokens, or an error will be thrown.
output_mode
Specification for the output of the layer. Defaults to "multi_hot". Values can be "one_hot", "multi_hot" or "count", configuring the layer as follows: - "one_hot": Encodes each individual element in the input into an array of num_tokens size, containing a 1 at the element index. If the last dimension is size 1, will encode on that dimension. If the last dimension is not size 1, will append a new dimension for the encoded output. - "multi_hot": Encodes each sample in the input into a single array of num_tokens size, containing a 1 for each vocabulary term present in the sample. Treats the last dimension as the sample dimension, if input shape is (…, sample_length), output shape will be (…, num_tokens). - "count": Like "multi_hot", but the int array contains a count of the number of times the token at that index appeared in the sample. For all output modes, currently only output up to rank 2 is supported.
sparse
Boolean. If true, returns a SparseTensor instead of a dense Tensor. Defaults to False.

Call arguments: inputs: A 1D or 2D tensor of integer inputs. count_weights: A tensor in the same shape as inputs indicating the weight for each sample value when summing up in count mode. Not used in "multi_hot" or "one_hot" modes.

Expand source code
class CategoryEncoding(base_layer.Layer):
  """Category encoding layer.

  This layer provides options for condensing data into a categorical encoding
  when the total number of tokens are known in advance. It accepts integer
  values as inputs, and it outputs a dense representation of those
  inputs. For integer inputs where the total number of tokens is not known,
  use instead `tf.keras.layers.IntegerLookup`.

  Examples:

  **One-hot encoding data**

  >>> layer = tf.keras.layers.CategoryEncoding(
  ...           num_tokens=4, output_mode="one_hot")
  >>> layer([3, 2, 0, 1])
  <tf.Tensor: shape=(4, 4), dtype=float32, numpy=
    array([[0., 0., 0., 1.],
           [0., 0., 1., 0.],
           [1., 0., 0., 0.],
           [0., 1., 0., 0.]], dtype=float32)>

  **Multi-hot encoding data**

  >>> layer = tf.keras.layers.CategoryEncoding(
  ...           num_tokens=4, output_mode="multi_hot")
  >>> layer([[0, 1], [0, 0], [1, 2], [3, 1]])
  <tf.Tensor: shape=(4, 4), dtype=float32, numpy=
    array([[1., 1., 0., 0.],
           [1., 0., 0., 0.],
           [0., 1., 1., 0.],
           [0., 1., 0., 1.]], dtype=float32)>

  **Using weighted inputs in `"count"` mode**

  >>> layer = tf.keras.layers.CategoryEncoding(
  ...           num_tokens=4, output_mode="count")
  >>> count_weights = np.array([[.1, .2], [.1, .1], [.2, .3], [.4, .2]])
  >>> layer([[0, 1], [0, 0], [1, 2], [3, 1]], count_weights=count_weights)
  <tf.Tensor: shape=(4, 4), dtype=float64, numpy=
    array([[0.1, 0.2, 0. , 0. ],
           [0.2, 0. , 0. , 0. ],
           [0. , 0.2, 0.3, 0. ],
           [0. , 0.2, 0. , 0.4]])>

  Args:
    num_tokens: The total number of tokens the layer should support. All inputs
      to the layer must integers in the range `0 <= value < num_tokens`, or an
      error will be thrown.
    output_mode: Specification for the output of the layer.
      Defaults to `"multi_hot"`. Values can be `"one_hot"`, `"multi_hot"` or
      `"count"`, configuring the layer as follows:
        - `"one_hot"`: Encodes each individual element in the input into an
          array of `num_tokens` size, containing a 1 at the element index. If
          the last dimension is size 1, will encode on that dimension. If the
          last dimension is not size 1, will append a new dimension for the
          encoded output.
        - `"multi_hot"`: Encodes each sample in the input into a single array
          of `num_tokens` size, containing a 1 for each vocabulary term present
          in the sample. Treats the last dimension as the sample dimension, if
          input shape is `(..., sample_length)`, output shape will be
          `(..., num_tokens)`.
        - `"count"`: Like `"multi_hot"`, but the int array contains a count of
          the number of times the token at that index appeared in the sample.
      For all output modes, currently only output up to rank 2 is supported.
    sparse: Boolean. If true, returns a `SparseTensor` instead of a dense
      `Tensor`. Defaults to `False`.

  Call arguments:
    inputs: A 1D or 2D tensor of integer inputs.
    count_weights: A tensor in the same shape as `inputs` indicating the
      weight for each sample value when summing up in `count` mode. Not used in
      `"multi_hot"` or `"one_hot"` modes.
  """

  def __init__(self,
               num_tokens=None,
               output_mode="multi_hot",
               sparse=False,
               **kwargs):
    # max_tokens is an old name for the num_tokens arg we continue to support
    # because of usage.
    if "max_tokens" in kwargs:
      logging.warning(
          "max_tokens is deprecated, please use num_tokens instead.")
      num_tokens = kwargs["max_tokens"]
      del kwargs["max_tokens"]

    super(CategoryEncoding, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell("CategoryEncoding").set(
        True)

    # Support deprecated names for output_modes.
    if output_mode == "binary":
      output_mode = MULTI_HOT
    # 'output_mode' must be one of (COUNT, ONE_HOT, MULTI_HOT)
    layer_utils.validate_string_arg(
        output_mode,
        allowable_strings=(COUNT, ONE_HOT, MULTI_HOT),
        layer_name="CategoryEncoding",
        arg_name="output_mode")

    if num_tokens is None:
      raise ValueError("num_tokens must be set to use this layer. If the "
                       "number of tokens is not known beforehand, use the "
                       "IntegerLookup layer instead.")
    if num_tokens < 1:
      raise ValueError("num_tokens must be >= 1.")

    self.num_tokens = num_tokens
    self.output_mode = output_mode
    self.sparse = sparse

  def compute_output_shape(self, input_shape):
    if not input_shape:
      return tf.TensorShape([self.num_tokens])
    if self.output_mode == ONE_HOT and input_shape[-1] != 1:
      return tf.TensorShape(input_shape + [self.num_tokens])
    else:
      return tf.TensorShape(input_shape[:-1] + [self.num_tokens])

  def compute_output_signature(self, input_spec):
    output_shape = self.compute_output_shape(input_spec.shape.as_list())
    if self.sparse:
      return tf.SparseTensorSpec(
          shape=output_shape, dtype=tf.int64)
    else:
      return tf.TensorSpec(shape=output_shape, dtype=tf.int64)

  def get_config(self):
    config = {
        "num_tokens": self.num_tokens,
        "output_mode": self.output_mode,
        "sparse": self.sparse,
    }
    base_config = super(CategoryEncoding, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def call(self, inputs, count_weights=None):
    if isinstance(inputs, (list, np.ndarray)):
      inputs = tf.convert_to_tensor(inputs)

    def expand_dims(inputs, axis):
      if tf_utils.is_sparse(inputs):
        return tf.sparse.expand_dims(inputs, axis)
      else:
        return tf.expand_dims(inputs, axis)

    original_shape = inputs.shape
    # In all cases, we should uprank scalar input to a single sample.
    if inputs.shape.rank == 0:
      inputs = expand_dims(inputs, -1)
    # One hot will unprank only if the final output dimension is not already 1.
    if self.output_mode == ONE_HOT:
      if inputs.shape[-1] != 1:
        inputs = expand_dims(inputs, -1)

    # TODO(b/190445202): remove output rank restriction.
    if inputs.shape.rank > 2:
      raise ValueError(
          "Received input shape {}, which would result in output rank {}. "
          "Currently only outputs up to rank 2 are supported.".format(
              original_shape, inputs.shape.rank))

    if count_weights is not None and self.output_mode != COUNT:
      raise ValueError(
          "`count_weights` is not used when `output_mode` is not `'count'`. "
          "Received `count_weights={}`.".format(count_weights))

    out_depth = self.num_tokens
    binary_output = self.output_mode in (MULTI_HOT, ONE_HOT)
    if isinstance(inputs, tf.SparseTensor):
      max_value = tf.reduce_max(inputs.values)
      min_value = tf.reduce_min(inputs.values)
    else:
      max_value = tf.reduce_max(inputs)
      min_value = tf.reduce_min(inputs)
    condition = tf.logical_and(
        tf.greater(
            tf.cast(out_depth, max_value.dtype), max_value),
        tf.greater_equal(
            min_value, tf.cast(0, min_value.dtype)))
    assertion = tf.Assert(condition, [
        "Input values must be in the range 0 <= values < num_tokens"
        " with num_tokens={}".format(out_depth)
    ])
    with tf.control_dependencies([assertion]):
      if self.sparse:
        return sparse_bincount(inputs, out_depth, binary_output,
                               count_weights)
      else:
        return dense_bincount(inputs, out_depth, binary_output,
                              count_weights)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class CenterCrop (height, width, **kwargs)

Crop the central portion of the images to target height and width.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, target_height, target_width, channels).

If the input height/width is even and the target height/width is odd (or inversely), the input image is left-padded by 1 pixel.

Args

height
Integer, the height of the output shape.
width
Integer, the width of the output shape.
Expand source code
class CenterCrop(base_layer.Layer):
  """Crop the central portion of the images to target height and width.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., target_height, target_width, channels)`.

  If the input height/width is even and the target height/width is odd (or
  inversely), the input image is left-padded by 1 pixel.

  Args:
    height: Integer, the height of the output shape.
    width: Integer, the width of the output shape.
  """

  def __init__(self, height, width, **kwargs):
    self.target_height = height
    self.target_width = width
    super(CenterCrop, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('CenterCrop').set(True)

  def call(self, inputs):
    inputs = tf.convert_to_tensor(inputs)
    inputs_shape = tf.shape(inputs)
    unbatched = inputs.shape.rank == 3
    img_hd = inputs_shape[H_AXIS]
    img_wd = inputs_shape[W_AXIS]
    img_hd_diff = img_hd - self.target_height
    img_wd_diff = img_wd - self.target_width
    checks = []
    checks.append(
        tf.debugging.assert_non_negative(
            img_hd_diff,
            message='The crop height {} should not be greater than input '
            'height.'.format(self.target_height)))
    checks.append(
        tf.debugging.assert_non_negative(
            img_wd_diff,
            message='The crop width {} should not be greater than input '
            'width.'.format(self.target_width)))
    with tf.control_dependencies(checks):
      bbox_h_start = tf.cast(img_hd_diff / 2, tf.int32)
      bbox_w_start = tf.cast(img_wd_diff / 2, tf.int32)
      if unbatched:
        bbox_begin = tf.stack([bbox_h_start, bbox_w_start, 0])
        bbox_size = tf.stack([self.target_height, self.target_width, -1])
      else:
        bbox_begin = tf.stack([0, bbox_h_start, bbox_w_start, 0])
        bbox_size = tf.stack([-1, self.target_height, self.target_width, -1])
      outputs = tf.slice(inputs, bbox_begin, bbox_size)
      return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    input_shape[H_AXIS] = self.target_height
    input_shape[W_AXIS] = self.target_width
    return tf.TensorShape(input_shape)

  def get_config(self):
    config = {
        'height': self.target_height,
        'width': self.target_width,
    }
    base_config = super(CenterCrop, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Concatenate (axis=-1, **kwargs)

Layer that concatenates a list of inputs.

It takes as input a list of tensors, all of the same shape except for the concatenation axis, and returns a single tensor that is the concatenation of all inputs.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.Concatenate(axis=1)([x, y])
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [20, 21, 22, 23, 24]],
       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]])>
>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> concatted = tf.keras.layers.Concatenate()([x1, x2])
>>> concatted.shape
TensorShape([5, 16])

Instantiates a Concatenate layer.

>>> x = np.arange(20).reshape(2, 2, 5)
>>> print(x)
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]
 [[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> y = np.arange(20, 30).reshape(2, 1, 5)
>>> print(y)
[[[20 21 22 23 24]]
 [[25 26 27 28 29]]]
>>> tf.keras.layers.Concatenate(axis=1)([x, y])
<tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
array([[[ 0,  1,  2,  3,  4],
        [ 5,  6,  7,  8,  9],
        [20, 21, 22, 23, 24]],
       [[10, 11, 12, 13, 14],
        [15, 16, 17, 18, 19],
        [25, 26, 27, 28, 29]]])>

Args

axis
Axis along which to concatenate.
**kwargs
standard layer keyword arguments.
Expand source code
class Concatenate(_Merge):
  """Layer that concatenates a list of inputs.

  It takes as input a list of tensors, all of the same shape except
  for the concatenation axis, and returns a single tensor that is the
  concatenation of all inputs.

  >>> x = np.arange(20).reshape(2, 2, 5)
  >>> print(x)
  [[[ 0  1  2  3  4]
    [ 5  6  7  8  9]]
   [[10 11 12 13 14]
    [15 16 17 18 19]]]
  >>> y = np.arange(20, 30).reshape(2, 1, 5)
  >>> print(y)
  [[[20 21 22 23 24]]
   [[25 26 27 28 29]]]
  >>> tf.keras.layers.Concatenate(axis=1)([x, y])
  <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
  array([[[ 0,  1,  2,  3,  4],
          [ 5,  6,  7,  8,  9],
          [20, 21, 22, 23, 24]],
         [[10, 11, 12, 13, 14],
          [15, 16, 17, 18, 19],
          [25, 26, 27, 28, 29]]])>

  >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
  >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
  >>> concatted = tf.keras.layers.Concatenate()([x1, x2])
  >>> concatted.shape
  TensorShape([5, 16])

  """

  def __init__(self, axis=-1, **kwargs):
    """Instantiates a Concatenate layer.

    >>> x = np.arange(20).reshape(2, 2, 5)
    >>> print(x)
    [[[ 0  1  2  3  4]
      [ 5  6  7  8  9]]
     [[10 11 12 13 14]
      [15 16 17 18 19]]]
    >>> y = np.arange(20, 30).reshape(2, 1, 5)
    >>> print(y)
    [[[20 21 22 23 24]]
     [[25 26 27 28 29]]]
    >>> tf.keras.layers.Concatenate(axis=1)([x, y])
    <tf.Tensor: shape=(2, 3, 5), dtype=int64, numpy=
    array([[[ 0,  1,  2,  3,  4],
            [ 5,  6,  7,  8,  9],
            [20, 21, 22, 23, 24]],
           [[10, 11, 12, 13, 14],
            [15, 16, 17, 18, 19],
            [25, 26, 27, 28, 29]]])>

    Args:
      axis: Axis along which to concatenate.
      **kwargs: standard layer keyword arguments.
    """
    super(Concatenate, self).__init__(**kwargs)
    self.axis = axis
    self.supports_masking = True
    self._reshape_required = False

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    # Used purely for shape validation.
    if not isinstance(input_shape[0], tuple) or len(input_shape) < 1:
      raise ValueError('A `Concatenate` layer should be called '
                       'on a list of at least 1 input.')
    if all(shape is None for shape in input_shape):
      return
    reduced_inputs_shapes = [list(shape) for shape in input_shape]
    shape_set = set()
    for i in range(len(reduced_inputs_shapes)):
      del reduced_inputs_shapes[i][self.axis]
      shape_set.add(tuple(reduced_inputs_shapes[i]))

    if len(shape_set) != 1:
      err_msg = ('A `Concatenate` layer requires inputs with matching shapes '
                 'except for the concat axis. Got inputs shapes: %s' %
                 input_shape)
      # Make sure all the shapes have same ranks.
      ranks = set(len(shape) for shape in shape_set)
      if len(ranks) != 1:
        raise ValueError(err_msg)
      # Get the only rank for the set.
      (rank,) = ranks
      for axis in range(rank):
        # Skip the Nones in the shape since they are dynamic, also the axis for
        # concat has been removed above.
        unique_dims = set(
            shape[axis] for shape in shape_set if shape[axis] is not None)
        if len(unique_dims) > 1:
          raise ValueError(err_msg)

  def _merge_function(self, inputs):
    return backend.concatenate(inputs, axis=self.axis)

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if ((not isinstance(input_shape, (tuple, list))) or
        (not isinstance(input_shape[0], (tuple, list)))):
      # The tf_utils.shape_type_conversion decorator turns tensorshapes
      # into tuples, so we need to verify that `input_shape` is a list/tuple,
      # *and* that the individual elements are themselves shape tuples.
      raise ValueError('A `Concatenate` layer should be called '
                       'on a list of inputs.')
    input_shapes = input_shape
    output_shape = list(input_shapes[0])
    for shape in input_shapes[1:]:
      if output_shape[self.axis] is None or shape[self.axis] is None:
        output_shape[self.axis] = None
        break
      output_shape[self.axis] += shape[self.axis]
    return tuple(output_shape)

  def compute_mask(self, inputs, mask=None):
    if mask is None:
      return None
    if not isinstance(mask, (tuple, list)):
      raise ValueError('`mask` should be a list.')
    if not isinstance(inputs, (tuple, list)):
      raise ValueError('`inputs` should be a list.')
    if len(mask) != len(inputs):
      raise ValueError('The lists `inputs` and `mask` '
                       'should have the same length.')
    if all(m is None for m in mask):
      return None
    # Make a list of masks while making sure
    # the dimensionality of each mask
    # is the same as the corresponding input.
    masks = []
    for input_i, mask_i in zip(inputs, mask):
      if mask_i is None:
        # Input is unmasked. Append all 1s to masks,
        masks.append(tf.ones_like(input_i, dtype='bool'))
      elif backend.ndim(mask_i) < backend.ndim(input_i):
        # Mask is smaller than the input, expand it
        masks.append(tf.expand_dims(mask_i, axis=-1))
      else:
        masks.append(mask_i)
    concatenated = backend.concatenate(masks, axis=self.axis)
    return backend.all(concatenated, axis=-1, keepdims=False)

  def get_config(self):
    config = {
        'axis': self.axis,
    }
    base_config = super(Concatenate, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Conv1D (filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

1D convolution layer (e.g. temporal convolution).

This layer creates a convolution kernel that is convolved with the layer input over a single spatial (or temporal) dimension to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide an input_shape argument (tuple of integers or None, e.g. (10, 128) for sequences of 10 vectors of 128-dimensional vectors, or (None, 128) for variable-length sequences of 128-dimensional vectors.

Examples:

>>> # The inputs are 128-length vectors with 10 timesteps, and the batch size
>>> # is 4.
>>> input_shape = (4, 10, 128)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv1D(
... 32, 3, activation='relu',input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 8, 32)
>>> # With extended batch shape [4, 7] (e.g. weather data where batch
>>> # dimensions correspond to spatial location and the third dimension
>>> # corresponds to time.)
>>> input_shape = (4, 7, 10, 128)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv1D(
... 32, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 8, 32)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of a single integer, specifying the length of the 1D convolution window.
strides
An integer or tuple/list of a single integer, specifying the stride length of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid", "same" or "causal" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input. "causal" results in causal (dilated) convolutions, e.g. output[t] does not depend on input[t+1:]. Useful when modeling temporal data where the model should not violate the temporal order. See WaveNet: A Generative Model for Raw Audio, section 2.1.
data_format
A string, one of channels_last (default) or channels_first.
dilation_rate
an integer or tuple/list of a single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 3+D tensor with shape: batch_shape + (steps, input_dim)

Output shape: 3+D tensor with shape: batch_shape + (new_steps, filters) steps value might have changed due to padding or strides.

Returns

A tensor of rank 3 representing activation(conv1d(inputs, kernel) + bias).

Raises

ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv1D(Conv):
  """1D convolution layer (e.g. temporal convolution).

  This layer creates a convolution kernel that is convolved
  with the layer input over a single spatial (or temporal) dimension
  to produce a tensor of outputs.
  If `use_bias` is True, a bias vector is created and added to the outputs.
  Finally, if `activation` is not `None`,
  it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide an `input_shape` argument
  (tuple of integers or `None`, e.g.
  `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors,
  or `(None, 128)` for variable-length sequences of 128-dimensional vectors.

  Examples:

  >>> # The inputs are 128-length vectors with 10 timesteps, and the batch size
  >>> # is 4.
  >>> input_shape = (4, 10, 128)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv1D(
  ... 32, 3, activation='relu',input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 8, 32)

  >>> # With extended batch shape [4, 7] (e.g. weather data where batch
  >>> # dimensions correspond to spatial location and the third dimension
  >>> # corresponds to time.)
  >>> input_shape = (4, 7, 10, 128)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv1D(
  ... 32, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 8, 32)

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of a single integer,
      specifying the length of the 1D convolution window.
    strides: An integer or tuple/list of a single integer,
      specifying the stride length of the convolution.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: One of `"valid"`, `"same"` or `"causal"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
      `"causal"` results in causal (dilated) convolutions, e.g. `output[t]`
      does not depend on `input[t+1:]`. Useful when modeling temporal data
      where the model should not violate the temporal order.
      See [WaveNet: A Generative Model for Raw Audio, section
        2.1](https://arxiv.org/abs/1609.03499).
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
    dilation_rate: an integer or tuple/list of a single integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any `strides` value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved
      separately with `filters / groups` filters. The output is the
      concatenation of all the `groups` results along the channel axis.
      Input channels and `filters` must both be divisible by `groups`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    3+D tensor with shape: `batch_shape + (steps, input_dim)`

  Output shape:
    3+D tensor with shape: `batch_shape + (new_steps, filters)`
      `steps` value might have changed due to padding or strides.

  Returns:
    A tensor of rank 3 representing
    `activation(conv1d(inputs, kernel) + bias)`.

  Raises:
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format='channels_last',
               dilation_rate=1,
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv1D, self).__init__(
        rank=1,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class Convolution1D (filters, kernel_size, strides=1, padding='valid', data_format='channels_last', dilation_rate=1, groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

1D convolution layer (e.g. temporal convolution).

This layer creates a convolution kernel that is convolved with the layer input over a single spatial (or temporal) dimension to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide an input_shape argument (tuple of integers or None, e.g. (10, 128) for sequences of 10 vectors of 128-dimensional vectors, or (None, 128) for variable-length sequences of 128-dimensional vectors.

Examples:

>>> # The inputs are 128-length vectors with 10 timesteps, and the batch size
>>> # is 4.
>>> input_shape = (4, 10, 128)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv1D(
... 32, 3, activation='relu',input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 8, 32)
>>> # With extended batch shape [4, 7] (e.g. weather data where batch
>>> # dimensions correspond to spatial location and the third dimension
>>> # corresponds to time.)
>>> input_shape = (4, 7, 10, 128)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv1D(
... 32, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 8, 32)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of a single integer, specifying the length of the 1D convolution window.
strides
An integer or tuple/list of a single integer, specifying the stride length of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid", "same" or "causal" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input. "causal" results in causal (dilated) convolutions, e.g. output[t] does not depend on input[t+1:]. Useful when modeling temporal data where the model should not violate the temporal order. See WaveNet: A Generative Model for Raw Audio, section 2.1.
data_format
A string, one of channels_last (default) or channels_first.
dilation_rate
an integer or tuple/list of a single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 3+D tensor with shape: batch_shape + (steps, input_dim)

Output shape: 3+D tensor with shape: batch_shape + (new_steps, filters) steps value might have changed due to padding or strides.

Returns

A tensor of rank 3 representing activation(conv1d(inputs, kernel) + bias).

Raises

ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv1D(Conv):
  """1D convolution layer (e.g. temporal convolution).

  This layer creates a convolution kernel that is convolved
  with the layer input over a single spatial (or temporal) dimension
  to produce a tensor of outputs.
  If `use_bias` is True, a bias vector is created and added to the outputs.
  Finally, if `activation` is not `None`,
  it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide an `input_shape` argument
  (tuple of integers or `None`, e.g.
  `(10, 128)` for sequences of 10 vectors of 128-dimensional vectors,
  or `(None, 128)` for variable-length sequences of 128-dimensional vectors.

  Examples:

  >>> # The inputs are 128-length vectors with 10 timesteps, and the batch size
  >>> # is 4.
  >>> input_shape = (4, 10, 128)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv1D(
  ... 32, 3, activation='relu',input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 8, 32)

  >>> # With extended batch shape [4, 7] (e.g. weather data where batch
  >>> # dimensions correspond to spatial location and the third dimension
  >>> # corresponds to time.)
  >>> input_shape = (4, 7, 10, 128)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv1D(
  ... 32, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 8, 32)

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of a single integer,
      specifying the length of the 1D convolution window.
    strides: An integer or tuple/list of a single integer,
      specifying the stride length of the convolution.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: One of `"valid"`, `"same"` or `"causal"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
      `"causal"` results in causal (dilated) convolutions, e.g. `output[t]`
      does not depend on `input[t+1:]`. Useful when modeling temporal data
      where the model should not violate the temporal order.
      See [WaveNet: A Generative Model for Raw Audio, section
        2.1](https://arxiv.org/abs/1609.03499).
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
    dilation_rate: an integer or tuple/list of a single integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any `strides` value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved
      separately with `filters / groups` filters. The output is the
      concatenation of all the `groups` results along the channel axis.
      Input channels and `filters` must both be divisible by `groups`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    3+D tensor with shape: `batch_shape + (steps, input_dim)`

  Output shape:
    3+D tensor with shape: `batch_shape + (new_steps, filters)`
      `steps` value might have changed due to padding or strides.

  Returns:
    A tensor of rank 3 representing
    `activation(conv1d(inputs, kernel) + bias)`.

  Raises:
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format='channels_last',
               dilation_rate=1,
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv1D, self).__init__(
        rank=1,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class Conv1DTranspose (filters, kernel_size, strides=1, padding='valid', output_padding=None, data_format=None, dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 3) for data with 128 time steps and 3 channels.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer length of the 1D convolution window.
strides
An integer specifying the stride of the convolution along the time dimension. Specifying a stride value != 1 is incompatible with specifying a dilation_rate value != 1. Defaults to 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer specifying the amount of padding along the time dimension of the output tensor. The amount of output padding must be lower than the stride. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, length, channels) while channels_first corresponds to inputs with shape (batch_size, channels, length).
dilation_rate
an integer, specifying the dilation rate to use for dilated convolution. Currently, specifying a dilation_rate value != 1 is incompatible with specifying a stride value != 1. Also dilation rate larger than 1 is not currently supported.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 3D tensor with shape: (batch_size, steps, channels)

Output shape: 3D tensor with shape: (batch_size, new_steps, filters) If output_padding is specified: new_timesteps = ((timesteps - 1) * strides + kernel_size - 2 * padding + output_padding)

Returns

A tensor of rank 3 representing activation(conv1dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv1DTranspose(Conv1D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 3)` for data with 128 time steps and 3 channels.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer length of the 1D convolution window.
    strides: An integer specifying the stride of the convolution along the
      time dimension. Specifying a stride value != 1 is incompatible with
      specifying a `dilation_rate` value != 1. Defaults to 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer specifying the amount of padding along
      the time dimension of the output tensor.
      The amount of output padding must be lower than the stride.
      If set to `None` (default), the output shape is inferred.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, length, channels)` while `channels_first` corresponds to
      inputs with shape `(batch_size, channels, length)`.
    dilation_rate: an integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying a `dilation_rate` value != 1 is
      incompatible with specifying a stride value != 1.
      Also dilation rate larger than 1 is not currently supported.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    3D tensor with shape:
    `(batch_size, steps, channels)`

  Output shape:
    3D tensor with shape:
    `(batch_size, new_steps, filters)`
    If `output_padding` is specified:
    ```
    new_timesteps = ((timesteps - 1) * strides + kernel_size -
    2 * padding + output_padding)
    ```

  Returns:
    A tensor of rank 3 representing
    `activation(conv1dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep learning](
      https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional Networks](
      https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv1DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 1, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 3:
      raise ValueError('Inputs should have rank 3. Received input shape: ' +
                       str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined. Found `None`.')
    input_dim = int(input_shape[channel_axis])
    self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim})
    kernel_shape = self.kernel_size + (self.filters, input_dim)

    self.kernel = self.add_weight(
        name='kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          name='bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      t_axis = 2
    else:
      t_axis = 1

    length = inputs_shape[t_axis]
    if self.output_padding is None:
      output_padding = None
    else:
      output_padding = self.output_padding[0]

    # Infer the dynamic output shape:
    out_length = conv_utils.deconv_output_length(
        length, self.kernel_size[0], padding=self.padding,
        output_padding=output_padding, stride=self.strides[0],
        dilation=self.dilation_rate[0])
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_length)
    else:
      output_shape = (batch_size, out_length, self.filters)
    data_format = conv_utils.convert_data_format(self.data_format, ndim=3)

    output_shape_tensor = tf.stack(output_shape)
    outputs = tf.nn.conv1d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides=self.strides,
        padding=self.padding.upper(),
        data_format=data_format,
        dilations=self.dilation_rate)

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=data_format)

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, t_axis = 1, 2
    else:
      c_axis, t_axis = 2, 1

    if self.output_padding is None:
      output_padding = None
    else:
      output_padding = self.output_padding[0]
    output_shape[c_axis] = self.filters
    output_shape[t_axis] = conv_utils.deconv_output_length(
        output_shape[t_axis],
        self.kernel_size[0],
        padding=self.padding,
        output_padding=output_padding,
        stride=self.strides[0],
        dilation=self.dilation_rate[0])
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv1DTranspose, self).get_config()
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv1D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Methods

def build(self, input_shape)

Creates the variables of the layer (optional, for subclass implementers).

This is a method that implementers of subclasses of Layer or Model can override if they need a state-creation step in-between layer instantiation and layer call.

This is typically used to create the weights of Layer subclasses.

Args

input_shape
Instance of TensorShape, or list of instances of TensorShape if the layer expects a list of inputs (one instance per input).
Expand source code
def build(self, input_shape):
  input_shape = tf.TensorShape(input_shape)
  if len(input_shape) != 3:
    raise ValueError('Inputs should have rank 3. Received input shape: ' +
                     str(input_shape))
  channel_axis = self._get_channel_axis()
  if input_shape.dims[channel_axis].value is None:
    raise ValueError('The channel dimension of the inputs '
                     'should be defined. Found `None`.')
  input_dim = int(input_shape[channel_axis])
  self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim})
  kernel_shape = self.kernel_size + (self.filters, input_dim)

  self.kernel = self.add_weight(
      name='kernel',
      shape=kernel_shape,
      initializer=self.kernel_initializer,
      regularizer=self.kernel_regularizer,
      constraint=self.kernel_constraint,
      trainable=True,
      dtype=self.dtype)
  if self.use_bias:
    self.bias = self.add_weight(
        name='bias',
        shape=(self.filters,),
        initializer=self.bias_initializer,
        regularizer=self.bias_regularizer,
        constraint=self.bias_constraint,
        trainable=True,
        dtype=self.dtype)
  else:
    self.bias = None
  self.built = True
def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  inputs_shape = tf.shape(inputs)
  batch_size = inputs_shape[0]
  if self.data_format == 'channels_first':
    t_axis = 2
  else:
    t_axis = 1

  length = inputs_shape[t_axis]
  if self.output_padding is None:
    output_padding = None
  else:
    output_padding = self.output_padding[0]

  # Infer the dynamic output shape:
  out_length = conv_utils.deconv_output_length(
      length, self.kernel_size[0], padding=self.padding,
      output_padding=output_padding, stride=self.strides[0],
      dilation=self.dilation_rate[0])
  if self.data_format == 'channels_first':
    output_shape = (batch_size, self.filters, out_length)
  else:
    output_shape = (batch_size, out_length, self.filters)
  data_format = conv_utils.convert_data_format(self.data_format, ndim=3)

  output_shape_tensor = tf.stack(output_shape)
  outputs = tf.nn.conv1d_transpose(
      inputs,
      self.kernel,
      output_shape_tensor,
      strides=self.strides,
      padding=self.padding.upper(),
      data_format=data_format,
      dilations=self.dilation_rate)

  if not tf.executing_eagerly():
    # Infer the static output shape:
    out_shape = self.compute_output_shape(inputs.shape)
    outputs.set_shape(out_shape)

  if self.use_bias:
    outputs = tf.nn.bias_add(
        outputs,
        self.bias,
        data_format=data_format)

  if self.activation is not None:
    return self.activation(outputs)
  return outputs
def compute_output_shape(self, input_shape)

Computes the output shape of the layer.

If the layer has not been built, this method will call build on the layer. This assumes that the layer will later be used with inputs that match the input shape provided here.

Args

input_shape
Shape tuple (tuple of integers) or list of shape tuples (one per output tensor of the layer). Shape tuples can include None for free dimensions, instead of an integer.

Returns

An input shape tuple.

Expand source code
def compute_output_shape(self, input_shape):
  input_shape = tf.TensorShape(input_shape).as_list()
  output_shape = list(input_shape)
  if self.data_format == 'channels_first':
    c_axis, t_axis = 1, 2
  else:
    c_axis, t_axis = 2, 1

  if self.output_padding is None:
    output_padding = None
  else:
    output_padding = self.output_padding[0]
  output_shape[c_axis] = self.filters
  output_shape[t_axis] = conv_utils.deconv_output_length(
      output_shape[t_axis],
      self.kernel_size[0],
      padding=self.padding,
      output_padding=output_padding,
      stride=self.strides[0],
      dilation=self.dilation_rate[0])
  return tf.TensorShape(output_shape)
def get_config(self)

Returns the config of the layer.

A layer config is a Python dictionary (serializable) containing the configuration of a layer. The same layer can be reinstantiated later (without its trained weights) from this configuration.

The config of a layer does not include connectivity information, nor the layer class name. These are handled by Network (one layer of abstraction above).

Note that get_config() does not guarantee to return a fresh copy of dict every time it is called. The callers should make a copy of the returned dict if they want to modify it.

Returns

Python dictionary.

Expand source code
def get_config(self):
  config = super(Conv1DTranspose, self).get_config()
  config['output_padding'] = self.output_padding
  return config
class Convolution1DTranspose (filters, kernel_size, strides=1, padding='valid', output_padding=None, data_format=None, dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 3) for data with 128 time steps and 3 channels.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer length of the 1D convolution window.
strides
An integer specifying the stride of the convolution along the time dimension. Specifying a stride value != 1 is incompatible with specifying a dilation_rate value != 1. Defaults to 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer specifying the amount of padding along the time dimension of the output tensor. The amount of output padding must be lower than the stride. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, length, channels) while channels_first corresponds to inputs with shape (batch_size, channels, length).
dilation_rate
an integer, specifying the dilation rate to use for dilated convolution. Currently, specifying a dilation_rate value != 1 is incompatible with specifying a stride value != 1. Also dilation rate larger than 1 is not currently supported.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 3D tensor with shape: (batch_size, steps, channels)

Output shape: 3D tensor with shape: (batch_size, new_steps, filters) If output_padding is specified: new_timesteps = ((timesteps - 1) * strides + kernel_size - 2 * padding + output_padding)

Returns

A tensor of rank 3 representing activation(conv1dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv1DTranspose(Conv1D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 3)` for data with 128 time steps and 3 channels.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer length of the 1D convolution window.
    strides: An integer specifying the stride of the convolution along the
      time dimension. Specifying a stride value != 1 is incompatible with
      specifying a `dilation_rate` value != 1. Defaults to 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer specifying the amount of padding along
      the time dimension of the output tensor.
      The amount of output padding must be lower than the stride.
      If set to `None` (default), the output shape is inferred.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, length, channels)` while `channels_first` corresponds to
      inputs with shape `(batch_size, channels, length)`.
    dilation_rate: an integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying a `dilation_rate` value != 1 is
      incompatible with specifying a stride value != 1.
      Also dilation rate larger than 1 is not currently supported.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    3D tensor with shape:
    `(batch_size, steps, channels)`

  Output shape:
    3D tensor with shape:
    `(batch_size, new_steps, filters)`
    If `output_padding` is specified:
    ```
    new_timesteps = ((timesteps - 1) * strides + kernel_size -
    2 * padding + output_padding)
    ```

  Returns:
    A tensor of rank 3 representing
    `activation(conv1dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep learning](
      https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional Networks](
      https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv1DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 1, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 3:
      raise ValueError('Inputs should have rank 3. Received input shape: ' +
                       str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined. Found `None`.')
    input_dim = int(input_shape[channel_axis])
    self.input_spec = InputSpec(ndim=3, axes={channel_axis: input_dim})
    kernel_shape = self.kernel_size + (self.filters, input_dim)

    self.kernel = self.add_weight(
        name='kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          name='bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      t_axis = 2
    else:
      t_axis = 1

    length = inputs_shape[t_axis]
    if self.output_padding is None:
      output_padding = None
    else:
      output_padding = self.output_padding[0]

    # Infer the dynamic output shape:
    out_length = conv_utils.deconv_output_length(
        length, self.kernel_size[0], padding=self.padding,
        output_padding=output_padding, stride=self.strides[0],
        dilation=self.dilation_rate[0])
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_length)
    else:
      output_shape = (batch_size, out_length, self.filters)
    data_format = conv_utils.convert_data_format(self.data_format, ndim=3)

    output_shape_tensor = tf.stack(output_shape)
    outputs = tf.nn.conv1d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides=self.strides,
        padding=self.padding.upper(),
        data_format=data_format,
        dilations=self.dilation_rate)

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=data_format)

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, t_axis = 1, 2
    else:
      c_axis, t_axis = 2, 1

    if self.output_padding is None:
      output_padding = None
    else:
      output_padding = self.output_padding[0]
    output_shape[c_axis] = self.filters
    output_shape[t_axis] = conv_utils.deconv_output_length(
        output_shape[t_axis],
        self.kernel_size[0],
        padding=self.padding,
        output_padding=output_padding,
        stride=self.strides[0],
        dilation=self.dilation_rate[0])
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv1DTranspose, self).get_config()
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv1D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Conv2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

2D convolution layer (e.g. spatial convolution over images).

This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 3) for 128x128 RGB pictures in data_format="channels_last". You can use None when a dimension has variable size.

Examples:

>>> # The inputs are 28x28 RGB images with <code>channels\_last</code> and the batch
>>> # size is 4.
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 26, 26, 2)
>>> # With <code>dilation\_rate</code> as 2.
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 24, 24, 2)
>>> # With <code>padding</code> as "same".
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 28, 28, 2)
>>> # With extended batch shape [4, 7]:
>>> input_shape = (4, 7, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 26, 26, 2)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width)<code>. It defaults to the </code>image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be channels_last.
dilation_rate
an integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied (see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix (see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector (see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector (see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix (see keras.constraints).
bias_constraint
Constraint function applied to the bias vector (see keras.constraints).

Input shape: 4+D tensor with shape: batch_shape + (channels, rows, cols) if data_format='channels_first' or 4+D tensor with shape: batch_shape + (rows, cols, channels) if data_format='channels_last'. Output shape: 4+D tensor with shape: batch_shape + (filters, new_rows, new_cols) if data_format='channels_first' or 4+D tensor with shape: batch_shape + (new_rows, new_cols, filters)<code> if </code>data_format='channels_last'<code>. </code>rows and cols values might have changed due to padding.

Returns

A tensor of rank 4+ representing activation(conv2d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv2D(Conv):
  """2D convolution layer (e.g. spatial convolution over images).

  This layer creates a convolution kernel that is convolved
  with the layer input to produce a tensor of
  outputs. If `use_bias` is True,
  a bias vector is created and added to the outputs. Finally, if
  `activation` is not `None`, it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
  in `data_format="channels_last"`. You can use `None` when
  a dimension has variable size.

  Examples:

  >>> # The inputs are 28x28 RGB images with `channels_last` and the batch
  >>> # size is 4.
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 26, 26, 2)

  >>> # With `dilation_rate` as 2.
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 24, 24, 2)

  >>> # With `padding` as "same".
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 28, 28, 2)

  >>> # With extended batch shape [4, 7]:
  >>> input_shape = (4, 7, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 26, 26, 2)


  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the height
      and width of the 2D convolution window. Can be a single integer to specify
      the same value for all spatial dimensions.
    strides: An integer or tuple/list of 2 integers, specifying the strides of
      the convolution along the height and width. Can be a single integer to
      specify the same value for all spatial dimensions. Specifying any stride
      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `(batch_size, height, width, channels)` while
      `channels_first` corresponds to inputs with shape `(batch_size, channels,
      height, width)`. It defaults to the `image_data_format` value found in
      your Keras config file at `~/.keras/keras.json`. If you never set it, then
      it will be `channels_last`.
    dilation_rate: an integer or tuple/list of 2 integers, specifying the
      dilation rate to use for dilated convolution. Can be a single integer to
      specify the same value for all spatial dimensions. Currently, specifying
      any `dilation_rate` value != 1 is incompatible with specifying any stride
      value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved separately
      with `filters / groups` filters. The output is the concatenation of all
      the `groups` results along the channel axis. Input channels and `filters`
      must both be divisible by `groups`.
    activation: Activation function to use. If you don't specify anything, no
      activation is applied (see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (see
      `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (see
      `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix (see `keras.regularizers`). 
    bias_regularizer: Regularizer function applied to the bias vector (see
      `keras.regularizers`). 
    activity_regularizer: Regularizer function applied to the output of the
      layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (see
      `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (see
      `keras.constraints`).
  Input shape:
    4+D tensor with shape: `batch_shape + (channels, rows, cols)` if
      `data_format='channels_first'`
    or 4+D tensor with shape: `batch_shape + (rows, cols, channels)` if
      `data_format='channels_last'`.
  Output shape:
    4+D tensor with shape: `batch_shape + (filters, new_rows, new_cols)` if
    `data_format='channels_first'` or 4+D tensor with shape: `batch_shape +
      (new_rows, new_cols, filters)` if `data_format='channels_last'`.  `rows`
      and `cols` values might have changed due to padding.

  Returns:
    A tensor of rank 4+ representing
    `activation(conv2d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is `"causal"`.
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1),
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv2D, self).__init__(
        rank=2,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class Convolution2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

2D convolution layer (e.g. spatial convolution over images).

This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 3) for 128x128 RGB pictures in data_format="channels_last". You can use None when a dimension has variable size.

Examples:

>>> # The inputs are 28x28 RGB images with <code>channels\_last</code> and the batch
>>> # size is 4.
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 26, 26, 2)
>>> # With <code>dilation\_rate</code> as 2.
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 24, 24, 2)
>>> # With <code>padding</code> as "same".
>>> input_shape = (4, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 28, 28, 2)
>>> # With extended batch shape [4, 7]:
>>> input_shape = (4, 7, 28, 28, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv2D(
... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 26, 26, 2)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width)<code>. It defaults to the </code>image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be channels_last.
dilation_rate
an integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied (see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix (see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector (see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector (see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix (see keras.constraints).
bias_constraint
Constraint function applied to the bias vector (see keras.constraints).

Input shape: 4+D tensor with shape: batch_shape + (channels, rows, cols) if data_format='channels_first' or 4+D tensor with shape: batch_shape + (rows, cols, channels) if data_format='channels_last'. Output shape: 4+D tensor with shape: batch_shape + (filters, new_rows, new_cols) if data_format='channels_first' or 4+D tensor with shape: batch_shape + (new_rows, new_cols, filters)<code> if </code>data_format='channels_last'<code>. </code>rows and cols values might have changed due to padding.

Returns

A tensor of rank 4+ representing activation(conv2d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv2D(Conv):
  """2D convolution layer (e.g. spatial convolution over images).

  This layer creates a convolution kernel that is convolved
  with the layer input to produce a tensor of
  outputs. If `use_bias` is True,
  a bias vector is created and added to the outputs. Finally, if
  `activation` is not `None`, it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
  in `data_format="channels_last"`. You can use `None` when
  a dimension has variable size.

  Examples:

  >>> # The inputs are 28x28 RGB images with `channels_last` and the batch
  >>> # size is 4.
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 26, 26, 2)

  >>> # With `dilation_rate` as 2.
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', dilation_rate=2, input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 24, 24, 2)

  >>> # With `padding` as "same".
  >>> input_shape = (4, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', padding="same", input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 28, 28, 2)

  >>> # With extended batch shape [4, 7]:
  >>> input_shape = (4, 7, 28, 28, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv2D(
  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 26, 26, 2)


  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the height
      and width of the 2D convolution window. Can be a single integer to specify
      the same value for all spatial dimensions.
    strides: An integer or tuple/list of 2 integers, specifying the strides of
      the convolution along the height and width. Can be a single integer to
      specify the same value for all spatial dimensions. Specifying any stride
      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `(batch_size, height, width, channels)` while
      `channels_first` corresponds to inputs with shape `(batch_size, channels,
      height, width)`. It defaults to the `image_data_format` value found in
      your Keras config file at `~/.keras/keras.json`. If you never set it, then
      it will be `channels_last`.
    dilation_rate: an integer or tuple/list of 2 integers, specifying the
      dilation rate to use for dilated convolution. Can be a single integer to
      specify the same value for all spatial dimensions. Currently, specifying
      any `dilation_rate` value != 1 is incompatible with specifying any stride
      value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved separately
      with `filters / groups` filters. The output is the concatenation of all
      the `groups` results along the channel axis. Input channels and `filters`
      must both be divisible by `groups`.
    activation: Activation function to use. If you don't specify anything, no
      activation is applied (see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (see
      `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (see
      `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix (see `keras.regularizers`). 
    bias_regularizer: Regularizer function applied to the bias vector (see
      `keras.regularizers`). 
    activity_regularizer: Regularizer function applied to the output of the
      layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (see
      `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (see
      `keras.constraints`).
  Input shape:
    4+D tensor with shape: `batch_shape + (channels, rows, cols)` if
      `data_format='channels_first'`
    or 4+D tensor with shape: `batch_shape + (rows, cols, channels)` if
      `data_format='channels_last'`.
  Output shape:
    4+D tensor with shape: `batch_shape + (filters, new_rows, new_cols)` if
    `data_format='channels_first'` or 4+D tensor with shape: `batch_shape +
      (new_rows, new_cols, filters)` if `data_format='channels_last'`.  `rows`
      and `cols` values might have changed due to padding.

  Returns:
    A tensor of rank 4+ representing
    `activation(conv2d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is `"causal"`.
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1),
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv2D, self).__init__(
        rank=2,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class Conv2DTranspose (filters, kernel_size, strides=(1, 1), padding='valid', output_padding=None, data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 3) for 128x128 RGB pictures in data_format="channels_last".

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer or tuple/list of 2 integers, specifying the amount of padding along the height and width of the output tensor. Can be a single integer to specify the same value for all spatial dimensions. The amount of output padding along a given dimension must be lower than the stride along that same dimension. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 4D tensor with shape: (batch_size, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, rows, cols, channels) if data_format='channels_last'.

Output shape: 4D tensor with shape: (batch_size, filters, new_rows, new_cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding. If output_padding is specified: new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + output_padding[0]) new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + output_padding[1])

Returns

A tensor of rank 4 representing activation(conv2dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv2DTranspose(Conv2D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
  in `data_format="channels_last"`.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer or tuple/list of 2 integers,
      specifying the amount of padding along the height and width
      of the output tensor.
      Can be a single integer to specify the same value for all
      spatial dimensions.
      The amount of output padding along a given dimension must be
      lower than the stride along that same dimension.
      If set to `None` (default), the output shape is inferred.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: an integer or tuple/list of 2 integers, specifying
      the dilation rate to use for dilated convolution.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    4D tensor with shape:
    `(batch_size, channels, rows, cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    4D tensor with shape:
    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
    `rows` and `cols` values might have changed due to padding.
    If `output_padding` is specified:
    ```
    new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
    output_padding[0])
    new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
    output_padding[1])
    ```

  Returns:
    A tensor of rank 4 representing
    `activation(conv2dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep
      learning](https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional
      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=(1, 1),
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv2DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 2, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 4:
      raise ValueError('Inputs should have rank 4. Received input '
                       'shape: ' + str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined. Found `None`.')
    input_dim = int(input_shape[channel_axis])
    self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
    kernel_shape = self.kernel_size + (self.filters, input_dim)

    self.kernel = self.add_weight(
        name='kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          name='bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      h_axis, w_axis = 2, 3
    else:
      h_axis, w_axis = 1, 2

    # Use the constant height and weight when possible.
    # TODO(scottzhu): Extract this into a utility function that can be applied
    # to all convolutional layers, which currently lost the static shape
    # information due to tf.shape().
    height, width = None, None
    if inputs.shape.rank is not None:
      dims = inputs.shape.as_list()
      height = dims[h_axis]
      width = dims[w_axis]
    height = height if height is not None else inputs_shape[h_axis]
    width = width if width is not None else inputs_shape[w_axis]

    kernel_h, kernel_w = self.kernel_size
    stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_h = out_pad_w = None
    else:
      out_pad_h, out_pad_w = self.output_padding

    # Infer the dynamic output shape:
    out_height = conv_utils.deconv_output_length(height,
                                                 kernel_h,
                                                 padding=self.padding,
                                                 output_padding=out_pad_h,
                                                 stride=stride_h,
                                                 dilation=self.dilation_rate[0])
    out_width = conv_utils.deconv_output_length(width,
                                                kernel_w,
                                                padding=self.padding,
                                                output_padding=out_pad_w,
                                                stride=stride_w,
                                                dilation=self.dilation_rate[1])
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_height, out_width)
    else:
      output_shape = (batch_size, out_height, out_width, self.filters)

    output_shape_tensor = tf.stack(output_shape)
    outputs = backend.conv2d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides=self.strides,
        padding=self.padding,
        data_format=self.data_format,
        dilation_rate=self.dilation_rate)

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, h_axis, w_axis = 1, 2, 3
    else:
      c_axis, h_axis, w_axis = 3, 1, 2

    kernel_h, kernel_w = self.kernel_size
    stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_h = out_pad_w = None
    else:
      out_pad_h, out_pad_w = self.output_padding

    output_shape[c_axis] = self.filters
    output_shape[h_axis] = conv_utils.deconv_output_length(
        output_shape[h_axis],
        kernel_h,
        padding=self.padding,
        output_padding=out_pad_h,
        stride=stride_h,
        dilation=self.dilation_rate[0])
    output_shape[w_axis] = conv_utils.deconv_output_length(
        output_shape[w_axis],
        kernel_w,
        padding=self.padding,
        output_padding=out_pad_w,
        stride=stride_w,
        dilation=self.dilation_rate[1])
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv2DTranspose, self).get_config()
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv2D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Methods

def build(self, input_shape)

Creates the variables of the layer (optional, for subclass implementers).

This is a method that implementers of subclasses of Layer or Model can override if they need a state-creation step in-between layer instantiation and layer call.

This is typically used to create the weights of Layer subclasses.

Args

input_shape
Instance of TensorShape, or list of instances of TensorShape if the layer expects a list of inputs (one instance per input).
Expand source code
def build(self, input_shape):
  input_shape = tf.TensorShape(input_shape)
  if len(input_shape) != 4:
    raise ValueError('Inputs should have rank 4. Received input '
                     'shape: ' + str(input_shape))
  channel_axis = self._get_channel_axis()
  if input_shape.dims[channel_axis].value is None:
    raise ValueError('The channel dimension of the inputs '
                     'should be defined. Found `None`.')
  input_dim = int(input_shape[channel_axis])
  self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
  kernel_shape = self.kernel_size + (self.filters, input_dim)

  self.kernel = self.add_weight(
      name='kernel',
      shape=kernel_shape,
      initializer=self.kernel_initializer,
      regularizer=self.kernel_regularizer,
      constraint=self.kernel_constraint,
      trainable=True,
      dtype=self.dtype)
  if self.use_bias:
    self.bias = self.add_weight(
        name='bias',
        shape=(self.filters,),
        initializer=self.bias_initializer,
        regularizer=self.bias_regularizer,
        constraint=self.bias_constraint,
        trainable=True,
        dtype=self.dtype)
  else:
    self.bias = None
  self.built = True
def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  inputs_shape = tf.shape(inputs)
  batch_size = inputs_shape[0]
  if self.data_format == 'channels_first':
    h_axis, w_axis = 2, 3
  else:
    h_axis, w_axis = 1, 2

  # Use the constant height and weight when possible.
  # TODO(scottzhu): Extract this into a utility function that can be applied
  # to all convolutional layers, which currently lost the static shape
  # information due to tf.shape().
  height, width = None, None
  if inputs.shape.rank is not None:
    dims = inputs.shape.as_list()
    height = dims[h_axis]
    width = dims[w_axis]
  height = height if height is not None else inputs_shape[h_axis]
  width = width if width is not None else inputs_shape[w_axis]

  kernel_h, kernel_w = self.kernel_size
  stride_h, stride_w = self.strides

  if self.output_padding is None:
    out_pad_h = out_pad_w = None
  else:
    out_pad_h, out_pad_w = self.output_padding

  # Infer the dynamic output shape:
  out_height = conv_utils.deconv_output_length(height,
                                               kernel_h,
                                               padding=self.padding,
                                               output_padding=out_pad_h,
                                               stride=stride_h,
                                               dilation=self.dilation_rate[0])
  out_width = conv_utils.deconv_output_length(width,
                                              kernel_w,
                                              padding=self.padding,
                                              output_padding=out_pad_w,
                                              stride=stride_w,
                                              dilation=self.dilation_rate[1])
  if self.data_format == 'channels_first':
    output_shape = (batch_size, self.filters, out_height, out_width)
  else:
    output_shape = (batch_size, out_height, out_width, self.filters)

  output_shape_tensor = tf.stack(output_shape)
  outputs = backend.conv2d_transpose(
      inputs,
      self.kernel,
      output_shape_tensor,
      strides=self.strides,
      padding=self.padding,
      data_format=self.data_format,
      dilation_rate=self.dilation_rate)

  if not tf.executing_eagerly():
    # Infer the static output shape:
    out_shape = self.compute_output_shape(inputs.shape)
    outputs.set_shape(out_shape)

  if self.use_bias:
    outputs = tf.nn.bias_add(
        outputs,
        self.bias,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  if self.activation is not None:
    return self.activation(outputs)
  return outputs
def compute_output_shape(self, input_shape)

Computes the output shape of the layer.

If the layer has not been built, this method will call build on the layer. This assumes that the layer will later be used with inputs that match the input shape provided here.

Args

input_shape
Shape tuple (tuple of integers) or list of shape tuples (one per output tensor of the layer). Shape tuples can include None for free dimensions, instead of an integer.

Returns

An input shape tuple.

Expand source code
def compute_output_shape(self, input_shape):
  input_shape = tf.TensorShape(input_shape).as_list()
  output_shape = list(input_shape)
  if self.data_format == 'channels_first':
    c_axis, h_axis, w_axis = 1, 2, 3
  else:
    c_axis, h_axis, w_axis = 3, 1, 2

  kernel_h, kernel_w = self.kernel_size
  stride_h, stride_w = self.strides

  if self.output_padding is None:
    out_pad_h = out_pad_w = None
  else:
    out_pad_h, out_pad_w = self.output_padding

  output_shape[c_axis] = self.filters
  output_shape[h_axis] = conv_utils.deconv_output_length(
      output_shape[h_axis],
      kernel_h,
      padding=self.padding,
      output_padding=out_pad_h,
      stride=stride_h,
      dilation=self.dilation_rate[0])
  output_shape[w_axis] = conv_utils.deconv_output_length(
      output_shape[w_axis],
      kernel_w,
      padding=self.padding,
      output_padding=out_pad_w,
      stride=stride_w,
      dilation=self.dilation_rate[1])
  return tf.TensorShape(output_shape)
def get_config(self)

Returns the config of the layer.

A layer config is a Python dictionary (serializable) containing the configuration of a layer. The same layer can be reinstantiated later (without its trained weights) from this configuration.

The config of a layer does not include connectivity information, nor the layer class name. These are handled by Network (one layer of abstraction above).

Note that get_config() does not guarantee to return a fresh copy of dict every time it is called. The callers should make a copy of the returned dict if they want to modify it.

Returns

Python dictionary.

Expand source code
def get_config(self):
  config = super(Conv2DTranspose, self).get_config()
  config['output_padding'] = self.output_padding
  return config
class Convolution2DTranspose (filters, kernel_size, strides=(1, 1), padding='valid', output_padding=None, data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 3) for 128x128 RGB pictures in data_format="channels_last".

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer or tuple/list of 2 integers, specifying the amount of padding along the height and width of the output tensor. Can be a single integer to specify the same value for all spatial dimensions. The amount of output padding along a given dimension must be lower than the stride along that same dimension. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 4D tensor with shape: (batch_size, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, rows, cols, channels) if data_format='channels_last'.

Output shape: 4D tensor with shape: (batch_size, filters, new_rows, new_cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding. If output_padding is specified: new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + output_padding[0]) new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + output_padding[1])

Returns

A tensor of rank 4 representing activation(conv2dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv2DTranspose(Conv2D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 3)` for 128x128 RGB pictures
  in `data_format="channels_last"`.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer or tuple/list of 2 integers,
      specifying the amount of padding along the height and width
      of the output tensor.
      Can be a single integer to specify the same value for all
      spatial dimensions.
      The amount of output padding along a given dimension must be
      lower than the stride along that same dimension.
      If set to `None` (default), the output shape is inferred.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: an integer or tuple/list of 2 integers, specifying
      the dilation rate to use for dilated convolution.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    4D tensor with shape:
    `(batch_size, channels, rows, cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    4D tensor with shape:
    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
    `rows` and `cols` values might have changed due to padding.
    If `output_padding` is specified:
    ```
    new_rows = ((rows - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
    output_padding[0])
    new_cols = ((cols - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
    output_padding[1])
    ```

  Returns:
    A tensor of rank 4 representing
    `activation(conv2dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep
      learning](https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional
      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=(1, 1),
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv2DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 2, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 4:
      raise ValueError('Inputs should have rank 4. Received input '
                       'shape: ' + str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined. Found `None`.')
    input_dim = int(input_shape[channel_axis])
    self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
    kernel_shape = self.kernel_size + (self.filters, input_dim)

    self.kernel = self.add_weight(
        name='kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          name='bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      h_axis, w_axis = 2, 3
    else:
      h_axis, w_axis = 1, 2

    # Use the constant height and weight when possible.
    # TODO(scottzhu): Extract this into a utility function that can be applied
    # to all convolutional layers, which currently lost the static shape
    # information due to tf.shape().
    height, width = None, None
    if inputs.shape.rank is not None:
      dims = inputs.shape.as_list()
      height = dims[h_axis]
      width = dims[w_axis]
    height = height if height is not None else inputs_shape[h_axis]
    width = width if width is not None else inputs_shape[w_axis]

    kernel_h, kernel_w = self.kernel_size
    stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_h = out_pad_w = None
    else:
      out_pad_h, out_pad_w = self.output_padding

    # Infer the dynamic output shape:
    out_height = conv_utils.deconv_output_length(height,
                                                 kernel_h,
                                                 padding=self.padding,
                                                 output_padding=out_pad_h,
                                                 stride=stride_h,
                                                 dilation=self.dilation_rate[0])
    out_width = conv_utils.deconv_output_length(width,
                                                kernel_w,
                                                padding=self.padding,
                                                output_padding=out_pad_w,
                                                stride=stride_w,
                                                dilation=self.dilation_rate[1])
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_height, out_width)
    else:
      output_shape = (batch_size, out_height, out_width, self.filters)

    output_shape_tensor = tf.stack(output_shape)
    outputs = backend.conv2d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides=self.strides,
        padding=self.padding,
        data_format=self.data_format,
        dilation_rate=self.dilation_rate)

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, h_axis, w_axis = 1, 2, 3
    else:
      c_axis, h_axis, w_axis = 3, 1, 2

    kernel_h, kernel_w = self.kernel_size
    stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_h = out_pad_w = None
    else:
      out_pad_h, out_pad_w = self.output_padding

    output_shape[c_axis] = self.filters
    output_shape[h_axis] = conv_utils.deconv_output_length(
        output_shape[h_axis],
        kernel_h,
        padding=self.padding,
        output_padding=out_pad_h,
        stride=stride_h,
        dilation=self.dilation_rate[0])
    output_shape[w_axis] = conv_utils.deconv_output_length(
        output_shape[w_axis],
        kernel_w,
        padding=self.padding,
        output_padding=out_pad_w,
        stride=stride_w,
        dilation=self.dilation_rate[1])
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv2DTranspose, self).get_config()
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv2D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class Conv3D (filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

3D convolution layer (e.g. spatial convolution over volumes).

This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 128, 1) for 128x128x128 volumes with a single channel, in data_format="channels_last".

Examples:

>>> # The inputs are 28x28x28 volumes with a single channel, and the
>>> # batch size is 4
>>> input_shape =(4, 28, 28, 28, 1)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv3D(
... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 26, 26, 26, 2)
>>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames,
>>> # with 7 frames per video.
>>> input_shape = (4, 7, 28, 28, 28, 1)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv3D(
... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 26, 26, 26, 2)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 3 integers, specifying the depth, height and width of the 3D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 3 integers, specifying the strides of the convolution along each spatial dimension. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape batch_shape + (spatial_dim1, spatial_dim2, spatial_dim3, channels)<code> while </code>channels_first corresponds to inputs with shape batch_shape + (channels, spatial_dim1, spatial_dim2, spatial_dim3)<code>. It defaults to the </code>image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 3 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied (see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix (see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector (see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector (see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix (see keras.constraints).
bias_constraint
Constraint function applied to the bias vector (see keras.constraints).

Input shape: 5+D tensor with shape: batch_shape + (channels, conv_dim1, conv_dim2, conv_dim3) if data_format='channels_first' or 5+D tensor with shape: batch_shape + (conv_dim1, conv_dim2, conv_dim3, channels) if data_format='channels_last'. Output shape: 5+D tensor with shape: batch_shape + (filters, new_conv_dim1, new_conv_dim2, new_conv_dim3) if data_format='channels_first' or 5+D tensor with shape: batch_shape + (new_conv_dim1, new_conv_dim2, new_conv_dim3, filters) if data_format='channels_last'. new_conv_dim1, new_conv_dim2 and new_conv_dim3 values might have changed due to padding.

Returns

A tensor of rank 5+ representing activation(conv3d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv3D(Conv):
  """3D convolution layer (e.g. spatial convolution over volumes).

  This layer creates a convolution kernel that is convolved
  with the layer input to produce a tensor of
  outputs. If `use_bias` is True,
  a bias vector is created and added to the outputs. Finally, if
  `activation` is not `None`, it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 128, 1)` for 128x128x128 volumes
  with a single channel,
  in `data_format="channels_last"`.

  Examples:

  >>> # The inputs are 28x28x28 volumes with a single channel, and the
  >>> # batch size is 4
  >>> input_shape =(4, 28, 28, 28, 1)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv3D(
  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 26, 26, 26, 2)

  >>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames,
  >>> # with 7 frames per video.
  >>> input_shape = (4, 7, 28, 28, 28, 1)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv3D(
  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 26, 26, 26, 2)

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of 3 integers, specifying the depth,
      height and width of the 3D convolution window. Can be a single integer to
      specify the same value for all spatial dimensions.
    strides: An integer or tuple/list of 3 integers, specifying the strides of
      the convolution along each spatial dimension. Can be a single integer to
      specify the same value for all spatial dimensions. Specifying any stride
      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `batch_shape + (spatial_dim1, spatial_dim2,
      spatial_dim3, channels)` while `channels_first` corresponds to inputs with
      shape `batch_shape + (channels, spatial_dim1, spatial_dim2,
      spatial_dim3)`. It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`. If you never set it, then it
      will be "channels_last".
    dilation_rate: an integer or tuple/list of 3 integers, specifying the
      dilation rate to use for dilated convolution. Can be a single integer to
      specify the same value for all spatial dimensions. Currently, specifying
      any `dilation_rate` value != 1 is incompatible with specifying any stride
      value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved separately
      with `filters / groups` filters. The output is the concatenation of all
      the `groups` results along the channel axis. Input channels and `filters`
      must both be divisible by `groups`.
    activation: Activation function to use. If you don't specify anything, no
      activation is applied (see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (see
      `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (see
      `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (see
      `keras.regularizers`).
    activity_regularizer: Regularizer function applied to the output of the
      layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (see
      `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (see
      `keras.constraints`).
  Input shape:
    5+D tensor with shape: `batch_shape + (channels, conv_dim1, conv_dim2,
      conv_dim3)` if data_format='channels_first'
    or 5+D tensor with shape: `batch_shape + (conv_dim1, conv_dim2, conv_dim3,
      channels)` if data_format='channels_last'.
  Output shape:
    5+D tensor with shape: `batch_shape + (filters, new_conv_dim1,
      new_conv_dim2, new_conv_dim3)` if data_format='channels_first'
    or 5+D tensor with shape: `batch_shape + (new_conv_dim1, new_conv_dim2,
      new_conv_dim3, filters)` if data_format='channels_last'. `new_conv_dim1`,
      `new_conv_dim2` and `new_conv_dim3` values might have changed due to
      padding.

  Returns:
    A tensor of rank 5+ representing
    `activation(conv3d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1, 1),
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv3D, self).__init__(
        rank=3,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class Convolution3D (filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), groups=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

3D convolution layer (e.g. spatial convolution over volumes).

This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 128, 1) for 128x128x128 volumes with a single channel, in data_format="channels_last".

Examples:

>>> # The inputs are 28x28x28 volumes with a single channel, and the
>>> # batch size is 4
>>> input_shape =(4, 28, 28, 28, 1)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv3D(
... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
>>> print(y.shape)
(4, 26, 26, 26, 2)
>>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames,
>>> # with 7 frames per video.
>>> input_shape = (4, 7, 28, 28, 28, 1)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.Conv3D(
... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
>>> print(y.shape)
(4, 7, 26, 26, 26, 2)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 3 integers, specifying the depth, height and width of the 3D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 3 integers, specifying the strides of the convolution along each spatial dimension. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape batch_shape + (spatial_dim1, spatial_dim2, spatial_dim3, channels)<code> while </code>channels_first corresponds to inputs with shape batch_shape + (channels, spatial_dim1, spatial_dim2, spatial_dim3)<code>. It defaults to the </code>image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 3 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
groups
A positive integer specifying the number of groups in which the input is split along the channel axis. Each group is convolved separately with filters / groups filters. The output is the concatenation of all the groups results along the channel axis. Input channels and filters must both be divisible by groups.
activation
Activation function to use. If you don't specify anything, no activation is applied (see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix (see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector (see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector (see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") (see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix (see keras.constraints).
bias_constraint
Constraint function applied to the bias vector (see keras.constraints).

Input shape: 5+D tensor with shape: batch_shape + (channels, conv_dim1, conv_dim2, conv_dim3) if data_format='channels_first' or 5+D tensor with shape: batch_shape + (conv_dim1, conv_dim2, conv_dim3, channels) if data_format='channels_last'. Output shape: 5+D tensor with shape: batch_shape + (filters, new_conv_dim1, new_conv_dim2, new_conv_dim3) if data_format='channels_first' or 5+D tensor with shape: batch_shape + (new_conv_dim1, new_conv_dim2, new_conv_dim3, filters) if data_format='channels_last'. new_conv_dim1, new_conv_dim2 and new_conv_dim3 values might have changed due to padding.

Returns

A tensor of rank 5+ representing activation(conv3d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class Conv3D(Conv):
  """3D convolution layer (e.g. spatial convolution over volumes).

  This layer creates a convolution kernel that is convolved
  with the layer input to produce a tensor of
  outputs. If `use_bias` is True,
  a bias vector is created and added to the outputs. Finally, if
  `activation` is not `None`, it is applied to the outputs as well.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 128, 1)` for 128x128x128 volumes
  with a single channel,
  in `data_format="channels_last"`.

  Examples:

  >>> # The inputs are 28x28x28 volumes with a single channel, and the
  >>> # batch size is 4
  >>> input_shape =(4, 28, 28, 28, 1)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv3D(
  ... 2, 3, activation='relu', input_shape=input_shape[1:])(x)
  >>> print(y.shape)
  (4, 26, 26, 26, 2)

  >>> # With extended batch shape [4, 7], e.g. a batch of 4 videos of 3D frames,
  >>> # with 7 frames per video.
  >>> input_shape = (4, 7, 28, 28, 28, 1)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.Conv3D(
  ... 2, 3, activation='relu', input_shape=input_shape[2:])(x)
  >>> print(y.shape)
  (4, 7, 26, 26, 26, 2)

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of 3 integers, specifying the depth,
      height and width of the 3D convolution window. Can be a single integer to
      specify the same value for all spatial dimensions.
    strides: An integer or tuple/list of 3 integers, specifying the strides of
      the convolution along each spatial dimension. Can be a single integer to
      specify the same value for all spatial dimensions. Specifying any stride
      value != 1 is incompatible with specifying any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `batch_shape + (spatial_dim1, spatial_dim2,
      spatial_dim3, channels)` while `channels_first` corresponds to inputs with
      shape `batch_shape + (channels, spatial_dim1, spatial_dim2,
      spatial_dim3)`. It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`. If you never set it, then it
      will be "channels_last".
    dilation_rate: an integer or tuple/list of 3 integers, specifying the
      dilation rate to use for dilated convolution. Can be a single integer to
      specify the same value for all spatial dimensions. Currently, specifying
      any `dilation_rate` value != 1 is incompatible with specifying any stride
      value != 1.
    groups: A positive integer specifying the number of groups in which the
      input is split along the channel axis. Each group is convolved separately
      with `filters / groups` filters. The output is the concatenation of all
      the `groups` results along the channel axis. Input channels and `filters`
      must both be divisible by `groups`.
    activation: Activation function to use. If you don't specify anything, no
      activation is applied (see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (see
      `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (see
      `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (see
      `keras.regularizers`).
    activity_regularizer: Regularizer function applied to the output of the
      layer (its "activation") (see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (see
      `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (see
      `keras.constraints`).
  Input shape:
    5+D tensor with shape: `batch_shape + (channels, conv_dim1, conv_dim2,
      conv_dim3)` if data_format='channels_first'
    or 5+D tensor with shape: `batch_shape + (conv_dim1, conv_dim2, conv_dim3,
      channels)` if data_format='channels_last'.
  Output shape:
    5+D tensor with shape: `batch_shape + (filters, new_conv_dim1,
      new_conv_dim2, new_conv_dim3)` if data_format='channels_first'
    or 5+D tensor with shape: `batch_shape + (new_conv_dim1, new_conv_dim2,
      new_conv_dim3, filters)` if data_format='channels_last'. `new_conv_dim1`,
      `new_conv_dim2` and `new_conv_dim3` values might have changed due to
      padding.

  Returns:
    A tensor of rank 5+ representing
    `activation(conv3d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides > 1` and `dilation_rate > 1`.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1, 1),
               groups=1,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv3D, self).__init__(
        rank=3,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        groups=groups,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

Ancestors

  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class Conv3DTranspose (filters, kernel_size, strides=(1, 1, 1), padding='valid', output_padding=None, data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 128, 3) for a 128x128x128 volume with 3 channels if data_format="channels_last".

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 3 integers, specifying the depth, height and width of the 3D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 3 integers, specifying the strides of the convolution along the depth, height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer or tuple/list of 3 integers, specifying the amount of padding along the depth, height, and width. Can be a single integer to specify the same value for all spatial dimensions. The amount of output padding along a given dimension must be lower than the stride along that same dimension. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, depth, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, depth, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 3 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix ( see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 5D tensor with shape: (batch_size, channels, depth, rows, cols) if data_format='channels_first' or 5D tensor with shape: (batch_size, depth, rows, cols, channels) if data_format='channels_last'.

Output shape: 5D tensor with shape: (batch_size, filters, new_depth, new_rows, new_cols) if data_format='channels_first' or 5D tensor with shape: (batch_size, new_depth, new_rows, new_cols, filters) if data_format='channels_last'. depth and rows and cols values might have changed due to padding. If output_padding is specified:: new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + output_padding[0]) new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + output_padding[1]) new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] + output_padding[2])

Returns

A tensor of rank 5 representing activation(conv3dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv3DTranspose(Conv3D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 128, 3)` for a 128x128x128 volume with 3 channels
  if `data_format="channels_last"`.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 3 integers, specifying the
      depth, height and width of the 3D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 3 integers,
      specifying the strides of the convolution along the depth, height
        and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer or tuple/list of 3 integers,
      specifying the amount of padding along the depth, height, and
      width.
      Can be a single integer to specify the same value for all
      spatial dimensions.
      The amount of output padding along a given dimension must be
      lower than the stride along that same dimension.
      If set to `None` (default), the output shape is inferred.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, depth, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, depth, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: an integer or tuple/list of 3 integers, specifying
      the dilation rate to use for dilated convolution.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (
      see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    5D tensor with shape:
    `(batch_size, channels, depth, rows, cols)` if data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, depth, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    5D tensor with shape:
    `(batch_size, filters, new_depth, new_rows, new_cols)` if
      data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, new_depth, new_rows, new_cols, filters)` if
      data_format='channels_last'.
    `depth` and `rows` and `cols` values might have changed due to padding.
    If `output_padding` is specified::
    ```
    new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
    output_padding[0])
    new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
    output_padding[1])
    new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] +
    output_padding[2])
    ```

  Returns:
    A tensor of rank 5 representing
    `activation(conv3dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep
      learning](https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional
      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1, 1),
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=(1, 1, 1),
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv3DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 3, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 5:
      raise ValueError('Inputs should have rank 5, received input shape:',
                       str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined, found None: ' + str(input_shape))
    input_dim = int(input_shape[channel_axis])
    kernel_shape = self.kernel_size + (self.filters, input_dim)
    self.input_spec = InputSpec(ndim=5, axes={channel_axis: input_dim})

    self.kernel = self.add_weight(
        'kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          'bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      d_axis, h_axis, w_axis = 2, 3, 4
    else:
      d_axis, h_axis, w_axis = 1, 2, 3

    depth = inputs_shape[d_axis]
    height = inputs_shape[h_axis]
    width = inputs_shape[w_axis]

    kernel_d, kernel_h, kernel_w = self.kernel_size
    stride_d, stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_d = out_pad_h = out_pad_w = None
    else:
      out_pad_d, out_pad_h, out_pad_w = self.output_padding

    # Infer the dynamic output shape:
    out_depth = conv_utils.deconv_output_length(depth,
                                                kernel_d,
                                                padding=self.padding,
                                                output_padding=out_pad_d,
                                                stride=stride_d)
    out_height = conv_utils.deconv_output_length(height,
                                                 kernel_h,
                                                 padding=self.padding,
                                                 output_padding=out_pad_h,
                                                 stride=stride_h)
    out_width = conv_utils.deconv_output_length(width,
                                                kernel_w,
                                                padding=self.padding,
                                                output_padding=out_pad_w,
                                                stride=stride_w)
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_depth, out_height,
                      out_width)
      strides = (1, 1, stride_d, stride_h, stride_w)
    else:
      output_shape = (batch_size, out_depth, out_height, out_width,
                      self.filters)
      strides = (1, stride_d, stride_h, stride_w, 1)

    output_shape_tensor = tf.stack(output_shape)
    outputs = tf.nn.conv3d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=5),
        padding=self.padding.upper())

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, d_axis, h_axis, w_axis = 1, 2, 3, 4
    else:
      c_axis, d_axis, h_axis, w_axis = 4, 1, 2, 3

    kernel_d, kernel_h, kernel_w = self.kernel_size
    stride_d, stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_d = out_pad_h = out_pad_w = None
    else:
      out_pad_d, out_pad_h, out_pad_w = self.output_padding

    output_shape[c_axis] = self.filters
    output_shape[d_axis] = conv_utils.deconv_output_length(
        output_shape[d_axis],
        kernel_d,
        padding=self.padding,
        output_padding=out_pad_d,
        stride=stride_d)
    output_shape[h_axis] = conv_utils.deconv_output_length(
        output_shape[h_axis],
        kernel_h,
        padding=self.padding,
        output_padding=out_pad_h,
        stride=stride_h)
    output_shape[w_axis] = conv_utils.deconv_output_length(
        output_shape[w_axis],
        kernel_w,
        padding=self.padding,
        output_padding=out_pad_w,
        stride=stride_w)
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv3DTranspose, self).get_config()
    config.pop('dilation_rate')
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv3D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Methods

def build(self, input_shape)

Creates the variables of the layer (optional, for subclass implementers).

This is a method that implementers of subclasses of Layer or Model can override if they need a state-creation step in-between layer instantiation and layer call.

This is typically used to create the weights of Layer subclasses.

Args

input_shape
Instance of TensorShape, or list of instances of TensorShape if the layer expects a list of inputs (one instance per input).
Expand source code
def build(self, input_shape):
  input_shape = tf.TensorShape(input_shape)
  if len(input_shape) != 5:
    raise ValueError('Inputs should have rank 5, received input shape:',
                     str(input_shape))
  channel_axis = self._get_channel_axis()
  if input_shape.dims[channel_axis].value is None:
    raise ValueError('The channel dimension of the inputs '
                     'should be defined, found None: ' + str(input_shape))
  input_dim = int(input_shape[channel_axis])
  kernel_shape = self.kernel_size + (self.filters, input_dim)
  self.input_spec = InputSpec(ndim=5, axes={channel_axis: input_dim})

  self.kernel = self.add_weight(
      'kernel',
      shape=kernel_shape,
      initializer=self.kernel_initializer,
      regularizer=self.kernel_regularizer,
      constraint=self.kernel_constraint,
      trainable=True,
      dtype=self.dtype)
  if self.use_bias:
    self.bias = self.add_weight(
        'bias',
        shape=(self.filters,),
        initializer=self.bias_initializer,
        regularizer=self.bias_regularizer,
        constraint=self.bias_constraint,
        trainable=True,
        dtype=self.dtype)
  else:
    self.bias = None
  self.built = True
def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  inputs_shape = tf.shape(inputs)
  batch_size = inputs_shape[0]
  if self.data_format == 'channels_first':
    d_axis, h_axis, w_axis = 2, 3, 4
  else:
    d_axis, h_axis, w_axis = 1, 2, 3

  depth = inputs_shape[d_axis]
  height = inputs_shape[h_axis]
  width = inputs_shape[w_axis]

  kernel_d, kernel_h, kernel_w = self.kernel_size
  stride_d, stride_h, stride_w = self.strides

  if self.output_padding is None:
    out_pad_d = out_pad_h = out_pad_w = None
  else:
    out_pad_d, out_pad_h, out_pad_w = self.output_padding

  # Infer the dynamic output shape:
  out_depth = conv_utils.deconv_output_length(depth,
                                              kernel_d,
                                              padding=self.padding,
                                              output_padding=out_pad_d,
                                              stride=stride_d)
  out_height = conv_utils.deconv_output_length(height,
                                               kernel_h,
                                               padding=self.padding,
                                               output_padding=out_pad_h,
                                               stride=stride_h)
  out_width = conv_utils.deconv_output_length(width,
                                              kernel_w,
                                              padding=self.padding,
                                              output_padding=out_pad_w,
                                              stride=stride_w)
  if self.data_format == 'channels_first':
    output_shape = (batch_size, self.filters, out_depth, out_height,
                    out_width)
    strides = (1, 1, stride_d, stride_h, stride_w)
  else:
    output_shape = (batch_size, out_depth, out_height, out_width,
                    self.filters)
    strides = (1, stride_d, stride_h, stride_w, 1)

  output_shape_tensor = tf.stack(output_shape)
  outputs = tf.nn.conv3d_transpose(
      inputs,
      self.kernel,
      output_shape_tensor,
      strides,
      data_format=conv_utils.convert_data_format(self.data_format, ndim=5),
      padding=self.padding.upper())

  if not tf.executing_eagerly():
    # Infer the static output shape:
    out_shape = self.compute_output_shape(inputs.shape)
    outputs.set_shape(out_shape)

  if self.use_bias:
    outputs = tf.nn.bias_add(
        outputs,
        self.bias,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  if self.activation is not None:
    return self.activation(outputs)
  return outputs
def compute_output_shape(self, input_shape)

Computes the output shape of the layer.

If the layer has not been built, this method will call build on the layer. This assumes that the layer will later be used with inputs that match the input shape provided here.

Args

input_shape
Shape tuple (tuple of integers) or list of shape tuples (one per output tensor of the layer). Shape tuples can include None for free dimensions, instead of an integer.

Returns

An input shape tuple.

Expand source code
def compute_output_shape(self, input_shape):
  input_shape = tf.TensorShape(input_shape).as_list()
  output_shape = list(input_shape)
  if self.data_format == 'channels_first':
    c_axis, d_axis, h_axis, w_axis = 1, 2, 3, 4
  else:
    c_axis, d_axis, h_axis, w_axis = 4, 1, 2, 3

  kernel_d, kernel_h, kernel_w = self.kernel_size
  stride_d, stride_h, stride_w = self.strides

  if self.output_padding is None:
    out_pad_d = out_pad_h = out_pad_w = None
  else:
    out_pad_d, out_pad_h, out_pad_w = self.output_padding

  output_shape[c_axis] = self.filters
  output_shape[d_axis] = conv_utils.deconv_output_length(
      output_shape[d_axis],
      kernel_d,
      padding=self.padding,
      output_padding=out_pad_d,
      stride=stride_d)
  output_shape[h_axis] = conv_utils.deconv_output_length(
      output_shape[h_axis],
      kernel_h,
      padding=self.padding,
      output_padding=out_pad_h,
      stride=stride_h)
  output_shape[w_axis] = conv_utils.deconv_output_length(
      output_shape[w_axis],
      kernel_w,
      padding=self.padding,
      output_padding=out_pad_w,
      stride=stride_w)
  return tf.TensorShape(output_shape)
def get_config(self)

Returns the config of the layer.

A layer config is a Python dictionary (serializable) containing the configuration of a layer. The same layer can be reinstantiated later (without its trained weights) from this configuration.

The config of a layer does not include connectivity information, nor the layer class name. These are handled by Network (one layer of abstraction above).

Note that get_config() does not guarantee to return a fresh copy of dict every time it is called. The callers should make a copy of the returned dict if they want to modify it.

Returns

Python dictionary.

Expand source code
def get_config(self):
  config = super(Conv3DTranspose, self).get_config()
  config.pop('dilation_rate')
  config['output_padding'] = self.output_padding
  return config
class Convolution3DTranspose (filters, kernel_size, strides=(1, 1, 1), padding='valid', output_padding=None, data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Transposed convolution layer (sometimes called Deconvolution).

The need for transposed convolutions generally arises from the desire to use a transformation going in the opposite direction of a normal convolution, i.e., from something that has the shape of the output of some convolution to something that has the shape of its input while maintaining a connectivity pattern that is compatible with said convolution.

When using this layer as the first layer in a model, provide the keyword argument input_shape (tuple of integers or None, does not include the sample axis), e.g. input_shape=(128, 128, 128, 3) for a 128x128x128 volume with 3 channels if data_format="channels_last".

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 3 integers, specifying the depth, height and width of the 3D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 3 integers, specifying the strides of the convolution along the depth, height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
output_padding
An integer or tuple/list of 3 integers, specifying the amount of padding along the depth, height, and width. Can be a single integer to specify the same value for all spatial dimensions. The amount of output padding along a given dimension must be lower than the stride along that same dimension. If set to None (default), the output shape is inferred.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, depth, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, depth, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
an integer or tuple/list of 3 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix ( see keras.initializers). Defaults to 'glorot_uniform'.
bias_initializer
Initializer for the bias vector ( see keras.initializers). Defaults to 'zeros'.
kernel_regularizer
Regularizer function applied to the kernel weights matrix ( see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
kernel_constraint
Constraint function applied to the kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 5D tensor with shape: (batch_size, channels, depth, rows, cols) if data_format='channels_first' or 5D tensor with shape: (batch_size, depth, rows, cols, channels) if data_format='channels_last'.

Output shape: 5D tensor with shape: (batch_size, filters, new_depth, new_rows, new_cols) if data_format='channels_first' or 5D tensor with shape: (batch_size, new_depth, new_rows, new_cols, filters) if data_format='channels_last'. depth and rows and cols values might have changed due to padding. If output_padding is specified:: new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] + output_padding[0]) new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] + output_padding[1]) new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] + output_padding[2])

Returns

A tensor of rank 5 representing activation(conv3dtranspose(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.

References

Expand source code
class Conv3DTranspose(Conv3D):
  """Transposed convolution layer (sometimes called Deconvolution).

  The need for transposed convolutions generally arises
  from the desire to use a transformation going in the opposite direction
  of a normal convolution, i.e., from something that has the shape of the
  output of some convolution to something that has the shape of its input
  while maintaining a connectivity pattern that is compatible with
  said convolution.

  When using this layer as the first layer in a model,
  provide the keyword argument `input_shape`
  (tuple of integers or `None`, does not include the sample axis),
  e.g. `input_shape=(128, 128, 128, 3)` for a 128x128x128 volume with 3 channels
  if `data_format="channels_last"`.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 3 integers, specifying the
      depth, height and width of the 3D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 3 integers,
      specifying the strides of the convolution along the depth, height
        and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    output_padding: An integer or tuple/list of 3 integers,
      specifying the amount of padding along the depth, height, and
      width.
      Can be a single integer to specify the same value for all
      spatial dimensions.
      The amount of output padding along a given dimension must be
      lower than the stride along that same dimension.
      If set to `None` (default), the output shape is inferred.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, depth, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, depth, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: an integer or tuple/list of 3 integers, specifying
      the dilation rate to use for dilated convolution.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix (
      see `keras.initializers`). Defaults to 'glorot_uniform'.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). Defaults to 'zeros'.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix (
      see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    kernel_constraint: Constraint function applied to the kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    5D tensor with shape:
    `(batch_size, channels, depth, rows, cols)` if data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, depth, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    5D tensor with shape:
    `(batch_size, filters, new_depth, new_rows, new_cols)` if
      data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, new_depth, new_rows, new_cols, filters)` if
      data_format='channels_last'.
    `depth` and `rows` and `cols` values might have changed due to padding.
    If `output_padding` is specified::
    ```
    new_depth = ((depth - 1) * strides[0] + kernel_size[0] - 2 * padding[0] +
    output_padding[0])
    new_rows = ((rows - 1) * strides[1] + kernel_size[1] - 2 * padding[1] +
    output_padding[1])
    new_cols = ((cols - 1) * strides[2] + kernel_size[2] - 2 * padding[2] +
    output_padding[2])
    ```

  Returns:
    A tensor of rank 5 representing
    `activation(conv3dtranspose(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.

  References:
    - [A guide to convolution arithmetic for deep
      learning](https://arxiv.org/abs/1603.07285v1)
    - [Deconvolutional
      Networks](https://www.matthewzeiler.com/mattzeiler/deconvolutionalnetworks.pdf)
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1, 1),
               padding='valid',
               output_padding=None,
               data_format=None,
               dilation_rate=(1, 1, 1),
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Conv3DTranspose, self).__init__(
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activations.get(activation),
        use_bias=use_bias,
        kernel_initializer=initializers.get(kernel_initializer),
        bias_initializer=initializers.get(bias_initializer),
        kernel_regularizer=regularizers.get(kernel_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        kernel_constraint=constraints.get(kernel_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

    self.output_padding = output_padding
    if self.output_padding is not None:
      self.output_padding = conv_utils.normalize_tuple(
          self.output_padding, 3, 'output_padding')
      for stride, out_pad in zip(self.strides, self.output_padding):
        if out_pad >= stride:
          raise ValueError('Stride ' + str(self.strides) + ' must be '
                           'greater than output padding ' +
                           str(self.output_padding))

  def build(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    if len(input_shape) != 5:
      raise ValueError('Inputs should have rank 5, received input shape:',
                       str(input_shape))
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs '
                       'should be defined, found None: ' + str(input_shape))
    input_dim = int(input_shape[channel_axis])
    kernel_shape = self.kernel_size + (self.filters, input_dim)
    self.input_spec = InputSpec(ndim=5, axes={channel_axis: input_dim})

    self.kernel = self.add_weight(
        'kernel',
        shape=kernel_shape,
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        trainable=True,
        dtype=self.dtype)
    if self.use_bias:
      self.bias = self.add_weight(
          'bias',
          shape=(self.filters,),
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          trainable=True,
          dtype=self.dtype)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    inputs_shape = tf.shape(inputs)
    batch_size = inputs_shape[0]
    if self.data_format == 'channels_first':
      d_axis, h_axis, w_axis = 2, 3, 4
    else:
      d_axis, h_axis, w_axis = 1, 2, 3

    depth = inputs_shape[d_axis]
    height = inputs_shape[h_axis]
    width = inputs_shape[w_axis]

    kernel_d, kernel_h, kernel_w = self.kernel_size
    stride_d, stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_d = out_pad_h = out_pad_w = None
    else:
      out_pad_d, out_pad_h, out_pad_w = self.output_padding

    # Infer the dynamic output shape:
    out_depth = conv_utils.deconv_output_length(depth,
                                                kernel_d,
                                                padding=self.padding,
                                                output_padding=out_pad_d,
                                                stride=stride_d)
    out_height = conv_utils.deconv_output_length(height,
                                                 kernel_h,
                                                 padding=self.padding,
                                                 output_padding=out_pad_h,
                                                 stride=stride_h)
    out_width = conv_utils.deconv_output_length(width,
                                                kernel_w,
                                                padding=self.padding,
                                                output_padding=out_pad_w,
                                                stride=stride_w)
    if self.data_format == 'channels_first':
      output_shape = (batch_size, self.filters, out_depth, out_height,
                      out_width)
      strides = (1, 1, stride_d, stride_h, stride_w)
    else:
      output_shape = (batch_size, out_depth, out_height, out_width,
                      self.filters)
      strides = (1, stride_d, stride_h, stride_w, 1)

    output_shape_tensor = tf.stack(output_shape)
    outputs = tf.nn.conv3d_transpose(
        inputs,
        self.kernel,
        output_shape_tensor,
        strides,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=5),
        padding=self.padding.upper())

    if not tf.executing_eagerly():
      # Infer the static output shape:
      out_shape = self.compute_output_shape(inputs.shape)
      outputs.set_shape(out_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = list(input_shape)
    if self.data_format == 'channels_first':
      c_axis, d_axis, h_axis, w_axis = 1, 2, 3, 4
    else:
      c_axis, d_axis, h_axis, w_axis = 4, 1, 2, 3

    kernel_d, kernel_h, kernel_w = self.kernel_size
    stride_d, stride_h, stride_w = self.strides

    if self.output_padding is None:
      out_pad_d = out_pad_h = out_pad_w = None
    else:
      out_pad_d, out_pad_h, out_pad_w = self.output_padding

    output_shape[c_axis] = self.filters
    output_shape[d_axis] = conv_utils.deconv_output_length(
        output_shape[d_axis],
        kernel_d,
        padding=self.padding,
        output_padding=out_pad_d,
        stride=stride_d)
    output_shape[h_axis] = conv_utils.deconv_output_length(
        output_shape[h_axis],
        kernel_h,
        padding=self.padding,
        output_padding=out_pad_h,
        stride=stride_h)
    output_shape[w_axis] = conv_utils.deconv_output_length(
        output_shape[w_axis],
        kernel_w,
        padding=self.padding,
        output_padding=out_pad_w,
        stride=stride_w)
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Conv3DTranspose, self).get_config()
    config.pop('dilation_rate')
    config['output_padding'] = self.output_padding
    return config

Ancestors

  • Conv3D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class ConvLSTM1D (filters, kernel_size, strides=1, padding='valid', data_format=None, dilation_rate=1, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, return_sequences=False, return_state=False, go_backwards=False, stateful=False, dropout=0.0, recurrent_dropout=0.0, **kwargs)

1D Convolutional LSTM.

Similar to an LSTM layer, but the input transformations and recurrent transformations are both convolutional.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of n integers, specifying the dimensions of the convolution window.
strides
An integer or tuple/list of n integers, specifying the strides of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, time, …, channels) while channels_first corresponds to inputs with shape (batch, time, channels, …). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
An integer or tuple/list of n integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
activation
Activation function to use. By default hyperbolic tangent activation function is applied (tanh(x)).
recurrent_activation
Activation function to use for the recurrent step.
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Use in combination with bias_initializer="zeros". This is recommended in Jozefowicz et al., 2015
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to.
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence. (default False)
return_state
Boolean Whether to return the last state in addition to the output. (default False)
go_backwards
Boolean (default False). If True, process the input sequence backwards.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.

Call arguments: inputs: A 4D tensor. mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout are set. initial_state: List of initial state tensors to be passed to the first call of the cell. Input shape: - If data_format='channels_first' 4D tensor with shape: (samples, time, channels, rows) - If data_format='channels_last' 4D tensor with shape: (samples, time, rows, channels) Output shape: - If return_state: a list of tensors. The first tensor is the output. The remaining tensors are the last states, each 3D tensor with shape: (samples, filters, new_rows) if data_format='channels_first' or shape: (samples, new_rows, filters) if data_format='channels_last'. rows values might have changed due to padding. - If return_sequences: 4D tensor with shape: (samples, timesteps, filters, new_rows) if data_format='channels_first' or shape: (samples, timesteps, new_rows, filters) if data_format='channels_last'. - Else, 3D tensor with shape: (samples, filters, new_rows) if data_format='channels_first' or shape: (samples, new_rows, filters) if data_format='channels_last'.

Raises

ValueError
in case of invalid constructor arguments.

References

  • Shi et al., 2015 (the current implementation does not include the feedback loop on the cells output).
Expand source code
class ConvLSTM1D(ConvLSTM):
  """1D Convolutional LSTM.

  Similar to an LSTM layer, but the input transformations
  and recurrent transformations are both convolutional.

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of n integers, specifying the
      dimensions of the convolution window.
    strides: An integer or tuple/list of n integers, specifying the strides of
      the convolution. Specifying any stride value != 1 is incompatible with
      specifying any `dilation_rate` value != 1.
    padding: One of `"valid"` or `"same"` (case-insensitive). `"valid"` means no
      padding. `"same"` results in padding evenly to the left/right or up/down
      of the input such that output has the same height/width dimension as the
      input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `(batch, time, ..., channels)` while `channels_first`
      corresponds to inputs with shape `(batch, time, channels, ...)`. It
      defaults to the `image_data_format` value found in your Keras config file
      at `~/.keras/keras.json`. If you never set it, then it will be
      "channels_last".
    dilation_rate: An integer or tuple/list of n integers, specifying the
      dilation rate to use for dilated convolution. Currently, specifying any
      `dilation_rate` value != 1 is incompatible with specifying any `strides`
      value != 1.
    activation: Activation function to use. By default hyperbolic tangent
      activation function is applied (`tanh(x)`).
    recurrent_activation: Activation function to use for the recurrent step.
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix, used for
      the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel` weights
      matrix, used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    unit_forget_bias: Boolean. If True, add 1 to the bias of the forget gate at
      initialization. Use in combination with `bias_initializer="zeros"`. This
      is recommended in [Jozefowicz et al., 2015](
        http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix.
    recurrent_regularizer: Regularizer function applied to the
      `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to.
    kernel_constraint: Constraint function applied to the `kernel` weights
      matrix.
    recurrent_constraint: Constraint function applied to the `recurrent_kernel`
      weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    return_sequences: Boolean. Whether to return the last output in the output
      sequence, or the full sequence. (default False)
    return_state: Boolean Whether to return the last state in addition to the
      output. (default False)
    go_backwards: Boolean (default False). If True, process the input sequence
      backwards.
    stateful: Boolean (default False). If True, the last state for each sample
      at index i in a batch will be used as initial state for the sample of
      index i in the following batch.
    dropout: Float between 0 and 1. Fraction of the units to drop for the linear
      transformation of the inputs.
    recurrent_dropout: Float between 0 and 1. Fraction of the units to drop for
      the linear transformation of the recurrent state.
  Call arguments:
    inputs: A 4D tensor.
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether a
      given timestep should be masked.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or `recurrent_dropout`
      are set.
    initial_state: List of initial state tensors to be passed to the first call
      of the cell.
  Input shape: - If data_format='channels_first'
        4D tensor with shape: `(samples, time, channels, rows)` - If
          data_format='channels_last'
        4D tensor with shape: `(samples, time, rows, channels)`
  Output shape:
    - If `return_state`: a list of tensors. The first tensor is the output. The
      remaining tensors are the last states,
      each 3D tensor with shape: `(samples, filters, new_rows)` if
        data_format='channels_first'
      or shape: `(samples, new_rows, filters)` if data_format='channels_last'.
        `rows` values might have changed due to padding.
    - If `return_sequences`: 4D tensor with shape: `(samples, timesteps,
      filters, new_rows)` if data_format='channels_first'
      or shape: `(samples, timesteps, new_rows, filters)` if
        data_format='channels_last'.
    - Else, 3D tensor with shape: `(samples, filters, new_rows)` if
      data_format='channels_first'
      or shape: `(samples, new_rows, filters)` if data_format='channels_last'.

  Raises:
    ValueError: in case of invalid constructor arguments.

  References:
    - [Shi et al., 2015](http://arxiv.org/abs/1506.04214v1)
    (the current implementation does not include the feedback loop on the
    cells output).
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format=None,
               dilation_rate=1,
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               dropout=0.0,
               recurrent_dropout=0.0,
               **kwargs):
    super(ConvLSTM1D, self).__init__(
        rank=1,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activation,
        recurrent_activation=recurrent_activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        bias_initializer=bias_initializer,
        unit_forget_bias=unit_forget_bias,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        activity_regularizer=activity_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        **kwargs)

Ancestors

Inherited members

class ConvLSTM2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, return_sequences=False, return_state=False, go_backwards=False, stateful=False, dropout=0.0, recurrent_dropout=0.0, **kwargs)

2D Convolutional LSTM.

Similar to an LSTM layer, but the input transformations and recurrent transformations are both convolutional.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of n integers, specifying the dimensions of the convolution window.
strides
An integer or tuple/list of n integers, specifying the strides of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, time, …, channels) while channels_first corresponds to inputs with shape (batch, time, channels, …). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
An integer or tuple/list of n integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
activation
Activation function to use. By default hyperbolic tangent activation function is applied (tanh(x)).
recurrent_activation
Activation function to use for the recurrent step.
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Use in combination with bias_initializer="zeros". This is recommended in Jozefowicz et al., 2015
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to.
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence. (default False)
return_state
Boolean Whether to return the last state in addition to the output. (default False)
go_backwards
Boolean (default False). If True, process the input sequence backwards.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.

Call arguments: inputs: A 5D tensor. mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout are set. initial_state: List of initial state tensors to be passed to the first call of the cell. Input shape: - If data_format='channels_first' 5D tensor with shape: (samples, time, channels, rows, cols) - If data_format='channels_last' 5D tensor with shape: (samples, time, rows, cols, channels) Output shape: - If return_state: a list of tensors. The first tensor is the output. The remaining tensors are the last states, each 4D tensor with shape: (samples, filters, new_rows, new_cols) if data_format='channels_first' or shape: (samples, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding. - If return_sequences: 5D tensor with shape: (samples, timesteps, filters, new_rows, new_cols) if data_format='channels_first' or shape: (samples, timesteps, new_rows, new_cols, filters) if data_format='channels_last'. - Else, 4D tensor with shape: (samples, filters, new_rows, new_cols) if data_format='channels_first' or shape: (samples, new_rows, new_cols, filters) if data_format='channels_last'.

Raises

ValueError
in case of invalid constructor arguments.

References

  • Shi et al., 2015 (the current implementation does not include the feedback loop on the cells output).
Expand source code
class ConvLSTM2D(ConvLSTM):
  """2D Convolutional LSTM.

  Similar to an LSTM layer, but the input transformations
  and recurrent transformations are both convolutional.

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of n integers, specifying the
      dimensions of the convolution window.
    strides: An integer or tuple/list of n integers, specifying the strides of
      the convolution. Specifying any stride value != 1 is incompatible with
      specifying any `dilation_rate` value != 1.
    padding: One of `"valid"` or `"same"` (case-insensitive). `"valid"` means no
      padding. `"same"` results in padding evenly to the left/right or up/down
      of the input such that output has the same height/width dimension as the
      input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `(batch, time, ..., channels)` while `channels_first`
      corresponds to inputs with shape `(batch, time, channels, ...)`. It
      defaults to the `image_data_format` value found in your Keras config file
      at `~/.keras/keras.json`. If you never set it, then it will be
      "channels_last".
    dilation_rate: An integer or tuple/list of n integers, specifying the
      dilation rate to use for dilated convolution. Currently, specifying any
      `dilation_rate` value != 1 is incompatible with specifying any `strides`
      value != 1.
    activation: Activation function to use. By default hyperbolic tangent
      activation function is applied (`tanh(x)`).
    recurrent_activation: Activation function to use for the recurrent step.
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix, used for
      the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel` weights
      matrix, used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    unit_forget_bias: Boolean. If True, add 1 to the bias of the forget gate at
      initialization. Use in combination with `bias_initializer="zeros"`. This
      is recommended in [Jozefowicz et al., 2015](
        http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix.
    recurrent_regularizer: Regularizer function applied to the
      `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to.
    kernel_constraint: Constraint function applied to the `kernel` weights
      matrix.
    recurrent_constraint: Constraint function applied to the `recurrent_kernel`
      weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    return_sequences: Boolean. Whether to return the last output in the output
      sequence, or the full sequence. (default False)
    return_state: Boolean Whether to return the last state in addition to the
      output. (default False)
    go_backwards: Boolean (default False). If True, process the input sequence
      backwards.
    stateful: Boolean (default False). If True, the last state for each sample
      at index i in a batch will be used as initial state for the sample of
      index i in the following batch.
    dropout: Float between 0 and 1. Fraction of the units to drop for the linear
      transformation of the inputs.
    recurrent_dropout: Float between 0 and 1. Fraction of the units to drop for
      the linear transformation of the recurrent state.
  Call arguments:
    inputs: A 5D tensor.
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether a
      given timestep should be masked.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or `recurrent_dropout`
      are set.
    initial_state: List of initial state tensors to be passed to the first call
      of the cell.
  Input shape: - If data_format='channels_first'
        5D tensor with shape: `(samples, time, channels, rows, cols)` - If
          data_format='channels_last'
        5D tensor with shape: `(samples, time, rows, cols, channels)`
  Output shape:
    - If `return_state`: a list of tensors. The first tensor is the output. The
      remaining tensors are the last states,
      each 4D tensor with shape: `(samples, filters, new_rows, new_cols)` if
        data_format='channels_first'
      or shape: `(samples, new_rows, new_cols, filters)` if
        data_format='channels_last'. `rows` and `cols` values might have changed
        due to padding.
    - If `return_sequences`: 5D tensor with shape: `(samples, timesteps,
      filters, new_rows, new_cols)` if data_format='channels_first'
      or shape: `(samples, timesteps, new_rows, new_cols, filters)` if
        data_format='channels_last'.
    - Else, 4D tensor with shape: `(samples, filters, new_rows, new_cols)` if
      data_format='channels_first'
      or shape: `(samples, new_rows, new_cols, filters)` if
        data_format='channels_last'.

  Raises:
    ValueError: in case of invalid constructor arguments.

  References:
    - [Shi et al., 2015](http://arxiv.org/abs/1506.04214v1)
    (the current implementation does not include the feedback loop on the
    cells output).
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1),
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               dropout=0.0,
               recurrent_dropout=0.0,
               **kwargs):
    super(ConvLSTM2D, self).__init__(
        rank=2,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activation,
        recurrent_activation=recurrent_activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        bias_initializer=bias_initializer,
        unit_forget_bias=unit_forget_bias,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        activity_regularizer=activity_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        **kwargs)

Ancestors

Inherited members

class ConvLSTM3D (filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, return_sequences=False, return_state=False, go_backwards=False, stateful=False, dropout=0.0, recurrent_dropout=0.0, **kwargs)

3D Convolutional LSTM.

Similar to an LSTM layer, but the input transformations and recurrent transformations are both convolutional.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of n integers, specifying the dimensions of the convolution window.
strides
An integer or tuple/list of n integers, specifying the strides of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, time, …, channels) while channels_first corresponds to inputs with shape (batch, time, channels, …). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
An integer or tuple/list of n integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
activation
Activation function to use. By default hyperbolic tangent activation function is applied (tanh(x)).
recurrent_activation
Activation function to use for the recurrent step.
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Use in combination with bias_initializer="zeros". This is recommended in Jozefowicz et al., 2015
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to.
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence. (default False)
return_state
Boolean Whether to return the last state in addition to the output. (default False)
go_backwards
Boolean (default False). If True, process the input sequence backwards.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.

Call arguments: inputs: A 6D tensor. mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout are set. initial_state: List of initial state tensors to be passed to the first call of the cell. Input shape: - If data_format='channels_first' 6D tensor with shape: (samples, time, channels, rows, cols, depth) - If data_format='channels_last' 5D tensor with shape: (samples, time, rows, cols, depth, channels) Output shape: - If return_state: a list of tensors. The first tensor is the output. The remaining tensors are the last states, each 5D tensor with shape: (samples, filters, new_rows, new_cols, new_depth) if data_format='channels_first' or shape: (samples, new_rows, new_cols, new_depth, filters) if data_format='channels_last'. rows, cols, and depth values might have changed due to padding. - If return_sequences: 6D tensor with shape: (samples, timesteps, filters, new_rows, new_cols, new_depth) if data_format='channels_first' or shape: (samples, timesteps, new_rows, new_cols, new_depth, filters) if data_format='channels_last'. - Else, 5D tensor with shape: (samples, filters, new_rows, new_cols, new_depth) if data_format='channels_first' or shape: (samples, new_rows, new_cols, new_depth, filters) if data_format='channels_last'.

Raises

ValueError
in case of invalid constructor arguments.

References

  • Shi et al., 2015 (the current implementation does not include the feedback loop on the cells output).
Expand source code
class ConvLSTM3D(ConvLSTM):
  """3D Convolutional LSTM.

  Similar to an LSTM layer, but the input transformations
  and recurrent transformations are both convolutional.

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number of
      output filters in the convolution).
    kernel_size: An integer or tuple/list of n integers, specifying the
      dimensions of the convolution window.
    strides: An integer or tuple/list of n integers, specifying the strides of
      the convolution. Specifying any stride value != 1 is incompatible with
      specifying any `dilation_rate` value != 1.
    padding: One of `"valid"` or `"same"` (case-insensitive). `"valid"` means no
      padding. `"same"` results in padding evenly to the left/right or up/down
      of the input such that output has the same height/width dimension as the
      input.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs. `channels_last` corresponds
      to inputs with shape `(batch, time, ..., channels)` while `channels_first`
      corresponds to inputs with shape `(batch, time, channels, ...)`. It
      defaults to the `image_data_format` value found in your Keras config file
      at `~/.keras/keras.json`. If you never set it, then it will be
      "channels_last".
    dilation_rate: An integer or tuple/list of n integers, specifying the
      dilation rate to use for dilated convolution. Currently, specifying any
      `dilation_rate` value != 1 is incompatible with specifying any `strides`
      value != 1.
    activation: Activation function to use. By default hyperbolic tangent
      activation function is applied (`tanh(x)`).
    recurrent_activation: Activation function to use for the recurrent step.
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix, used for
      the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel` weights
      matrix, used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    unit_forget_bias: Boolean. If True, add 1 to the bias of the forget gate at
      initialization. Use in combination with `bias_initializer="zeros"`. This
      is recommended in [Jozefowicz et al., 2015](
        http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix.
    recurrent_regularizer: Regularizer function applied to the
      `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to.
    kernel_constraint: Constraint function applied to the `kernel` weights
      matrix.
    recurrent_constraint: Constraint function applied to the `recurrent_kernel`
      weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    return_sequences: Boolean. Whether to return the last output in the output
      sequence, or the full sequence. (default False)
    return_state: Boolean Whether to return the last state in addition to the
      output. (default False)
    go_backwards: Boolean (default False). If True, process the input sequence
      backwards.
    stateful: Boolean (default False). If True, the last state for each sample
      at index i in a batch will be used as initial state for the sample of
      index i in the following batch.
    dropout: Float between 0 and 1. Fraction of the units to drop for the linear
      transformation of the inputs.
    recurrent_dropout: Float between 0 and 1. Fraction of the units to drop for
      the linear transformation of the recurrent state.
  Call arguments:
    inputs: A 6D tensor.
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether a
      given timestep should be masked.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or `recurrent_dropout`
      are set.
    initial_state: List of initial state tensors to be passed to the first call
      of the cell.
  Input shape: - If data_format='channels_first'
        6D tensor with shape: `(samples, time, channels, rows, cols, depth)` -
          If data_format='channels_last'
        5D tensor with shape: `(samples, time, rows, cols, depth, channels)`
  Output shape:
    - If `return_state`: a list of tensors. The first tensor is the output. The
      remaining tensors are the last states,
      each 5D tensor with shape: `(samples, filters, new_rows, new_cols,
        new_depth)` if data_format='channels_first'
      or shape: `(samples, new_rows, new_cols, new_depth, filters)` if
        data_format='channels_last'. `rows`, `cols`, and `depth` values might
        have changed due to padding.
    - If `return_sequences`: 6D tensor with shape: `(samples, timesteps,
      filters, new_rows, new_cols, new_depth)` if data_format='channels_first'
      or shape: `(samples, timesteps, new_rows, new_cols, new_depth, filters)`
        if data_format='channels_last'.
    - Else, 5D tensor with shape: `(samples, filters, new_rows, new_cols,
      new_depth)` if data_format='channels_first'
      or shape: `(samples, new_rows, new_cols, new_depth, filters)` if
        data_format='channels_last'.

  Raises:
    ValueError: in case of invalid constructor arguments.

  References:
    - [Shi et al., 2015](http://arxiv.org/abs/1506.04214v1)
    (the current implementation does not include the feedback loop on the
    cells output).
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1, 1),
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               dropout=0.0,
               recurrent_dropout=0.0,
               **kwargs):
    super(ConvLSTM3D, self).__init__(
        rank=3,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activation,
        recurrent_activation=recurrent_activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        bias_initializer=bias_initializer,
        unit_forget_bias=unit_forget_bias,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        activity_regularizer=activity_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        **kwargs)

Ancestors

Inherited members

class Cropping1D (cropping=(1, 1), **kwargs)

Cropping layer for 1D input (e.g. temporal sequence).

It crops along the time dimension (axis 1).

Examples:

>>> input_shape = (2, 3, 2)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> print(x)
[[[ 0  1]
  [ 2  3]
  [ 4  5]]
 [[ 6  7]
  [ 8  9]
  [10 11]]]
>>> y = tf.keras.layers.Cropping1D(cropping=1)(x)
>>> print(y)
tf.Tensor(
  [[[2 3]]
   [[8 9]]], shape=(2, 1, 2), dtype=int64)

Args

cropping
Int or tuple of int (length 2) How many units should be trimmed off at the beginning and end of the cropping dimension (axis 1). If a single int is provided, the same value will be used for both.

Input shape: 3D tensor with shape (batch_size, axis_to_crop, features)

Output shape: 3D tensor with shape (batch_size, cropped_axis, features)

Expand source code
class Cropping1D(Layer):
  """Cropping layer for 1D input (e.g. temporal sequence).

  It crops along the time dimension (axis 1).

  Examples:

  >>> input_shape = (2, 3, 2)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> print(x)
  [[[ 0  1]
    [ 2  3]
    [ 4  5]]
   [[ 6  7]
    [ 8  9]
    [10 11]]]
  >>> y = tf.keras.layers.Cropping1D(cropping=1)(x)
  >>> print(y)
  tf.Tensor(
    [[[2 3]]
     [[8 9]]], shape=(2, 1, 2), dtype=int64)

  Args:
    cropping: Int or tuple of int (length 2)
      How many units should be trimmed off at the beginning and end of
      the cropping dimension (axis 1).
      If a single int is provided, the same value will be used for both.

  Input shape:
    3D tensor with shape `(batch_size, axis_to_crop, features)`

  Output shape:
    3D tensor with shape `(batch_size, cropped_axis, features)`
  """

  def __init__(self, cropping=(1, 1), **kwargs):
    super(Cropping1D, self).__init__(**kwargs)
    self.cropping = conv_utils.normalize_tuple(cropping, 2, 'cropping')
    self.input_spec = InputSpec(ndim=3)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if input_shape[1] is not None:
      length = input_shape[1] - self.cropping[0] - self.cropping[1]
    else:
      length = None
    return tf.TensorShape([input_shape[0], length, input_shape[2]])

  def call(self, inputs):
    if self.cropping[1] == 0:
      return inputs[:, self.cropping[0]:, :]
    else:
      return inputs[:, self.cropping[0]:-self.cropping[1], :]

  def get_config(self):
    config = {'cropping': self.cropping}
    base_config = super(Cropping1D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Cropping2D (cropping=((0, 0), (0, 0)), data_format=None, **kwargs)

Cropping layer for 2D input (e.g. picture).

It crops along spatial dimensions, i.e. height and width.

Examples:

>>> input_shape = (2, 28, 28, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> y = tf.keras.layers.Cropping2D(cropping=((2, 2), (4, 4)))(x)
>>> print(y.shape)
(2, 24, 20, 3)

Args

cropping
Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints. - If int: the same symmetric cropping is applied to height and width. - If tuple of 2 ints: interpreted as two different symmetric cropping values for height and width: (symmetric_height_crop, symmetric_width_crop). - If tuple of 2 tuples of 2 ints: interpreted as ((top_crop, bottom_crop), (left_crop, right_crop))
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, rows, cols, channels) - If data_format is "channels_first": (batch_size, channels, rows, cols)

Output shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, cropped_rows, cropped_cols, channels) - If data_format is "channels_first": (batch_size, channels, cropped_rows, cropped_cols)

Expand source code
class Cropping2D(Layer):
  """Cropping layer for 2D input (e.g. picture).

  It crops along spatial dimensions, i.e. height and width.

  Examples:

  >>> input_shape = (2, 28, 28, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> y = tf.keras.layers.Cropping2D(cropping=((2, 2), (4, 4)))(x)
  >>> print(y.shape)
  (2, 24, 20, 3)

  Args:
    cropping: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
      - If int: the same symmetric cropping
        is applied to height and width.
      - If tuple of 2 ints:
        interpreted as two different
        symmetric cropping values for height and width:
        `(symmetric_height_crop, symmetric_width_crop)`.
      - If tuple of 2 tuples of 2 ints:
        interpreted as
        `((top_crop, bottom_crop), (left_crop, right_crop))`
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
      `(batch_size, rows, cols, channels)`
    - If `data_format` is `"channels_first"`:
      `(batch_size, channels, rows, cols)`

  Output shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
      `(batch_size, cropped_rows, cropped_cols, channels)`
    - If `data_format` is `"channels_first"`:
      `(batch_size, channels, cropped_rows, cropped_cols)`
  """

  def __init__(self, cropping=((0, 0), (0, 0)), data_format=None, **kwargs):
    super(Cropping2D, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    if isinstance(cropping, int):
      self.cropping = ((cropping, cropping), (cropping, cropping))
    elif hasattr(cropping, '__len__'):
      if len(cropping) != 2:
        raise ValueError('`cropping` should have two elements. '
                         'Found: ' + str(cropping))
      height_cropping = conv_utils.normalize_tuple(cropping[0], 2,
                                                   '1st entry of cropping')
      width_cropping = conv_utils.normalize_tuple(cropping[1], 2,
                                                  '2nd entry of cropping')
      self.cropping = (height_cropping, width_cropping)
    else:
      raise ValueError('`cropping` should be either an int, '
                       'a tuple of 2 ints '
                       '(symmetric_height_crop, symmetric_width_crop), '
                       'or a tuple of 2 tuples of 2 ints '
                       '((top_crop, bottom_crop), (left_crop, right_crop)). '
                       'Found: ' + str(cropping))
    self.input_spec = InputSpec(ndim=4)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    # pylint: disable=invalid-unary-operand-type
    if self.data_format == 'channels_first':
      return tf.TensorShape([
          input_shape[0], input_shape[1],
          input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
          if input_shape[2] else None,
          input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
          if input_shape[3] else None
      ])
    else:
      return tf.TensorShape([
          input_shape[0],
          input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
          if input_shape[1] else None,
          input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
          if input_shape[2] else None, input_shape[3]
      ])
    # pylint: enable=invalid-unary-operand-type

  def call(self, inputs):
    # pylint: disable=invalid-unary-operand-type
    if self.data_format == 'channels_first':
      if self.cropping[0][1] == self.cropping[1][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:]
      elif self.cropping[0][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
                      -self.cropping[1][1]]
      elif self.cropping[1][1] == 0:
        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
                      self.cropping[1][0]:]
      return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
                    self.cropping[1][0]:-self.cropping[1][1]]
    else:
      if self.cropping[0][1] == self.cropping[1][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:, :]
      elif self.cropping[0][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
                      -self.cropping[1][1], :]
      elif self.cropping[1][1] == 0:
        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
                      self.cropping[1][0]:, :]
      return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
          1][0]:-self.cropping[1][1], :]  # pylint: disable=invalid-unary-operand-type
    # pylint: enable=invalid-unary-operand-type

  def get_config(self):
    config = {'cropping': self.cropping, 'data_format': self.data_format}
    base_config = super(Cropping2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Cropping3D (cropping=((1, 1), (1, 1), (1, 1)), data_format=None, **kwargs)

Cropping layer for 3D data (e.g. spatial or spatio-temporal).

Examples:

>>> input_shape = (2, 28, 28, 10, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> y = tf.keras.layers.Cropping3D(cropping=(2, 4, 2))(x)
>>> print(y.shape)
(2, 24, 20, 6, 3)

Args

cropping
Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints. - If int: the same symmetric cropping is applied to depth, height, and width. - If tuple of 3 ints: interpreted as two different symmetric cropping values for depth, height, and width: (symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop). - If tuple of 3 tuples of 2 ints: interpreted as ((left_dim1_crop, right_dim1_crop), (left_dim2_crop, right_dim2_crop), (left_dim3_crop, right_dim3_crop))
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop, depth) - If data_format is "channels_first": (batch_size, depth, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop)

Output shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, first_cropped_axis, second_cropped_axis, third_cropped_axis, depth) - If data_format is "channels_first": (batch_size, depth, first_cropped_axis, second_cropped_axis, third_cropped_axis)

Expand source code
class Cropping3D(Layer):
  """Cropping layer for 3D data (e.g. spatial or spatio-temporal).

    Examples:

  >>> input_shape = (2, 28, 28, 10, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> y = tf.keras.layers.Cropping3D(cropping=(2, 4, 2))(x)
  >>> print(y.shape)
  (2, 24, 20, 6, 3)

  Args:
    cropping: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints.
      - If int: the same symmetric cropping
        is applied to depth, height, and width.
      - If tuple of 3 ints: interpreted as two different
        symmetric cropping values for depth, height, and width:
        `(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop)`.
      - If tuple of 3 tuples of 2 ints: interpreted as
        `((left_dim1_crop, right_dim1_crop), (left_dim2_crop,
          right_dim2_crop), (left_dim3_crop, right_dim3_crop))`
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
      `(batch_size, first_axis_to_crop, second_axis_to_crop, third_axis_to_crop,
        depth)`
    - If `data_format` is `"channels_first"`:
      `(batch_size, depth, first_axis_to_crop, second_axis_to_crop,
        third_axis_to_crop)`

  Output shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
      `(batch_size, first_cropped_axis, second_cropped_axis, third_cropped_axis,
        depth)`
    - If `data_format` is `"channels_first"`:
      `(batch_size, depth, first_cropped_axis, second_cropped_axis,
        third_cropped_axis)`
  """

  def __init__(self,
               cropping=((1, 1), (1, 1), (1, 1)),
               data_format=None,
               **kwargs):
    super(Cropping3D, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    if isinstance(cropping, int):
      self.cropping = ((cropping, cropping), (cropping, cropping), (cropping,
                                                                    cropping))
    elif hasattr(cropping, '__len__'):
      if len(cropping) != 3:
        raise ValueError('`cropping` should have 3 elements. '
                         'Found: ' + str(cropping))
      dim1_cropping = conv_utils.normalize_tuple(cropping[0], 2,
                                                 '1st entry of cropping')
      dim2_cropping = conv_utils.normalize_tuple(cropping[1], 2,
                                                 '2nd entry of cropping')
      dim3_cropping = conv_utils.normalize_tuple(cropping[2], 2,
                                                 '3rd entry of cropping')
      self.cropping = (dim1_cropping, dim2_cropping, dim3_cropping)
    else:
      raise ValueError(
          '`cropping` should be either an int, '
          'a tuple of 3 ints '
          '(symmetric_dim1_crop, symmetric_dim2_crop, symmetric_dim3_crop), '
          'or a tuple of 3 tuples of 2 ints '
          '((left_dim1_crop, right_dim1_crop),'
          ' (left_dim2_crop, right_dim2_crop),'
          ' (left_dim3_crop, right_dim2_crop)). '
          'Found: ' + str(cropping))
    self.input_spec = InputSpec(ndim=5)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    # pylint: disable=invalid-unary-operand-type
    if self.data_format == 'channels_first':
      if input_shape[2] is not None:
        dim1 = input_shape[2] - self.cropping[0][0] - self.cropping[0][1]
      else:
        dim1 = None
      if input_shape[3] is not None:
        dim2 = input_shape[3] - self.cropping[1][0] - self.cropping[1][1]
      else:
        dim2 = None
      if input_shape[4] is not None:
        dim3 = input_shape[4] - self.cropping[2][0] - self.cropping[2][1]
      else:
        dim3 = None
      return tf.TensorShape(
          [input_shape[0], input_shape[1], dim1, dim2, dim3])
    elif self.data_format == 'channels_last':
      if input_shape[1] is not None:
        dim1 = input_shape[1] - self.cropping[0][0] - self.cropping[0][1]
      else:
        dim1 = None
      if input_shape[2] is not None:
        dim2 = input_shape[2] - self.cropping[1][0] - self.cropping[1][1]
      else:
        dim2 = None
      if input_shape[3] is not None:
        dim3 = input_shape[3] - self.cropping[2][0] - self.cropping[2][1]
      else:
        dim3 = None
      return tf.TensorShape(
          [input_shape[0], dim1, dim2, dim3, input_shape[4]])
    # pylint: enable=invalid-unary-operand-type

  def call(self, inputs):
    # pylint: disable=invalid-unary-operand-type
    if self.data_format == 'channels_first':
      if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
                      self.cropping[2][0]:]
      elif self.cropping[0][1] == self.cropping[1][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:,
                      self.cropping[2][0]:-self.cropping[2][1]]
      elif self.cropping[1][1] == self.cropping[2][1] == 0:
        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
                      self.cropping[1][0]:, self.cropping[2][0]:]
      elif self.cropping[0][1] == self.cropping[2][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][0]:
                      -self.cropping[1][1], self.cropping[2][0]:]
      elif self.cropping[0][1] == 0:
        return inputs[:, :, self.cropping[0][0]:, self.cropping[1][
            0]:-self.cropping[1][1], self.cropping[2][0]:-self.cropping[2][1]]
      elif self.cropping[1][1] == 0:
        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
                      cropping[1][0]:, self.cropping[2][0]:-self.cropping[2][1]]
      elif self.cropping[2][1] == 0:
        return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1], self.
                      cropping[1][0]:-self.cropping[1][1], self.cropping[2][0]:]
      return inputs[:, :, self.cropping[0][0]:-self.cropping[0][1],
                    self.cropping[1][0]:-self.cropping[1][1], self.cropping[2][
                        0]:-self.cropping[2][1]]
    else:
      if self.cropping[0][1] == self.cropping[1][1] == self.cropping[2][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
                      self.cropping[2][0]:, :]
      elif self.cropping[0][1] == self.cropping[1][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:,
                      self.cropping[2][0]:-self.cropping[2][1], :]
      elif self.cropping[1][1] == self.cropping[2][1] == 0:
        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
                      self.cropping[1][0]:, self.cropping[2][0]:, :]
      elif self.cropping[0][1] == self.cropping[2][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][0]:
                      -self.cropping[1][1], self.cropping[2][0]:, :]
      elif self.cropping[0][1] == 0:
        return inputs[:, self.cropping[0][0]:, self.cropping[1][
            0]:-self.cropping[1][1], self.cropping[2][0]:
                      -self.cropping[2][1], :]
      elif self.cropping[1][1] == 0:
        return inputs[:, self.cropping[0][
            0]:-self.cropping[0][1], self.cropping[1][0]:, self.cropping[2][0]:
                      -self.cropping[2][1], :]
      elif self.cropping[2][1] == 0:
        return inputs[:, self.cropping[0][0]:-self.cropping[0][1],
                      self.cropping[1][0]:-self.cropping[1][1], self.cropping[
                          2][0]:, :]
      return inputs[:, self.cropping[0][0]:-self.cropping[0][1], self.cropping[
          1][0]:-self.cropping[1][1], self.cropping[2][0]:  # pylint: disable=invalid-unary-operand-type
                    -self.cropping[2][1], :]  # pylint: disable=invalid-unary-operand-type
    # pylint: enable=invalid-unary-operand-type

  def get_config(self):
    config = {'cropping': self.cropping, 'data_format': self.data_format}
    base_config = super(Cropping3D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class CuDNNGRU (units, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, return_sequences=False, return_state=False, go_backwards=False, stateful=False, **kwargs)

Fast GRU implementation backed by cuDNN.

More information about cuDNN can be found on the NVIDIA developer website. Can only be run on GPU.

Args

units
Positive integer, dimensionality of the output space.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation").
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence.
return_state
Boolean. Whether to return the last state in addition to the output.
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
Expand source code
class CuDNNGRU(_CuDNNRNN):
  """Fast GRU implementation backed by cuDNN.

  More information about cuDNN can be found on the [NVIDIA
  developer website](https://developer.nvidia.com/cudnn).
  Can only be run on GPU.

  Args:
      units: Positive integer, dimensionality of the output space.
      kernel_initializer: Initializer for the `kernel` weights matrix, used for
        the linear transformation of the inputs.
      recurrent_initializer: Initializer for the `recurrent_kernel` weights
        matrix, used for the linear transformation of the recurrent state.
      bias_initializer: Initializer for the bias vector.
      kernel_regularizer: Regularizer function applied to the `kernel` weights
        matrix.
      recurrent_regularizer: Regularizer function applied to the
        `recurrent_kernel` weights matrix.
      bias_regularizer: Regularizer function applied to the bias vector.
      activity_regularizer: Regularizer function applied to the output of the
        layer (its "activation").
      kernel_constraint: Constraint function applied to the `kernel` weights
        matrix.
      recurrent_constraint: Constraint function applied to the
        `recurrent_kernel` weights matrix.
      bias_constraint: Constraint function applied to the bias vector.
      return_sequences: Boolean. Whether to return the last output in the output
        sequence, or the full sequence.
      return_state: Boolean. Whether to return the last state in addition to the
        output.
      go_backwards: Boolean (default False). If True, process the input sequence
        backwards and return the reversed sequence.
      stateful: Boolean (default False). If True, the last state for each sample
        at index i in a batch will be used as initial state for the sample of
        index i in the following batch.
  """

  def __init__(self,
               units,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               **kwargs):
    self.units = units
    cell_spec = collections.namedtuple('cell', 'state_size')
    self._cell = cell_spec(state_size=self.units)
    super(CuDNNGRU, self).__init__(
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        **kwargs)

    self.kernel_initializer = initializers.get(kernel_initializer)
    self.recurrent_initializer = initializers.get(recurrent_initializer)
    self.bias_initializer = initializers.get(bias_initializer)

    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)

    self.kernel_constraint = constraints.get(kernel_constraint)
    self.recurrent_constraint = constraints.get(recurrent_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

  @property
  def cell(self):
    return self._cell

  def build(self, input_shape):
    super(CuDNNGRU, self).build(input_shape)
    if isinstance(input_shape, list):
      input_shape = input_shape[0]
    input_dim = int(input_shape[-1])

    self.kernel = self.add_weight(
        shape=(input_dim, self.units * 3),
        name='kernel',
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint)

    self.recurrent_kernel = self.add_weight(
        shape=(self.units, self.units * 3),
        name='recurrent_kernel',
        initializer=self.recurrent_initializer,
        regularizer=self.recurrent_regularizer,
        constraint=self.recurrent_constraint)

    self.bias = self.add_weight(
        shape=(self.units * 6,),
        name='bias',
        initializer=self.bias_initializer,
        regularizer=self.bias_regularizer,
        constraint=self.bias_constraint)

    self.built = True

  def _process_batch(self, inputs, initial_state):
    if not self.time_major:
      inputs = tf.transpose(inputs, perm=(1, 0, 2))
    input_h = initial_state[0]
    input_h = tf.expand_dims(input_h, axis=0)

    params = recurrent_v2._canonical_to_params(    # pylint: disable=protected-access
        weights=[
            self.kernel[:, self.units:self.units * 2],
            self.kernel[:, :self.units],
            self.kernel[:, self.units * 2:],
            self.recurrent_kernel[:, self.units:self.units * 2],
            self.recurrent_kernel[:, :self.units],
            self.recurrent_kernel[:, self.units * 2:],
        ],
        biases=[
            self.bias[self.units:self.units * 2],
            self.bias[:self.units],
            self.bias[self.units * 2:self.units * 3],
            self.bias[self.units * 4:self.units * 5],
            self.bias[self.units * 3:self.units * 4],
            self.bias[self.units * 5:],
        ],
        shape=self._vector_shape)

    args = {
        'input': inputs,
        'input_h': input_h,
        'input_c': 0,
        'params': params,
        'is_training': True,
        'rnn_mode': 'gru',
    }

    outputs, h, _, _, _ = tf.raw_ops.CudnnRNNV2(**args)

    if self.stateful or self.return_state:
      h = h[0]
    if self.return_sequences:
      if self.time_major:
        output = outputs
      else:
        output = tf.transpose(outputs, perm=(1, 0, 2))
    else:
      output = outputs[-1]
    return output, [h]

  def get_config(self):
    config = {
        'units': self.units,
        'kernel_initializer': initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer': initializers.serialize(self.bias_initializer),
        'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer': regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint': constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint': constraints.serialize(self.bias_constraint)
    }
    base_config = super(CuDNNGRU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • keras.layers.cudnn_recurrent._CuDNNRNN
  • RNN
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Instance variables

var cell
Expand source code
@property
def cell(self):
  return self._cell

Inherited members

class CuDNNLSTM (units, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, return_sequences=False, return_state=False, go_backwards=False, stateful=False, **kwargs)

Fast LSTM implementation backed by cuDNN.

More information about cuDNN can be found on the NVIDIA developer website. Can only be run on GPU.

Args

units
Positive integer, dimensionality of the output space.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Setting it to true will also force bias_initializer="zeros". This is recommended in Jozefowicz et al.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation").
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
return_sequences
Boolean. Whether to return the last output. in the output sequence, or the full sequence.
return_state
Boolean. Whether to return the last state in addition to the output.
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
Expand source code
class CuDNNLSTM(_CuDNNRNN):
  """Fast LSTM implementation backed by cuDNN.

  More information about cuDNN can be found on the [NVIDIA
  developer website](https://developer.nvidia.com/cudnn).
  Can only be run on GPU.

  Args:
      units: Positive integer, dimensionality of the output space.
      kernel_initializer: Initializer for the `kernel` weights matrix, used for
        the linear transformation of the inputs.
      unit_forget_bias: Boolean. If True, add 1 to the bias of the forget gate
        at initialization. Setting it to true will also force
        `bias_initializer="zeros"`. This is recommended in [Jozefowicz et
        al.](http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
      recurrent_initializer: Initializer for the `recurrent_kernel` weights
        matrix, used for the linear transformation of the recurrent state.
      bias_initializer: Initializer for the bias vector.
      kernel_regularizer: Regularizer function applied to the `kernel` weights
        matrix.
      recurrent_regularizer: Regularizer function applied to the
        `recurrent_kernel` weights matrix.
      bias_regularizer: Regularizer function applied to the bias vector.
      activity_regularizer: Regularizer function applied to the output of the
        layer (its "activation").
      kernel_constraint: Constraint function applied to the `kernel` weights
        matrix.
      recurrent_constraint: Constraint function applied to the
        `recurrent_kernel` weights matrix.
      bias_constraint: Constraint function applied to the bias vector.
      return_sequences: Boolean. Whether to return the last output. in the
        output sequence, or the full sequence.
      return_state: Boolean. Whether to return the last state in addition to the
        output.
      go_backwards: Boolean (default False). If True, process the input sequence
        backwards and return the reversed sequence.
      stateful: Boolean (default False). If True, the last state for each sample
        at index i in a batch will be used as initial state for the sample of
        index i in the following batch.
  """

  def __init__(self,
               units,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               **kwargs):
    self.units = units
    cell_spec = collections.namedtuple('cell', 'state_size')
    self._cell = cell_spec(state_size=(self.units, self.units))
    super(CuDNNLSTM, self).__init__(
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        **kwargs)

    self.kernel_initializer = initializers.get(kernel_initializer)
    self.recurrent_initializer = initializers.get(recurrent_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.unit_forget_bias = unit_forget_bias

    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)

    self.kernel_constraint = constraints.get(kernel_constraint)
    self.recurrent_constraint = constraints.get(recurrent_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

  @property
  def cell(self):
    return self._cell

  def build(self, input_shape):
    super(CuDNNLSTM, self).build(input_shape)
    if isinstance(input_shape, list):
      input_shape = input_shape[0]
    input_dim = int(input_shape[-1])

    self.kernel = self.add_weight(
        shape=(input_dim, self.units * 4),
        name='kernel',
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint)

    self.recurrent_kernel = self.add_weight(
        shape=(self.units, self.units * 4),
        name='recurrent_kernel',
        initializer=self.recurrent_initializer,
        regularizer=self.recurrent_regularizer,
        constraint=self.recurrent_constraint)

    if self.unit_forget_bias:

      def bias_initializer(_, *args, **kwargs):
        return tf.concat([
            self.bias_initializer((self.units * 5,), *args, **kwargs),
            tf.compat.v1.ones_initializer()((self.units,), *args, **kwargs),
            self.bias_initializer((self.units * 2,), *args, **kwargs),
        ], axis=0)
    else:
      bias_initializer = self.bias_initializer
    self.bias = self.add_weight(
        shape=(self.units * 8,),
        name='bias',
        initializer=bias_initializer,
        regularizer=self.bias_regularizer,
        constraint=self.bias_constraint)

    self.built = True

  def _process_batch(self, inputs, initial_state):
    if not self.time_major:
      inputs = tf.transpose(inputs, perm=(1, 0, 2))
    input_h = initial_state[0]
    input_c = initial_state[1]
    input_h = tf.expand_dims(input_h, axis=0)
    input_c = tf.expand_dims(input_c, axis=0)

    params = recurrent_v2._canonical_to_params(    # pylint: disable=protected-access
        weights=[
            self.kernel[:, :self.units],
            self.kernel[:, self.units:self.units * 2],
            self.kernel[:, self.units * 2:self.units * 3],
            self.kernel[:, self.units * 3:],
            self.recurrent_kernel[:, :self.units],
            self.recurrent_kernel[:, self.units:self.units * 2],
            self.recurrent_kernel[:, self.units * 2:self.units * 3],
            self.recurrent_kernel[:, self.units * 3:],
        ],
        biases=[
            self.bias[:self.units],
            self.bias[self.units:self.units * 2],
            self.bias[self.units * 2:self.units * 3],
            self.bias[self.units * 3:self.units * 4],
            self.bias[self.units * 4:self.units * 5],
            self.bias[self.units * 5:self.units * 6],
            self.bias[self.units * 6:self.units * 7],
            self.bias[self.units * 7:],
        ],
        shape=self._vector_shape)

    args = {
        'input': inputs,
        'input_h': input_h,
        'input_c': input_c,
        'params': params,
        'is_training': True,
    }

    outputs, h, c, _, _ = tf.raw_ops.CudnnRNNV2(**args)

    if self.stateful or self.return_state:
      h = h[0]
      c = c[0]
    if self.return_sequences:
      if self.time_major:
        output = outputs
      else:
        output = tf.transpose(outputs, perm=(1, 0, 2))
    else:
      output = outputs[-1]
    return output, [h, c]

  def get_config(self):
    config = {
        'units': self.units,
        'kernel_initializer': initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer': initializers.serialize(self.bias_initializer),
        'unit_forget_bias': self.unit_forget_bias,
        'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer': regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint': constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint': constraints.serialize(self.bias_constraint)
    }
    base_config = super(CuDNNLSTM, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • keras.layers.cudnn_recurrent._CuDNNRNN
  • RNN
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Instance variables

var cell
Expand source code
@property
def cell(self):
  return self._cell

Inherited members

class Dense (units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

Just your regular densely-connected NN layer.

Dense implements the operation: output = activation(dot(input, kernel) + bias) where activation is the element-wise activation function passed as the activation argument, kernel is a weights matrix created by the layer, and bias is a bias vector created by the layer (only applicable if use_bias is True). These are all attributes of Dense.

Note: If the input to the layer has a rank greater than 2, then Dense computes the dot product between the inputs and the kernel along the last axis of the inputs and axis 0 of the kernel (using tf.tensordot). For example, if input has dimensions (batch_size, d0, d1), then we create a kernel with shape (d1, units), and the kernel operates along axis 2 of the input, on every sub-tensor of shape (1, 1, d1) (there are batch_size * d0 such sub-tensors). The output in this case will have shape (batch_size, d0, units).

Besides, layer attributes cannot be modified after the layer has been called once (except the trainable attribute). When a popular kwarg input_shape is passed, then keras will create an input layer to insert before the current layer. This can be treated equivalent to explicitly defining an InputLayer.

Example:

>>> # Create a <code>Sequential</code> model and add a Dense layer as the first layer.
>>> model = tf.keras.models.Sequential()
>>> model.add(tf.keras.Input(shape=(16,)))
>>> model.add(tf.keras.layers.Dense(32, activation='relu'))
>>> # Now the model will take as input arrays of shape (None, 16)
>>> # and output arrays of shape (None, 32).
>>> # Note that after the first layer, you don't need to specify
>>> # the size of the input anymore:
>>> model.add(tf.keras.layers.Dense(32))
>>> model.output_shape
(None, 32)

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation").
kernel_constraint
Constraint function applied to the kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.

Input shape: N-D tensor with shape: (batch_size, …, input_dim). The most common situation would be a 2D input with shape (batch_size, input_dim).

Output shape: N-D tensor with shape: (batch_size, …, units). For instance, for a 2D input with shape (batch_size, input_dim), the output would have shape (batch_size, units).

Expand source code
class Dense(Layer):
  """Just your regular densely-connected NN layer.

  `Dense` implements the operation:
  `output = activation(dot(input, kernel) + bias)`
  where `activation` is the element-wise activation function
  passed as the `activation` argument, `kernel` is a weights matrix
  created by the layer, and `bias` is a bias vector created by the layer
  (only applicable if `use_bias` is `True`). These are all attributes of
  `Dense`.

  Note: If the input to the layer has a rank greater than 2, then `Dense`
  computes the dot product between the `inputs` and the `kernel` along the
  last axis of the `inputs` and axis 0 of the `kernel` (using `tf.tensordot`).
  For example, if input has dimensions `(batch_size, d0, d1)`,
  then we create a `kernel` with shape `(d1, units)`, and the `kernel` operates
  along axis 2 of the `input`, on every sub-tensor of shape `(1, 1, d1)`
  (there are `batch_size * d0` such sub-tensors).
  The output in this case will have shape `(batch_size, d0, units)`.

  Besides, layer attributes cannot be modified after the layer has been called
  once (except the `trainable` attribute).
  When a popular kwarg `input_shape` is passed, then keras will create
  an input layer to insert before the current layer. This can be treated
  equivalent to explicitly defining an `InputLayer`.

  Example:

  >>> # Create a `Sequential` model and add a Dense layer as the first layer.
  >>> model = tf.keras.models.Sequential()
  >>> model.add(tf.keras.Input(shape=(16,)))
  >>> model.add(tf.keras.layers.Dense(32, activation='relu'))
  >>> # Now the model will take as input arrays of shape (None, 16)
  >>> # and output arrays of shape (None, 32).
  >>> # Note that after the first layer, you don't need to specify
  >>> # the size of the input anymore:
  >>> model.add(tf.keras.layers.Dense(32))
  >>> model.output_shape
  (None, 32)

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix.
    bias_initializer: Initializer for the bias vector.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation").
    kernel_constraint: Constraint function applied to
      the `kernel` weights matrix.
    bias_constraint: Constraint function applied to the bias vector.

  Input shape:
    N-D tensor with shape: `(batch_size, ..., input_dim)`.
    The most common situation would be
    a 2D input with shape `(batch_size, input_dim)`.

  Output shape:
    N-D tensor with shape: `(batch_size, ..., units)`.
    For instance, for a 2D input with shape `(batch_size, input_dim)`,
    the output would have shape `(batch_size, units)`.
  """

  def __init__(self,
               units,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(Dense, self).__init__(
        activity_regularizer=activity_regularizer, **kwargs)

    self.units = int(units) if not isinstance(units, int) else units
    if self.units < 0:
      raise ValueError(f'Received an invalid value for `units`, expected '
                       f'a positive integer, got {units}.')
    self.activation = activations.get(activation)
    self.use_bias = use_bias
    self.kernel_initializer = initializers.get(kernel_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.kernel_constraint = constraints.get(kernel_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

    self.input_spec = InputSpec(min_ndim=2)
    self.supports_masking = True

  def build(self, input_shape):
    dtype = tf.as_dtype(self.dtype or K.floatx())
    if not (dtype.is_floating or dtype.is_complex):
      raise TypeError('Unable to build `Dense` layer with non-floating point '
                      'dtype %s' % (dtype,))

    input_shape = tf.TensorShape(input_shape)
    last_dim = tf.compat.dimension_value(input_shape[-1])
    if last_dim is None:
      raise ValueError('The last dimension of the inputs to `Dense` '
                       'should be defined. Found `None`.')
    self.input_spec = InputSpec(min_ndim=2, axes={-1: last_dim})
    self.kernel = self.add_weight(
        'kernel',
        shape=[last_dim, self.units],
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        dtype=self.dtype,
        trainable=True)
    if self.use_bias:
      self.bias = self.add_weight(
          'bias',
          shape=[self.units,],
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          dtype=self.dtype,
          trainable=True)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs):
    if inputs.dtype.base_dtype != self._compute_dtype_object.base_dtype:
      inputs = tf.cast(inputs, dtype=self._compute_dtype_object)

    rank = inputs.shape.rank
    if rank == 2 or rank is None:
      # We use embedding_lookup_sparse as a more efficient matmul operation for
      # large sparse input tensors. The op will result in a sparse gradient, as
      # opposed to sparse_ops.sparse_tensor_dense_matmul which results in dense
      # gradients. This can lead to sigfinicant speedups, see b/171762937.
      if isinstance(inputs, tf.SparseTensor):
        # We need to fill empty rows, as the op assumes at least one id per row.
        inputs, _ = tf.sparse.fill_empty_rows(inputs, 0)
        # We need to do some munging of our input to use the embedding lookup as
        # a matrix multiply. We split our input matrix into separate ids and
        # weights tensors. The values of the ids tensor should be the column
        # indices of our input matrix and the values of the weights tensor
        # can continue to the actual matrix weights.
        # The column arrangement of ids and weights
        # will be summed over and does not matter. See the documentation for
        # sparse_ops.sparse_tensor_dense_matmul a more detailed explanation
        # of the inputs to both ops.
        ids = tf.SparseTensor(
            indices=inputs.indices,
            values=inputs.indices[:, 1],
            dense_shape=inputs.dense_shape)
        weights = inputs
        outputs = tf.nn.embedding_lookup_sparse(
            self.kernel, ids, weights, combiner='sum')
      else:
        outputs = tf.raw_ops.MatMul(a=inputs, b=self.kernel)
    # Broadcast kernel to inputs.
    else:
      outputs = tf.tensordot(inputs, self.kernel, [[rank - 1], [0]])
      # Reshape the output back to the original ndim of the input.
      if not tf.executing_eagerly():
        shape = inputs.shape.as_list()
        output_shape = shape[:-1] + [self.kernel.shape[-1]]
        outputs.set_shape(output_shape)

    if self.use_bias:
      outputs = tf.nn.bias_add(outputs, self.bias)

    if self.activation is not None:
      outputs = self.activation(outputs)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape)
    input_shape = input_shape.with_rank_at_least(2)
    if tf.compat.dimension_value(input_shape[-1]) is None:
      raise ValueError(
          'The innermost dimension of input_shape must be defined, but saw: %s'
          % (input_shape,))
    return input_shape[:-1].concatenate(self.units)

  def get_config(self):
    config = super(Dense, self).get_config()
    config.update({
        'units': self.units,
        'activation': activations.serialize(self.activation),
        'use_bias': self.use_bias,
        'kernel_initializer': initializers.serialize(self.kernel_initializer),
        'bias_initializer': initializers.serialize(self.bias_initializer),
        'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
        'bias_regularizer': regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint': constraints.serialize(self.kernel_constraint),
        'bias_constraint': constraints.serialize(self.bias_constraint)
    })
    return config

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class DenseFeatures (feature_columns, trainable=True, name=None, partitioner=None, **kwargs)

A layer that produces a dense Tensor based on given feature_columns.

Generally a single example in training data is described with FeatureColumns. At the first layer of the model, this column-oriented data should be converted to a single Tensor.

This layer can be called multiple times with different features.

This is the V1 version of this layer that uses variable_scope's or partitioner to create variables which works well with PartitionedVariables. Variable scopes are deprecated in V2, so the V2 version uses name_scopes instead. But currently that lacks support for partitioned variables. Use this if you need partitioned variables. Use the partitioner argument if you have a Keras model and uses tf.compat.v1.keras.estimator.model_to_estimator for training.

Example:

price = tf.feature_column.numeric_column('price')
keywords_embedded = tf.feature_column.embedding_column(
    tf.feature_column.categorical_column_with_hash_bucket("keywords", 10K),
    dimension=16)
columns = [price, keywords_embedded, ...]
partitioner = tf.compat.v1.fixed_size_partitioner(num_shards=4)
feature_layer = tf.compat.v1.keras.layers.DenseFeatures(
    feature_columns=columns, partitioner=partitioner)

features = tf.io.parse_example(
    ..., features=tf.feature_column.make_parse_example_spec(columns))
dense_tensor = feature_layer(features)
for units in [128, 64, 32]:
  dense_tensor = tf.compat.v1.keras.layers.Dense(
                     units, activation='relu')(dense_tensor)
prediction = tf.compat.v1.keras.layers.Dense(1)(dense_tensor)

Constructs a DenseFeatures layer.

Args

feature_columns
An iterable containing the FeatureColumns to use as inputs to your model. All items should be instances of classes derived from DenseColumn such as numeric_column, embedding_column, bucketized_column, indicator_column. If you have categorical features, you can wrap them with an embedding_column or indicator_column.
trainable
Boolean, whether the layer's variables will be updated via gradient descent during training.
name
Name to give to the DenseFeatures.
partitioner
Partitioner for input layer. Defaults to None.
**kwargs
Keyword arguments to construct a layer.

Raises

ValueError
if an item in feature_columns is not a DenseColumn.
Expand source code
class DenseFeatures(kfc._BaseFeaturesLayer):  # pylint: disable=protected-access
  """A layer that produces a dense `Tensor` based on given `feature_columns`.

  Generally a single example in training data is described with FeatureColumns.
  At the first layer of the model, this column-oriented data should be converted
  to a single `Tensor`.

  This layer can be called multiple times with different features.

  This is the V1 version of this layer that uses variable_scope's or partitioner
  to create variables which works well with PartitionedVariables. Variable
  scopes are deprecated in V2, so the V2 version uses name_scopes instead. But
  currently that lacks support for partitioned variables. Use this if you need
  partitioned variables. Use the partitioner argument if you have a Keras model
  and uses `tf.compat.v1.keras.estimator.model_to_estimator` for training.

  Example:

  ```python
  price = tf.feature_column.numeric_column('price')
  keywords_embedded = tf.feature_column.embedding_column(
      tf.feature_column.categorical_column_with_hash_bucket("keywords", 10K),
      dimension=16)
  columns = [price, keywords_embedded, ...]
  partitioner = tf.compat.v1.fixed_size_partitioner(num_shards=4)
  feature_layer = tf.compat.v1.keras.layers.DenseFeatures(
      feature_columns=columns, partitioner=partitioner)

  features = tf.io.parse_example(
      ..., features=tf.feature_column.make_parse_example_spec(columns))
  dense_tensor = feature_layer(features)
  for units in [128, 64, 32]:
    dense_tensor = tf.compat.v1.keras.layers.Dense(
                       units, activation='relu')(dense_tensor)
  prediction = tf.compat.v1.keras.layers.Dense(1)(dense_tensor)
  ```
  """

  def __init__(self,
               feature_columns,
               trainable=True,
               name=None,
               partitioner=None,
               **kwargs):
    """Constructs a DenseFeatures layer.

    Args:
      feature_columns: An iterable containing the FeatureColumns to use as
        inputs to your model. All items should be instances of classes derived
        from `DenseColumn` such as `numeric_column`, `embedding_column`,
        `bucketized_column`, `indicator_column`. If you have categorical
        features, you can wrap them with an `embedding_column` or
        `indicator_column`.
      trainable:  Boolean, whether the layer's variables will be updated via
        gradient descent during training.
      name: Name to give to the DenseFeatures.
      partitioner: Partitioner for input layer. Defaults to None.
      **kwargs: Keyword arguments to construct a layer.

    Raises:
      ValueError: if an item in `feature_columns` is not a `DenseColumn`.
    """
    super(DenseFeatures, self).__init__(
        feature_columns=feature_columns,
        trainable=trainable,
        name=name,
        partitioner=partitioner,
        expected_column_type=tf.__internal__.feature_column.DenseColumn,
        **kwargs)

  @property
  def _is_feature_layer(self):
    return True

  @property
  def _tracking_metadata(self):
    """String stored in metadata field in the SavedModel proto.

    Returns:
      A serialized JSON storing information necessary for recreating this layer.
    """
    metadata = json.loads(super(DenseFeatures, self)._tracking_metadata)
    metadata['_is_feature_layer'] = True
    return json.dumps(metadata, default=json_utils.get_json_type)

  def _target_shape(self, input_shape, total_elements):
    return (input_shape[0], total_elements)

  def call(self, features, cols_to_output_tensors=None, training=None):
    """Returns a dense tensor corresponding to the `feature_columns`.

    Example usage:

    >>> t1 = tf.feature_column.embedding_column(
    ...    tf.feature_column.categorical_column_with_hash_bucket("t1", 2),
    ...    dimension=8)
    >>> t2 = tf.feature_column.numeric_column('t2')
    >>> feature_layer = tf.compat.v1.keras.layers.DenseFeatures([t1, t2])
    >>> features = {"t1": tf.constant(["a", "b"]), "t2": tf.constant([1, 2])}
    >>> dense_tensor = feature_layer(features, training=True)

    Args:
      features: A mapping from key to tensors. `FeatureColumn`s look up via
        these keys. For example `numeric_column('price')` will look at 'price'
        key in this dict. Values can be a `SparseTensor` or a `Tensor` depends
        on corresponding `FeatureColumn`.
      cols_to_output_tensors: If not `None`, this will be filled with a dict
        mapping feature columns to output tensors created.
      training: Python boolean or None, indicating whether to the layer is being
        run in training mode. This argument is passed to the call method of any
        `FeatureColumn` that takes a `training` argument. For example, if a
        `FeatureColumn` performed dropout, the column could expose a `training`
        argument to control whether the dropout should be applied. If `None`,
        defaults to `tf.keras.backend.learning_phase()`.


    Returns:
      A `Tensor` which represents input layer of a model. Its shape
      is (batch_size, first_layer_dimension) and its dtype is `float32`.
      first_layer_dimension is determined based on given `feature_columns`.

    Raises:
      ValueError: If features are not a dictionary.
    """
    if training is None:
      training = backend.learning_phase()
    if not isinstance(features, dict):
      raise ValueError('We expected a dictionary here. Instead we got: ',
                       features)
    transformation_cache = tf.__internal__.feature_column.FeatureTransformationCache(features)
    output_tensors = []
    for column in self._feature_columns:
      with backend.name_scope(column.name):
        try:
          tensor = column.get_dense_tensor(
              transformation_cache, self._state_manager, training=training)
        except TypeError:
          tensor = column.get_dense_tensor(transformation_cache,
                                           self._state_manager)
        processed_tensors = self._process_dense_tensor(column, tensor)
        if cols_to_output_tensors is not None:
          cols_to_output_tensors[column] = processed_tensors
        output_tensors.append(processed_tensors)
    return self._verify_and_concat_tensors(output_tensors)

Ancestors

  • keras.feature_column.base_feature_layer._BaseFeaturesLayer
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Methods

def call(self, features, cols_to_output_tensors=None, training=None)

Returns a dense tensor corresponding to the feature_columns.

Example usage:

>>> t1 = tf.feature_column.embedding_column(
...    tf.feature_column.categorical_column_with_hash_bucket("t1", 2),
...    dimension=8)
>>> t2 = tf.feature_column.numeric_column('t2')
>>> feature_layer = tf.compat.v1.keras.layers.DenseFeatures([t1, t2])
>>> features = {"t1": tf.constant(["a", "b"]), "t2": tf.constant([1, 2])}
>>> dense_tensor = feature_layer(features, training=True)

Args

features
A mapping from key to tensors. FeatureColumns look up via these keys. For example numeric_column('price') will look at 'price' key in this dict. Values can be a SparseTensor or a Tensor depends on corresponding FeatureColumn.
cols_to_output_tensors
If not None, this will be filled with a dict mapping feature columns to output tensors created.
training
Python boolean or None, indicating whether to the layer is being run in training mode. This argument is passed to the call method of any FeatureColumn that takes a training argument. For example, if a FeatureColumn performed dropout, the column could expose a training argument to control whether the dropout should be applied. If None, defaults to tf.keras.backend.learning_phase().

Returns

A Tensor which represents input layer of a model. Its shape is (batch_size, first_layer_dimension) and its dtype is float32. first_layer_dimension is determined based on given feature_columns.

Raises

ValueError
If features are not a dictionary.
Expand source code
def call(self, features, cols_to_output_tensors=None, training=None):
  """Returns a dense tensor corresponding to the `feature_columns`.

  Example usage:

  >>> t1 = tf.feature_column.embedding_column(
  ...    tf.feature_column.categorical_column_with_hash_bucket("t1", 2),
  ...    dimension=8)
  >>> t2 = tf.feature_column.numeric_column('t2')
  >>> feature_layer = tf.compat.v1.keras.layers.DenseFeatures([t1, t2])
  >>> features = {"t1": tf.constant(["a", "b"]), "t2": tf.constant([1, 2])}
  >>> dense_tensor = feature_layer(features, training=True)

  Args:
    features: A mapping from key to tensors. `FeatureColumn`s look up via
      these keys. For example `numeric_column('price')` will look at 'price'
      key in this dict. Values can be a `SparseTensor` or a `Tensor` depends
      on corresponding `FeatureColumn`.
    cols_to_output_tensors: If not `None`, this will be filled with a dict
      mapping feature columns to output tensors created.
    training: Python boolean or None, indicating whether to the layer is being
      run in training mode. This argument is passed to the call method of any
      `FeatureColumn` that takes a `training` argument. For example, if a
      `FeatureColumn` performed dropout, the column could expose a `training`
      argument to control whether the dropout should be applied. If `None`,
      defaults to `tf.keras.backend.learning_phase()`.


  Returns:
    A `Tensor` which represents input layer of a model. Its shape
    is (batch_size, first_layer_dimension) and its dtype is `float32`.
    first_layer_dimension is determined based on given `feature_columns`.

  Raises:
    ValueError: If features are not a dictionary.
  """
  if training is None:
    training = backend.learning_phase()
  if not isinstance(features, dict):
    raise ValueError('We expected a dictionary here. Instead we got: ',
                     features)
  transformation_cache = tf.__internal__.feature_column.FeatureTransformationCache(features)
  output_tensors = []
  for column in self._feature_columns:
    with backend.name_scope(column.name):
      try:
        tensor = column.get_dense_tensor(
            transformation_cache, self._state_manager, training=training)
      except TypeError:
        tensor = column.get_dense_tensor(transformation_cache,
                                         self._state_manager)
      processed_tensors = self._process_dense_tensor(column, tensor)
      if cols_to_output_tensors is not None:
        cols_to_output_tensors[column] = processed_tensors
      output_tensors.append(processed_tensors)
  return self._verify_and_concat_tensors(output_tensors)

Inherited members

class DepthwiseConv2D (kernel_size, strides=(1, 1), padding='valid', depth_multiplier=1, data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, depthwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, bias_constraint=None, **kwargs)

Depthwise 2D convolution.

Depthwise convolution is a type of convolution in which a single convolutional filter is apply to each input channel (i.e. in a depthwise way). You can understand depthwise convolution as being the first step in a depthwise separable convolution.

It is implemented via the following steps:

  • Split the input into individual channels.
  • Convolve each input with the layer's kernel (called a depthwise kernel).
  • Stack the convolved outputs together (along the channels axis).

Unlike a regular 2D convolution, depthwise convolution does not mix information across different input channels.

The depth_multiplier argument controls how many output channels are generated per input channel in the depthwise step.

Args

kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of 'valid' or 'same' (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
depth_multiplier
The number of depthwise convolution output channels for each input channel. The total number of depthwise convolution output channels will be equal to filters_in * depth_multiplier.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be 'channels_last'.
dilation_rate
An integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
depthwise_initializer
Initializer for the depthwise kernel matrix ( see keras.initializers). If None, the default initializer ( 'glorot_uniform') will be used.
bias_initializer
Initializer for the bias vector ( see keras.initializers). If None, the default initializer ( 'zeros') will bs used.
depthwise_regularizer
Regularizer function applied to the depthwise kernel matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its 'activation') ( see keras.regularizers).
depthwise_constraint
Constraint function applied to the depthwise kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 4D tensor with shape: [batch_size, channels, rows, cols] if data_format='channels_first' or 4D tensor with shape: [batch_size, rows, cols, channels] if data_format='channels_last'.

Output shape: 4D tensor with shape: [batch_size, channels * depth_multiplier, new_rows, new_cols] if data_format='channels_first' or 4D tensor with shape: [batch_size, new_rows, new_cols, channels * depth_multiplier] if data_format='channels_last'. rows and cols values might have changed due to padding.

Returns

A tensor of rank 4 representing activation(depthwiseconv2d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class DepthwiseConv2D(Conv2D):
  """Depthwise 2D convolution.

  Depthwise convolution is a type of convolution in which a single convolutional
  filter is apply to each input channel (i.e. in a depthwise way).
  You can understand depthwise convolution as being
  the first step in a depthwise separable convolution.

  It is implemented via the following steps:

  - Split the input into individual channels.
  - Convolve each input with the layer's kernel (called a depthwise kernel).
  - Stack the convolved outputs together (along the channels axis).

  Unlike a regular 2D convolution, depthwise convolution does not mix
  information across different input channels.

  The `depth_multiplier` argument controls how many
  output channels are generated per input channel in the depthwise step.

  Args:
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `'valid'` or `'same'` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    depth_multiplier: The number of depthwise convolution output channels
      for each input channel.
      The total number of depthwise convolution output
      channels will be equal to `filters_in * depth_multiplier`.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be 'channels_last'.
    dilation_rate: An integer or tuple/list of 2 integers, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any `strides` value != 1.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    depthwise_initializer: Initializer for the depthwise kernel matrix (
      see `keras.initializers`). If None, the default initializer (
      'glorot_uniform') will be used.
    bias_initializer: Initializer for the bias vector (
      see `keras.initializers`). If None, the default initializer (
      'zeros') will bs used.
    depthwise_regularizer: Regularizer function applied to
      the depthwise kernel matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its 'activation') (
      see `keras.regularizers`).
    depthwise_constraint: Constraint function applied to
      the depthwise kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    4D tensor with shape:
    `[batch_size, channels, rows, cols]` if data_format='channels_first'
    or 4D tensor with shape:
    `[batch_size, rows, cols, channels]` if data_format='channels_last'.

  Output shape:
    4D tensor with shape:
    `[batch_size, channels * depth_multiplier, new_rows, new_cols]` if
    data_format='channels_first' or 4D tensor with shape:
    `[batch_size, new_rows, new_cols, channels * depth_multiplier]` if
    data_format='channels_last'. `rows` and `cols` values might have
    changed due to padding.

  Returns:
    A tensor of rank 4 representing
    `activation(depthwiseconv2d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
  """

  def __init__(self,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               depth_multiplier=1,
               data_format=None,
               dilation_rate=(1, 1),
               activation=None,
               use_bias=True,
               depthwise_initializer='glorot_uniform',
               bias_initializer='zeros',
               depthwise_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               depthwise_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(DepthwiseConv2D, self).__init__(
        filters=None,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        activation=activation,
        use_bias=use_bias,
        bias_regularizer=bias_regularizer,
        activity_regularizer=activity_regularizer,
        bias_constraint=bias_constraint,
        **kwargs)
    self.depth_multiplier = depth_multiplier
    self.depthwise_initializer = initializers.get(depthwise_initializer)
    self.depthwise_regularizer = regularizers.get(depthwise_regularizer)
    self.depthwise_constraint = constraints.get(depthwise_constraint)
    self.bias_initializer = initializers.get(bias_initializer)

  def build(self, input_shape):
    if len(input_shape) < 4:
      raise ValueError('Inputs to `DepthwiseConv2D` should have rank 4. '
                       'Received input shape:', str(input_shape))
    input_shape = tf.TensorShape(input_shape)
    channel_axis = self._get_channel_axis()
    if input_shape.dims[channel_axis].value is None:
      raise ValueError('The channel dimension of the inputs to '
                       '`DepthwiseConv2D` '
                       'should be defined. Found `None`.')
    input_dim = int(input_shape[channel_axis])
    depthwise_kernel_shape = (self.kernel_size[0],
                              self.kernel_size[1],
                              input_dim,
                              self.depth_multiplier)

    self.depthwise_kernel = self.add_weight(
        shape=depthwise_kernel_shape,
        initializer=self.depthwise_initializer,
        name='depthwise_kernel',
        regularizer=self.depthwise_regularizer,
        constraint=self.depthwise_constraint)

    if self.use_bias:
      self.bias = self.add_weight(shape=(input_dim * self.depth_multiplier,),
                                  initializer=self.bias_initializer,
                                  name='bias',
                                  regularizer=self.bias_regularizer,
                                  constraint=self.bias_constraint)
    else:
      self.bias = None
    # Set input spec.
    self.input_spec = InputSpec(ndim=4, axes={channel_axis: input_dim})
    self.built = True

  def call(self, inputs):
    outputs = backend.depthwise_conv2d(
        inputs,
        self.depthwise_kernel,
        strides=self.strides,
        padding=self.padding,
        dilation_rate=self.dilation_rate,
        data_format=self.data_format)

    if self.use_bias:
      outputs = backend.bias_add(
          outputs,
          self.bias,
          data_format=self.data_format)

    if self.activation is not None:
      return self.activation(outputs)

    return outputs

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if self.data_format == 'channels_first':
      rows = input_shape[2]
      cols = input_shape[3]
      out_filters = input_shape[1] * self.depth_multiplier
    elif self.data_format == 'channels_last':
      rows = input_shape[1]
      cols = input_shape[2]
      out_filters = input_shape[3] * self.depth_multiplier

    rows = conv_utils.conv_output_length(rows, self.kernel_size[0],
                                         self.padding,
                                         self.strides[0],
                                         self.dilation_rate[0])
    cols = conv_utils.conv_output_length(cols, self.kernel_size[1],
                                         self.padding,
                                         self.strides[1],
                                         self.dilation_rate[1])
    if self.data_format == 'channels_first':
      return (input_shape[0], out_filters, rows, cols)
    elif self.data_format == 'channels_last':
      return (input_shape[0], rows, cols, out_filters)

  def get_config(self):
    config = super(DepthwiseConv2D, self).get_config()
    config.pop('filters')
    config.pop('kernel_initializer')
    config.pop('kernel_regularizer')
    config.pop('kernel_constraint')
    config['depth_multiplier'] = self.depth_multiplier
    config['depthwise_initializer'] = initializers.serialize(
        self.depthwise_initializer)
    config['depthwise_regularizer'] = regularizers.serialize(
        self.depthwise_regularizer)
    config['depthwise_constraint'] = constraints.serialize(
        self.depthwise_constraint)
    return config

Ancestors

  • Conv2D
  • Conv
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Discretization (bin_boundaries=None, num_bins=None, epsilon=0.01, **kwargs)

Buckets data into discrete ranges.

This layer will place each element of its input data into one of several contiguous ranges and output an integer index indicating which range each element was placed in.

Input shape: Any tf.Tensor or tf.RaggedTensor of dimension 2 or higher.

Output shape: Same as input shape.

Attributes

bin_boundaries
A list of bin boundaries. The leftmost and rightmost bins will always extend to -inf and inf, so bin_boundaries=[0., 1., 2.] generates bins (-inf, 0.), [0., 1.), [1., 2.), and [2., +inf). If this option is set, adapt should not be called.
num_bins
The integer number of bins to compute. If this option is set, adapt should be called to learn the bin boundaries.
epsilon
Error tolerance, typically a small fraction close to zero (e.g. 0.01). Higher values of epsilon increase the quantile approximation, and hence result in more unequal buckets, but could improve performance and resource consumption.

Examples:

Bucketize float values based on provided buckets.

>>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
>>> layer = tf.keras.layers.Discretization(bin_boundaries=[0., 1., 2.])
>>> layer(input)
<tf.Tensor: shape=(2, 4), dtype=int64, numpy=
array([[0, 2, 3, 1],
       [1, 3, 2, 1]], dtype=int64)>

Bucketize float values based on a number of buckets to compute.

>>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
>>> layer = tf.keras.layers.Discretization(num_bins=4, epsilon=0.01)
>>> layer.adapt(input)
>>> layer(input)
<tf.Tensor: shape=(2, 4), dtype=int64, numpy=
array([[0, 2, 3, 2],
       [1, 3, 3, 1]], dtype=int64)>
Expand source code
class Discretization(base_preprocessing_layer.PreprocessingLayer):
  """Buckets data into discrete ranges.

  This layer will place each element of its input data into one of several
  contiguous ranges and output an integer index indicating which range each
  element was placed in.

  Input shape:
    Any `tf.Tensor` or `tf.RaggedTensor` of dimension 2 or higher.

  Output shape:
    Same as input shape.

  Attributes:
    bin_boundaries: A list of bin boundaries. The leftmost and rightmost bins
      will always extend to `-inf` and `inf`, so `bin_boundaries=[0., 1., 2.]`
      generates bins `(-inf, 0.)`, `[0., 1.)`, `[1., 2.)`, and `[2., +inf)`. If
      this option is set, `adapt` should not be called.
    num_bins: The integer number of bins to compute. If this option is set,
      `adapt` should be called to learn the bin boundaries.
    epsilon: Error tolerance, typically a small fraction close to zero (e.g.
      0.01). Higher values of epsilon increase the quantile approximation, and
      hence result in more unequal buckets, but could improve performance
      and resource consumption.

  Examples:

  Bucketize float values based on provided buckets.
  >>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
  >>> layer = tf.keras.layers.Discretization(bin_boundaries=[0., 1., 2.])
  >>> layer(input)
  <tf.Tensor: shape=(2, 4), dtype=int64, numpy=
  array([[0, 2, 3, 1],
         [1, 3, 2, 1]], dtype=int64)>

  Bucketize float values based on a number of buckets to compute.
  >>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
  >>> layer = tf.keras.layers.Discretization(num_bins=4, epsilon=0.01)
  >>> layer.adapt(input)
  >>> layer(input)
  <tf.Tensor: shape=(2, 4), dtype=int64, numpy=
  array([[0, 2, 3, 2],
         [1, 3, 3, 1]], dtype=int64)>
  """

  def __init__(self,
               bin_boundaries=None,
               num_bins=None,
               epsilon=0.01,
               **kwargs):
    # bins is a deprecated arg for setting bin_boundaries or num_bins that still
    # has some usage.
    if "bins" in kwargs:
      logging.warning(
          "bins is deprecated, please use bin_boundaries or num_bins instead.")
      if isinstance(kwargs["bins"], int) and num_bins is None:
        num_bins = kwargs["bins"]
      elif bin_boundaries is None:
        bin_boundaries = kwargs["bins"]
      del kwargs["bins"]
    super().__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell("Discretization").set(
        True)
    if num_bins is not None and num_bins < 0:
      raise ValueError("`num_bins` must be must be greater than or equal to 0. "
                       "You passed `num_bins={}`".format(num_bins))
    if num_bins is not None and bin_boundaries is not None:
      raise ValueError("Both `num_bins` and `bin_boundaries` should not be "
                       "set. You passed `num_bins={}` and "
                       "`bin_boundaries={}`".format(num_bins, bin_boundaries))
    bin_boundaries = self._convert_to_list(bin_boundaries)
    self.input_bin_boundaries = bin_boundaries
    self.bin_boundaries = bin_boundaries if bin_boundaries is not None else []
    self.num_bins = num_bins
    self.epsilon = epsilon

  def build(self, input_shape):
    super().build(input_shape)

    if self.input_bin_boundaries is not None:
      return

    # Summary contains two equal length vectors of bins at index 0 and weights
    # at index 1.
    self.summary = self.add_weight(
        name="summary",
        shape=(2, None),
        dtype=tf.float32,
        initializer=lambda shape, dtype: [[], []],  # pylint: disable=unused-arguments
        trainable=False)

  def update_state(self, data):
    if self.input_bin_boundaries is not None:
      raise ValueError(
          "Cannot adapt a Discretization layer that has been initialized with "
          "`bin_boundaries`, use `num_bins` instead. You passed "
          "`bin_boundaries={}`.".format(self.input_bin_boundaries))

    if not self.built:
      raise RuntimeError("`build` must be called before `update_state`.")

    data = tf.convert_to_tensor(data)
    if data.dtype != tf.float32:
      data = tf.cast(data, tf.float32)
    summary = summarize(data, self.epsilon)
    self.summary.assign(merge_summaries(summary, self.summary, self.epsilon))

  def finalize_state(self):
    if self.input_bin_boundaries is not None or not self.built:
      return

    # The bucketize op only support list boundaries.
    self.bin_boundaries = self._convert_to_list(
        get_bin_boundaries(self.summary, self.num_bins))

  def reset_state(self):  # pylint: disable=method-hidden
    if self.input_bin_boundaries is not None or not self.built:
      return

    self.summary.assign([[], []])

  def get_config(self):
    config = super().get_config()
    config.update({
        "bin_boundaries": self.input_bin_boundaries,
        "num_bins": self.num_bins,
        "epsilon": self.epsilon,
    })
    return config

  def compute_output_shape(self, input_shape):
    return input_shape

  def compute_output_signature(self, input_spec):
    output_shape = self.compute_output_shape(input_spec.shape.as_list())
    output_dtype = tf.int64
    if isinstance(input_spec, tf.SparseTensorSpec):
      return tf.SparseTensorSpec(
          shape=output_shape, dtype=output_dtype)
    return tf.TensorSpec(shape=output_shape, dtype=output_dtype)

  def call(self, inputs):
    def bucketize(inputs):
      outputs = tf.raw_ops.Bucketize(
          input=inputs, boundaries=self.bin_boundaries)
      # All other preprocessing layers use int64 for int output, so we conform
      # here. Sadly the underlying op only supports int32, so we need to cast.
      return tf.cast(outputs, tf.int64)

    if tf_utils.is_ragged(inputs):
      integer_buckets = tf.ragged.map_flat_values(bucketize, inputs)
      # Ragged map_flat_values doesn't touch the non-values tensors in the
      # ragged composite tensor. If this op is the only op a Keras model,
      # this can cause errors in Graph mode, so wrap the tensor in an identity.
      return tf.identity(integer_buckets)
    elif tf_utils.is_sparse(inputs):
      return tf.SparseTensor(
          indices=tf.identity(inputs.indices),
          values=bucketize(inputs.values),
          dense_shape=tf.identity(inputs.dense_shape))
    else:
      return bucketize(inputs)

  def _convert_to_list(self, inputs):
    if tf.is_tensor(inputs):
      inputs = inputs.numpy()
    if isinstance(inputs, (np.ndarray)):
      inputs = inputs.tolist()
      inputs = list(inputs)
    return inputs

Ancestors

Inherited members

class Dot (axes, normalize=False, **kwargs)

Layer that computes a dot product between samples in two tensors.

E.g. if applied to a list of two tensors a and b of shape (batch_size, n), the output will be a tensor of shape (batch_size, 1) where each entry i will be the dot product between a[i] and b[i].

>>> x = np.arange(10).reshape(1, 5, 2)
>>> print(x)
[[[0 1]
  [2 3]
  [4 5]
  [6 7]
  [8 9]]]
>>> y = np.arange(10, 20).reshape(1, 2, 5)
>>> print(y)
[[[10 11 12 13 14]
  [15 16 17 18 19]]]
>>> tf.keras.layers.Dot(axes=(1, 2))([x, y])
<tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
array([[[260, 360],
        [320, 445]]])>
>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> dotted = tf.keras.layers.Dot(axes=1)([x1, x2])
>>> dotted.shape
TensorShape([5, 1])

Initializes a layer that computes the element-wise dot product.

x = np.arange(10).reshape(1, 5, 2) print(x) [[[0 1] [2 3] [4 5] [6 7] [8 9]]] y = np.arange(10, 20).reshape(1, 2, 5) print(y) [[[10 11 12 13 14] [15 16 17 18 19]]] tf.keras.layers.Dot(axes=(1, 2))([x, y])

Args

axes
Integer or tuple of integers, axis or axes along which to take the dot product. If a tuple, should be two integers corresponding to the desired axis from the first input and the desired axis from the second input, respectively. Note that the size of the two selected axes must match.
normalize
Whether to L2-normalize samples along the dot product axis before taking the dot product. If set to True, then the output of the dot product is the cosine proximity between the two samples.
**kwargs
Standard layer keyword arguments.
Expand source code
class Dot(_Merge):
  """Layer that computes a dot product between samples in two tensors.

  E.g. if applied to a list of two tensors `a` and `b` of shape
  `(batch_size, n)`, the output will be a tensor of shape `(batch_size, 1)`
  where each entry `i` will be the dot product between
  `a[i]` and `b[i]`.

  >>> x = np.arange(10).reshape(1, 5, 2)
  >>> print(x)
  [[[0 1]
    [2 3]
    [4 5]
    [6 7]
    [8 9]]]
  >>> y = np.arange(10, 20).reshape(1, 2, 5)
  >>> print(y)
  [[[10 11 12 13 14]
    [15 16 17 18 19]]]
  >>> tf.keras.layers.Dot(axes=(1, 2))([x, y])
  <tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
  array([[[260, 360],
          [320, 445]]])>

  >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
  >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
  >>> dotted = tf.keras.layers.Dot(axes=1)([x1, x2])
  >>> dotted.shape
  TensorShape([5, 1])


  """

  def __init__(self, axes, normalize=False, **kwargs):
    """Initializes a layer that computes the element-wise dot product.

      >>> x = np.arange(10).reshape(1, 5, 2)
      >>> print(x)
      [[[0 1]
        [2 3]
        [4 5]
        [6 7]
        [8 9]]]
      >>> y = np.arange(10, 20).reshape(1, 2, 5)
      >>> print(y)
      [[[10 11 12 13 14]
        [15 16 17 18 19]]]
      >>> tf.keras.layers.Dot(axes=(1, 2))([x, y])
      <tf.Tensor: shape=(1, 2, 2), dtype=int64, numpy=
      array([[[260, 360],
              [320, 445]]])>

    Args:
      axes: Integer or tuple of integers,
        axis or axes along which to take the dot product. If a tuple, should
        be two integers corresponding to the desired axis from the first input
        and the desired axis from the second input, respectively. Note that the
        size of the two selected axes must match.
      normalize: Whether to L2-normalize samples along the
        dot product axis before taking the dot product.
        If set to True, then the output of the dot product
        is the cosine proximity between the two samples.
      **kwargs: Standard layer keyword arguments.
    """
    super(Dot, self).__init__(**kwargs)
    if not isinstance(axes, int):
      if not isinstance(axes, (list, tuple)):
        raise TypeError('Invalid type for `axes` - '
                        'should be a list or an int.')
      if len(axes) != 2:
        raise ValueError('Invalid format for `axes` - '
                         'should contain two elements.')
      if not isinstance(axes[0], int) or not isinstance(axes[1], int):
        raise ValueError('Invalid format for `axes` - '
                         'list elements should be "int".')
    self.axes = axes
    self.normalize = normalize
    self.supports_masking = True
    self._reshape_required = False

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    # Used purely for shape validation.
    if not isinstance(input_shape[0], tuple) or len(input_shape) != 2:
      raise ValueError('A `Dot` layer should be called '
                       'on a list of 2 inputs.')
    shape1 = input_shape[0]
    shape2 = input_shape[1]
    if shape1 is None or shape2 is None:
      return
    if isinstance(self.axes, int):
      if self.axes < 0:
        axes = [self.axes % len(shape1), self.axes % len(shape2)]
      else:
        axes = [self.axes] * 2
    else:
      axes = self.axes
    if shape1[axes[0]] != shape2[axes[1]]:
      raise ValueError('Dimension incompatibility '
                       '%s != %s. ' % (shape1[axes[0]], shape2[axes[1]]) +
                       'Layer shapes: %s, %s. ' % (shape1, shape2) +
                       'Chosen axes: %s, %s' % (axes[0], axes[1]))

  def _merge_function(self, inputs):
    base_layer_utils.no_ragged_support(inputs, self.name)
    if len(inputs) != 2:
      raise ValueError('A `Dot` layer should be called on exactly 2 inputs')
    x1 = inputs[0]
    x2 = inputs[1]
    if isinstance(self.axes, int):
      if self.axes < 0:
        axes = [self.axes % backend.ndim(x1), self.axes % backend.ndim(x2)]
      else:
        axes = [self.axes] * 2
    else:
      axes = []
      for i in range(len(self.axes)):
        if self.axes[i] < 0:
          axes.append(self.axes[i] % backend.ndim(inputs[i]))
        else:
          axes.append(self.axes[i])
    if self.normalize:
      x1 = tf.linalg.l2_normalize(x1, axis=axes[0])
      x2 = tf.linalg.l2_normalize(x2, axis=axes[1])
    output = backend.batch_dot(x1, x2, axes)
    return output

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if not isinstance(input_shape, (tuple, list)) or len(input_shape) != 2:
      raise ValueError('A `Dot` layer should be called '
                       'on a list of 2 inputs.')
    shape1 = list(input_shape[0])
    shape2 = list(input_shape[1])
    if isinstance(self.axes, int):
      if self.axes < 0:
        axes = [self.axes % len(shape1), self.axes % len(shape2)]
      else:
        axes = [self.axes] * 2
    else:
      axes = self.axes
    shape1.pop(axes[0])
    shape2.pop(axes[1])
    shape2.pop(0)
    output_shape = shape1 + shape2
    if len(output_shape) == 1:
      output_shape += [1]
    return tuple(output_shape)

  def compute_mask(self, inputs, mask=None):
    return None

  def get_config(self):
    config = {
        'axes': self.axes,
        'normalize': self.normalize,
    }
    base_config = super(Dot, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Dropout (rate, noise_shape=None, seed=None, **kwargs)

Applies Dropout to the input.

The Dropout layer randomly sets input units to 0 with a frequency of rate at each step during training time, which helps prevent overfitting. Inputs not set to 0 are scaled up by 1/(1 - rate) such that the sum over all inputs is unchanged.

Note that the Dropout layer only applies when training is set to True such that no values are dropped during inference. When using model.fit, training will be appropriately set to True automatically, and in other contexts, you can set the kwarg explicitly to True when calling the layer.

(This is in contrast to setting trainable=False for a Dropout layer. trainable does not affect the layer's behavior, as Dropout does not have any variables/weights that can be frozen during training.)

>>> tf.random.set_seed(0)
>>> layer = tf.keras.layers.Dropout(.2, input_shape=(2,))
>>> data = np.arange(10).reshape(5, 2).astype(np.float32)
>>> print(data)
[[0. 1.]
 [2. 3.]
 [4. 5.]
 [6. 7.]
 [8. 9.]]
>>> outputs = layer(data, training=True)
>>> print(outputs)
tf.Tensor(
[[ 0.    1.25]
 [ 2.5   3.75]
 [ 5.    6.25]
 [ 7.5   8.75]
 [10.    0.  ]], shape=(5, 2), dtype=float32)

Args

rate
Float between 0 and 1. Fraction of the input units to drop.
noise_shape
1D integer tensor representing the shape of the binary dropout mask that will be multiplied with the input. For instance, if your inputs have shape (batch_size, timesteps, features) and you want the dropout mask to be the same for all timesteps, you can use noise_shape=(batch_size, 1, features).
seed
A Python integer to use as random seed.

Call arguments: inputs: Input tensor (of any rank). training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Expand source code
class Dropout(Layer):
  """Applies Dropout to the input.

  The Dropout layer randomly sets input units to 0 with a frequency of `rate`
  at each step during training time, which helps prevent overfitting.
  Inputs not set to 0 are scaled up by 1/(1 - rate) such that the sum over
  all inputs is unchanged.

  Note that the Dropout layer only applies when `training` is set to True
  such that no values are dropped during inference. When using `model.fit`,
  `training` will be appropriately set to True automatically, and in other
  contexts, you can set the kwarg explicitly to True when calling the layer.

  (This is in contrast to setting `trainable=False` for a Dropout layer.
  `trainable` does not affect the layer's behavior, as Dropout does
  not have any variables/weights that can be frozen during training.)

  >>> tf.random.set_seed(0)
  >>> layer = tf.keras.layers.Dropout(.2, input_shape=(2,))
  >>> data = np.arange(10).reshape(5, 2).astype(np.float32)
  >>> print(data)
  [[0. 1.]
   [2. 3.]
   [4. 5.]
   [6. 7.]
   [8. 9.]]
  >>> outputs = layer(data, training=True)
  >>> print(outputs)
  tf.Tensor(
  [[ 0.    1.25]
   [ 2.5   3.75]
   [ 5.    6.25]
   [ 7.5   8.75]
   [10.    0.  ]], shape=(5, 2), dtype=float32)

  Args:
    rate: Float between 0 and 1. Fraction of the input units to drop.
    noise_shape: 1D integer tensor representing the shape of the
      binary dropout mask that will be multiplied with the input.
      For instance, if your inputs have shape
      `(batch_size, timesteps, features)` and
      you want the dropout mask to be the same for all timesteps,
      you can use `noise_shape=(batch_size, 1, features)`.
    seed: A Python integer to use as random seed.

  Call arguments:
    inputs: Input tensor (of any rank).
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).
  """

  def __init__(self, rate, noise_shape=None, seed=None, **kwargs):
    super(Dropout, self).__init__(**kwargs)
    if isinstance(rate, (int, float)) and not 0 <= rate <= 1:
      raise ValueError(f'Invalid value {rate} received for '
                       f'`rate`, expected a value between 0 and 1.')
    self.rate = rate
    if isinstance(rate, (int, float)) and not rate:
      keras_temporary_dropout_rate.get_cell().set(True)
    else:
      keras_temporary_dropout_rate.get_cell().set(False)
    self.noise_shape = noise_shape
    self.seed = seed
    self.supports_masking = True

  def _get_noise_shape(self, inputs):
    # Subclasses of `Dropout` may implement `_get_noise_shape(self, inputs)`,
    # which will override `self.noise_shape`, and allows for custom noise
    # shapes with dynamically sized inputs.
    if self.noise_shape is None:
      return None

    concrete_inputs_shape = tf.shape(inputs)
    noise_shape = []
    for i, value in enumerate(self.noise_shape):
      noise_shape.append(concrete_inputs_shape[i] if value is None else value)
    return tf.convert_to_tensor(noise_shape)

  def call(self, inputs, training=None):
    if training is None:
      training = K.learning_phase()

    def dropped_inputs():
      return tf.nn.dropout(
          inputs,
          noise_shape=self._get_noise_shape(inputs),
          seed=self.seed,
          rate=self.rate)

    output = control_flow_util.smart_cond(training, dropped_inputs,
                                          lambda: tf.identity(inputs))
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'rate': self.rate,
        'noise_shape': self.noise_shape,
        'seed': self.seed
    }
    base_config = super(Dropout, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class ELU (alpha=1.0, **kwargs)

Exponential Linear Unit.

It follows:

  f(x) =  alpha * (exp(x) - 1.) for x < 0
  f(x) = x for x >= 0

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

alpha
Scale for the negative factor.
Expand source code
class ELU(Layer):
  """Exponential Linear Unit.

  It follows:

  ```
    f(x) =  alpha * (exp(x) - 1.) for x < 0
    f(x) = x for x >= 0
  ```

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    alpha: Scale for the negative factor.
  """

  def __init__(self, alpha=1.0, **kwargs):
    super(ELU, self).__init__(**kwargs)
    if alpha is None:
      raise ValueError('Alpha of an ELU layer cannot be None, '
                       'requires a float. Got %s' % alpha)
    self.supports_masking = True
    self.alpha = backend.cast_to_floatx(alpha)

  def call(self, inputs):
    return backend.elu(inputs, self.alpha)

  def get_config(self):
    config = {'alpha': float(self.alpha)}
    base_config = super(ELU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Embedding (input_dim, output_dim, embeddings_initializer='uniform', embeddings_regularizer=None, activity_regularizer=None, embeddings_constraint=None, mask_zero=False, input_length=None, **kwargs)

Turns positive integers (indexes) into dense vectors of fixed size.

e.g. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]

This layer can only be used as the first layer in a model.

Example:

>>> model = tf.keras.Sequential()
>>> model.add(tf.keras.layers.Embedding(1000, 64, input_length=10))
>>> # The model will take as input an integer matrix of size (batch,
>>> # input_length), and the largest integer (i.e. word index) in the input
>>> # should be no larger than 999 (vocabulary size).
>>> # Now model.output_shape is (None, 10, 64), where <code>None</code> is the batch
>>> # dimension.
>>> input_array = np.random.randint(1000, size=(32, 10))
>>> model.compile('rmsprop', 'mse')
>>> output_array = model.predict(input_array)
>>> print(output_array.shape)
(32, 10, 64)

Args

input_dim
Integer. Size of the vocabulary, i.e. maximum integer index + 1.
output_dim
Integer. Dimension of the dense embedding.
embeddings_initializer
Initializer for the embeddings matrix (see keras.initializers).
embeddings_regularizer
Regularizer function applied to the embeddings matrix (see keras.regularizers).
embeddings_constraint
Constraint function applied to the embeddings matrix (see keras.constraints).
mask_zero
Boolean, whether or not the input value 0 is a special "padding" value that should be masked out. This is useful when using recurrent layers which may take variable length input. If this is True, then all subsequent layers in the model need to support masking or an exception will be raised. If mask_zero is set to True, as a consequence, index 0 cannot be used in the vocabulary (input_dim should equal size of vocabulary + 1).
input_length
Length of input sequences, when it is constant. This argument is required if you are going to connect Flatten then Dense layers upstream (without it, the shape of the dense outputs cannot be computed).

Input shape: 2D tensor with shape: (batch_size, input_length).

Output shape: 3D tensor with shape: (batch_size, input_length, output_dim).

Note on variable placement: By default, if a GPU is available, the embedding matrix will be placed on the GPU. This achieves the best performance, but it might cause issues:

  • You may be using an optimizer that does not support sparse GPU kernels. In this case you will see an error upon training your model.
  • Your embedding matrix may be too large to fit on your GPU. In this case you will see an Out Of Memory (OOM) error.

In such cases, you should place the embedding matrix on the CPU memory. You can do so with a device scope, as such:

with tf.device('cpu:0'):
  embedding_layer = Embedding(...)
  embedding_layer.build()

The pre-built embedding_layer instance can then be added to a Sequential model (e.g. model.add(embedding_layer)), called in a Functional model (e.g. x = embedding_layer(x)), or used in a subclassed model.

Expand source code
class Embedding(Layer):
  """Turns positive integers (indexes) into dense vectors of fixed size.

  e.g. `[[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]`

  This layer can only be used as the first layer in a model.

  Example:

  >>> model = tf.keras.Sequential()
  >>> model.add(tf.keras.layers.Embedding(1000, 64, input_length=10))
  >>> # The model will take as input an integer matrix of size (batch,
  >>> # input_length), and the largest integer (i.e. word index) in the input
  >>> # should be no larger than 999 (vocabulary size).
  >>> # Now model.output_shape is (None, 10, 64), where `None` is the batch
  >>> # dimension.
  >>> input_array = np.random.randint(1000, size=(32, 10))
  >>> model.compile('rmsprop', 'mse')
  >>> output_array = model.predict(input_array)
  >>> print(output_array.shape)
  (32, 10, 64)

  Args:
    input_dim: Integer. Size of the vocabulary,
      i.e. maximum integer index + 1.
    output_dim: Integer. Dimension of the dense embedding.
    embeddings_initializer: Initializer for the `embeddings`
      matrix (see `keras.initializers`).
    embeddings_regularizer: Regularizer function applied to
      the `embeddings` matrix (see `keras.regularizers`).
    embeddings_constraint: Constraint function applied to
      the `embeddings` matrix (see `keras.constraints`).
    mask_zero: Boolean, whether or not the input value 0 is a special "padding"
      value that should be masked out.
      This is useful when using recurrent layers
      which may take variable length input.
      If this is `True`, then all subsequent layers
      in the model need to support masking or an exception will be raised.
      If mask_zero is set to True, as a consequence, index 0 cannot be
      used in the vocabulary (input_dim should equal size of
      vocabulary + 1).
    input_length: Length of input sequences, when it is constant.
      This argument is required if you are going to connect
      `Flatten` then `Dense` layers upstream
      (without it, the shape of the dense outputs cannot be computed).

  Input shape:
    2D tensor with shape: `(batch_size, input_length)`.

  Output shape:
    3D tensor with shape: `(batch_size, input_length, output_dim)`.

  **Note on variable placement:**
  By default, if a GPU is available, the embedding matrix will be placed on
  the GPU. This achieves the best performance, but it might cause issues:

  - You may be using an optimizer that does not support sparse GPU kernels.
  In this case you will see an error upon training your model.
  - Your embedding matrix may be too large to fit on your GPU. In this case
  you will see an Out Of Memory (OOM) error.

  In such cases, you should place the embedding matrix on the CPU memory.
  You can do so with a device scope, as such:

  ```python
  with tf.device('cpu:0'):
    embedding_layer = Embedding(...)
    embedding_layer.build()
  ```

  The pre-built `embedding_layer` instance can then be added to a `Sequential`
  model (e.g. `model.add(embedding_layer)`), called in a Functional model
  (e.g. `x = embedding_layer(x)`), or used in a subclassed model.
  """

  def __init__(self,
               input_dim,
               output_dim,
               embeddings_initializer='uniform',
               embeddings_regularizer=None,
               activity_regularizer=None,
               embeddings_constraint=None,
               mask_zero=False,
               input_length=None,
               **kwargs):
    if 'input_shape' not in kwargs:
      if input_length:
        kwargs['input_shape'] = (input_length,)
      else:
        kwargs['input_shape'] = (None,)
    if input_dim <= 0 or output_dim <= 0:
      raise ValueError('Both `input_dim` and `output_dim` should be positive, '
                       'found input_dim {} and output_dim {}'.format(
                           input_dim, output_dim))
    if (not base_layer_utils.v2_dtype_behavior_enabled() and
        'dtype' not in kwargs):
      # In TF1, the dtype defaults to the input dtype which is typically int32,
      # so explicitly set it to floatx
      kwargs['dtype'] = backend.floatx()
    # We set autocast to False, as we do not want to cast floating- point inputs
    # to self.dtype. In call(), we cast to int32, and casting to self.dtype
    # before casting to int32 might cause the int32 values to be different due
    # to a loss of precision.
    kwargs['autocast'] = False
    super(Embedding, self).__init__(**kwargs)

    self.input_dim = input_dim
    self.output_dim = output_dim
    self.embeddings_initializer = initializers.get(embeddings_initializer)
    self.embeddings_regularizer = regularizers.get(embeddings_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.embeddings_constraint = constraints.get(embeddings_constraint)
    self.mask_zero = mask_zero
    self.supports_masking = mask_zero
    self.input_length = input_length

  @tf_utils.shape_type_conversion
  def build(self, input_shape=None):
    self.embeddings = self.add_weight(
        shape=(self.input_dim, self.output_dim),
        initializer=self.embeddings_initializer,
        name='embeddings',
        regularizer=self.embeddings_regularizer,
        constraint=self.embeddings_constraint,
        experimental_autocast=False)
    self.built = True

  def compute_mask(self, inputs, mask=None):
    if not self.mask_zero:
      return None
    return tf.not_equal(inputs, 0)

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if self.input_length is None:
      return input_shape + (self.output_dim,)
    else:
      # input_length can be tuple if input is 3D or higher
      if isinstance(self.input_length, (list, tuple)):
        in_lens = list(self.input_length)
      else:
        in_lens = [self.input_length]
      if len(in_lens) != len(input_shape) - 1:
        raise ValueError('"input_length" is %s, '
                         'but received input has shape %s' % (str(
                             self.input_length), str(input_shape)))
      else:
        for i, (s1, s2) in enumerate(zip(in_lens, input_shape[1:])):
          if s1 is not None and s2 is not None and s1 != s2:
            raise ValueError('"input_length" is %s, '
                             'but received input has shape %s' % (str(
                                 self.input_length), str(input_shape)))
          elif s1 is None:
            in_lens[i] = s2
      return (input_shape[0],) + tuple(in_lens) + (self.output_dim,)

  def call(self, inputs):
    dtype = backend.dtype(inputs)
    if dtype != 'int32' and dtype != 'int64':
      inputs = tf.cast(inputs, 'int32')
    out = tf.nn.embedding_lookup(self.embeddings, inputs)
    if self._dtype_policy.compute_dtype != self._dtype_policy.variable_dtype:
      # Instead of casting the variable as in most layers, cast the output, as
      # this is mathematically equivalent but is faster.
      out = tf.cast(out, self._dtype_policy.compute_dtype)
    return out

  def get_config(self):
    config = {
        'input_dim': self.input_dim,
        'output_dim': self.output_dim,
        'embeddings_initializer':
            initializers.serialize(self.embeddings_initializer),
        'embeddings_regularizer':
            regularizers.serialize(self.embeddings_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'embeddings_constraint':
            constraints.serialize(self.embeddings_constraint),
        'mask_zero': self.mask_zero,
        'input_length': self.input_length
    }
    base_config = super(Embedding, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Flatten (data_format=None, **kwargs)

Flattens the input. Does not affect the batch size.

Note: If inputs are shaped (batch,) without a feature axis, then flattening adds an extra channel dimension and output shape is (batch, 1).

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, …, channels) while channels_first corresponds to inputs with shape (batch, channels, …). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Example:

>>> model = tf.keras.Sequential()
>>> model.add(tf.keras.layers.Conv2D(64, 3, 3, input_shape=(3, 32, 32)))
>>> model.output_shape
(None, 1, 10, 64)
>>> model.add(Flatten())
>>> model.output_shape
(None, 640)
Expand source code
class Flatten(Layer):
  """Flattens the input. Does not affect the batch size.

  Note: If inputs are shaped `(batch,)` without a feature axis, then
  flattening adds an extra channel dimension and output shape is `(batch, 1)`.

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, ..., channels)` while `channels_first` corresponds to
      inputs with shape `(batch, channels, ...)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Example:

  >>> model = tf.keras.Sequential()
  >>> model.add(tf.keras.layers.Conv2D(64, 3, 3, input_shape=(3, 32, 32)))
  >>> model.output_shape
  (None, 1, 10, 64)

  >>> model.add(Flatten())
  >>> model.output_shape
  (None, 640)

  """

  def __init__(self, data_format=None, **kwargs):
    super(Flatten, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    self.input_spec = InputSpec(min_ndim=1)
    self._channels_first = self.data_format == 'channels_first'

  def call(self, inputs):
    if self._channels_first:
      rank = inputs.shape.rank
      if rank and rank > 1:
        # Switch to channels-last format.
        permutation = [0]
        permutation.extend(range(2, rank))
        permutation.append(1)
        inputs = tf.transpose(inputs, perm=permutation)

    if tf.executing_eagerly():
      # Full static shape is guaranteed to be available.
      # Performance: Using `constant_op` is much faster than passing a list.
      flattened_shape = tf.constant([inputs.shape[0], -1])
      return tf.reshape(inputs, flattened_shape)
    else:
      input_shape = inputs.shape
      rank = input_shape.rank
      if rank == 1:
        return tf.expand_dims(inputs, axis=1)
      else:
        batch_dim = tf.compat.dimension_value(input_shape[0])
        non_batch_dims = input_shape[1:]
        # Reshape in a way that preserves as much shape info as possible.
        if non_batch_dims.is_fully_defined():
          last_dim = int(functools.reduce(operator.mul, non_batch_dims))
          flattened_shape = tf.constant([-1, last_dim])
        elif batch_dim is not None:
          flattened_shape = tf.constant([int(batch_dim), -1])
        else:
          flattened_shape = [tf.shape(inputs)[0], -1]
        return tf.reshape(inputs, flattened_shape)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if not input_shape:
      output_shape = tf.TensorShape([1])
    else:
      output_shape = [input_shape[0]]
    if np.all(input_shape[1:]):
      output_shape += [np.prod(input_shape[1:], dtype=int)]
    else:
      output_shape += [None]
    return tf.TensorShape(output_shape)

  def get_config(self):
    config = super(Flatten, self).get_config()
    config.update({'data_format': self.data_format})
    return config

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class GRU (units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False, reset_after=False, **kwargs)

Gated Recurrent Unit - Cho et al. 2014.

There are two variants. The default one is based on 1406.1078v3 and has reset gate applied to hidden state before matrix multiplication. The other one is based on original 1406.1078v1 and has the order reversed.

The second variant is compatible with CuDNNGRU (GPU-only) and allows inference on CPU. Thus it has separate biases for kernel and recurrent_kernel. Use 'reset_after'=True and recurrent_activation='sigmoid'.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
recurrent_activation
Activation function to use for the recurrent step. Default: hard sigmoid (hard_sigmoid). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation")..
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence.
return_state
Boolean. Whether to return the last state in addition to the output.
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
unroll
Boolean (default False). If True, the network will be unrolled, else a symbolic loop will be used. Unrolling can speed-up a RNN, although it tends to be more memory-intensive. Unrolling is only suitable for short sequences.
time_major
The shape format of the inputs and outputs tensors. If True, the inputs and outputs will be in shape (timesteps, batch, …), whereas in the False case, it will be (batch, timesteps, …). Using time_major = True is a bit more efficient because it avoids transposes at the beginning and end of the RNN calculation. However, most TensorFlow data is batch-major, so by default this function accepts input and emits output in batch-major form.
reset_after
GRU convention (whether to apply reset gate after or before matrix multiplication). False = "before" (default), True = "after" (CuDNN compatible).

Call arguments: inputs: A 3D tensor. mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. An individual True entry indicates that the corresponding timestep should be utilized, while a False entry indicates that the corresponding timestep should be ignored. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout is used. initial_state: List of initial state tensors to be passed to the first call of the cell.

Expand source code
class GRU(RNN):
  """Gated Recurrent Unit - Cho et al. 2014.

  There are two variants. The default one is based on 1406.1078v3 and
  has reset gate applied to hidden state before matrix multiplication. The
  other one is based on original 1406.1078v1 and has the order reversed.

  The second variant is compatible with CuDNNGRU (GPU-only) and allows
  inference on CPU. Thus it has separate biases for `kernel` and
  `recurrent_kernel`. Use `'reset_after'=True` and
  `recurrent_activation='sigmoid'`.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    recurrent_activation: Activation function to use
      for the recurrent step.
      Default: hard sigmoid (`hard_sigmoid`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix, used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix.
    recurrent_regularizer: Regularizer function applied to
      the `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation")..
    kernel_constraint: Constraint function applied to
      the `kernel` weights matrix.
    recurrent_constraint: Constraint function applied to
      the `recurrent_kernel` weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the inputs.
    recurrent_dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the recurrent state.
    return_sequences: Boolean. Whether to return the last output
      in the output sequence, or the full sequence.
    return_state: Boolean. Whether to return the last state
      in addition to the output.
    go_backwards: Boolean (default False).
      If True, process the input sequence backwards and return the
      reversed sequence.
    stateful: Boolean (default False). If True, the last state
      for each sample at index i in a batch will be used as initial
      state for the sample of index i in the following batch.
    unroll: Boolean (default False).
      If True, the network will be unrolled,
      else a symbolic loop will be used.
      Unrolling can speed-up a RNN,
      although it tends to be more memory-intensive.
      Unrolling is only suitable for short sequences.
    time_major: The shape format of the `inputs` and `outputs` tensors.
      If True, the inputs and outputs will be in shape
      `(timesteps, batch, ...)`, whereas in the False case, it will be
      `(batch, timesteps, ...)`. Using `time_major = True` is a bit more
      efficient because it avoids transposes at the beginning and end of the
      RNN calculation. However, most TensorFlow data is batch-major, so by
      default this function accepts input and emits output in batch-major
      form.
    reset_after: GRU convention (whether to apply reset gate after or
      before matrix multiplication). False = "before" (default),
      True = "after" (CuDNN compatible).

  Call arguments:
    inputs: A 3D tensor.
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether
      a given timestep should be masked. An individual `True` entry indicates
      that the corresponding timestep should be utilized, while a `False`
      entry indicates that the corresponding timestep should be ignored.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or
      `recurrent_dropout` is used.
    initial_state: List of initial state tensors to be passed to the first
      call of the cell.
  """

  def __init__(self,
               units,
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               unroll=False,
               reset_after=False,
               **kwargs):
    implementation = kwargs.pop('implementation', 1)
    if implementation == 0:
      logging.warning('`implementation=0` has been deprecated, '
                      'and now defaults to `implementation=1`.'
                      'Please update your layer call.')
    if 'enable_caching_device' in kwargs:
      cell_kwargs = {'enable_caching_device':
                     kwargs.pop('enable_caching_device')}
    else:
      cell_kwargs = {}
    cell = GRUCell(
        units,
        activation=activation,
        recurrent_activation=recurrent_activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        bias_initializer=bias_initializer,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        implementation=implementation,
        reset_after=reset_after,
        dtype=kwargs.get('dtype'),
        trainable=kwargs.get('trainable', True),
        **cell_kwargs)
    super(GRU, self).__init__(
        cell,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        unroll=unroll,
        **kwargs)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.input_spec = [InputSpec(ndim=3)]

  def call(self, inputs, mask=None, training=None, initial_state=None):
    return super(GRU, self).call(
        inputs, mask=mask, training=training, initial_state=initial_state)

  @property
  def units(self):
    return self.cell.units

  @property
  def activation(self):
    return self.cell.activation

  @property
  def recurrent_activation(self):
    return self.cell.recurrent_activation

  @property
  def use_bias(self):
    return self.cell.use_bias

  @property
  def kernel_initializer(self):
    return self.cell.kernel_initializer

  @property
  def recurrent_initializer(self):
    return self.cell.recurrent_initializer

  @property
  def bias_initializer(self):
    return self.cell.bias_initializer

  @property
  def kernel_regularizer(self):
    return self.cell.kernel_regularizer

  @property
  def recurrent_regularizer(self):
    return self.cell.recurrent_regularizer

  @property
  def bias_regularizer(self):
    return self.cell.bias_regularizer

  @property
  def kernel_constraint(self):
    return self.cell.kernel_constraint

  @property
  def recurrent_constraint(self):
    return self.cell.recurrent_constraint

  @property
  def bias_constraint(self):
    return self.cell.bias_constraint

  @property
  def dropout(self):
    return self.cell.dropout

  @property
  def recurrent_dropout(self):
    return self.cell.recurrent_dropout

  @property
  def implementation(self):
    return self.cell.implementation

  @property
  def reset_after(self):
    return self.cell.reset_after

  def get_config(self):
    config = {
        'units':
            self.units,
        'activation':
            activations.serialize(self.activation),
        'recurrent_activation':
            activations.serialize(self.recurrent_activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'dropout':
            self.dropout,
        'recurrent_dropout':
            self.recurrent_dropout,
        'implementation':
            self.implementation,
        'reset_after':
            self.reset_after
    }
    config.update(_config_for_enable_caching_device(self.cell))
    base_config = super(GRU, self).get_config()
    del base_config['cell']
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config):
    if 'implementation' in config and config['implementation'] == 0:
      config['implementation'] = 1
    return cls(**config)

Ancestors

  • RNN
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Instance variables

var activation
Expand source code
@property
def activation(self):
  return self.cell.activation
var bias_constraint
Expand source code
@property
def bias_constraint(self):
  return self.cell.bias_constraint
var bias_initializer
Expand source code
@property
def bias_initializer(self):
  return self.cell.bias_initializer
var bias_regularizer
Expand source code
@property
def bias_regularizer(self):
  return self.cell.bias_regularizer
var dropout
Expand source code
@property
def dropout(self):
  return self.cell.dropout
var implementation
Expand source code
@property
def implementation(self):
  return self.cell.implementation
var kernel_constraint
Expand source code
@property
def kernel_constraint(self):
  return self.cell.kernel_constraint
var kernel_initializer
Expand source code
@property
def kernel_initializer(self):
  return self.cell.kernel_initializer
var kernel_regularizer
Expand source code
@property
def kernel_regularizer(self):
  return self.cell.kernel_regularizer
var recurrent_activation
Expand source code
@property
def recurrent_activation(self):
  return self.cell.recurrent_activation
var recurrent_constraint
Expand source code
@property
def recurrent_constraint(self):
  return self.cell.recurrent_constraint
var recurrent_dropout
Expand source code
@property
def recurrent_dropout(self):
  return self.cell.recurrent_dropout
var recurrent_initializer
Expand source code
@property
def recurrent_initializer(self):
  return self.cell.recurrent_initializer
var recurrent_regularizer
Expand source code
@property
def recurrent_regularizer(self):
  return self.cell.recurrent_regularizer
var reset_after
Expand source code
@property
def reset_after(self):
  return self.cell.reset_after
var units
Expand source code
@property
def units(self):
  return self.cell.units
var use_bias
Expand source code
@property
def use_bias(self):
  return self.cell.use_bias

Inherited members

class GRUCell (units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, reset_after=False, **kwargs)

Cell class for the GRU layer.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
recurrent_activation
Activation function to use for the recurrent step. Default: hard sigmoid (hard_sigmoid). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.
reset_after
GRU convention (whether to apply reset gate after or before matrix multiplication). False = "before" (default), True = "after" (CuDNN compatible).

Call arguments: inputs: A 2D tensor. states: List of state tensors corresponding to the previous timestep. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. Only relevant when dropout or recurrent_dropout is used.

Expand source code
class GRUCell(DropoutRNNCellMixin, Layer):
  """Cell class for the GRU layer.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass None, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    recurrent_activation: Activation function to use
      for the recurrent step.
      Default: hard sigmoid (`hard_sigmoid`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix,
      used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix.
    recurrent_regularizer: Regularizer function applied to
      the `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    kernel_constraint: Constraint function applied to
      the `kernel` weights matrix.
    recurrent_constraint: Constraint function applied to
      the `recurrent_kernel` weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    dropout: Float between 0 and 1.
      Fraction of the units to drop for the linear transformation of the inputs.
    recurrent_dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the recurrent state.
    reset_after: GRU convention (whether to apply reset gate after or
      before matrix multiplication). False = "before" (default),
      True = "after" (CuDNN compatible).

  Call arguments:
    inputs: A 2D tensor.
    states: List of state tensors corresponding to the previous timestep.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. Only relevant when `dropout` or
      `recurrent_dropout` is used.
  """

  def __init__(self,
               units,
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               reset_after=False,
               **kwargs):
    if units < 0:
      raise ValueError(f'Received an invalid value for units, expected '
                       f'a positive integer, got {units}.')
    # By default use cached variable under v2 mode, see b/143699808.
    if tf.compat.v1.executing_eagerly_outside_functions():
      self._enable_caching_device = kwargs.pop('enable_caching_device', True)
    else:
      self._enable_caching_device = kwargs.pop('enable_caching_device', False)
    super(GRUCell, self).__init__(**kwargs)
    self.units = units
    self.activation = activations.get(activation)
    self.recurrent_activation = activations.get(recurrent_activation)
    self.use_bias = use_bias

    self.kernel_initializer = initializers.get(kernel_initializer)
    self.recurrent_initializer = initializers.get(recurrent_initializer)
    self.bias_initializer = initializers.get(bias_initializer)

    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)

    self.kernel_constraint = constraints.get(kernel_constraint)
    self.recurrent_constraint = constraints.get(recurrent_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

    self.dropout = min(1., max(0., dropout))
    self.recurrent_dropout = min(1., max(0., recurrent_dropout))

    implementation = kwargs.pop('implementation', 1)
    if self.recurrent_dropout != 0 and implementation != 1:
      logging.debug(RECURRENT_DROPOUT_WARNING_MSG)
      self.implementation = 1
    else:
      self.implementation = implementation
    self.reset_after = reset_after
    self.state_size = self.units
    self.output_size = self.units

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    input_dim = input_shape[-1]
    default_caching_device = _caching_device(self)
    self.kernel = self.add_weight(
        shape=(input_dim, self.units * 3),
        name='kernel',
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        caching_device=default_caching_device)
    self.recurrent_kernel = self.add_weight(
        shape=(self.units, self.units * 3),
        name='recurrent_kernel',
        initializer=self.recurrent_initializer,
        regularizer=self.recurrent_regularizer,
        constraint=self.recurrent_constraint,
        caching_device=default_caching_device)

    if self.use_bias:
      if not self.reset_after:
        bias_shape = (3 * self.units,)
      else:
        # separate biases for input and recurrent kernels
        # Note: the shape is intentionally different from CuDNNGRU biases
        # `(2 * 3 * self.units,)`, so that we can distinguish the classes
        # when loading and converting saved weights.
        bias_shape = (2, 3 * self.units)
      self.bias = self.add_weight(shape=bias_shape,
                                  name='bias',
                                  initializer=self.bias_initializer,
                                  regularizer=self.bias_regularizer,
                                  constraint=self.bias_constraint,
                                  caching_device=default_caching_device)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs, states, training=None):
    h_tm1 = states[0] if tf.nest.is_nested(states) else states  # previous memory

    dp_mask = self.get_dropout_mask_for_cell(inputs, training, count=3)
    rec_dp_mask = self.get_recurrent_dropout_mask_for_cell(
        h_tm1, training, count=3)

    if self.use_bias:
      if not self.reset_after:
        input_bias, recurrent_bias = self.bias, None
      else:
        input_bias, recurrent_bias = tf.unstack(self.bias)

    if self.implementation == 1:
      if 0. < self.dropout < 1.:
        inputs_z = inputs * dp_mask[0]
        inputs_r = inputs * dp_mask[1]
        inputs_h = inputs * dp_mask[2]
      else:
        inputs_z = inputs
        inputs_r = inputs
        inputs_h = inputs

      x_z = backend.dot(inputs_z, self.kernel[:, :self.units])
      x_r = backend.dot(inputs_r, self.kernel[:, self.units:self.units * 2])
      x_h = backend.dot(inputs_h, self.kernel[:, self.units * 2:])

      if self.use_bias:
        x_z = backend.bias_add(x_z, input_bias[:self.units])
        x_r = backend.bias_add(x_r, input_bias[self.units: self.units * 2])
        x_h = backend.bias_add(x_h, input_bias[self.units * 2:])

      if 0. < self.recurrent_dropout < 1.:
        h_tm1_z = h_tm1 * rec_dp_mask[0]
        h_tm1_r = h_tm1 * rec_dp_mask[1]
        h_tm1_h = h_tm1 * rec_dp_mask[2]
      else:
        h_tm1_z = h_tm1
        h_tm1_r = h_tm1
        h_tm1_h = h_tm1

      recurrent_z = backend.dot(h_tm1_z, self.recurrent_kernel[:, :self.units])
      recurrent_r = backend.dot(
          h_tm1_r, self.recurrent_kernel[:, self.units:self.units * 2])
      if self.reset_after and self.use_bias:
        recurrent_z = backend.bias_add(recurrent_z, recurrent_bias[:self.units])
        recurrent_r = backend.bias_add(
            recurrent_r, recurrent_bias[self.units:self.units * 2])

      z = self.recurrent_activation(x_z + recurrent_z)
      r = self.recurrent_activation(x_r + recurrent_r)

      # reset gate applied after/before matrix multiplication
      if self.reset_after:
        recurrent_h = backend.dot(
            h_tm1_h, self.recurrent_kernel[:, self.units * 2:])
        if self.use_bias:
          recurrent_h = backend.bias_add(
              recurrent_h, recurrent_bias[self.units * 2:])
        recurrent_h = r * recurrent_h
      else:
        recurrent_h = backend.dot(
            r * h_tm1_h, self.recurrent_kernel[:, self.units * 2:])

      hh = self.activation(x_h + recurrent_h)
    else:
      if 0. < self.dropout < 1.:
        inputs = inputs * dp_mask[0]

      # inputs projected by all gate matrices at once
      matrix_x = backend.dot(inputs, self.kernel)
      if self.use_bias:
        # biases: bias_z_i, bias_r_i, bias_h_i
        matrix_x = backend.bias_add(matrix_x, input_bias)

      x_z, x_r, x_h = tf.split(matrix_x, 3, axis=-1)

      if self.reset_after:
        # hidden state projected by all gate matrices at once
        matrix_inner = backend.dot(h_tm1, self.recurrent_kernel)
        if self.use_bias:
          matrix_inner = backend.bias_add(matrix_inner, recurrent_bias)
      else:
        # hidden state projected separately for update/reset and new
        matrix_inner = backend.dot(
            h_tm1, self.recurrent_kernel[:, :2 * self.units])

      recurrent_z, recurrent_r, recurrent_h = tf.split(
          matrix_inner, [self.units, self.units, -1], axis=-1)

      z = self.recurrent_activation(x_z + recurrent_z)
      r = self.recurrent_activation(x_r + recurrent_r)

      if self.reset_after:
        recurrent_h = r * recurrent_h
      else:
        recurrent_h = backend.dot(
            r * h_tm1, self.recurrent_kernel[:, 2 * self.units:])

      hh = self.activation(x_h + recurrent_h)
    # previous and candidate state mixed by update gate
    h = z * h_tm1 + (1 - z) * hh
    new_state = [h] if tf.nest.is_nested(states) else h
    return h, new_state

  def get_config(self):
    config = {
        'units': self.units,
        'activation': activations.serialize(self.activation),
        'recurrent_activation':
            activations.serialize(self.recurrent_activation),
        'use_bias': self.use_bias,
        'kernel_initializer': initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer': initializers.serialize(self.bias_initializer),
        'kernel_regularizer': regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer': regularizers.serialize(self.bias_regularizer),
        'kernel_constraint': constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint': constraints.serialize(self.bias_constraint),
        'dropout': self.dropout,
        'recurrent_dropout': self.recurrent_dropout,
        'implementation': self.implementation,
        'reset_after': self.reset_after
    }
    config.update(_config_for_enable_caching_device(self))
    base_config = super(GRUCell, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
    return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

Ancestors

Subclasses

Methods

def get_initial_state(self, inputs=None, batch_size=None, dtype=None)
Expand source code
def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
  return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

Inherited members

class GaussianDropout (rate, **kwargs)

Apply multiplicative 1-centered Gaussian noise.

As it is a regularization layer, it is only active at training time.

Args

rate
Float, drop probability (as with Dropout). The multiplicative noise will have standard deviation sqrt(rate / (1 - rate)).

Call arguments: inputs: Input tensor (of any rank). training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Expand source code
class GaussianDropout(Layer):
  """Apply multiplicative 1-centered Gaussian noise.

  As it is a regularization layer, it is only active at training time.

  Args:
    rate: Float, drop probability (as with `Dropout`).
      The multiplicative noise will have
      standard deviation `sqrt(rate / (1 - rate))`.

  Call arguments:
    inputs: Input tensor (of any rank).
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as input.
  """

  def __init__(self, rate, **kwargs):
    super(GaussianDropout, self).__init__(**kwargs)
    self.supports_masking = True
    self.rate = rate

  def call(self, inputs, training=None):
    if 0 < self.rate < 1:

      def noised():
        stddev = np.sqrt(self.rate / (1.0 - self.rate))
        return inputs * backend.random_normal(
            shape=tf.shape(inputs),
            mean=1.0,
            stddev=stddev,
            dtype=inputs.dtype)

      return backend.in_train_phase(noised, inputs, training=training)
    return inputs

  def get_config(self):
    config = {'rate': self.rate}
    base_config = super(GaussianDropout, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class GaussianNoise (stddev, **kwargs)

Apply additive zero-centered Gaussian noise.

This is useful to mitigate overfitting (you could see it as a form of random data augmentation). Gaussian Noise (GS) is a natural choice as corruption process for real valued inputs.

As it is a regularization layer, it is only active at training time.

Args

stddev
Float, standard deviation of the noise distribution.

Call arguments: inputs: Input tensor (of any rank). training: Python boolean indicating whether the layer should behave in training mode (adding noise) or in inference mode (doing nothing).

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Expand source code
class GaussianNoise(Layer):
  """Apply additive zero-centered Gaussian noise.

  This is useful to mitigate overfitting
  (you could see it as a form of random data augmentation).
  Gaussian Noise (GS) is a natural choice as corruption process
  for real valued inputs.

  As it is a regularization layer, it is only active at training time.

  Args:
    stddev: Float, standard deviation of the noise distribution.

  Call arguments:
    inputs: Input tensor (of any rank).
    training: Python boolean indicating whether the layer should behave in
      training mode (adding noise) or in inference mode (doing nothing).

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as input.
  """

  def __init__(self, stddev, **kwargs):
    super(GaussianNoise, self).__init__(**kwargs)
    self.supports_masking = True
    self.stddev = stddev

  def call(self, inputs, training=None):

    def noised():
      return inputs + backend.random_normal(
          shape=tf.shape(inputs),
          mean=0.,
          stddev=self.stddev,
          dtype=inputs.dtype)

    return backend.in_train_phase(noised, inputs, training=training)

  def get_config(self):
    config = {'stddev': self.stddev}
    base_config = super(GaussianNoise, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class GlobalAveragePooling1D (data_format='channels_last', **kwargs)

Global average pooling operation for temporal data.

Examples:

>>> input_shape = (2, 3, 4)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalAveragePooling1D()(x)
>>> print(y.shape)
(2, 4)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).
keepdims
A boolean, whether to keep the temporal dimension or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the temporal dimension are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Call arguments: inputs: A 3D tensor. mask: Binary tensor of shape (batch_size, steps) indicating whether a given step should be masked (excluded from the average).

Input shape: - If data_format='channels_last': 3D tensor with shape: (batch_size, steps, features) - If data_format='channels_first': 3D tensor with shape: (batch_size, features, steps)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, features). - If keepdims=True: - If data_format='channels_last': 3D tensor with shape (batch_size, 1, features) - If data_format='channels_first': 3D tensor with shape (batch_size, features, 1)

Expand source code
class GlobalAveragePooling1D(GlobalPooling1D):
  """Global average pooling operation for temporal data.

  Examples:

  >>> input_shape = (2, 3, 4)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalAveragePooling1D()(x)
  >>> print(y.shape)
  (2, 4)

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.
    keepdims: A boolean, whether to keep the temporal dimension or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the temporal dimension are retained with
      length 1.
      The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Call arguments:
    inputs: A 3D tensor.
    mask: Binary tensor of shape `(batch_size, steps)` indicating whether
      a given step should be masked (excluded from the average).

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape:
      `(batch_size, steps, features)`
    - If `data_format='channels_first'`:
      3D tensor with shape:
      `(batch_size, features, steps)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, features)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        3D tensor with shape `(batch_size, 1, features)`
      - If `data_format='channels_first'`:
        3D tensor with shape `(batch_size, features, 1)`
  """

  def __init__(self, data_format='channels_last', **kwargs):
    super(GlobalAveragePooling1D, self).__init__(data_format=data_format,
                                                 **kwargs)
    self.supports_masking = True

  def call(self, inputs, mask=None):
    steps_axis = 1 if self.data_format == 'channels_last' else 2
    if mask is not None:
      mask = tf.cast(mask, inputs[0].dtype)
      mask = tf.expand_dims(
          mask, 2 if self.data_format == 'channels_last' else 1)
      inputs *= mask
      return backend.sum(
          inputs, axis=steps_axis,
          keepdims=self.keepdims) / tf.reduce_sum(
              mask, axis=steps_axis, keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=steps_axis, keepdims=self.keepdims)

  def compute_mask(self, inputs, mask=None):
    return None

Ancestors

Methods

def call(self, inputs, mask=None)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs, mask=None):
  steps_axis = 1 if self.data_format == 'channels_last' else 2
  if mask is not None:
    mask = tf.cast(mask, inputs[0].dtype)
    mask = tf.expand_dims(
        mask, 2 if self.data_format == 'channels_last' else 1)
    inputs *= mask
    return backend.sum(
        inputs, axis=steps_axis,
        keepdims=self.keepdims) / tf.reduce_sum(
            mask, axis=steps_axis, keepdims=self.keepdims)
  else:
    return backend.mean(inputs, axis=steps_axis, keepdims=self.keepdims)
def compute_mask(self, inputs, mask=None)

Computes an output mask tensor.

Args

inputs
Tensor or list of tensors.
mask
Tensor or list of tensors.

Returns

None or a tensor (or list of tensors, one per output tensor of the layer).

Expand source code
def compute_mask(self, inputs, mask=None):
  return None
class GlobalAvgPool1D (data_format='channels_last', **kwargs)

Global average pooling operation for temporal data.

Examples:

>>> input_shape = (2, 3, 4)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalAveragePooling1D()(x)
>>> print(y.shape)
(2, 4)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).
keepdims
A boolean, whether to keep the temporal dimension or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the temporal dimension are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Call arguments: inputs: A 3D tensor. mask: Binary tensor of shape (batch_size, steps) indicating whether a given step should be masked (excluded from the average).

Input shape: - If data_format='channels_last': 3D tensor with shape: (batch_size, steps, features) - If data_format='channels_first': 3D tensor with shape: (batch_size, features, steps)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, features). - If keepdims=True: - If data_format='channels_last': 3D tensor with shape (batch_size, 1, features) - If data_format='channels_first': 3D tensor with shape (batch_size, features, 1)

Expand source code
class GlobalAveragePooling1D(GlobalPooling1D):
  """Global average pooling operation for temporal data.

  Examples:

  >>> input_shape = (2, 3, 4)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalAveragePooling1D()(x)
  >>> print(y.shape)
  (2, 4)

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.
    keepdims: A boolean, whether to keep the temporal dimension or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the temporal dimension are retained with
      length 1.
      The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Call arguments:
    inputs: A 3D tensor.
    mask: Binary tensor of shape `(batch_size, steps)` indicating whether
      a given step should be masked (excluded from the average).

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape:
      `(batch_size, steps, features)`
    - If `data_format='channels_first'`:
      3D tensor with shape:
      `(batch_size, features, steps)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, features)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        3D tensor with shape `(batch_size, 1, features)`
      - If `data_format='channels_first'`:
        3D tensor with shape `(batch_size, features, 1)`
  """

  def __init__(self, data_format='channels_last', **kwargs):
    super(GlobalAveragePooling1D, self).__init__(data_format=data_format,
                                                 **kwargs)
    self.supports_masking = True

  def call(self, inputs, mask=None):
    steps_axis = 1 if self.data_format == 'channels_last' else 2
    if mask is not None:
      mask = tf.cast(mask, inputs[0].dtype)
      mask = tf.expand_dims(
          mask, 2 if self.data_format == 'channels_last' else 1)
      inputs *= mask
      return backend.sum(
          inputs, axis=steps_axis,
          keepdims=self.keepdims) / tf.reduce_sum(
              mask, axis=steps_axis, keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=steps_axis, keepdims=self.keepdims)

  def compute_mask(self, inputs, mask=None):
    return None

Ancestors

Inherited members

class GlobalAveragePooling2D (data_format=None, keepdims=False, **kwargs)

Global average pooling operation for spatial data.

Examples:

>>> input_shape = (2, 4, 5, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalAveragePooling2D()(x)
>>> print(y.shape)
(2, 3)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 4D tensor with shape (batch_size, 1, 1, channels) - If data_format='channels_first': 4D tensor with shape (batch_size, channels, 1, 1)

Expand source code
class GlobalAveragePooling2D(GlobalPooling2D):
  """Global average pooling operation for spatial data.

  Examples:

  >>> input_shape = (2, 4, 5, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalAveragePooling2D()(x)
  >>> print(y.shape)
  (2, 3)

  Args:
      data_format: A string,
        one of `channels_last` (default) or `channels_first`.
        The ordering of the dimensions in the inputs.
        `channels_last` corresponds to inputs with shape
        `(batch, height, width, channels)` while `channels_first`
        corresponds to inputs with shape
        `(batch, channels, height, width)`.
        It defaults to the `image_data_format` value found in your
        Keras config file at `~/.keras/keras.json`.
        If you never set it, then it will be "channels_last".
      keepdims: A boolean, whether to keep the spatial dimensions or not.
        If `keepdims` is `False` (default), the rank of the tensor is reduced
        for spatial dimensions.
        If `keepdims` is `True`, the spatial dimensions are retained with
        length 1.
        The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        4D tensor with shape `(batch_size, 1, 1, channels)`
      - If `data_format='channels_first'`:
        4D tensor with shape `(batch_size, channels, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.mean(inputs, axis=[1, 2], keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=[2, 3], keepdims=self.keepdims)

Ancestors

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  if self.data_format == 'channels_last':
    return backend.mean(inputs, axis=[1, 2], keepdims=self.keepdims)
  else:
    return backend.mean(inputs, axis=[2, 3], keepdims=self.keepdims)
class GlobalAvgPool2D (data_format=None, keepdims=False, **kwargs)

Global average pooling operation for spatial data.

Examples:

>>> input_shape = (2, 4, 5, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalAveragePooling2D()(x)
>>> print(y.shape)
(2, 3)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 4D tensor with shape (batch_size, 1, 1, channels) - If data_format='channels_first': 4D tensor with shape (batch_size, channels, 1, 1)

Expand source code
class GlobalAveragePooling2D(GlobalPooling2D):
  """Global average pooling operation for spatial data.

  Examples:

  >>> input_shape = (2, 4, 5, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalAveragePooling2D()(x)
  >>> print(y.shape)
  (2, 3)

  Args:
      data_format: A string,
        one of `channels_last` (default) or `channels_first`.
        The ordering of the dimensions in the inputs.
        `channels_last` corresponds to inputs with shape
        `(batch, height, width, channels)` while `channels_first`
        corresponds to inputs with shape
        `(batch, channels, height, width)`.
        It defaults to the `image_data_format` value found in your
        Keras config file at `~/.keras/keras.json`.
        If you never set it, then it will be "channels_last".
      keepdims: A boolean, whether to keep the spatial dimensions or not.
        If `keepdims` is `False` (default), the rank of the tensor is reduced
        for spatial dimensions.
        If `keepdims` is `True`, the spatial dimensions are retained with
        length 1.
        The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        4D tensor with shape `(batch_size, 1, 1, channels)`
      - If `data_format='channels_first'`:
        4D tensor with shape `(batch_size, channels, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.mean(inputs, axis=[1, 2], keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=[2, 3], keepdims=self.keepdims)

Ancestors

Inherited members

class GlobalAveragePooling3D (data_format=None, keepdims=False, **kwargs)

Global Average pooling operation for 3D data.

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 5D tensor with shape (batch_size, 1, 1, 1, channels) - If data_format='channels_first': 5D tensor with shape (batch_size, channels, 1, 1, 1)

Expand source code
class GlobalAveragePooling3D(GlobalPooling3D):
  """Global Average pooling operation for 3D data.

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        5D tensor with shape `(batch_size, 1, 1, 1, channels)`
      - If `data_format='channels_first'`:
        5D tensor with shape `(batch_size, channels, 1, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.mean(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=[2, 3, 4], keepdims=self.keepdims)

Ancestors

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  if self.data_format == 'channels_last':
    return backend.mean(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
  else:
    return backend.mean(inputs, axis=[2, 3, 4], keepdims=self.keepdims)
class GlobalAvgPool3D (data_format=None, keepdims=False, **kwargs)

Global Average pooling operation for 3D data.

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_mean or np.mean.

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 5D tensor with shape (batch_size, 1, 1, 1, channels) - If data_format='channels_first': 5D tensor with shape (batch_size, channels, 1, 1, 1)

Expand source code
class GlobalAveragePooling3D(GlobalPooling3D):
  """Global Average pooling operation for 3D data.

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_mean` or `np.mean`.

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        5D tensor with shape `(batch_size, 1, 1, 1, channels)`
      - If `data_format='channels_first'`:
        5D tensor with shape `(batch_size, channels, 1, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.mean(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
    else:
      return backend.mean(inputs, axis=[2, 3, 4], keepdims=self.keepdims)

Ancestors

Inherited members

class GlobalMaxPool1D (data_format='channels_last', keepdims=False, **kwargs)

Global max pooling operation for 1D temporal data.

Downsamples the input representation by taking the maximum value over the time dimension.

For example:

>>> x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
>>> x = tf.reshape(x, [3, 3, 1])
>>> x
<tf.Tensor: shape=(3, 3, 1), dtype=float32, numpy=
array([[[1.], [2.], [3.]],
       [[4.], [5.], [6.]],
       [[7.], [8.], [9.]]], dtype=float32)>
>>> max_pool_1d = tf.keras.layers.GlobalMaxPooling1D()
>>> max_pool_1d(x)
<tf.Tensor: shape=(3, 1), dtype=float32, numpy=
array([[3.],
       [6.],
       [9.], dtype=float32)>

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).
keepdims
A boolean, whether to keep the temporal dimension or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the temporal dimension are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 3D tensor with shape: (batch_size, steps, features) - If data_format='channels_first': 3D tensor with shape: (batch_size, features, steps)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, features). - If keepdims=True: - If data_format='channels_last': 3D tensor with shape (batch_size, 1, features) - If data_format='channels_first': 3D tensor with shape (batch_size, features, 1)

Expand source code
class GlobalMaxPooling1D(GlobalPooling1D):
  """Global max pooling operation for 1D temporal data.

  Downsamples the input representation by taking the maximum value over
  the time dimension.

  For example:

  >>> x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
  >>> x = tf.reshape(x, [3, 3, 1])
  >>> x
  <tf.Tensor: shape=(3, 3, 1), dtype=float32, numpy=
  array([[[1.], [2.], [3.]],
         [[4.], [5.], [6.]],
         [[7.], [8.], [9.]]], dtype=float32)>
  >>> max_pool_1d = tf.keras.layers.GlobalMaxPooling1D()
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(3, 1), dtype=float32, numpy=
  array([[3.],
         [6.],
         [9.], dtype=float32)>

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.
    keepdims: A boolean, whether to keep the temporal dimension or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the temporal dimension are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape:
      `(batch_size, steps, features)`
    - If `data_format='channels_first'`:
      3D tensor with shape:
      `(batch_size, features, steps)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, features)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        3D tensor with shape `(batch_size, 1, features)`
      - If `data_format='channels_first'`:
        3D tensor with shape `(batch_size, features, 1)`
  """

  def call(self, inputs):
    steps_axis = 1 if self.data_format == 'channels_last' else 2
    return backend.max(inputs, axis=steps_axis, keepdims=self.keepdims)

Ancestors

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  steps_axis = 1 if self.data_format == 'channels_last' else 2
  return backend.max(inputs, axis=steps_axis, keepdims=self.keepdims)
class GlobalMaxPooling1D (data_format='channels_last', keepdims=False, **kwargs)

Global max pooling operation for 1D temporal data.

Downsamples the input representation by taking the maximum value over the time dimension.

For example:

>>> x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
>>> x = tf.reshape(x, [3, 3, 1])
>>> x
<tf.Tensor: shape=(3, 3, 1), dtype=float32, numpy=
array([[[1.], [2.], [3.]],
       [[4.], [5.], [6.]],
       [[7.], [8.], [9.]]], dtype=float32)>
>>> max_pool_1d = tf.keras.layers.GlobalMaxPooling1D()
>>> max_pool_1d(x)
<tf.Tensor: shape=(3, 1), dtype=float32, numpy=
array([[3.],
       [6.],
       [9.], dtype=float32)>

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).
keepdims
A boolean, whether to keep the temporal dimension or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the temporal dimension are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 3D tensor with shape: (batch_size, steps, features) - If data_format='channels_first': 3D tensor with shape: (batch_size, features, steps)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, features). - If keepdims=True: - If data_format='channels_last': 3D tensor with shape (batch_size, 1, features) - If data_format='channels_first': 3D tensor with shape (batch_size, features, 1)

Expand source code
class GlobalMaxPooling1D(GlobalPooling1D):
  """Global max pooling operation for 1D temporal data.

  Downsamples the input representation by taking the maximum value over
  the time dimension.

  For example:

  >>> x = tf.constant([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]])
  >>> x = tf.reshape(x, [3, 3, 1])
  >>> x
  <tf.Tensor: shape=(3, 3, 1), dtype=float32, numpy=
  array([[[1.], [2.], [3.]],
         [[4.], [5.], [6.]],
         [[7.], [8.], [9.]]], dtype=float32)>
  >>> max_pool_1d = tf.keras.layers.GlobalMaxPooling1D()
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(3, 1), dtype=float32, numpy=
  array([[3.],
         [6.],
         [9.], dtype=float32)>

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.
    keepdims: A boolean, whether to keep the temporal dimension or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the temporal dimension are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape:
      `(batch_size, steps, features)`
    - If `data_format='channels_first'`:
      3D tensor with shape:
      `(batch_size, features, steps)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, features)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        3D tensor with shape `(batch_size, 1, features)`
      - If `data_format='channels_first'`:
        3D tensor with shape `(batch_size, features, 1)`
  """

  def call(self, inputs):
    steps_axis = 1 if self.data_format == 'channels_last' else 2
    return backend.max(inputs, axis=steps_axis, keepdims=self.keepdims)

Ancestors

Inherited members

class GlobalMaxPool2D (data_format=None, keepdims=False, **kwargs)

Global max pooling operation for spatial data.

Examples:

>>> input_shape = (2, 4, 5, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalMaxPool2D()(x)
>>> print(y.shape)
(2, 3)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 4D tensor with shape (batch_size, 1, 1, channels) - If data_format='channels_first': 4D tensor with shape (batch_size, channels, 1, 1)

Expand source code
class GlobalMaxPooling2D(GlobalPooling2D):
  """Global max pooling operation for spatial data.

  Examples:

  >>> input_shape = (2, 4, 5, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalMaxPool2D()(x)
  >>> print(y.shape)
  (2, 3)

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        4D tensor with shape `(batch_size, 1, 1, channels)`
      - If `data_format='channels_first'`:
        4D tensor with shape `(batch_size, channels, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.max(inputs, axis=[1, 2], keepdims=self.keepdims)
    else:
      return backend.max(inputs, axis=[2, 3], keepdims=self.keepdims)

Ancestors

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  if self.data_format == 'channels_last':
    return backend.max(inputs, axis=[1, 2], keepdims=self.keepdims)
  else:
    return backend.max(inputs, axis=[2, 3], keepdims=self.keepdims)
class GlobalMaxPooling2D (data_format=None, keepdims=False, **kwargs)

Global max pooling operation for spatial data.

Examples:

>>> input_shape = (2, 4, 5, 3)
>>> x = tf.random.normal(input_shape)
>>> y = tf.keras.layers.GlobalMaxPool2D()(x)
>>> print(y.shape)
(2, 3)

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 4D tensor with shape (batch_size, 1, 1, channels) - If data_format='channels_first': 4D tensor with shape (batch_size, channels, 1, 1)

Expand source code
class GlobalMaxPooling2D(GlobalPooling2D):
  """Global max pooling operation for spatial data.

  Examples:

  >>> input_shape = (2, 4, 5, 3)
  >>> x = tf.random.normal(input_shape)
  >>> y = tf.keras.layers.GlobalMaxPool2D()(x)
  >>> print(y.shape)
  (2, 3)

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        4D tensor with shape `(batch_size, 1, 1, channels)`
      - If `data_format='channels_first'`:
        4D tensor with shape `(batch_size, channels, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.max(inputs, axis=[1, 2], keepdims=self.keepdims)
    else:
      return backend.max(inputs, axis=[2, 3], keepdims=self.keepdims)

Ancestors

Inherited members

class GlobalMaxPool3D (data_format=None, keepdims=False, **kwargs)

Global Max pooling operation for 3D data.

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 5D tensor with shape (batch_size, 1, 1, 1, channels) - If data_format='channels_first': 5D tensor with shape (batch_size, channels, 1, 1, 1)

Expand source code
class GlobalMaxPooling3D(GlobalPooling3D):
  """Global Max pooling operation for 3D data.

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        5D tensor with shape `(batch_size, 1, 1, 1, channels)`
      - If `data_format='channels_first'`:
        5D tensor with shape `(batch_size, channels, 1, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.max(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
    else:
      return backend.max(inputs, axis=[2, 3, 4], keepdims=self.keepdims)

Ancestors

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  if self.data_format == 'channels_last':
    return backend.max(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
  else:
    return backend.max(inputs, axis=[2, 3, 4], keepdims=self.keepdims)
class GlobalMaxPooling3D (data_format=None, keepdims=False, **kwargs)

Global Max pooling operation for 3D data.

Args

data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
keepdims
A boolean, whether to keep the spatial dimensions or not. If keepdims is False (default), the rank of the tensor is reduced for spatial dimensions. If keepdims is True, the spatial dimensions are retained with length 1. The behavior is the same as for tf.reduce_max or np.max.

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If keepdims=False: 2D tensor with shape (batch_size, channels). - If keepdims=True: - If data_format='channels_last': 5D tensor with shape (batch_size, 1, 1, 1, channels) - If data_format='channels_first': 5D tensor with shape (batch_size, channels, 1, 1, 1)

Expand source code
class GlobalMaxPooling3D(GlobalPooling3D):
  """Global Max pooling operation for 3D data.

  Args:
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    keepdims: A boolean, whether to keep the spatial dimensions or not.
      If `keepdims` is `False` (default), the rank of the tensor is reduced
      for spatial dimensions.
      If `keepdims` is `True`, the spatial dimensions are retained with
      length 1.
      The behavior is the same as for `tf.reduce_max` or `np.max`.

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `keepdims`=False:
      2D tensor with shape `(batch_size, channels)`.
    - If `keepdims`=True:
      - If `data_format='channels_last'`:
        5D tensor with shape `(batch_size, 1, 1, 1, channels)`
      - If `data_format='channels_first'`:
        5D tensor with shape `(batch_size, channels, 1, 1, 1)`
  """

  def call(self, inputs):
    if self.data_format == 'channels_last':
      return backend.max(inputs, axis=[1, 2, 3], keepdims=self.keepdims)
    else:
      return backend.max(inputs, axis=[2, 3, 4], keepdims=self.keepdims)

Ancestors

Inherited members

class Hashing (num_bins, mask_value=None, salt=None, **kwargs)

Implements categorical feature hashing, also known as "hashing trick".

This layer transforms single or multiple categorical inputs to hashed output. It converts a sequence of int or string to a sequence of int. The stable hash function uses tensorflow::ops::Fingerprint to produce the same output consistently across all platforms.

This layer uses FarmHash64 by default, which provides a consistent hashed output across different platforms and is stable across invocations, regardless of device and context, by mixing the input bits thoroughly.

If you want to obfuscate the hashed output, you can also pass a random salt argument in the constructor. In that case, the layer will use the SipHash64 hash function, with the salt value serving as additional input to the hash function.

Example (FarmHash64)

>>> layer = tf.keras.layers.Hashing(num_bins=3)
>>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
>>> layer(inp)
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[1],
         [0],
         [1],
         [1],
         [2]])>

Example (FarmHash64) with a mask value

>>> layer = tf.keras.layers.Hashing(num_bins=3, mask_value='')
>>> inp = [['A'], ['B'], [''], ['C'], ['D']]
>>> layer(inp)
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[1],
         [1],
         [0],
         [2],
         [2]])>

Example (SipHash64)

>>> layer = tf.keras.layers.Hashing(num_bins=3, salt=[133, 137])
>>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
>>> layer(inp)
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[1],
         [2],
         [1],
         [0],
         [2]])>

Example (Siphash64 with a single integer, same as salt=[133, 133])

>>> layer = tf.keras.layers.Hashing(num_bins=3, salt=133)
>>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
>>> layer(inp)
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[0],
         [0],
         [2],
         [1],
         [0]])>

Args

num_bins
Number of hash bins. Note that this includes the mask_value bin, so the effective number of bins is (num_bins - 1) if mask_value is set.
mask_value
A value that represents masked inputs, which are mapped to index 0. Defaults to None, meaning no mask term will be added and the hashing will start at index 0.
salt
A single unsigned integer or None. If passed, the hash function used will be SipHash64, with these values used as an additional input (known as a "salt" in cryptography). These should be non-zero. Defaults to None (in that case, the FarmHash64 hash function is used). It also supports tuple/list of 2 unsigned integer numbers, see reference paper for details.
**kwargs
Keyword arguments to construct a layer.

Input shape: A single or list of string, int32 or int64 Tensor, SparseTensor or RaggedTensor of shape (batch_size, …,)

Output shape: An int64 Tensor, SparseTensor or RaggedTensor of shape (batch_size, …). If any input is RaggedTensor then output is RaggedTensor, otherwise if any input is SparseTensor then output is SparseTensor, otherwise the output is Tensor.

Reference

Expand source code
class Hashing(base_layer.Layer):
  """Implements categorical feature hashing, also known as "hashing trick".

  This layer transforms single or multiple categorical inputs to hashed output.
  It converts a sequence of int or string to a sequence of int. The stable hash
  function uses `tensorflow::ops::Fingerprint` to produce the same output
  consistently across all platforms.

  This layer uses [FarmHash64](https://github.com/google/farmhash) by default,
  which provides a consistent hashed output across different platforms and is
  stable across invocations, regardless of device and context, by mixing the
  input bits thoroughly.

  If you want to obfuscate the hashed output, you can also pass a random `salt`
  argument in the constructor. In that case, the layer will use the
  [SipHash64](https://github.com/google/highwayhash) hash function, with
  the `salt` value serving as additional input to the hash function.

  **Example (FarmHash64)**

  >>> layer = tf.keras.layers.Hashing(num_bins=3)
  >>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
  >>> layer(inp)
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
    array([[1],
           [0],
           [1],
           [1],
           [2]])>

  **Example (FarmHash64) with a mask value**

  >>> layer = tf.keras.layers.Hashing(num_bins=3, mask_value='')
  >>> inp = [['A'], ['B'], [''], ['C'], ['D']]
  >>> layer(inp)
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
    array([[1],
           [1],
           [0],
           [2],
           [2]])>

  **Example (SipHash64)**

  >>> layer = tf.keras.layers.Hashing(num_bins=3, salt=[133, 137])
  >>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
  >>> layer(inp)
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
    array([[1],
           [2],
           [1],
           [0],
           [2]])>

  **Example (Siphash64 with a single integer, same as `salt=[133, 133]`)**

  >>> layer = tf.keras.layers.Hashing(num_bins=3, salt=133)
  >>> inp = [['A'], ['B'], ['C'], ['D'], ['E']]
  >>> layer(inp)
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
    array([[0],
           [0],
           [2],
           [1],
           [0]])>

  Args:
    num_bins: Number of hash bins. Note that this includes the `mask_value` bin,
      so the effective number of bins is `(num_bins - 1)` if `mask_value` is
      set.
    mask_value: A value that represents masked inputs, which are mapped to
      index 0. Defaults to None, meaning no mask term will be added and the
      hashing will start at index 0.
    salt: A single unsigned integer or None.
      If passed, the hash function used will be SipHash64, with these values
      used as an additional input (known as a "salt" in cryptography).
      These should be non-zero. Defaults to `None` (in that
      case, the FarmHash64 hash function is used). It also supports
      tuple/list of 2 unsigned integer numbers, see reference paper for details.
    **kwargs: Keyword arguments to construct a layer.

  Input shape:
    A single or list of string, int32 or int64 `Tensor`,
    `SparseTensor` or `RaggedTensor` of shape `(batch_size, ...,)`

  Output shape:
    An int64 `Tensor`, `SparseTensor` or `RaggedTensor` of shape
    `(batch_size, ...)`. If any input is `RaggedTensor` then output is
    `RaggedTensor`, otherwise if any input is `SparseTensor` then output is
    `SparseTensor`, otherwise the output is `Tensor`.

  Reference:
    - [SipHash with salt](https://www.131002.net/siphash/siphash.pdf)

  """

  def __init__(self, num_bins, mask_value=None, salt=None, **kwargs):
    if num_bins is None or num_bins <= 0:
      raise ValueError('`num_bins` cannot be `None` or non-positive values.')
    super().__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('Hashing').set(True)
    self.num_bins = num_bins
    self.mask_value = mask_value
    self.strong_hash = True if salt is not None else False
    self.salt = None
    if salt is not None:
      if isinstance(salt, (tuple, list)) and len(salt) == 2:
        self.salt = salt
      elif isinstance(salt, int):
        self.salt = [salt, salt]
      else:
        raise ValueError('`salt can only be a tuple of size 2 integers, or a '
                         'single integer, given {}'.format(salt))

  def call(self, inputs):
    if isinstance(inputs, (list, tuple, np.ndarray)):
      inputs = tf.convert_to_tensor(inputs)
    if isinstance(inputs, tf.SparseTensor):
      return tf.SparseTensor(
          indices=inputs.indices,
          values=self._hash_values_to_bins(inputs.values),
          dense_shape=inputs.dense_shape)
    return self._hash_values_to_bins(inputs)

  def _hash_values_to_bins(self, values):
    """Converts a non-sparse tensor of values to bin indices."""
    str_to_hash_bucket = self._get_string_to_hash_bucket_fn()
    num_available_bins = self.num_bins
    mask = None
    # If mask_value is set, the zeroth bin is reserved for it.
    if self.mask_value is not None and num_available_bins > 1:
      num_available_bins -= 1
      mask = tf.equal(values, self.mask_value)
    # Convert all values to strings before hashing.
    if values.dtype.is_integer:
      values = tf.as_string(values)
    values = str_to_hash_bucket(values, num_available_bins, name='hash')
    if mask is not None:
      values = tf.add(values, tf.ones_like(values))
      values = tf.where(mask, tf.zeros_like(values), values)
    return values

  def _get_string_to_hash_bucket_fn(self):
    """Returns the string_to_hash_bucket op to use based on `hasher_key`."""
    # string_to_hash_bucket_fast uses FarmHash64 as hash function.
    if not self.strong_hash:
      return tf.strings.to_hash_bucket_fast
    # string_to_hash_bucket_strong uses SipHash64 as hash function.
    else:
      return functools.partial(
          tf.strings.to_hash_bucket_strong, key=self.salt)

  def compute_output_shape(self, input_shape):
    return input_shape

  def compute_output_signature(self, input_spec):
    output_shape = self.compute_output_shape(input_spec.shape)
    output_dtype = tf.int64
    if isinstance(input_spec, tf.SparseTensorSpec):
      return tf.SparseTensorSpec(
          shape=output_shape, dtype=output_dtype)
    else:
      return tf.TensorSpec(shape=output_shape, dtype=output_dtype)

  def get_config(self):
    config = super().get_config()
    config.update({
        'num_bins': self.num_bins,
        'salt': self.salt,
        'mask_value': self.mask_value,
    })
    return config

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class InputLayer (input_shape=None, batch_size=None, dtype=None, input_tensor=None, sparse=None, name=None, ragged=None, type_spec=None, **kwargs)

Layer to be used as an entry point into a Network (a graph of layers).

It can either wrap an existing tensor (pass an input_tensor argument) or create a placeholder tensor (pass arguments input_shape, and optionally, dtype).

It is generally recommend to use the functional layer API via Input(), (which creates an InputLayer) without directly using InputLayer.

When using InputLayer with Keras Sequential model, it can be skipped by moving the input_shape parameter to the first layer after the InputLayer.

This class can create placeholders for tf.Tensors, tf.SparseTensors, and tf.RaggedTensors by choosing 'sparse=True' or 'ragged=True'. Note that 'sparse' and 'ragged' can't be configured to True at same time. Usage:

# With explicit InputLayer.
model = tf.keras.Sequential([
  tf.keras.layers.InputLayer(input_shape=(4,)),
  tf.keras.layers.Dense(8)])
model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
model.fit(np.zeros((10, 4)),
          np.ones((10, 8)))

# Without InputLayer and let the first layer to have the input_shape.
# Keras will add a input for the model behind the scene.
model = tf.keras.Sequential([
  tf.keras.layers.Dense(8, input_shape=(4,))])
model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
model.fit(np.zeros((10, 4)),
          np.ones((10, 8)))

Args

input_shape
Shape tuple (not including the batch axis), or TensorShape instance (not including the batch axis).
batch_size
Optional input batch size (integer or None).
dtype
Optional datatype of the input. When not provided, the Keras default float type will be used.
input_tensor
Optional tensor to use as layer input. If set, the layer will use the tf.TypeSpec of this tensor rather than creating a new placeholder tensor.
sparse
Boolean, whether the placeholder created is meant to be sparse. Default to False.
ragged
Boolean, whether the placeholder created is meant to be ragged. In this case, values of 'None' in the 'shape' argument represent ragged dimensions. For more information about RaggedTensors, see this guide. Default to False.
type_spec
A tf.TypeSpec object to create Input from. This tf.TypeSpec represents the entire batch. When provided, all other args except name must be None.
name
Optional name of the layer (string).
Expand source code
class InputLayer(base_layer.Layer):
  """Layer to be used as an entry point into a Network (a graph of layers).

  It can either wrap an existing tensor (pass an `input_tensor` argument)
  or create a placeholder tensor (pass arguments `input_shape`, and
  optionally, `dtype`).

  It is generally recommend to use the functional layer API via `Input`,
  (which creates an `InputLayer`) without directly using `InputLayer`.

  When using InputLayer with Keras Sequential model, it can be skipped by
  moving the input_shape parameter to the first layer after the InputLayer.

  This class can create placeholders for tf.Tensors, tf.SparseTensors, and
  tf.RaggedTensors by choosing 'sparse=True' or 'ragged=True'. Note that
  'sparse' and 'ragged' can't be configured to True at same time.
  Usage:

  ```python
  # With explicit InputLayer.
  model = tf.keras.Sequential([
    tf.keras.layers.InputLayer(input_shape=(4,)),
    tf.keras.layers.Dense(8)])
  model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
  model.fit(np.zeros((10, 4)),
            np.ones((10, 8)))

  # Without InputLayer and let the first layer to have the input_shape.
  # Keras will add a input for the model behind the scene.
  model = tf.keras.Sequential([
    tf.keras.layers.Dense(8, input_shape=(4,))])
  model.compile(tf.optimizers.RMSprop(0.001), loss='mse')
  model.fit(np.zeros((10, 4)),
            np.ones((10, 8)))
  ```

  Args:
      input_shape: Shape tuple (not including the batch axis), or `TensorShape`
        instance (not including the batch axis).
      batch_size: Optional input batch size (integer or None).
      dtype: Optional datatype of the input. When not provided, the Keras
          default float type will be used.
      input_tensor: Optional tensor to use as layer input. If set, the layer
          will use the `tf.TypeSpec` of this tensor rather
          than creating a new placeholder tensor.
      sparse: Boolean, whether the placeholder created is meant to be sparse.
          Default to False.
      ragged: Boolean, whether the placeholder created is meant to be ragged.
          In this case, values of 'None' in the 'shape' argument represent
          ragged dimensions. For more information about RaggedTensors, see
          [this guide](https://www.tensorflow.org/guide/ragged_tensors).
          Default to False.
      type_spec: A `tf.TypeSpec` object to create Input from. This `tf.TypeSpec`
          represents the entire batch. When provided, all other args except
          name must be None.
      name: Optional name of the layer (string).
  """

  def __init__(self,
               input_shape=None,
               batch_size=None,
               dtype=None,
               input_tensor=None,
               sparse=None,
               name=None,
               ragged=None,
               type_spec=None,
               **kwargs):
    self._init_input_shape = input_shape
    self._init_batch_size = batch_size
    self._init_dtype = dtype
    self._init_sparse = sparse
    self._init_ragged = ragged
    self._init_type_spec = type_spec

    strategy = tf.distribute.get_strategy()
    if strategy and batch_size is not None and \
        distributed_training_utils.global_batch_size_supported(strategy):
      if batch_size % strategy.num_replicas_in_sync != 0:
        raise ValueError('The `batch_size` argument ({}) must be divisible by '
                         'the number of replicas ({})'.format(
                             batch_size, strategy.num_replicas_in_sync))
      batch_size = batch_size // strategy.num_replicas_in_sync

    if 'batch_input_shape' in kwargs:
      batch_input_shape = kwargs.pop('batch_input_shape')
      if input_shape and batch_input_shape:
        raise ValueError('Only provide the input_shape OR '
                         'batch_input_shape argument to '
                         'InputLayer, not both at the same time.')
      # Set the input shape and batch size from the batch_input_shape.
      # Note that batch_input_shape can be None (unknown rank) or [] (scalar),
      # in which case the batch size must be None.
      if batch_input_shape:
        batch_size = batch_input_shape[0]
        input_shape = batch_input_shape[1:]
    if kwargs:
      raise ValueError('Unrecognized keyword arguments:', kwargs.keys())

    if sparse and ragged:
      raise ValueError(
          'Cannot set both sparse and ragged to True in a Keras input.')

    if not name:
      prefix = 'input'
      name = prefix + '_' + str(backend.get_uid(prefix))

    if not dtype:
      if input_tensor is None:
        dtype = backend.floatx()
      else:
        dtype = backend.dtype(input_tensor)
    elif input_tensor is not None and input_tensor.dtype != dtype:
      raise ValueError('`input_tensor.dtype` differs from `dtype`: %s vs. %s' %
                       (input_tensor.dtype, dtype))
    super(InputLayer, self).__init__(dtype=dtype, name=name)
    self.built = True
    self.sparse = True if sparse else False
    self.ragged = True if ragged else False
    self.batch_size = batch_size
    self.supports_masking = True

    if isinstance(input_shape, tf.TensorShape):
      input_shape = tuple(input_shape.as_list())
    elif isinstance(input_shape, int):
      input_shape = (input_shape,)

    if type_spec is not None:
      args_that_must_be_none = [
          ('(input_)shape', self._init_input_shape),
          ('batch_size', self._init_batch_size),
          ('dtype', self._init_dtype),
          ('input_tensor', input_tensor),
          ('sparse', self._init_sparse),
          ('ragged', self._init_ragged),
      ]
      for arg_name, arg in args_that_must_be_none:
        _assert_other_arg_none(arg_name, arg)
      if not tf.compat.v1.executing_eagerly_outside_functions():
        raise ValueError('Creating Keras inputs from a type_spec is only '
                         'supported when eager execution is enabled.')
      input_tensor = keras_tensor.keras_tensor_from_type_spec(type_spec)
      if isinstance(input_tensor, keras_tensor.SparseKerasTensor):
        self.sparse = True
      if isinstance(input_tensor, keras_tensor.RaggedKerasTensor):
        self.ragged = True
      self.is_placeholder = True
      try:
        self._batch_input_shape = tuple(input_tensor.shape.as_list())
      except ValueError:
        # If the shape cannot be represented as a tuple (e.g. unknown rank)
        self._batch_input_shape = None
    elif input_tensor is None:
      if input_shape is not None:
        batch_input_shape = (batch_size,) + tuple(input_shape)
      else:
        batch_input_shape = None
      graph = backend.get_graph()
      with graph.as_default():
        input_tensor = backend.placeholder(
            shape=batch_input_shape,
            dtype=dtype,
            name=self.name,
            sparse=sparse,
            ragged=ragged)

      self.is_placeholder = True
      self._batch_input_shape = batch_input_shape
    else:
      if tf.compat.v1.executing_eagerly_outside_functions():
        if not isinstance(input_tensor, keras_tensor.KerasTensor):
          input_tensor = keras_tensor.keras_tensor_from_tensor(input_tensor)
      else:
        if not tf_utils.is_symbolic_tensor(input_tensor):
          raise ValueError('You should not pass an EagerTensor to `Input`. '
                           'For example, instead of creating an '
                           'InputLayer, you should instantiate your model and '
                           'directly call it on your input.')
      self.is_placeholder = False
      try:
        self._batch_input_shape = tuple(input_tensor.shape.as_list())
      except ValueError:
        # If the shape cannot be represented as a tuple (e.g. unknown rank)
        self._batch_input_shape = None
    # Create an input node.
    input_tensor._keras_mask = None
    node_module.Node(layer=self, outputs=input_tensor)

    # Store type spec
    if isinstance(input_tensor, keras_tensor.KerasTensor) or (
        tf_utils.is_extension_type(input_tensor)):
      self._type_spec = input_tensor._type_spec  # pylint: disable=protected-access
    else:
      self._type_spec = tf.TensorSpec(
          shape=input_tensor.shape, dtype=input_tensor.dtype, name=self.name)

  def get_config(self):
    if self._init_type_spec is not None:
      config = {
          'name': self.name,
          'type_spec': self._init_type_spec
      }
    else:
      config = {
          'batch_input_shape': self._batch_input_shape,
          'dtype': self.dtype,
          'sparse': self.sparse,
          'ragged': self.ragged,
          'name': self.name,
      }
    return config

  @property
  def _trackable_saved_model_saver(self):
    return layer_serialization.InputLayerSavedModelSaver(self)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class InputSpec (dtype=None, shape=None, ndim=None, max_ndim=None, min_ndim=None, axes=None, allow_last_axis_squeeze=False, name=None)

Specifies the rank, dtype and shape of every input to a layer.

Layers can expose (if appropriate) an input_spec attribute: an instance of InputSpec, or a nested structure of InputSpec instances (one per input tensor). These objects enable the layer to run input compatibility checks for input structure, input rank, input shape, and input dtype.

A None entry in a shape is compatible with any dimension, a None shape is compatible with any shape.

Args

dtype
Expected DataType of the input.
shape
Shape tuple, expected shape of the input (may include None for unchecked axes). Includes the batch size.
ndim
Integer, expected rank of the input.
max_ndim
Integer, maximum rank of the input.
min_ndim
Integer, minimum rank of the input.
axes
Dictionary mapping integer axes to a specific dimension value.
allow_last_axis_squeeze
If True, then allow inputs of rank N+1 as long as the last axis of the input is 1, as well as inputs of rank N-1 as long as the last axis of the spec is 1.
name
Expected key corresponding to this input when passing data as a dictionary.

Example:

class MyLayer(Layer):
    def __init__(self):
        super(MyLayer, self).__init__()
        # The layer will accept inputs with shape (?, 28, 28) & (?, 28, 28, 1)
        # and raise an appropriate error message otherwise.
        self.input_spec = InputSpec(
            shape=(None, 28, 28, 1),
            allow_last_axis_squeeze=True)
Expand source code
class InputSpec(object):
  """Specifies the rank, dtype and shape of every input to a layer.

  Layers can expose (if appropriate) an `input_spec` attribute:
  an instance of `InputSpec`, or a nested structure of `InputSpec` instances
  (one per input tensor). These objects enable the layer to run input
  compatibility checks for input structure, input rank, input shape, and
  input dtype.

  A None entry in a shape is compatible with any dimension,
  a None shape is compatible with any shape.

  Args:
    dtype: Expected DataType of the input.
    shape: Shape tuple, expected shape of the input
      (may include None for unchecked axes). Includes the batch size.
    ndim: Integer, expected rank of the input.
    max_ndim: Integer, maximum rank of the input.
    min_ndim: Integer, minimum rank of the input.
    axes: Dictionary mapping integer axes to
      a specific dimension value.
    allow_last_axis_squeeze: If True, then allow inputs of rank N+1 as long
      as the last axis of the input is 1, as well as inputs of rank N-1
      as long as the last axis of the spec is 1.
    name: Expected key corresponding to this input when passing data as
      a dictionary.

  Example:

  ```python
  class MyLayer(Layer):
      def __init__(self):
          super(MyLayer, self).__init__()
          # The layer will accept inputs with shape (?, 28, 28) & (?, 28, 28, 1)
          # and raise an appropriate error message otherwise.
          self.input_spec = InputSpec(
              shape=(None, 28, 28, 1),
              allow_last_axis_squeeze=True)
  ```
  """

  def __init__(self,
               dtype=None,
               shape=None,
               ndim=None,
               max_ndim=None,
               min_ndim=None,
               axes=None,
               allow_last_axis_squeeze=False,
               name=None):
    self.dtype = tf.as_dtype(dtype).name if dtype is not None else None
    shape = tf.TensorShape(shape)
    if shape.rank is None:
      shape = None
    else:
      shape = tuple(shape.as_list())
    if shape is not None:
      self.ndim = len(shape)
      self.shape = shape
    else:
      self.ndim = ndim
      self.shape = None
    self.max_ndim = max_ndim
    self.min_ndim = min_ndim
    self.name = name
    self.allow_last_axis_squeeze = allow_last_axis_squeeze
    try:
      axes = axes or {}
      self.axes = {int(k): axes[k] for k in axes}
    except (ValueError, TypeError):
      raise TypeError('The keys in axes must be integers.')

    if self.axes and (self.ndim is not None or self.max_ndim is not None):
      max_dim = (self.ndim if self.ndim else self.max_ndim) - 1
      max_axis = max(self.axes)
      if max_axis > max_dim:
        raise ValueError('Axis {} is greater than the maximum allowed value: {}'
                         .format(max_axis, max_dim))

  def __repr__(self):
    spec = [('dtype=' + str(self.dtype)) if self.dtype else '',
            ('shape=' + str(self.shape)) if self.shape else '',
            ('ndim=' + str(self.ndim)) if self.ndim else '',
            ('max_ndim=' + str(self.max_ndim)) if self.max_ndim else '',
            ('min_ndim=' + str(self.min_ndim)) if self.min_ndim else '',
            ('axes=' + str(self.axes)) if self.axes else '']
    return 'InputSpec(%s)' % ', '.join(x for x in spec if x)

  def get_config(self):
    return {
        'dtype': self.dtype,
        'shape': self.shape,
        'ndim': self.ndim,
        'max_ndim': self.max_ndim,
        'min_ndim': self.min_ndim,
        'axes': self.axes}

  @classmethod
  def from_config(cls, config):
    return cls(**config)

Static methods

def from_config(config)
Expand source code
@classmethod
def from_config(cls, config):
  return cls(**config)

Methods

def get_config(self)
Expand source code
def get_config(self):
  return {
      'dtype': self.dtype,
      'shape': self.shape,
      'ndim': self.ndim,
      'max_ndim': self.max_ndim,
      'min_ndim': self.min_ndim,
      'axes': self.axes}
class LSTM (units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False, **kwargs)

Long Short-Term Memory layer - Hochreiter 1997.

Note that this cell is not optimized for performance on GPU. Please use tf.compat.v1.keras.layers.CuDNNLSTM for better performance on GPU.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
recurrent_activation
Activation function to use for the recurrent step. Default: hard sigmoid (hard_sigmoid). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs..
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Setting it to true will also force bias_initializer="zeros". This is recommended in Jozefowicz et al., 2015.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation").
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.
return_sequences
Boolean. Whether to return the last output. in the output sequence, or the full sequence.
return_state
Boolean. Whether to return the last state in addition to the output.
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
unroll
Boolean (default False). If True, the network will be unrolled, else a symbolic loop will be used. Unrolling can speed-up a RNN, although it tends to be more memory-intensive. Unrolling is only suitable for short sequences.
time_major
The shape format of the inputs and outputs tensors. If True, the inputs and outputs will be in shape (timesteps, batch, …), whereas in the False case, it will be (batch, timesteps, …). Using time_major = True is a bit more efficient because it avoids transposes at the beginning and end of the RNN calculation. However, most TensorFlow data is batch-major, so by default this function accepts input and emits output in batch-major form.

Call arguments: inputs: A 3D tensor. mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. An individual True entry indicates that the corresponding timestep should be utilized, while a False entry indicates that the corresponding timestep should be ignored. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout is used. initial_state: List of initial state tensors to be passed to the first call of the cell.

Expand source code
class LSTM(RNN):
  """Long Short-Term Memory layer - Hochreiter 1997.

   Note that this cell is not optimized for performance on GPU. Please use
  `tf.compat.v1.keras.layers.CuDNNLSTM` for better performance on GPU.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    recurrent_activation: Activation function to use
      for the recurrent step.
      Default: hard sigmoid (`hard_sigmoid`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs..
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix,
      used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    unit_forget_bias: Boolean.
      If True, add 1 to the bias of the forget gate at initialization.
      Setting it to true will also force `bias_initializer="zeros"`.
      This is recommended in [Jozefowicz et al., 2015](
        http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf).
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix.
    recurrent_regularizer: Regularizer function applied to
      the `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation").
    kernel_constraint: Constraint function applied to
      the `kernel` weights matrix.
    recurrent_constraint: Constraint function applied to
      the `recurrent_kernel` weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the inputs.
    recurrent_dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the recurrent state.
    return_sequences: Boolean. Whether to return the last output.
      in the output sequence, or the full sequence.
    return_state: Boolean. Whether to return the last state
      in addition to the output.
    go_backwards: Boolean (default False).
      If True, process the input sequence backwards and return the
      reversed sequence.
    stateful: Boolean (default False). If True, the last state
      for each sample at index i in a batch will be used as initial
      state for the sample of index i in the following batch.
    unroll: Boolean (default False).
      If True, the network will be unrolled,
      else a symbolic loop will be used.
      Unrolling can speed-up a RNN,
      although it tends to be more memory-intensive.
      Unrolling is only suitable for short sequences.
    time_major: The shape format of the `inputs` and `outputs` tensors.
      If True, the inputs and outputs will be in shape
      `(timesteps, batch, ...)`, whereas in the False case, it will be
      `(batch, timesteps, ...)`. Using `time_major = True` is a bit more
      efficient because it avoids transposes at the beginning and end of the
      RNN calculation. However, most TensorFlow data is batch-major, so by
      default this function accepts input and emits output in batch-major
      form.

  Call arguments:
    inputs: A 3D tensor.
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether
      a given timestep should be masked. An individual `True` entry indicates
      that the corresponding timestep should be utilized, while a `False`
      entry indicates that the corresponding timestep should be ignored.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or
      `recurrent_dropout` is used.
    initial_state: List of initial state tensors to be passed to the first
      call of the cell.
  """

  def __init__(self,
               units,
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               unroll=False,
               **kwargs):
    implementation = kwargs.pop('implementation', 1)
    if implementation == 0:
      logging.warning('`implementation=0` has been deprecated, '
                      'and now defaults to `implementation=1`.'
                      'Please update your layer call.')
    if 'enable_caching_device' in kwargs:
      cell_kwargs = {'enable_caching_device':
                     kwargs.pop('enable_caching_device')}
    else:
      cell_kwargs = {}
    cell = LSTMCell(
        units,
        activation=activation,
        recurrent_activation=recurrent_activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        unit_forget_bias=unit_forget_bias,
        bias_initializer=bias_initializer,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        implementation=implementation,
        dtype=kwargs.get('dtype'),
        trainable=kwargs.get('trainable', True),
        **cell_kwargs)
    super(LSTM, self).__init__(
        cell,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        unroll=unroll,
        **kwargs)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.input_spec = [InputSpec(ndim=3)]

  def call(self, inputs, mask=None, training=None, initial_state=None):
    return super(LSTM, self).call(
        inputs, mask=mask, training=training, initial_state=initial_state)

  @property
  def units(self):
    return self.cell.units

  @property
  def activation(self):
    return self.cell.activation

  @property
  def recurrent_activation(self):
    return self.cell.recurrent_activation

  @property
  def use_bias(self):
    return self.cell.use_bias

  @property
  def kernel_initializer(self):
    return self.cell.kernel_initializer

  @property
  def recurrent_initializer(self):
    return self.cell.recurrent_initializer

  @property
  def bias_initializer(self):
    return self.cell.bias_initializer

  @property
  def unit_forget_bias(self):
    return self.cell.unit_forget_bias

  @property
  def kernel_regularizer(self):
    return self.cell.kernel_regularizer

  @property
  def recurrent_regularizer(self):
    return self.cell.recurrent_regularizer

  @property
  def bias_regularizer(self):
    return self.cell.bias_regularizer

  @property
  def kernel_constraint(self):
    return self.cell.kernel_constraint

  @property
  def recurrent_constraint(self):
    return self.cell.recurrent_constraint

  @property
  def bias_constraint(self):
    return self.cell.bias_constraint

  @property
  def dropout(self):
    return self.cell.dropout

  @property
  def recurrent_dropout(self):
    return self.cell.recurrent_dropout

  @property
  def implementation(self):
    return self.cell.implementation

  def get_config(self):
    config = {
        'units':
            self.units,
        'activation':
            activations.serialize(self.activation),
        'recurrent_activation':
            activations.serialize(self.recurrent_activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'unit_forget_bias':
            self.unit_forget_bias,
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'dropout':
            self.dropout,
        'recurrent_dropout':
            self.recurrent_dropout,
        'implementation':
            self.implementation
    }
    config.update(_config_for_enable_caching_device(self.cell))
    base_config = super(LSTM, self).get_config()
    del base_config['cell']
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config):
    if 'implementation' in config and config['implementation'] == 0:
      config['implementation'] = 1
    return cls(**config)

Ancestors

  • RNN
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Instance variables

var activation
Expand source code
@property
def activation(self):
  return self.cell.activation
var bias_constraint
Expand source code
@property
def bias_constraint(self):
  return self.cell.bias_constraint
var bias_initializer
Expand source code
@property
def bias_initializer(self):
  return self.cell.bias_initializer
var bias_regularizer
Expand source code
@property
def bias_regularizer(self):
  return self.cell.bias_regularizer
var dropout
Expand source code
@property
def dropout(self):
  return self.cell.dropout
var implementation
Expand source code
@property
def implementation(self):
  return self.cell.implementation
var kernel_constraint
Expand source code
@property
def kernel_constraint(self):
  return self.cell.kernel_constraint
var kernel_initializer
Expand source code
@property
def kernel_initializer(self):
  return self.cell.kernel_initializer
var kernel_regularizer
Expand source code
@property
def kernel_regularizer(self):
  return self.cell.kernel_regularizer
var recurrent_activation
Expand source code
@property
def recurrent_activation(self):
  return self.cell.recurrent_activation
var recurrent_constraint
Expand source code
@property
def recurrent_constraint(self):
  return self.cell.recurrent_constraint
var recurrent_dropout
Expand source code
@property
def recurrent_dropout(self):
  return self.cell.recurrent_dropout
var recurrent_initializer
Expand source code
@property
def recurrent_initializer(self):
  return self.cell.recurrent_initializer
var recurrent_regularizer
Expand source code
@property
def recurrent_regularizer(self):
  return self.cell.recurrent_regularizer
var unit_forget_bias
Expand source code
@property
def unit_forget_bias(self):
  return self.cell.unit_forget_bias
var units
Expand source code
@property
def units(self):
  return self.cell.units
var use_bias
Expand source code
@property
def use_bias(self):
  return self.cell.use_bias

Inherited members

class LSTMCell (units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, **kwargs)

Cell class for the LSTM layer.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
recurrent_activation
Activation function to use for the recurrent step. Default: hard sigmoid (hard_sigmoid). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state.
bias_initializer
Initializer for the bias vector.
unit_forget_bias
Boolean. If True, add 1 to the bias of the forget gate at initialization. Setting it to true will also force bias_initializer="zeros". This is recommended in Jozefowicz et al., 2015
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
kernel_constraint
Constraint function applied to the kernel weights matrix.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix.
bias_constraint
Constraint function applied to the bias vector.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state.

Call arguments: inputs: A 2D tensor. states: List of state tensors corresponding to the previous timestep. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. Only relevant when dropout or recurrent_dropout is used.

Expand source code
class LSTMCell(DropoutRNNCellMixin, Layer):
  """Cell class for the LSTM layer.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    recurrent_activation: Activation function to use
      for the recurrent step.
      Default: hard sigmoid (`hard_sigmoid`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs.
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix,
      used for the linear transformation of the recurrent state.
    bias_initializer: Initializer for the bias vector.
    unit_forget_bias: Boolean.
      If True, add 1 to the bias of the forget gate at initialization.
      Setting it to true will also force `bias_initializer="zeros"`.
      This is recommended in [Jozefowicz et al., 2015](
        http://www.jmlr.org/proceedings/papers/v37/jozefowicz15.pdf)
    kernel_regularizer: Regularizer function applied to
      the `kernel` weights matrix.
    recurrent_regularizer: Regularizer function applied to
      the `recurrent_kernel` weights matrix.
    bias_regularizer: Regularizer function applied to the bias vector.
    kernel_constraint: Constraint function applied to
      the `kernel` weights matrix.
    recurrent_constraint: Constraint function applied to
      the `recurrent_kernel` weights matrix.
    bias_constraint: Constraint function applied to the bias vector.
    dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the inputs.
    recurrent_dropout: Float between 0 and 1.
      Fraction of the units to drop for
      the linear transformation of the recurrent state.

  Call arguments:
    inputs: A 2D tensor.
    states: List of state tensors corresponding to the previous timestep.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. Only relevant when `dropout` or
      `recurrent_dropout` is used.
  """

  def __init__(self,
               units,
               activation='tanh',
               recurrent_activation='hard_sigmoid',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               unit_forget_bias=True,
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               **kwargs):
    if units < 0:
      raise ValueError(f'Received an invalid value for units, expected '
                       f'a positive integer, got {units}.')
    # By default use cached variable under v2 mode, see b/143699808.
    if tf.compat.v1.executing_eagerly_outside_functions():
      self._enable_caching_device = kwargs.pop('enable_caching_device', True)
    else:
      self._enable_caching_device = kwargs.pop('enable_caching_device', False)
    super(LSTMCell, self).__init__(**kwargs)
    self.units = units
    self.activation = activations.get(activation)
    self.recurrent_activation = activations.get(recurrent_activation)
    self.use_bias = use_bias

    self.kernel_initializer = initializers.get(kernel_initializer)
    self.recurrent_initializer = initializers.get(recurrent_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.unit_forget_bias = unit_forget_bias

    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)

    self.kernel_constraint = constraints.get(kernel_constraint)
    self.recurrent_constraint = constraints.get(recurrent_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

    self.dropout = min(1., max(0., dropout))
    self.recurrent_dropout = min(1., max(0., recurrent_dropout))
    implementation = kwargs.pop('implementation', 1)
    if self.recurrent_dropout != 0 and implementation != 1:
      logging.debug(RECURRENT_DROPOUT_WARNING_MSG)
      self.implementation = 1
    else:
      self.implementation = implementation
    self.state_size = [self.units, self.units]
    self.output_size = self.units

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    default_caching_device = _caching_device(self)
    input_dim = input_shape[-1]
    self.kernel = self.add_weight(
        shape=(input_dim, self.units * 4),
        name='kernel',
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        caching_device=default_caching_device)
    self.recurrent_kernel = self.add_weight(
        shape=(self.units, self.units * 4),
        name='recurrent_kernel',
        initializer=self.recurrent_initializer,
        regularizer=self.recurrent_regularizer,
        constraint=self.recurrent_constraint,
        caching_device=default_caching_device)

    if self.use_bias:
      if self.unit_forget_bias:

        def bias_initializer(_, *args, **kwargs):
          return backend.concatenate([
              self.bias_initializer((self.units,), *args, **kwargs),
              initializers.get('ones')((self.units,), *args, **kwargs),
              self.bias_initializer((self.units * 2,), *args, **kwargs),
          ])
      else:
        bias_initializer = self.bias_initializer
      self.bias = self.add_weight(
          shape=(self.units * 4,),
          name='bias',
          initializer=bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          caching_device=default_caching_device)
    else:
      self.bias = None
    self.built = True

  def _compute_carry_and_output(self, x, h_tm1, c_tm1):
    """Computes carry and output using split kernels."""
    x_i, x_f, x_c, x_o = x
    h_tm1_i, h_tm1_f, h_tm1_c, h_tm1_o = h_tm1
    i = self.recurrent_activation(
        x_i + backend.dot(h_tm1_i, self.recurrent_kernel[:, :self.units]))
    f = self.recurrent_activation(x_f + backend.dot(
        h_tm1_f, self.recurrent_kernel[:, self.units:self.units * 2]))
    c = f * c_tm1 + i * self.activation(x_c + backend.dot(
        h_tm1_c, self.recurrent_kernel[:, self.units * 2:self.units * 3]))
    o = self.recurrent_activation(
        x_o + backend.dot(h_tm1_o, self.recurrent_kernel[:, self.units * 3:]))
    return c, o

  def _compute_carry_and_output_fused(self, z, c_tm1):
    """Computes carry and output using fused kernels."""
    z0, z1, z2, z3 = z
    i = self.recurrent_activation(z0)
    f = self.recurrent_activation(z1)
    c = f * c_tm1 + i * self.activation(z2)
    o = self.recurrent_activation(z3)
    return c, o

  def call(self, inputs, states, training=None):
    h_tm1 = states[0]  # previous memory state
    c_tm1 = states[1]  # previous carry state

    dp_mask = self.get_dropout_mask_for_cell(inputs, training, count=4)
    rec_dp_mask = self.get_recurrent_dropout_mask_for_cell(
        h_tm1, training, count=4)

    if self.implementation == 1:
      if 0 < self.dropout < 1.:
        inputs_i = inputs * dp_mask[0]
        inputs_f = inputs * dp_mask[1]
        inputs_c = inputs * dp_mask[2]
        inputs_o = inputs * dp_mask[3]
      else:
        inputs_i = inputs
        inputs_f = inputs
        inputs_c = inputs
        inputs_o = inputs
      k_i, k_f, k_c, k_o = tf.split(
          self.kernel, num_or_size_splits=4, axis=1)
      x_i = backend.dot(inputs_i, k_i)
      x_f = backend.dot(inputs_f, k_f)
      x_c = backend.dot(inputs_c, k_c)
      x_o = backend.dot(inputs_o, k_o)
      if self.use_bias:
        b_i, b_f, b_c, b_o = tf.split(
            self.bias, num_or_size_splits=4, axis=0)
        x_i = backend.bias_add(x_i, b_i)
        x_f = backend.bias_add(x_f, b_f)
        x_c = backend.bias_add(x_c, b_c)
        x_o = backend.bias_add(x_o, b_o)

      if 0 < self.recurrent_dropout < 1.:
        h_tm1_i = h_tm1 * rec_dp_mask[0]
        h_tm1_f = h_tm1 * rec_dp_mask[1]
        h_tm1_c = h_tm1 * rec_dp_mask[2]
        h_tm1_o = h_tm1 * rec_dp_mask[3]
      else:
        h_tm1_i = h_tm1
        h_tm1_f = h_tm1
        h_tm1_c = h_tm1
        h_tm1_o = h_tm1
      x = (x_i, x_f, x_c, x_o)
      h_tm1 = (h_tm1_i, h_tm1_f, h_tm1_c, h_tm1_o)
      c, o = self._compute_carry_and_output(x, h_tm1, c_tm1)
    else:
      if 0. < self.dropout < 1.:
        inputs = inputs * dp_mask[0]
      z = backend.dot(inputs, self.kernel)
      z += backend.dot(h_tm1, self.recurrent_kernel)
      if self.use_bias:
        z = backend.bias_add(z, self.bias)

      z = tf.split(z, num_or_size_splits=4, axis=1)
      c, o = self._compute_carry_and_output_fused(z, c_tm1)

    h = o * self.activation(c)
    return h, [h, c]

  def get_config(self):
    config = {
        'units':
            self.units,
        'activation':
            activations.serialize(self.activation),
        'recurrent_activation':
            activations.serialize(self.recurrent_activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'unit_forget_bias':
            self.unit_forget_bias,
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'dropout':
            self.dropout,
        'recurrent_dropout':
            self.recurrent_dropout,
        'implementation':
            self.implementation
    }
    config.update(_config_for_enable_caching_device(self))
    base_config = super(LSTMCell, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
    return list(_generate_zero_filled_state_for_cell(
        self, inputs, batch_size, dtype))

Ancestors

Subclasses

Methods

def get_initial_state(self, inputs=None, batch_size=None, dtype=None)
Expand source code
def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
  return list(_generate_zero_filled_state_for_cell(
      self, inputs, batch_size, dtype))

Inherited members

class Lambda (function, output_shape=None, mask=None, arguments=None, **kwargs)

Wraps arbitrary expressions as a Layer object.

The Lambda layer exists so that arbitrary expressions can be used as a Layer when constructing Sequential and Functional API models. Lambda layers are best suited for simple operations or quick experimentation. For more advanced use cases, follow this guide for subclassing tf.keras.layers.Layer.

WARNING: tf.keras.layers.Lambda layers have (de)serialization limitations!

The main reason to subclass tf.keras.layers.Layer instead of using a Lambda layer is saving and inspecting a Model. Lambda layers are saved by serializing the Python bytecode, which is fundamentally non-portable. They should only be loaded in the same environment where they were saved. Subclassed layers can be saved in a more portable way by overriding their get_config method. Models that rely on subclassed Layers are also often easier to visualize and reason about.

Examples:

# add a x -> x^2 layer
model.add(Lambda(lambda x: x ** 2))
# add a layer that returns the concatenation
# of the positive part of the input and
# the opposite of the negative part

def antirectifier(x):
    x -= K.mean(x, axis=1, keepdims=True)
    x = K.l2_normalize(x, axis=1)
    pos = K.relu(x)
    neg = K.relu(-x)
    return K.concatenate([pos, neg], axis=1)

model.add(Lambda(antirectifier))

Variables

While it is possible to use Variables with Lambda layers, this practice is discouraged as it can easily lead to bugs. For instance, consider the following layer:

  scale = tf.Variable(1.)
  scale_layer = tf.keras.layers.Lambda(lambda x: x * scale)

Because scale_layer does not directly track the scale variable, it will not appear in scale_layer.trainable_weights and will therefore not be trained if scale_layer is used in a Model.

A better pattern is to write a subclassed Layer:

  class ScaleLayer(tf.keras.layers.Layer):
    def __init__(self):
      super(ScaleLayer, self).__init__()
      self.scale = tf.Variable(1.)

    def call(self, inputs):
      return inputs * self.scale

In general, Lambda layers can be convenient for simple stateless computation, but anything more complex should use a subclass Layer instead.

Args

function
The function to be evaluated. Takes input tensor as first argument.
output_shape
Expected output shape from function. This argument can be inferred if not explicitly provided. Can be a tuple or function. If a tuple, it only specifies the first dimension onward; sample dimension is assumed either the same as the input: output_shape = (input_shape[0], ) + output_shape<code> or, the input is </code>None and the sample dimension is also None: output_shape = (None, ) + output_shape If a function, it specifies the entire shape as a function of the input shape: output_shape = f(input_shape)
mask
Either None (indicating no masking) or a callable with the same signature as the compute_mask layer method, or a tensor that will be returned as output mask regardless of what the input is.
arguments
Optional dictionary of keyword arguments to be passed to the function.

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Specified by output_shape argument

Expand source code
class Lambda(Layer):
  """Wraps arbitrary expressions as a `Layer` object.

  The `Lambda` layer exists so that arbitrary expressions can be used
  as a `Layer` when constructing `Sequential`
  and Functional API models. `Lambda` layers are best suited for simple
  operations or quick experimentation. For more advanced use cases, follow
  [this guide](https://www.tensorflow.org/guide/keras/custom_layers_and_models)
  for subclassing `tf.keras.layers.Layer`.

  WARNING: `tf.keras.layers.Lambda` layers have (de)serialization limitations!

  The main reason to subclass `tf.keras.layers.Layer` instead of using a
  `Lambda` layer is saving and inspecting a Model. `Lambda` layers
  are saved by serializing the Python bytecode, which is fundamentally
  non-portable. They should only be loaded in the same environment where
  they were saved. Subclassed layers can be saved in a more portable way
  by overriding their `get_config` method. Models that rely on
  subclassed Layers are also often easier to visualize and reason about.

  Examples:

  ```python
  # add a x -> x^2 layer
  model.add(Lambda(lambda x: x ** 2))
  ```
  ```python
  # add a layer that returns the concatenation
  # of the positive part of the input and
  # the opposite of the negative part

  def antirectifier(x):
      x -= K.mean(x, axis=1, keepdims=True)
      x = K.l2_normalize(x, axis=1)
      pos = K.relu(x)
      neg = K.relu(-x)
      return K.concatenate([pos, neg], axis=1)

  model.add(Lambda(antirectifier))
  ```

  Variables:
    While it is possible to use Variables with Lambda layers, this practice is
    discouraged as it can easily lead to bugs. For instance, consider the
    following layer:

    ```python
      scale = tf.Variable(1.)
      scale_layer = tf.keras.layers.Lambda(lambda x: x * scale)
    ```

    Because scale_layer does not directly track the `scale` variable, it will
    not appear in `scale_layer.trainable_weights` and will therefore not be
    trained if `scale_layer` is used in a Model.

    A better pattern is to write a subclassed Layer:

    ```python
      class ScaleLayer(tf.keras.layers.Layer):
        def __init__(self):
          super(ScaleLayer, self).__init__()
          self.scale = tf.Variable(1.)

        def call(self, inputs):
          return inputs * self.scale
    ```

    In general, Lambda layers can be convenient for simple stateless
    computation, but anything more complex should use a subclass Layer instead.

  Args:
    function: The function to be evaluated. Takes input tensor as first
      argument.
    output_shape: Expected output shape from function. This argument can be
      inferred if not explicitly provided. Can be a tuple or function. If a
      tuple, it only specifies the first dimension onward;
      sample dimension is assumed either the same as the input: `output_shape =
        (input_shape[0], ) + output_shape` or, the input is `None` and
      the sample dimension is also `None`: `output_shape = (None, ) +
        output_shape` If a function, it specifies the entire shape as a function
        of the
      input shape: `output_shape = f(input_shape)`
    mask: Either None (indicating no masking) or a callable with the same
      signature as the `compute_mask` layer method, or a tensor that will be
      returned as output mask regardless of what the input is.
    arguments: Optional dictionary of keyword arguments to be passed to the
      function.

  Input shape:
    Arbitrary. Use the keyword argument input_shape (tuple of
    integers, does not include the samples axis) when using this layer as the
    first layer in a model.

  Output shape:
    Specified by `output_shape` argument
  """

  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def __init__(self, function, output_shape=None, mask=None, arguments=None,
               **kwargs):
    super(Lambda, self).__init__(**kwargs)

    self.arguments = arguments or {}
    self.function = function

    if mask is not None:
      self.supports_masking = True
    self.mask = mask
    self._output_shape = output_shape

    # Warning on every invocation will be quite irksome in Eager mode.
    self._already_warned = False

    function_args = tf_inspect.getfullargspec(function).args
    self._fn_expects_training_arg = 'training' in function_args
    self._fn_expects_mask_arg = 'mask' in function_args

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if self._output_shape is None:
      # Make use of existing autocomputation but provide Lambda-specific
      # error message. This is always safe to run even when the outer context
      # is Graph mode because Lambda layers don't have side effects such as
      # `add_loss`.
      with tf.__internal__.eager_context.eager_mode():
        try:
          return super(Lambda, self).compute_output_shape(input_shape)
        except NotImplementedError:
          raise NotImplementedError(
              'We could not automatically infer the shape of the Lambda\'s '
              'output. Please specify `output_shape` for this Lambda.')

    if callable(self._output_shape):
      output_shapes = self._output_shape(input_shape)
      return tf_utils.convert_shapes(output_shapes, to_tuples=False)

    # Output shapes are passed directly and don't include batch dimension.
    input_tensor_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
    batch_size = tf.nest.flatten(input_tensor_shape)[0][0] if input_shape else None

    def _add_batch(shape):
      return tf.TensorShape([batch_size] + shape.as_list())

    output_shapes = tf_utils.convert_shapes(self._output_shape, to_tuples=False)
    return tf.nest.map_structure(_add_batch, output_shapes)

  def call(self, inputs, mask=None, training=None):
    # We must copy for thread safety, but it only needs to be a shallow copy.
    kwargs = {k: v for k, v in self.arguments.items()}
    if self._fn_expects_mask_arg:
      kwargs['mask'] = mask
    if self._fn_expects_training_arg:
      kwargs['training'] = training

    created_variables = []
    def _variable_creator(next_creator, **kwargs):
      var = next_creator(**kwargs)
      created_variables.append(var)
      return var

    with tf.GradientTape(watch_accessed_variables=True) as tape,\
        tf.variable_creator_scope(_variable_creator):
      result = self.function(inputs, **kwargs)
    self._check_variables(created_variables, tape.watched_variables())
    return result

  def _check_variables(self, created_variables, accessed_variables):
    if not created_variables and not accessed_variables:
      # In the common case that a Lambda layer does not touch a Variable, we
      # don't want to incur the runtime cost of assembling any state used for
      # checking only to immediately discard it.
      return

    tracked_weights = set(v.ref() for v in self.weights)
    untracked_new_vars = [
        v for v in created_variables if v.ref() not in tracked_weights
    ]
    if untracked_new_vars:
      variable_str = '\n'.join('  {}'.format(i) for i in untracked_new_vars)
      error_str = textwrap.dedent(
          '''
          The following Variables were created within a Lambda layer ({name})
          but are not tracked by said layer:
          {variable_str}
          The layer cannot safely ensure proper Variable reuse across multiple
          calls, and consquently this behavior is disallowed for safety. Lambda
          layers are not well suited to stateful computation; instead, writing a
          subclassed Layer is the recommend way to define layers with
          Variables.'''
      ).format(name=self.name, variable_str=variable_str)
      raise ValueError(error_str)

    untracked_used_vars = [
        v for v in accessed_variables if v.ref() not in tracked_weights
    ]
    if untracked_used_vars and not self._already_warned:
      variable_str = '\n'.join('  {}'.format(i) for i in untracked_used_vars)
      self._warn(textwrap.dedent(
          '''
          The following Variables were used a Lambda layer's call ({name}), but
          are not present in its tracked objects:
          {variable_str}
          It is possible that this is intended behavior, but it is more likely
          an omission. This is a strong indication that this layer should be
          formulated as a subclassed Layer rather than a Lambda layer.'''
      ).format(name=self.name, variable_str=variable_str))
      self._already_warned = True

  def _warn(self, msg):
    # This method will be overridden in a unit test to raise an error, because
    # self.assertWarns is not universally implemented.
    return tf_logging.warning(msg)

  def compute_mask(self, inputs, mask=None):
    if callable(self.mask):
      return self.mask(inputs, mask)
    return self.mask

  def get_config(self):
    function_config = self._serialize_function_to_config(self.function)
    output_shape_config = self._serialize_function_to_config(self._output_shape,
                                                             allow_raw=True)
    config = {
        'function': function_config[0],
        'function_type': function_config[1],
        'module': function_config[2],
        'output_shape': output_shape_config[0],
        'output_shape_type': output_shape_config[1],
        'output_shape_module': output_shape_config[2],
    }
    if self.mask is not None:
      mask_config = self._serialize_function_to_config(self.mask)
      config.update({
          'mask': mask_config[0],
          'mask_type': mask_config[1],
          'mask_module': mask_config[2]
      })
    config['arguments'] = self.arguments

    base_config = super(Lambda, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  def _serialize_function_to_config(self, inputs, allow_raw=False):
    if isinstance(inputs, python_types.LambdaType):
      output = generic_utils.func_dump(inputs)
      output_type = 'lambda'
      module = inputs.__module__
    elif callable(inputs):
      output = inputs.__name__
      output_type = 'function'
      module = inputs.__module__
    elif allow_raw:
      output = inputs
      output_type = 'raw'
      module = None
    else:
      raise ValueError(
          'Invalid input for serialization, type: %s ' % type(inputs))

    return output, output_type, module

  @classmethod
  def from_config(cls, config, custom_objects=None):
    config = config.copy()
    function = cls._parse_function_from_config(
        config, custom_objects, 'function', 'module', 'function_type')

    output_shape = cls._parse_function_from_config(
        config, custom_objects, 'output_shape', 'output_shape_module',
        'output_shape_type')
    if 'mask' in config:
      mask = cls._parse_function_from_config(
          config, custom_objects, 'mask', 'mask_module', 'mask_type')
    else:
      mask = None

    config['function'] = function
    config['output_shape'] = output_shape
    config['mask'] = mask

    # If arguments were numpy array, they have been saved as
    # list. We need to recover the ndarray
    if 'arguments' in config:
      for key in config['arguments']:
        if isinstance(config['arguments'][key], dict):
          arg_dict = config['arguments'][key]
          if 'type' in arg_dict and arg_dict['type'] == 'ndarray':
            # Overwrite the argument with its numpy translation
            config['arguments'][key] = np.array(arg_dict['value'])

    return cls(**config)

  @classmethod
  def _parse_function_from_config(
      cls, config, custom_objects, func_attr_name, module_attr_name,
      func_type_attr_name):
    globs = globals().copy()
    module = config.pop(module_attr_name, None)
    if module in sys.modules:
      globs.update(sys.modules[module].__dict__)
    elif module is not None:
      # Note: we don't know the name of the function if it's a lambda.
      warnings.warn('{} is not loaded, but a Lambda layer uses it. '
                    'It may cause errors.'.format(module)
                    , UserWarning)
    if custom_objects:
      globs.update(custom_objects)
    function_type = config.pop(func_type_attr_name)
    if function_type == 'function':
      # Simple lookup in custom objects
      function = generic_utils.deserialize_keras_object(
          config[func_attr_name],
          custom_objects=custom_objects,
          printable_module_name='function in Lambda layer')
    elif function_type == 'lambda':
      # Unsafe deserialization from bytecode
      function = generic_utils.func_load(
          config[func_attr_name], globs=globs)
    elif function_type == 'raw':
      function = config[func_attr_name]
    else:
      raise TypeError('Unknown function type:', function_type)
    return function

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Layer (trainable=True, name=None, dtype=None, dynamic=False, **kwargs)

This is the class from which all layers inherit.

A layer is a callable object that takes as input one or more tensors and that outputs one or more tensors. It involves computation, defined in the call() method, and a state (weight variables), defined either in the constructor __init__() or in the build() method.

Users will just instantiate a layer and then treat it as a callable.

Args

trainable
Boolean, whether the layer's variables should be trainable.
name
String name of the layer.
dtype
The dtype of the layer's computations and weights. Can also be a tf.keras.mixed_precision.Policy, which allows the computation and weight dtype to differ. Default of None means to use tf.keras.mixed_precision.global_policy(), which is a float32 policy unless set to different value.
dynamic
Set this to True if your layer should only be run eagerly, and should not be used to generate a static computation graph. This would be the case for a Tree-RNN or a recursive network, for example, or generally for any layer that manipulates tensors using Python control flow. If False, we assume that the layer can safely be used to generate a static computation graph.

Attributes

name
The name of the layer (string).
dtype
The dtype of the layer's weights.
variable_dtype
Alias of dtype.
compute_dtype
The dtype of the layer's computations. Layers automatically cast inputs to this dtype which causes the computations and output to also be in this dtype. When mixed precision is used with a tf.keras.mixed_precision.Policy, this will be different than variable_dtype.
dtype_policy
The layer's dtype policy. See the tf.keras.mixed_precision.Policy documentation for details.
trainable_weights
List of variables to be included in backprop.
non_trainable_weights
List of variables that should not be included in backprop.
weights
The concatenation of the lists trainable_weights and non_trainable_weights (in this order).
trainable
Whether the layer should be trained (boolean), i.e. whether its potentially-trainable weights should be returned as part of layer.trainable_weights.
input_spec
Optional (list of) InputSpec object(s) specifying the constraints on inputs that can be accepted by the layer.

We recommend that descendants of Layer implement the following methods:

  • __init__(): Defines custom layer attributes, and creates layer state variables that do not depend on input shapes, using add_weight().
  • build(self, input_shape): This method can be used to create weights that depend on the shape(s) of the input(s), using add_weight(). __call__() will automatically build the layer (if it has not been built yet) by calling build().
  • call(self, inputs, *args, **kwargs): Called in __call__ after making sure build() has been called. call() performs the logic of applying the layer to the input tensors (which should be passed in as argument). Two reserved keyword arguments you can optionally use in call() are:
    • training (boolean, whether the call is in inference mode or training mode). See more details in the layer/model subclassing guide
    • mask (boolean tensor encoding masked timesteps in the input, used in RNN layers). See more details in the layer/model subclassing guide A typical signature for this method is call(self, inputs), and user could optionally add training and mask if the layer need them. *args and **kwargs is only useful for future extension when more input parameters are planned to be added.
  • get_config(self): Returns a dictionary containing the configuration used to initialize this layer. If the keys differ from the arguments in __init__, then override from_config(self) as well. This method is used when saving the layer or a model that contains this layer.

Examples:

Here's a basic example: a layer with two variables, w and b, that returns y = w . x + b. It shows how to implement build() and call(). Variables set as attributes of a layer are tracked as weights of the layers (in layer.weights).

class SimpleDense(Layer):

  def __init__(self, units=32):
      super(SimpleDense, self).__init__()
      self.units = units

  def build(self, input_shape):  # Create the state of the layer (weights)
    w_init = tf.random_normal_initializer()
    self.w = tf.Variable(
        initial_value=w_init(shape=(input_shape[-1], self.units),
                             dtype='float32'),
        trainable=True)
    b_init = tf.zeros_initializer()
    self.b = tf.Variable(
        initial_value=b_init(shape=(self.units,), dtype='float32'),
        trainable=True)

  def call(self, inputs):  # Defines the computation from inputs to outputs
      return tf.matmul(inputs, self.w) + self.b

# Instantiates the layer.
linear_layer = SimpleDense(4)

# This will also call `build(input_shape)` and create the weights.
y = linear_layer(tf.ones((2, 2)))
assert len(linear_layer.weights) == 2

# These weights are trainable, so they're listed in `trainable_weights`:
assert len(linear_layer.trainable_weights) == 2

Note that the method add_weight() offers a shortcut to create weights:

class SimpleDense(Layer):

  def __init__(self, units=32):
      super(SimpleDense, self).__init__()
      self.units = units

  def build(self, input_shape):
      self.w = self.add_weight(shape=(input_shape[-1], self.units),
                               initializer='random_normal',
                               trainable=True)
      self.b = self.add_weight(shape=(self.units,),
                               initializer='random_normal',
                               trainable=True)

  def call(self, inputs):
      return tf.matmul(inputs, self.w) + self.b

Besides trainable weights, updated via backpropagation during training, layers can also have non-trainable weights. These weights are meant to be updated manually during call(). Here's a example layer that computes the running sum of its inputs:

class ComputeSum(Layer):

  def __init__(self, input_dim):
      super(ComputeSum, self).__init__()
      # Create a non-trainable weight.
      self.total = tf.Variable(initial_value=tf.zeros((input_dim,)),
                               trainable=False)

  def call(self, inputs):
      self.total.assign_add(tf.reduce_sum(inputs, axis=0))
      return self.total

my_sum = ComputeSum(2)
x = tf.ones((2, 2))

y = my_sum(x)
print(y.numpy())  # [2. 2.]

y = my_sum(x)
print(y.numpy())  # [4. 4.]

assert my_sum.weights == [my_sum.total]
assert my_sum.non_trainable_weights == [my_sum.total]
assert my_sum.trainable_weights == []

For more information about creating layers, see the guide Making new Layers and Models via subclassing

Expand source code
class Layer(tf.Module, version_utils.LayerVersionSelector):
  """This is the class from which all layers inherit.

  A layer is a callable object that takes as input one or more tensors and
  that outputs one or more tensors. It involves *computation*, defined
  in the `call()` method, and a *state* (weight variables), defined
  either in the constructor `__init__()` or in the `build()` method.

  Users will just instantiate a layer and then treat it as a callable.

  Args:
    trainable: Boolean, whether the layer's variables should be trainable.
    name: String name of the layer.
    dtype: The dtype of the layer's computations and weights. Can also be a
      `tf.keras.mixed_precision.Policy`, which allows the computation and weight
      dtype to differ. Default of `None` means to use
      `tf.keras.mixed_precision.global_policy()`, which is a float32 policy
      unless set to different value.
    dynamic: Set this to `True` if your layer should only be run eagerly, and
      should not be used to generate a static computation graph.
      This would be the case for a Tree-RNN or a recursive network,
      for example, or generally for any layer that manipulates tensors
      using Python control flow. If `False`, we assume that the layer can
      safely be used to generate a static computation graph.

  Attributes:
    name: The name of the layer (string).
    dtype: The dtype of the layer's weights.
    variable_dtype: Alias of `dtype`.
    compute_dtype: The dtype of the layer's computations. Layers automatically
      cast inputs to this dtype which causes the computations and output to also
      be in this dtype. When mixed precision is used with a
      `tf.keras.mixed_precision.Policy`, this will be different than
      `variable_dtype`.
    dtype_policy: The layer's dtype policy. See the
      `tf.keras.mixed_precision.Policy` documentation for details.
    trainable_weights: List of variables to be included in backprop.
    non_trainable_weights: List of variables that should not be
      included in backprop.
    weights: The concatenation of the lists trainable_weights and
      non_trainable_weights (in this order).
    trainable: Whether the layer should be trained (boolean), i.e. whether
      its potentially-trainable weights should be returned as part of
      `layer.trainable_weights`.
    input_spec: Optional (list of) `InputSpec` object(s) specifying the
      constraints on inputs that can be accepted by the layer.

  We recommend that descendants of `Layer` implement the following methods:

  * `__init__()`: Defines custom layer attributes, and creates layer state
    variables that do not depend on input shapes, using `add_weight()`.
  * `build(self, input_shape)`: This method can be used to create weights that
    depend on the shape(s) of the input(s), using `add_weight()`. `__call__()`
    will automatically build the layer (if it has not been built yet) by
    calling `build()`.
  * `call(self, inputs, *args, **kwargs)`: Called in `__call__` after making
    sure `build()` has been called. `call()` performs the logic of applying the
    layer to the input tensors (which should be passed in as argument).
    Two reserved keyword arguments you can optionally use in `call()` are:
      - `training` (boolean, whether the call is in inference mode or training
        mode). See more details in [the layer/model subclassing guide](
        https://www.tensorflow.org/guide/keras/custom_layers_and_models#privileged_training_argument_in_the_call_method)
      - `mask` (boolean tensor encoding masked timesteps in the input, used
        in RNN layers). See more details in [the layer/model subclassing guide](
        https://www.tensorflow.org/guide/keras/custom_layers_and_models#privileged_mask_argument_in_the_call_method)
    A typical signature for this method is `call(self, inputs)`, and user could
    optionally add `training` and `mask` if the layer need them. `*args` and
    `**kwargs` is only useful for future extension when more input parameters
    are planned to be added.
  * `get_config(self)`: Returns a dictionary containing the configuration used
    to initialize this layer. If the keys differ from the arguments
    in `__init__`, then override `from_config(self)` as well.
    This method is used when saving
    the layer or a model that contains this layer.

  Examples:

  Here's a basic example: a layer with two variables, `w` and `b`,
  that returns `y = w . x + b`.
  It shows how to implement `build()` and `call()`.
  Variables set as attributes of a layer are tracked as weights
  of the layers (in `layer.weights`).

  ```python
  class SimpleDense(Layer):

    def __init__(self, units=32):
        super(SimpleDense, self).__init__()
        self.units = units

    def build(self, input_shape):  # Create the state of the layer (weights)
      w_init = tf.random_normal_initializer()
      self.w = tf.Variable(
          initial_value=w_init(shape=(input_shape[-1], self.units),
                               dtype='float32'),
          trainable=True)
      b_init = tf.zeros_initializer()
      self.b = tf.Variable(
          initial_value=b_init(shape=(self.units,), dtype='float32'),
          trainable=True)

    def call(self, inputs):  # Defines the computation from inputs to outputs
        return tf.matmul(inputs, self.w) + self.b

  # Instantiates the layer.
  linear_layer = SimpleDense(4)

  # This will also call `build(input_shape)` and create the weights.
  y = linear_layer(tf.ones((2, 2)))
  assert len(linear_layer.weights) == 2

  # These weights are trainable, so they're listed in `trainable_weights`:
  assert len(linear_layer.trainable_weights) == 2
  ```

  Note that the method `add_weight()` offers a shortcut to create weights:

  ```python
  class SimpleDense(Layer):

    def __init__(self, units=32):
        super(SimpleDense, self).__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(shape=(input_shape[-1], self.units),
                                 initializer='random_normal',
                                 trainable=True)
        self.b = self.add_weight(shape=(self.units,),
                                 initializer='random_normal',
                                 trainable=True)

    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b
  ```

  Besides trainable weights, updated via backpropagation during training,
  layers can also have non-trainable weights. These weights are meant to
  be updated manually during `call()`. Here's a example layer that computes
  the running sum of its inputs:

  ```python
  class ComputeSum(Layer):

    def __init__(self, input_dim):
        super(ComputeSum, self).__init__()
        # Create a non-trainable weight.
        self.total = tf.Variable(initial_value=tf.zeros((input_dim,)),
                                 trainable=False)

    def call(self, inputs):
        self.total.assign_add(tf.reduce_sum(inputs, axis=0))
        return self.total

  my_sum = ComputeSum(2)
  x = tf.ones((2, 2))

  y = my_sum(x)
  print(y.numpy())  # [2. 2.]

  y = my_sum(x)
  print(y.numpy())  # [4. 4.]

  assert my_sum.weights == [my_sum.total]
  assert my_sum.non_trainable_weights == [my_sum.total]
  assert my_sum.trainable_weights == []
  ```

  For more information about creating layers, see the guide
  [Making new Layers and Models via subclassing](
    https://www.tensorflow.org/guide/keras/custom_layers_and_models)
  """

  # See tf.Module for the usage of this property.
  # The key for _obj_reference_counts_dict is a Trackable, which could be a
  # variable or layer etc. tf.Module._flatten will fail to flatten the key
  # since it is trying to convert Trackable to a string. This attribute can be
  # ignored even after the fix of nest lib, since the trackable object should
  # already been available as individual attributes. _obj_reference_counts_dict
  # just contains a copy of them.
  _TF_MODULE_IGNORED_PROPERTIES = frozenset(itertools.chain(
      ('_obj_reference_counts_dict',),
      tf.Module._TF_MODULE_IGNORED_PROPERTIES
  ))

  # When loading from a SavedModel, Layers typically can be revived into a
  # generic Layer wrapper. Sometimes, however, layers may implement methods
  # that go beyond this wrapper, as in the case of PreprocessingLayers'
  # `adapt` method. When this is the case, layer implementers can override
  # must_restore_from_config to return True; layers with this property must
  # be restored into their actual objects (and will fail if the object is
  # not available to the restoration code).
  _must_restore_from_config = False

  def _get_cell_name(self):
    canonical_name = get_canonical_name_for_symbol(
        self.__class__, api_name='keras', add_prefix_to_v1_names=True)
    if canonical_name is not None:
      return 'tf.{}'.format(canonical_name)
    return self.__class__.__module__ + '.' + self.__class__.__name__

  def _instrument_layer_creation(self):
    self._instrumented_keras_api = False
    self._instrumented_keras_layer_class = False
    self._instrumented_keras_model_class = False
    if not getattr(self, '_disable_keras_instrumentation', False):
      keras_api_gauge.get_cell('layer').set(True)
      self._instrumented_keras_api = True
      if getattr(self, '_is_model_for_instrumentation', False):
        keras_models_gauge.get_cell(self._get_cell_name()).set(True)
        self._instrumented_keras_model_class = True
      else:
        keras_layers_gauge.get_cell(self._get_cell_name()).set(True)
        self._instrumented_keras_layer_class = True

  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def __init__(self,
               trainable=True,
               name=None,
               dtype=None,
               dynamic=False,
               **kwargs):
    self._instrument_layer_creation()

    # These properties should be set by the user via keyword arguments.
    # note that 'dtype', 'input_shape' and 'batch_input_shape'
    # are only applicable to input layers: do not pass these keywords
    # to non-input layers.
    allowed_kwargs = {
        'input_dim',
        'input_shape',
        'batch_input_shape',
        'batch_size',
        'weights',
        'activity_regularizer',
        'autocast',
        'implementation',
    }
    # Validate optional keyword arguments.
    generic_utils.validate_kwargs(kwargs, allowed_kwargs)

    # Mutable properties
    # Indicates whether the layer's weights are updated during training
    # and whether the layer's updates are run during training.
    self._trainable = trainable
    # A stateful layer is a layer whose updates are run during inference too,
    # for instance stateful RNNs.
    self._stateful = False
    # Indicates whether `build` needs to be called upon layer call, to create
    # the layer's weights.
    self.built = False
    # Provides information about which inputs are compatible with the layer.
    self._input_spec = None

    # SavedModel-related attributes.
    # Record the build input shape for loading purposes.
    # TODO(kathywu): Move this to Layer._set_save_spec once cl/290121460 is
    # submitted.
    self._build_input_shape = None
    self._saved_model_inputs_spec = None
    self._saved_model_arg_spec = None

    # `Layer.compute_mask` will be called at the end of `Layer.__call__` if
    # `Layer.compute_mask` is overridden, or if the `Layer` subclass sets
    # `self.supports_masking=True`.
    self._supports_masking = not generic_utils.is_default(self.compute_mask)

    self._init_set_name(name)
    self._activity_regularizer = regularizers.get(
        kwargs.pop('activity_regularizer', None))
    self._maybe_create_attribute('_trainable_weights', [])
    self._maybe_create_attribute('_non_trainable_weights', [])
    self._updates = []
    # Object to store all thread local layer properties.
    self._thread_local = threading.local()
    # A list of zero-argument lambdas which return Tensors, used for variable
    # regularizers.
    self._callable_losses = []
    # A list of symbolic Tensors containing activity regularizers and losses
    # manually added through `add_loss` in graph-building mode.
    self._losses = []
    # A list of metric instances corresponding to the symbolic metric tensors
    # added using the `add_metric` API.
    self._metrics = []
    # Ensures the same metric is not added multiple times in `MirroredStrategy`.
    self._metrics_lock = threading.Lock()

    # Both graph and subclassed networks have a dtype policy. For graph
    # networks, the policy's compute and variable dtypes are ignored. Such
    # networks only use the policy if it is a PolicyV1, in which case it uses
    # the PolicyV1's loss_scale (Policy does not have a loss_scale). For
    # subclassed networks, the compute and variable dtypes are used as like any
    # ordinary layer.
    self._set_dtype_policy(dtype)
    # Boolean indicating whether the layer automatically casts its inputs to the
    # layer's compute_dtype.
    self._autocast = kwargs.get('autocast',
                                base_layer_utils.v2_dtype_behavior_enabled())

    # Tracks `TrackableDataStructure`s, `Module`s, and `Layer`s.
    # Ordered by when the object was assigned as an attr.
    # Entries are unique.
    self._maybe_create_attribute('_self_tracked_trackables', [])

    # These lists will be filled via successive calls
    # to self._add_inbound_node().
    # Used in symbolic mode only, only in conjunction with graph-networks
    self._inbound_nodes_value = []
    self._outbound_nodes_value = []

    self._init_call_fn_args()

    # Whether the `call` method can be used to build a TF graph without issues.
    # This attribute has no effect if the model is created using the Functional
    # API. Instead, `model.dynamic` is determined based on the internal layers.
    self._dynamic = dynamic

    # Manage input shape information if passed.
    if 'input_dim' in kwargs and 'input_shape' not in kwargs:
      # Backwards compatibility: alias 'input_dim' to 'input_shape'.
      kwargs['input_shape'] = (kwargs['input_dim'],)
    if 'input_shape' in kwargs or 'batch_input_shape' in kwargs:
      # In this case we will later create an input layer
      # to insert before the current layer
      if 'batch_input_shape' in kwargs:
        batch_input_shape = tuple(kwargs['batch_input_shape'])
      elif 'input_shape' in kwargs:
        if 'batch_size' in kwargs:
          batch_size = kwargs['batch_size']
        else:
          batch_size = None
        batch_input_shape = (batch_size,) + tuple(kwargs['input_shape'])
      self._batch_input_shape = batch_input_shape

    # Manage initial weight values if passed.
    self._initial_weights = kwargs.get('weights', None)

    # Whether the layer will track any layers that is set as attribute on itself
    # as sub-layers, the weights from the sub-layers will be included in the
    # parent layer's variables() as well.
    # Default to True, which means auto tracking is turned on. Certain subclass
    # might want to turn it off, like Sequential model.
    self._auto_track_sub_layers = True

    # For backwards compat reasons, most built-in layers do not guarantee
    # That they will 100% preserve the structure of input args when saving
    # / loading configs. E.g. they may un-nest an arg that is
    # a list with one element.
    self._preserve_input_structure_in_config = False

    # Save outer name scope at layer declaration so that it is preserved at
    # the actual layer construction.
    self._outer_name_scope = tf.get_current_name_scope()

  @tf.__internal__.tracking.no_automatic_dependency_tracking
  @generic_utils.default
  def build(self, input_shape):
    """Creates the variables of the layer (optional, for subclass implementers).

    This is a method that implementers of subclasses of `Layer` or `Model`
    can override if they need a state-creation step in-between
    layer instantiation and layer call.

    This is typically used to create the weights of `Layer` subclasses.

    Args:
      input_shape: Instance of `TensorShape`, or list of instances of
        `TensorShape` if the layer expects a list of inputs
        (one instance per input).
    """
    # Only record the build input shapes of overridden build methods.
    if not hasattr(self.build, '_is_default'):
      self._build_input_shape = input_shape
    self.built = True

  @doc_controls.for_subclass_implementers
  def call(self, inputs, *args, **kwargs):  # pylint: disable=unused-argument
    """This is where the layer's logic lives.

    Note here that `call()` method in `tf.keras` is little bit different
    from `keras` API. In `keras` API, you can pass support masking for
    layers as additional arguments. Whereas `tf.keras` has `compute_mask()`
    method to support masking.

    Args:
      inputs: Input tensor, or dict/list/tuple of input tensors.
        The first positional `inputs` argument is subject to special rules:
        - `inputs` must be explicitly passed. A layer cannot have zero
          arguments, and `inputs` cannot be provided via the default value
          of a keyword argument.
        - NumPy array or Python scalar values in `inputs` get cast as tensors.
        - Keras mask metadata is only collected from `inputs`.
        - Layers are built (`build(input_shape)` method)
          using shape info from `inputs` only.
        - `input_spec` compatibility is only checked against `inputs`.
        - Mixed precision input casting is only applied to `inputs`.
          If a layer has tensor arguments in `*args` or `**kwargs`, their
          casting behavior in mixed precision should be handled manually.
        - The SavedModel input specification is generated using `inputs` only.
        - Integration with various ecosystem packages like TFMOT, TFLite,
          TF.js, etc is only supported for `inputs` and not for tensors in
          positional and keyword arguments.
      *args: Additional positional arguments. May contain tensors, although
        this is not recommended, for the reasons above.
      **kwargs: Additional keyword arguments. May contain tensors, although
        this is not recommended, for the reasons above.
        The following optional keyword arguments are reserved:
        - `training`: Boolean scalar tensor of Python boolean indicating
          whether the `call` is meant for training or inference.
        - `mask`: Boolean input mask. If the layer's `call()` method takes a
          `mask` argument, its default value will be set to the mask generated
          for `inputs` by the previous layer (if `input` did come from a layer
          that generated a corresponding mask, i.e. if it came from a Keras
          layer with masking support).

    Returns:
      A tensor or list/tuple of tensors.
    """
    return inputs

  @doc_controls.for_subclass_implementers
  def _add_trackable(self, trackable_object, trainable):
    """Adds a Trackable object to this layer's state.

    Args:
      trackable_object: The tf.tracking.Trackable object to add.
      trainable: Boolean, whether the variable should be part of the layer's
        "trainable_variables" (e.g. variables, biases) or
        "non_trainable_variables" (e.g. BatchNorm mean and variance).

    Returns:
      The TrackableWeightHandler used to track this object.
    """
    if isinstance(trackable_object, base_layer_utils.TrackableWeightHandler):
      handler = trackable_object
    else:
      handler = base_layer_utils.TrackableWeightHandler(trackable_object)
    if trainable:
      self._trainable_weights.append(handler)
    else:
      self._non_trainable_weights.append(handler)
    return handler

  @doc_controls.for_subclass_implementers
  def add_weight(self,
                 name=None,
                 shape=None,
                 dtype=None,
                 initializer=None,
                 regularizer=None,
                 trainable=None,
                 constraint=None,
                 use_resource=None,
                 synchronization=tf.VariableSynchronization.AUTO,
                 aggregation=tf.VariableAggregation.NONE,
                 **kwargs):
    """Adds a new variable to the layer.

    Args:
      name: Variable name.
      shape: Variable shape. Defaults to scalar if unspecified.
      dtype: The type of the variable. Defaults to `self.dtype`.
      initializer: Initializer instance (callable).
      regularizer: Regularizer instance (callable).
      trainable: Boolean, whether the variable should be part of the layer's
        "trainable_variables" (e.g. variables, biases)
        or "non_trainable_variables" (e.g. BatchNorm mean and variance).
        Note that `trainable` cannot be `True` if `synchronization`
        is set to `ON_READ`.
      constraint: Constraint instance (callable).
      use_resource: Whether to use `ResourceVariable`.
      synchronization: Indicates when a distributed a variable will be
        aggregated. Accepted values are constants defined in the class
        `tf.VariableSynchronization`. By default the synchronization is set to
        `AUTO` and the current `DistributionStrategy` chooses
        when to synchronize. If `synchronization` is set to `ON_READ`,
        `trainable` must not be set to `True`.
      aggregation: Indicates how a distributed variable will be aggregated.
        Accepted values are constants defined in the class
        `tf.VariableAggregation`.
      **kwargs: Additional keyword arguments. Accepted values are `getter`,
        `collections`, `experimental_autocast` and `caching_device`.

    Returns:
      The variable created.

    Raises:
      ValueError: When giving unsupported dtype and no initializer or when
        trainable has been set to True with synchronization set as `ON_READ`.
    """
    if shape is None:
      shape = ()
    kwargs.pop('partitioner', None)  # Ignored.
    # Validate optional keyword arguments.
    for kwarg in kwargs:
      if kwarg not in ['collections', 'experimental_autocast',
                       'caching_device', 'getter']:
        raise TypeError('Unknown keyword argument:', kwarg)
    collections_arg = kwargs.pop('collections', None)
    # 'experimental_autocast' can be set to False by the caller to indicate an
    # AutoCastVariable should never be created.
    autocast = kwargs.pop('experimental_autocast', True)
    # See the docstring for tf.Variable about the details for caching_device.
    caching_device = kwargs.pop('caching_device', None)

    if dtype is None:
      dtype = self.dtype or backend.floatx()
    dtype = tf.as_dtype(dtype)
    if self._dtype_policy.variable_dtype is None:
      # The policy is "_infer", so we infer the policy from the variable dtype.
      self._set_dtype_policy(policy.Policy(dtype.base_dtype.name))
    initializer = initializers.get(initializer)
    regularizer = regularizers.get(regularizer)
    constraint = constraints.get(constraint)

    if synchronization == tf.VariableSynchronization.ON_READ:
      if trainable:
        raise ValueError(
            'Synchronization value can be set to '
            'VariableSynchronization.ON_READ only for non-trainable variables. '
            'You have specified trainable=True and '
            'synchronization=VariableSynchronization.ON_READ.')
      else:
        # Set trainable to be false when variable is to be synced on read.
        trainable = False
    elif trainable is None:
      trainable = True

    # Initialize variable when no initializer provided
    if initializer is None:
      # If dtype is DT_FLOAT, provide a uniform unit scaling initializer
      if dtype.is_floating:
        initializer = initializers.get('glorot_uniform')
      # If dtype is DT_INT/DT_UINT, provide a default value `zero`
      # If dtype is DT_BOOL, provide a default value `FALSE`
      elif dtype.is_integer or dtype.is_unsigned or dtype.is_bool:
        initializer = initializers.get('zeros')
      # NOTES:Do we need to support for handling DT_STRING and DT_COMPLEX here?
      elif 'getter' not in kwargs:
        # When `getter` is specified, it's possibly fine for `initializer` to be
        # None since it's up to the custom `getter` to raise error in case it
        # indeed needs `initializer`.
        raise ValueError('An initializer for variable %s of type %s is required'
                         ' for layer %s' % (name, dtype.base_dtype, self.name))

    getter = kwargs.pop('getter', base_layer_utils.make_variable)
    if (autocast and
        self._dtype_policy.compute_dtype != self._dtype_policy.variable_dtype
        and dtype.is_floating):
      old_getter = getter
      # Wrap variable constructor to return an AutoCastVariable.
      def getter(*args, **kwargs):  # pylint: disable=function-redefined
        variable = old_getter(*args, **kwargs)
        return autocast_variable.create_autocast_variable(variable)
      # Also the caching_device does not work with the mixed precision API,
      # disable it if it is specified.
      # TODO(b/142020079): Reenable it once the bug is fixed.
      if caching_device is not None:
        tf_logging.warning(
            '`caching_device` does not work with mixed precision API. Ignoring '
            'user specified `caching_device`.')
        caching_device = None

    variable = self._add_variable_with_custom_getter(
        name=name,
        shape=shape,
        # TODO(allenl): a `make_variable` equivalent should be added as a
        # `Trackable` method.
        getter=getter,
        # Manage errors in Layer rather than Trackable.
        overwrite=True,
        initializer=initializer,
        dtype=dtype,
        constraint=constraint,
        trainable=trainable,
        use_resource=use_resource,
        collections=collections_arg,
        synchronization=synchronization,
        aggregation=aggregation,
        caching_device=caching_device)
    if regularizer is not None:
      # TODO(fchollet): in the future, this should be handled at the
      # level of variable creation, and weight regularization losses
      # should be variable attributes.
      name_in_scope = variable.name[:variable.name.find(':')]
      self._handle_weight_regularization(name_in_scope,
                                         variable,
                                         regularizer)
    if base_layer_utils.is_split_variable(variable):
      for v in variable:
        backend.track_variable(v)
        if trainable:
          self._trainable_weights.append(v)
        else:
          self._non_trainable_weights.append(v)
    else:
      backend.track_variable(variable)
      if trainable:
        self._trainable_weights.append(variable)
      else:
        self._non_trainable_weights.append(variable)
    return variable

  @generic_utils.default
  def get_config(self):
    """Returns the config of the layer.

    A layer config is a Python dictionary (serializable)
    containing the configuration of a layer.
    The same layer can be reinstantiated later
    (without its trained weights) from this configuration.

    The config of a layer does not include connectivity
    information, nor the layer class name. These are handled
    by `Network` (one layer of abstraction above).

    Note that `get_config()` does not guarantee to return a fresh copy of dict
    every time it is called. The callers should make a copy of the returned dict
    if they want to modify it.

    Returns:
        Python dictionary.
    """
    all_args = tf_inspect.getfullargspec(self.__init__).args
    config = {
        'name': self.name,
        'trainable': self.trainable,
    }
    if hasattr(self, '_batch_input_shape'):
      config['batch_input_shape'] = self._batch_input_shape
    config['dtype'] = policy.serialize(self._dtype_policy)
    if hasattr(self, 'dynamic'):
      # Only include `dynamic` in the `config` if it is `True`
      if self.dynamic:
        config['dynamic'] = self.dynamic
      elif 'dynamic' in all_args:
        all_args.remove('dynamic')
    expected_args = config.keys()
    # Finds all arguments in the `__init__` that are not in the config:
    extra_args = [arg for arg in all_args if arg not in expected_args]
    # Check that either the only argument in the `__init__` is  `self`,
    # or that `get_config` has been overridden:
    if len(extra_args) > 1 and hasattr(self.get_config, '_is_default'):
      raise NotImplementedError('Layer %s has arguments in `__init__` and '
                                'therefore must override `get_config`.' %
                                self.__class__.__name__)
    return config

  @classmethod
  def from_config(cls, config):
    """Creates a layer from its config.

    This method is the reverse of `get_config`,
    capable of instantiating the same layer from the config
    dictionary. It does not handle layer connectivity
    (handled by Network), nor weights (handled by `set_weights`).

    Args:
        config: A Python dictionary, typically the
            output of get_config.

    Returns:
        A layer instance.
    """
    return cls(**config)

  def compute_output_shape(self, input_shape):
    """Computes the output shape of the layer.

    If the layer has not been built, this method will call `build` on the
    layer. This assumes that the layer will later be used with inputs that
    match the input shape provided here.

    Args:
        input_shape: Shape tuple (tuple of integers)
            or list of shape tuples (one per output tensor of the layer).
            Shape tuples can include None for free dimensions,
            instead of an integer.

    Returns:
        An input shape tuple.
    """
    if tf.executing_eagerly():
      # In this case we build the model first in order to do shape inference.
      # This is acceptable because the framework only calls
      # `compute_output_shape` on shape values that the layer would later be
      # built for. It would however cause issues in case a user attempts to
      # use `compute_output_shape` manually with shapes that are incompatible
      # with the shape the Layer will be called on (these users will have to
      # implement `compute_output_shape` themselves).
      self._maybe_build(input_shape)
      with tf.__internal__.FuncGraph(str(self.name) + '_scratch_graph').as_default():
        input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
        def _make_placeholder_like(shape):
          ph = backend.placeholder(shape=shape, dtype=self.dtype)
          ph._keras_mask = None
          return ph
        inputs = tf.nest.map_structure(_make_placeholder_like, input_shape)
        try:
          outputs = self(inputs, training=False)
        except TypeError as e:
          raise NotImplementedError(
              'We could not automatically infer the static shape of the '
              'layer\'s output. Please implement the '
              '`compute_output_shape` method on your layer (%s).' %
              self.__class__.__name__) from e
      return tf.nest.map_structure(lambda t: t.shape, outputs)
    raise NotImplementedError(
        'Please run in eager mode or implement the `compute_output_shape` '
        'method on your layer (%s).' % self.__class__.__name__)

  @doc_controls.for_subclass_implementers
  def compute_output_signature(self, input_signature):
    """Compute the output tensor signature of the layer based on the inputs.

    Unlike a TensorShape object, a TensorSpec object contains both shape
    and dtype information for a tensor. This method allows layers to provide
    output dtype information if it is different from the input dtype.
    For any layer that doesn't implement this function,
    the framework will fall back to use `compute_output_shape`, and will
    assume that the output dtype matches the input dtype.

    Args:
      input_signature: Single TensorSpec or nested structure of TensorSpec
        objects, describing a candidate input for the layer.

    Returns:
      Single TensorSpec or nested structure of TensorSpec objects, describing
        how the layer would transform the provided input.

    Raises:
      TypeError: If input_signature contains a non-TensorSpec object.
    """
    def check_type_return_shape(s):
      if not isinstance(s, tf.TensorSpec):
        raise TypeError('Only TensorSpec signature types are supported, '
                        'but saw signature entry: {}.'.format(s))
      return s.shape
    input_shape = tf.nest.map_structure(check_type_return_shape, input_signature)
    output_shape = self.compute_output_shape(input_shape)
    dtype = self._compute_dtype
    if dtype is None:
      input_dtypes = [s.dtype for s in tf.nest.flatten(input_signature)]
      # Default behavior when self.dtype is None, is to use the first input's
      # dtype.
      dtype = input_dtypes[0]
    return tf.nest.map_structure(
        lambda s: tf.TensorSpec(dtype=dtype, shape=s),
        output_shape)

  def _keras_tensor_symbolic_call(self, inputs, input_masks, args, kwargs):
    if self.dynamic:
      # We will use static shape inference to return symbolic tensors
      # matching the specifications of the layer outputs.
      # Since `self.dynamic` is True, we will never attempt to
      # run the underlying TF graph (which is disconnected).
      # TODO(fchollet): consider py_func as an alternative, which
      # would enable us to run the underlying graph if needed.
      input_signature = tf.nest.map_structure(
          lambda x: tf.TensorSpec(shape=x.shape, dtype=x.dtype),
          inputs)
      output_signature = self.compute_output_signature(input_signature)
      return tf.nest.map_structure(keras_tensor.KerasTensor, output_signature)
    else:
      return self._infer_output_signature(inputs, args, kwargs, input_masks)

  def _infer_output_signature(self, inputs, args, kwargs, input_masks):
    """TODO(kaftan): Docstring."""

    call_fn = self.call
    # Wrapping `call` function in autograph to allow for dynamic control
    # flow and control dependencies in call. We are limiting this to
    # subclassed layers as autograph is strictly needed only for
    # subclassed layers and models.
    # tf_convert will respect the value of autograph setting in the
    # enclosing tf.function, if any.
    if (base_layer_utils.is_subclassed(self) and
        not base_layer_utils.from_saved_model(self)):
      call_fn = tf.__internal__.autograph.tf_convert(self.call, tf.__internal__.autograph.control_status_ctx())

    # We enter a scratch graph and build placeholder inputs inside of it that
    # match the input args.
    # We then call the layer inside of the scratch graph to identify the
    # output signatures, then we build KerasTensors corresponding to those
    # outputs.
    scratch_graph = tf.__internal__.FuncGraph(str(self.name) + '_scratch_graph')
    with scratch_graph.as_default():
      inputs = tf.nest.map_structure(
          keras_tensor.keras_tensor_to_placeholder, inputs)
      args = tf.nest.map_structure(
          keras_tensor.keras_tensor_to_placeholder, args)
      kwargs = tf.nest.map_structure(
          keras_tensor.keras_tensor_to_placeholder, kwargs)
      input_masks = tf.nest.map_structure(
          keras_tensor.keras_tensor_to_placeholder, input_masks)

      with backend.name_scope(self._name_scope()):  # pylint: disable=not-callable
        with autocast_variable.enable_auto_cast_variables(
            self._compute_dtype_object):
          # Build layer if applicable (if the `build` method has been
          # overridden).
          # TODO(kaftan): do we maybe_build here, or have we already done it?
          self._maybe_build(inputs)
          inputs = self._maybe_cast_inputs(inputs)
          outputs = call_fn(inputs, *args, **kwargs)

        self._handle_activity_regularization(inputs, outputs)
      self._set_mask_metadata(inputs, outputs, input_masks,
                              build_graph=False)
      outputs = tf.nest.map_structure(
          keras_tensor.keras_tensor_from_tensor, outputs)

    if hasattr(self, '_set_inputs') and not self.inputs:
      # TODO(kaftan): figure out if we need to do this at all
      # Subclassed network: explicitly set metadata normally set by
      # a call to self._set_inputs().
      self._set_inputs(inputs, outputs)
    del scratch_graph
    return outputs

  @generic_utils.default
  def compute_mask(self, inputs, mask=None):  # pylint: disable=unused-argument
    """Computes an output mask tensor.

    Args:
        inputs: Tensor or list of tensors.
        mask: Tensor or list of tensors.

    Returns:
        None or a tensor (or list of tensors,
            one per output tensor of the layer).
    """
    if not self._supports_masking:
      if any(m is not None for m in tf.nest.flatten(mask)):
        raise TypeError('Layer ' + self.name + ' does not support masking, '
                        'but was passed an input_mask: ' + str(mask))
      # masking not explicitly supported: return None as mask.
      return None
    # if masking is explicitly supported, by default
    # carry over the input mask
    return mask

  def __call__(self, *args, **kwargs):
    """Wraps `call`, applying pre- and post-processing steps.

    Args:
      *args: Positional arguments to be passed to `self.call`.
      **kwargs: Keyword arguments to be passed to `self.call`.

    Returns:
      Output tensor(s).

    Note:
      - The following optional keyword arguments are reserved for specific uses:
        * `training`: Boolean scalar tensor of Python boolean indicating
          whether the `call` is meant for training or inference.
        * `mask`: Boolean input mask.
      - If the layer's `call` method takes a `mask` argument (as some Keras
        layers do), its default value will be set to the mask generated
        for `inputs` by the previous layer (if `input` did come from
        a layer that generated a corresponding mask, i.e. if it came from
        a Keras layer with masking support.
      - If the layer is not built, the method will call `build`.

    Raises:
      ValueError: if the layer's `call` method returns None (an invalid value).
      RuntimeError: if `super().__init__()` was not called in the constructor.
    """
    if not hasattr(self, '_thread_local'):
      raise RuntimeError(
          'You must call `super().__init__()` in the layer constructor.')

    # `inputs` (the first arg in the method spec) is special cased in
    # layer call due to historical reasons.
    # This special casing currently takes the form of:
    # - 'inputs' must be explicitly passed. A layer cannot have zero arguments,
    #   and inputs cannot have been provided via the default value of a kwarg.
    # - numpy/scalar values in `inputs` get converted to tensors
    # - implicit masks / mask metadata are only collected from 'inputs`
    # - Layers are built using shape info from 'inputs' only
    # - input_spec compatibility is only checked against `inputs`
    # - mixed precision casting (autocast) is only applied to `inputs`,
    #   not to any other argument.
    inputs, args, kwargs = self._split_out_first_arg(args, kwargs)
    input_list = tf.nest.flatten(inputs)

    # Functional Model construction mode is invoked when `Layer`s are called on
    # symbolic `KerasTensor`s, i.e.:
    # >> inputs = tf.keras.Input(10)
    # >> outputs = MyLayer()(inputs)  # Functional construction mode.
    # >> model = tf.keras.Model(inputs, outputs)
    if _in_functional_construction_mode(self, inputs, args, kwargs, input_list):
      return self._functional_construction_call(inputs, args, kwargs,
                                                input_list)

    # Maintains info about the `Layer.call` stack.
    call_context = base_layer_utils.call_context()

    # Accept NumPy and scalar inputs by converting to Tensors.
    if any(isinstance(x, (
        tf.Tensor, np.ndarray, float, int)) for x in input_list):
      inputs = tf.nest.map_structure(_convert_numpy_or_python_types, inputs)
      input_list = tf.nest.flatten(inputs)

    # Handle `mask` propagation from previous layer to current layer. Masks can
    # be propagated explicitly via the `mask` argument, or implicitly via
    # setting the `_keras_mask` attribute on the inputs to a Layer. Masks passed
    # explicitly take priority.
    input_masks, mask_is_implicit = self._get_input_masks(
        inputs, input_list, args, kwargs)
    if self._expects_mask_arg and mask_is_implicit:
      kwargs['mask'] = input_masks

    # Training mode for `Layer.call` is set via (in order of priority):
    # (1) The `training` argument passed to this `Layer.call`, if it is not None
    # (2) The training mode of an outer `Layer.call`.
    # (3) The default mode set by `tf.keras.backend.set_learning_phase` (if set)
    # (4) Any non-None default value for `training` specified in the call
    #  signature
    # (5) False (treating the layer as if it's in inference)
    args, kwargs, training_mode = self._set_training_mode(
        args, kwargs, call_context)

    # Losses are cleared for all sublayers on the outermost `Layer.call`.
    # Losses are not cleared on inner `Layer.call`s, because sublayers can be
    # called multiple times.
    if not call_context.in_call:
      self._clear_losses()

    eager = tf.executing_eagerly()
    with call_context.enter(
        layer=self,
        inputs=inputs,
        build_graph=not eager,
        training=training_mode):

      input_spec.assert_input_compatibility(self.input_spec, inputs, self.name)
      if eager:
        call_fn = self.call
        name_scope = self._name
      else:
        name_scope = self._name_scope()  # Avoid autoincrementing.  # pylint: disable=not-callable
        call_fn = self._autographed_call()

      with tf.name_scope(name_scope):
        if not self.built:
          self._maybe_build(inputs)

        if self._autocast:
          inputs = self._maybe_cast_inputs(inputs, input_list)

        with autocast_variable.enable_auto_cast_variables(
            self._compute_dtype_object):
          outputs = call_fn(inputs, *args, **kwargs)

        if self._activity_regularizer:
          self._handle_activity_regularization(inputs, outputs)
        if self._supports_masking:
          self._set_mask_metadata(inputs, outputs, input_masks, not eager)
        if self._saved_model_inputs_spec is None:
          self._set_save_spec(inputs, args, kwargs)

        return outputs

  def _functional_construction_call(self, inputs, args, kwargs, input_list):
    call_context = base_layer_utils.call_context()

    # Accept NumPy and scalar inputs by converting to Tensors.
    if any(isinstance(x, (
        tf.Tensor, np.ndarray, float, int)) for x in input_list):

      def _convert_non_tensor(x):
        # Don't call `ops.convert_to_tensor` on all `inputs` because
        # `SparseTensors` can't be converted to `Tensor`.
        if isinstance(x, (tf.Tensor, np.ndarray, float, int)):
          return tf.convert_to_tensor(x)
        return x

      inputs = tf.nest.map_structure(_convert_non_tensor, inputs)
      input_list = tf.nest.flatten(inputs)

    # Handle `mask` propagation from previous layer to current layer. Masks can
    # be propagated explicitly via the `mask` argument, or implicitly via
    # setting the `_keras_mask` attribute on the inputs to a Layer. Masks passed
    # explicitly take priority.
    mask_arg_passed_by_framework = False
    input_masks, mask_is_implicit = self._get_input_masks(
        inputs, input_list, args, kwargs)
    if self._expects_mask_arg and mask_is_implicit:
      kwargs['mask'] = input_masks
      mask_arg_passed_by_framework = True

    # If `training` argument is None or not explicitly passed,
    # propagate `training` value from this layer's calling layer.
    training_value = None
    training_arg_passed_by_framework = False
    # Priority 1: `training` was explicitly passed a non-None value.
    if self._call_arg_was_passed('training', args, kwargs):
      training_value = self._get_call_arg_value('training', args, kwargs)
      if not self._expects_training_arg:
        kwargs.pop('training')

    if training_value is None:
      # Priority 2: `training` was passed to a parent layer.
      if call_context.training is not None:
        training_value = call_context.training
      # Priority 3: `learning_phase()` has been set.
      elif backend.global_learning_phase_is_set():
        training_value = backend.learning_phase()
        # Force the training_value to be bool type which matches to the contract
        # for layer/model call args.
        if tf.is_tensor(training_value):
          training_value = tf.cast(training_value, tf.bool)
        else:
          training_value = bool(training_value)
      # Priority 4: trace layer with the default training argument specified
      # in the `call` signature (or in inference mode if the `call` signature
      # specifies no non-None default).
      else:
        training_value = self._default_training_arg
      # In cases (2), (3), (4) the training argument is passed automatically
      # by the framework, and will not be hard-coded into the model.
      if self._expects_training_arg:
        args, kwargs = self._set_call_arg_value('training', training_value,
                                                args, kwargs)
        training_arg_passed_by_framework = True

    with call_context.enter(
        layer=self, inputs=inputs, build_graph=True, training=training_value):
      # Check input assumptions set after layer building, e.g. input shape.
      outputs = self._keras_tensor_symbolic_call(
          inputs, input_masks, args, kwargs)

      if outputs is None:
        raise ValueError('A layer\'s `call` method should return a '
                         'Tensor or a list of Tensors, not None '
                         '(layer: ' + self.name + ').')
      if training_arg_passed_by_framework:
        args, kwargs = self._set_call_arg_value(
            'training', None, args, kwargs, pop_kwarg_if_none=True)
      if mask_arg_passed_by_framework:
        kwargs.pop('mask')
      # Node connectivity does not special-case the first argument.
      outputs = self._set_connectivity_metadata((inputs,) + args, kwargs,
                                                outputs)
      return outputs

  def _set_training_mode(self, args, kwargs, call_context):
    training_mode = None
    if self._expects_training_arg:
      # (1) `training` was passed to this `Layer.call`.
      if self._call_arg_was_passed('training', args, kwargs):
        training_mode = self._get_call_arg_value('training', args, kwargs)
      # If no `training` arg was passed, or `None` was explicitly passed,
      # the framework will make a decision about the training mode is.
      if training_mode is None:
        call_ctx_training = call_context.training
        # (2) `training` mode is inferred from an outer `Layer.call`.
        if call_ctx_training is not None:
          training_mode = call_ctx_training
        # (3) User set `tf.keras.backend.set_learning_phase`.
        elif backend.global_learning_phase_is_set():
          training_mode = backend.learning_phase()
          # Ensure value is a `bool` or `tf.bool`.
          if isinstance(training_mode, bool):
            pass
          elif tf.is_tensor(training_mode):
            training_mode = tf.cast(training_mode, tf.bool)
          else:
            training_mode = bool(training_mode)
        # (4) We default to using `call`'s default value for `training`,
        # or treating the layer as if it is in inference if no non-None default
        # is specified in the `call` signature.
        else:
          training_mode = self._default_training_arg

        # For case (2), (3), (4) `training` arg is passed by framework.
        args, kwargs = self._set_call_arg_value('training', training_mode, args,
                                                kwargs)
    else:
      if 'training' in kwargs:
        # `training` was passed to this `Layer` but is not needed for
        # `Layer.call`. It will set the default mode for inner `Layer.call`s.
        training_mode = kwargs.pop('training')
      else:
        # Grab the current `training` mode from any outer `Layer.call`.
        training_mode = call_context.training

    return args, kwargs, training_mode

  def _autographed_call(self):
    # Wrapping `call` function in autograph to allow for dynamic control
    # flow and control dependencies in call. We are limiting this to
    # subclassed layers as autograph is strictly needed only for
    # subclassed layers and models.
    # tf_convert will respect the value of autograph setting in the
    # enclosing tf.function, if any.
    if (base_layer_utils.is_subclassed(self) and
        not base_layer_utils.from_saved_model(self)):
      return tf.__internal__.autograph.tf_convert(self.call, tf.__internal__.autograph.control_status_ctx())
    else:
      return self.call

  @property
  def dtype(self):
    """The dtype of the layer weights.

    This is equivalent to `Layer.dtype_policy.variable_dtype`. Unless
    mixed precision is used, this is the same as `Layer.compute_dtype`, the
    dtype of the layer's computations.
    """
    return self._dtype_policy.variable_dtype

  @property
  def name(self):
    """Name of the layer (string), set in the constructor."""
    return self._name

  @property
  def supports_masking(self):
    """Whether this layer supports computing a mask using `compute_mask`."""
    return self._supports_masking

  @supports_masking.setter
  def supports_masking(self, value):
    self._supports_masking = value

  @property
  def dynamic(self):
    """Whether the layer is dynamic (eager-only); set in the constructor."""
    return any(layer._dynamic for layer in self._flatten_layers())

  @property
  @doc_controls.do_not_doc_inheritable
  def stateful(self):
    return any(layer._stateful for layer in self._flatten_layers())

  @stateful.setter
  def stateful(self, value):
    self._stateful = value

  @property
  def trainable(self):
    return self._trainable

  @trainable.setter
  def trainable(self, value):
    """Sets trainable attribute for the layer and its sublayers.

    When this value is changed during training (e.g. with a
    `tf.keras.callbacks.Callback`) you need to call the parent
    `tf.keras.Model.make_train_function` with `force=True` in order to recompile
    the training graph.

    Args:
      value: Boolean with the desired state for the layer's trainable attribute.
    """
    for layer in self._flatten_layers():
      layer._trainable = value

  @property
  def activity_regularizer(self):
    """Optional regularizer function for the output of this layer."""
    return self._activity_regularizer

  @activity_regularizer.setter
  def activity_regularizer(self, regularizer):
    """Optional regularizer function for the output of this layer."""
    self._activity_regularizer = regularizer

  @property
  def input_spec(self):
    """`InputSpec` instance(s) describing the input format for this layer.

    When you create a layer subclass, you can set `self.input_spec` to enable
    the layer to run input compatibility checks when it is called.
    Consider a `Conv2D` layer: it can only be called on a single input tensor
    of rank 4. As such, you can set, in `__init__()`:

    ```python
    self.input_spec = tf.keras.layers.InputSpec(ndim=4)
    ```

    Now, if you try to call the layer on an input that isn't rank 4
    (for instance, an input of shape `(2,)`, it will raise a nicely-formatted
    error:

    ```
    ValueError: Input 0 of layer conv2d is incompatible with the layer:
    expected ndim=4, found ndim=1. Full shape received: [2]
    ```

    Input checks that can be specified via `input_spec` include:
    - Structure (e.g. a single input, a list of 2 inputs, etc)
    - Shape
    - Rank (ndim)
    - Dtype

    For more information, see `tf.keras.layers.InputSpec`.

    Returns:
      A `tf.keras.layers.InputSpec` instance, or nested structure thereof.
    """
    return self._input_spec

  @input_spec.setter
  # Must be decorated to prevent tracking, since the input_spec can be nested
  # InputSpec objects.
  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def input_spec(self, value):
    for v in tf.nest.flatten(value):
      if v is not None and not isinstance(v, InputSpec):
        raise TypeError('Layer input_spec must be an instance of InputSpec. '
                        'Got: {}'.format(v))
    self._input_spec = value

  @property
  def trainable_weights(self):
    """List of all trainable weights tracked by this layer.

    Trainable weights are updated via gradient descent during training.

    Returns:
      A list of trainable variables.
    """
    if self.trainable:
      children_weights = self._gather_children_attribute('trainable_variables')
      return self._dedup_weights(self._trainable_weights + children_weights)
    else:
      return []

  @property
  def non_trainable_weights(self):
    """List of all non-trainable weights tracked by this layer.

    Non-trainable weights are *not* updated during training. They are expected
    to be updated manually in `call()`.

    Returns:
      A list of non-trainable variables.
    """
    if self.trainable:
      children_weights = self._gather_children_attribute(
          'non_trainable_variables')
      non_trainable_weights = self._non_trainable_weights + children_weights
    else:
      children_weights = self._gather_children_attribute('variables')
      non_trainable_weights = (
          self._trainable_weights + self._non_trainable_weights +
          children_weights)
    return self._dedup_weights(non_trainable_weights)

  @property
  def weights(self):
    """Returns the list of all layer variables/weights.

    Returns:
      A list of variables.
    """
    return self.trainable_weights + self.non_trainable_weights

  @property
  @doc_controls.do_not_generate_docs
  def updates(self):
    warnings.warn('`layer.updates` will be removed in a future version. '
                  'This property should not be used in TensorFlow 2.0, '
                  'as `updates` are applied automatically.')
    return []

  @property
  def losses(self):
    """List of losses added using the `add_loss()` API.

    Variable regularization tensors are created when this property is accessed,
    so it is eager safe: accessing `losses` under a `tf.GradientTape` will
    propagate gradients back to the corresponding variables.

    Examples:

    >>> class MyLayer(tf.keras.layers.Layer):
    ...   def call(self, inputs):
    ...     self.add_loss(tf.abs(tf.reduce_mean(inputs)))
    ...     return inputs
    >>> l = MyLayer()
    >>> l(np.ones((10, 1)))
    >>> l.losses
    [1.0]

    >>> inputs = tf.keras.Input(shape=(10,))
    >>> x = tf.keras.layers.Dense(10)(inputs)
    >>> outputs = tf.keras.layers.Dense(1)(x)
    >>> model = tf.keras.Model(inputs, outputs)
    >>> # Activity regularization.
    >>> len(model.losses)
    0
    >>> model.add_loss(tf.abs(tf.reduce_mean(x)))
    >>> len(model.losses)
    1

    >>> inputs = tf.keras.Input(shape=(10,))
    >>> d = tf.keras.layers.Dense(10, kernel_initializer='ones')
    >>> x = d(inputs)
    >>> outputs = tf.keras.layers.Dense(1)(x)
    >>> model = tf.keras.Model(inputs, outputs)
    >>> # Weight regularization.
    >>> model.add_loss(lambda: tf.reduce_mean(d.kernel))
    >>> model.losses
    [<tf.Tensor: shape=(), dtype=float32, numpy=1.0>]

    Returns:
      A list of tensors.
    """
    collected_losses = []
    for layer in self._flatten_layers():
      # If any eager losses are present, we assume the model to be part of an
      # eager training loop (either a custom one or the one used when
      # `run_eagerly=True`) and so we always return just the eager losses.
      if layer._eager_losses:
        # Filter placeholder losses that may have been added by revived layers.
        # (see base_layer_utils for details).
        if (layer._eager_losses[0] is
            not base_layer_utils.REVIVED_LOSS_PLACEHOLDER):
          collected_losses.extend(layer._eager_losses)
      else:
        collected_losses.extend(layer._losses)
      for regularizer in layer._callable_losses:
        loss_tensor = regularizer()
        if loss_tensor is not None:
          collected_losses.append(loss_tensor)
    return collected_losses

  def add_loss(self, losses, **kwargs):
    """Add loss tensor(s), potentially dependent on layer inputs.

    Some losses (for instance, activity regularization losses) may be dependent
    on the inputs passed when calling a layer. Hence, when reusing the same
    layer on different inputs `a` and `b`, some entries in `layer.losses` may
    be dependent on `a` and some on `b`. This method automatically keeps track
    of dependencies.

    This method can be used inside a subclassed layer or model's `call`
    function, in which case `losses` should be a Tensor or list of Tensors.

    Example:

    ```python
    class MyLayer(tf.keras.layers.Layer):
      def call(self, inputs):
        self.add_loss(tf.abs(tf.reduce_mean(inputs)))
        return inputs
    ```

    This method can also be called directly on a Functional Model during
    construction. In this case, any loss Tensors passed to this Model must
    be symbolic and be able to be traced back to the model's `Input`s. These
    losses become part of the model's topology and are tracked in `get_config`.

    Example:

    ```python
    inputs = tf.keras.Input(shape=(10,))
    x = tf.keras.layers.Dense(10)(inputs)
    outputs = tf.keras.layers.Dense(1)(x)
    model = tf.keras.Model(inputs, outputs)
    # Activity regularization.
    model.add_loss(tf.abs(tf.reduce_mean(x)))
    ```

    If this is not the case for your loss (if, for example, your loss references
    a `Variable` of one of the model's layers), you can wrap your loss in a
    zero-argument lambda. These losses are not tracked as part of the model's
    topology since they can't be serialized.

    Example:

    ```python
    inputs = tf.keras.Input(shape=(10,))
    d = tf.keras.layers.Dense(10)
    x = d(inputs)
    outputs = tf.keras.layers.Dense(1)(x)
    model = tf.keras.Model(inputs, outputs)
    # Weight regularization.
    model.add_loss(lambda: tf.reduce_mean(d.kernel))
    ```

    Args:
      losses: Loss tensor, or list/tuple of tensors. Rather than tensors, losses
        may also be zero-argument callables which create a loss tensor.
      **kwargs: Additional keyword arguments for backward compatibility.
        Accepted values:
          inputs - Deprecated, will be automatically inferred.
    """
    kwargs.pop('inputs', None)
    if kwargs:
      raise TypeError('Unknown keyword arguments: %s' % (kwargs.keys(),))

    def _tag_callable(loss):
      """Tags callable loss tensor as `_unconditional_loss`."""
      if callable(loss):
        # We run the loss without autocasting, as regularizers are often
        # numerically unstable in float16.
        with autocast_variable.enable_auto_cast_variables(None):
          loss = loss()
      if loss is None:
        return None  # Will be filtered out when computing the .losses property
      if not tf.is_tensor(loss):
        loss = tf.convert_to_tensor(
            loss, dtype=backend.floatx())
      loss._unconditional_loss = True  # pylint: disable=protected-access
      return loss

    losses = tf.nest.flatten(losses)

    callable_losses = []
    eager_losses = []
    symbolic_losses = []
    for loss in losses:
      if callable(loss):
        callable_losses.append(functools.partial(_tag_callable, loss))
        continue
      if loss is None:
        continue
      if not tf.is_tensor(loss) and not isinstance(
          loss, keras_tensor.KerasTensor):
        loss = tf.convert_to_tensor(
            loss, dtype=backend.floatx())
      # TF Functions should take the eager path.
      if ((tf_utils.is_symbolic_tensor(loss) or
           isinstance(loss, keras_tensor.KerasTensor)) and
          not base_layer_utils.is_in_tf_function()):
        symbolic_losses.append(loss)
      elif tf.is_tensor(loss):
        eager_losses.append(loss)

    self._callable_losses.extend(callable_losses)

    in_call_context = base_layer_utils.call_context().in_call
    if eager_losses and not in_call_context:
      raise ValueError(
          'Expected a symbolic Tensors or a callable for the loss value. '
          'Please wrap your loss computation in a zero argument `lambda`.')

    self._eager_losses.extend(eager_losses)

    for symbolic_loss in symbolic_losses:
      if getattr(self, '_is_graph_network', False):
        self._graph_network_add_loss(symbolic_loss)
      else:
        # Possible a loss was added in a Layer's `build`.
        self._losses.append(symbolic_loss)

  def _clear_losses(self):
    """Used every step in eager to reset losses."""
    # Set to thread local directly to avoid Layer.__setattr__ overhead.
    if not getattr(self, '_self_tracked_trackables',
                   None):  # Fast path for single Layer.
      self._thread_local._eager_losses = []
    else:
      for layer in self._flatten_layers():
        layer._thread_local._eager_losses = []

  @property
  def metrics(self):
    """List of metrics added using the `add_metric()` API.

    Example:

    >>> input = tf.keras.layers.Input(shape=(3,))
    >>> d = tf.keras.layers.Dense(2)
    >>> output = d(input)
    >>> d.add_metric(tf.reduce_max(output), name='max')
    >>> d.add_metric(tf.reduce_min(output), name='min')
    >>> [m.name for m in d.metrics]
    ['max', 'min']

    Returns:
      A list of `Metric` objects.
    """
    collected_metrics = []
    for layer in self._flatten_layers():
      with layer._metrics_lock:
        collected_metrics.extend(layer._metrics)
    return collected_metrics

  def add_metric(self, value, name=None, **kwargs):
    """Adds metric tensor to the layer.

    This method can be used inside the `call()` method of a subclassed layer
    or model.

    ```python
    class MyMetricLayer(tf.keras.layers.Layer):
      def __init__(self):
        super(MyMetricLayer, self).__init__(name='my_metric_layer')
        self.mean = tf.keras.metrics.Mean(name='metric_1')

      def call(self, inputs):
        self.add_metric(self.mean(inputs))
        self.add_metric(tf.reduce_sum(inputs), name='metric_2')
        return inputs
    ```

    This method can also be called directly on a Functional Model during
    construction. In this case, any tensor passed to this Model must
    be symbolic and be able to be traced back to the model's `Input`s. These
    metrics become part of the model's topology and are tracked when you
    save the model via `save()`.

    ```python
    inputs = tf.keras.Input(shape=(10,))
    x = tf.keras.layers.Dense(10)(inputs)
    outputs = tf.keras.layers.Dense(1)(x)
    model = tf.keras.Model(inputs, outputs)
    model.add_metric(math_ops.reduce_sum(x), name='metric_1')
    ```

    Note: Calling `add_metric()` with the result of a metric object on a
    Functional Model, as shown in the example below, is not supported. This is
    because we cannot trace the metric result tensor back to the model's inputs.

    ```python
    inputs = tf.keras.Input(shape=(10,))
    x = tf.keras.layers.Dense(10)(inputs)
    outputs = tf.keras.layers.Dense(1)(x)
    model = tf.keras.Model(inputs, outputs)
    model.add_metric(tf.keras.metrics.Mean()(x), name='metric_1')
    ```

    Args:
      value: Metric tensor.
      name: String metric name.
      **kwargs: Additional keyword arguments for backward compatibility.
        Accepted values:
        `aggregation` - When the `value` tensor provided is not the result of
        calling a `keras.Metric` instance, it will be aggregated by default
        using a `keras.Metric.Mean`.
    """
    kwargs_keys = list(kwargs.keys())
    if (len(kwargs_keys) > 1 or
        (len(kwargs_keys) == 1 and kwargs_keys[0] != 'aggregation')):
      raise TypeError('Unknown keyword arguments: ', str(kwargs.keys()))

    from_metric_obj = hasattr(value, '_metric_obj')
    is_symbolic = isinstance(value, keras_tensor.KerasTensor)
    in_call_context = base_layer_utils.call_context().in_call

    if name is None and not from_metric_obj:
      # Eg. `self.add_metric(math_ops.reduce_sum(x))`
      # In eager mode, we use metric name to lookup a metric. Without a name,
      # a new Mean metric wrapper will be created on every model/layer call.
      # So, we raise an error when no name is provided.
      # We will do the same for symbolic mode for consistency although a name
      # will be generated if no name is provided.

      # We will not raise this error in the foll use case for the sake of
      # consistency as name in provided in the metric constructor.
      # mean = metrics.Mean(name='my_metric')
      # model.add_metric(mean(outputs))
      raise ValueError('Please provide a name for your metric like '
                       '`self.add_metric(tf.reduce_sum(inputs), '
                       'name=\'mean_activation\')`')
    elif from_metric_obj:
      name = value._metric_obj.name

    if not in_call_context and not is_symbolic:
      raise ValueError('Expected a symbolic Tensor for the metric value, '
                       'received: ' + str(value))

    # If a metric was added in a Layer's `call` or `build`.
    if in_call_context or not getattr(self, '_is_graph_network', False):
      # TF Function path should take the eager path.

      # If the given metric is available in `metrics` list we just update state
      # on it, otherwise we create a new metric instance and
      # add it to the `metrics` list.
      metric_obj = getattr(value, '_metric_obj', None)
      # Tensors that come from a Metric object already updated the Metric state.
      should_update_state = not metric_obj
      name = metric_obj.name if metric_obj else name

      with self._metrics_lock:
        match = self._get_existing_metric(name)
        if match:
          metric_obj = match
        elif metric_obj:
          self._metrics.append(metric_obj)
        else:
          # Build the metric object with the value's dtype if it defines one
          metric_obj = metrics_mod.Mean(
              name=name, dtype=getattr(value, 'dtype', None))
          self._metrics.append(metric_obj)

      if should_update_state:
        metric_obj(value)
    else:
      if from_metric_obj:
        raise ValueError('Using the result of calling a `Metric` object '
                         'when calling `add_metric` on a Functional '
                         'Model is not supported. Please pass the '
                         'Tensor to monitor directly.')

      # Insert layers into the Keras Graph Network.
      aggregation = None if from_metric_obj else 'mean'
      self._graph_network_add_metric(value, aggregation, name)

  @doc_controls.do_not_doc_inheritable
  def add_update(self, updates, inputs=None):
    """Add update op(s), potentially dependent on layer inputs.

    Weight updates (for instance, the updates of the moving mean and variance
    in a BatchNormalization layer) may be dependent on the inputs passed
    when calling a layer. Hence, when reusing the same layer on
    different inputs `a` and `b`, some entries in `layer.updates` may be
    dependent on `a` and some on `b`. This method automatically keeps track
    of dependencies.

    This call is ignored when eager execution is enabled (in that case, variable
    updates are run on the fly and thus do not need to be tracked for later
    execution).

    Args:
      updates: Update op, or list/tuple of update ops, or zero-arg callable
        that returns an update op. A zero-arg callable should be passed in
        order to disable running the updates by setting `trainable=False`
        on this Layer, when executing in Eager mode.
      inputs: Deprecated, will be automatically inferred.
    """
    if inputs is not None:
      tf_logging.warning(
          '`add_update` `inputs` kwarg has been deprecated. You no longer need '
          'to pass a value to `inputs` as it is being automatically inferred.')
    call_context = base_layer_utils.call_context()
    # No need to run updates during Functional API construction.
    if call_context.in_keras_graph:
      return

    # Callable updates are disabled by setting `trainable=False`.
    if not call_context.frozen:
      for update in tf.nest.flatten(updates):
        if callable(update):
          update()  # pylint: disable=not-callable

  def set_weights(self, weights):
    """Sets the weights of the layer, from NumPy arrays.

    The weights of a layer represent the state of the layer. This function
    sets the weight values from numpy arrays. The weight values should be
    passed in the order they are created by the layer. Note that the layer's
    weights must be instantiated before calling this function, by calling
    the layer.

    For example, a `Dense` layer returns a list of two values: the kernel matrix
    and the bias vector. These can be used to set the weights of another
    `Dense` layer:

    >>> layer_a = tf.keras.layers.Dense(1,
    ...   kernel_initializer=tf.constant_initializer(1.))
    >>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
    >>> layer_a.get_weights()
    [array([[1.],
           [1.],
           [1.]], dtype=float32), array([0.], dtype=float32)]
    >>> layer_b = tf.keras.layers.Dense(1,
    ...   kernel_initializer=tf.constant_initializer(2.))
    >>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
    >>> layer_b.get_weights()
    [array([[2.],
           [2.],
           [2.]], dtype=float32), array([0.], dtype=float32)]
    >>> layer_b.set_weights(layer_a.get_weights())
    >>> layer_b.get_weights()
    [array([[1.],
           [1.],
           [1.]], dtype=float32), array([0.], dtype=float32)]

    Args:
      weights: a list of NumPy arrays. The number
        of arrays and their shape must match
        number of the dimensions of the weights
        of the layer (i.e. it should match the
        output of `get_weights`).

    Raises:
      ValueError: If the provided weights list does not match the
        layer's specifications.
    """
    params = self.weights

    expected_num_weights = 0
    for param in params:
      if isinstance(param, base_layer_utils.TrackableWeightHandler):
        expected_num_weights += param.num_tensors
      else:
        expected_num_weights += 1

    if expected_num_weights != len(weights):
      raise ValueError(
          'You called `set_weights(weights)` on layer "%s" '
          'with a weight list of length %s, but the layer was '
          'expecting %s weights. Provided weights: %s...' %
          (self.name, len(weights), expected_num_weights, str(weights)[:50]))

    weight_index = 0
    weight_value_tuples = []
    for param in params:
      if isinstance(param, base_layer_utils.TrackableWeightHandler):
        num_tensors = param.num_tensors
        tensors = weights[weight_index:weight_index + num_tensors]
        param.set_weights(tensors)
        weight_index += num_tensors
      else:
        weight = weights[weight_index]
        weight_shape = weight.shape if hasattr(weight, 'shape') else ()
        ref_shape = param.shape
        if not ref_shape.is_compatible_with(weight_shape):
          raise ValueError(
              'Layer weight shape %s not compatible with provided weight '
              'shape %s' % (ref_shape, weight_shape))
        weight_value_tuples.append((param, weight))
        weight_index += 1

    backend.batch_set_value(weight_value_tuples)

    # Perform any layer defined finalization of the layer state.
    for layer in self._flatten_layers():
      layer.finalize_state()

  def get_weights(self):
    """Returns the current weights of the layer, as NumPy arrays.

    The weights of a layer represent the state of the layer. This function
    returns both trainable and non-trainable weight values associated with this
    layer as a list of NumPy arrays, which can in turn be used to load state
    into similarly parameterized layers.

    For example, a `Dense` layer returns a list of two values: the kernel matrix
    and the bias vector. These can be used to set the weights of another
    `Dense` layer:

    >>> layer_a = tf.keras.layers.Dense(1,
    ...   kernel_initializer=tf.constant_initializer(1.))
    >>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
    >>> layer_a.get_weights()
    [array([[1.],
           [1.],
           [1.]], dtype=float32), array([0.], dtype=float32)]
    >>> layer_b = tf.keras.layers.Dense(1,
    ...   kernel_initializer=tf.constant_initializer(2.))
    >>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
    >>> layer_b.get_weights()
    [array([[2.],
           [2.],
           [2.]], dtype=float32), array([0.], dtype=float32)]
    >>> layer_b.set_weights(layer_a.get_weights())
    >>> layer_b.get_weights()
    [array([[1.],
           [1.],
           [1.]], dtype=float32), array([0.], dtype=float32)]

    Returns:
        Weights values as a list of NumPy arrays.
    """
    weights = self.weights
    output_weights = []
    for weight in weights:
      if isinstance(weight, base_layer_utils.TrackableWeightHandler):
        output_weights.extend(weight.get_tensors())
      else:
        output_weights.append(weight)
    return backend.batch_get_value(output_weights)

  @doc_controls.do_not_generate_docs
  def finalize_state(self):
    """Finalizes the layers state after updating layer weights.

    This function can be subclassed in a layer and will be called after updating
    a layer weights. It can be overridden to finalize any additional layer state
    after a weight update.
    """
    pass

  @doc_controls.do_not_generate_docs
  def get_updates_for(self, inputs):
    """Deprecated, do NOT use!

    Retrieves updates relevant to a specific set of inputs.

    Args:
      inputs: Input tensor or list/tuple of input tensors.

    Returns:
      List of update ops of the layer that depend on `inputs`.
    """
    warnings.warn('`layer.get_updates_for` is deprecated and '
                  'will be removed in a future version. '
                  'Please use `layer.updates` method instead.')
    return self.updates

  @doc_controls.do_not_generate_docs
  def get_losses_for(self, inputs):
    """Deprecated, do NOT use!

    Retrieves losses relevant to a specific set of inputs.

    Args:
      inputs: Input tensor or list/tuple of input tensors.

    Returns:
      List of loss tensors of the layer that depend on `inputs`.
    """
    warnings.warn('`layer.get_losses_for` is deprecated and '
                  'will be removed in a future version. '
                  'Please use `layer.losses` instead.')
    return self.losses

  @doc_controls.do_not_doc_inheritable
  def get_input_mask_at(self, node_index):
    """Retrieves the input mask tensor(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first time the layer was called.

    Returns:
        A mask tensor
        (or list of tensors if the layer has multiple inputs).
    """
    inputs = self.get_input_at(node_index)
    if isinstance(inputs, list):
      return [getattr(x, '_keras_mask', None) for x in inputs]
    else:
      return getattr(inputs, '_keras_mask', None)

  @doc_controls.do_not_doc_inheritable
  def get_output_mask_at(self, node_index):
    """Retrieves the output mask tensor(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first time the layer was called.

    Returns:
        A mask tensor
        (or list of tensors if the layer has multiple outputs).
    """
    output = self.get_output_at(node_index)
    if isinstance(output, list):
      return [getattr(x, '_keras_mask', None) for x in output]
    else:
      return getattr(output, '_keras_mask', None)

  @property
  @doc_controls.do_not_doc_inheritable
  def input_mask(self):
    """Retrieves the input mask tensor(s) of a layer.

    Only applicable if the layer has exactly one inbound node,
    i.e. if it is connected to one incoming layer.

    Returns:
        Input mask tensor (potentially None) or list of input
        mask tensors.

    Raises:
        AttributeError: if the layer is connected to
        more than one incoming layers.
    """
    inputs = self.input
    if isinstance(inputs, list):
      return [getattr(x, '_keras_mask', None) for x in inputs]
    else:
      return getattr(inputs, '_keras_mask', None)

  @property
  @doc_controls.do_not_doc_inheritable
  def output_mask(self):
    """Retrieves the output mask tensor(s) of a layer.

    Only applicable if the layer has exactly one inbound node,
    i.e. if it is connected to one incoming layer.

    Returns:
        Output mask tensor (potentially None) or list of output
        mask tensors.

    Raises:
        AttributeError: if the layer is connected to
        more than one incoming layers.
    """
    output = self.output
    if isinstance(output, list):
      return [getattr(x, '_keras_mask', None) for x in output]
    else:
      return getattr(output, '_keras_mask', None)

  @doc_controls.do_not_doc_inheritable
  def get_input_shape_at(self, node_index):
    """Retrieves the input shape(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first time the layer was called.

    Returns:
        A shape tuple
        (or list of shape tuples if the layer has multiple inputs).

    Raises:
      RuntimeError: If called in Eager mode.
    """
    return self._get_node_attribute_at_index(node_index, 'input_shapes',
                                             'input shape')

  @doc_controls.do_not_doc_inheritable
  def get_output_shape_at(self, node_index):
    """Retrieves the output shape(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first time the layer was called.

    Returns:
        A shape tuple
        (or list of shape tuples if the layer has multiple outputs).

    Raises:
      RuntimeError: If called in Eager mode.
    """
    return self._get_node_attribute_at_index(node_index, 'output_shapes',
                                             'output shape')

  @doc_controls.do_not_doc_inheritable
  def get_input_at(self, node_index):
    """Retrieves the input tensor(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first input node of the layer.

    Returns:
        A tensor (or list of tensors if the layer has multiple inputs).

    Raises:
      RuntimeError: If called in Eager mode.
    """
    return self._get_node_attribute_at_index(node_index, 'input_tensors',
                                             'input')

  @doc_controls.do_not_doc_inheritable
  def get_output_at(self, node_index):
    """Retrieves the output tensor(s) of a layer at a given node.

    Args:
        node_index: Integer, index of the node
            from which to retrieve the attribute.
            E.g. `node_index=0` will correspond to the
            first output node of the layer.

    Returns:
        A tensor (or list of tensors if the layer has multiple outputs).

    Raises:
      RuntimeError: If called in Eager mode.
    """
    return self._get_node_attribute_at_index(node_index, 'output_tensors',
                                             'output')

  @property
  def input(self):
    """Retrieves the input tensor(s) of a layer.

    Only applicable if the layer has exactly one input,
    i.e. if it is connected to one incoming layer.

    Returns:
        Input tensor or list of input tensors.

    Raises:
      RuntimeError: If called in Eager mode.
      AttributeError: If no inbound nodes are found.
    """
    if not self._inbound_nodes:
      raise AttributeError('Layer ' + self.name +
                           ' is not connected, no input to return.')
    return self._get_node_attribute_at_index(0, 'input_tensors', 'input')

  @property
  def output(self):
    """Retrieves the output tensor(s) of a layer.

    Only applicable if the layer has exactly one output,
    i.e. if it is connected to one incoming layer.

    Returns:
      Output tensor or list of output tensors.

    Raises:
      AttributeError: if the layer is connected to more than one incoming
        layers.
      RuntimeError: if called in Eager mode.
    """
    if not self._inbound_nodes:
      raise AttributeError('Layer ' + self.name + ' has no inbound nodes.')
    return self._get_node_attribute_at_index(0, 'output_tensors', 'output')

  @property
  @doc_controls.do_not_doc_inheritable
  def input_shape(self):
    """Retrieves the input shape(s) of a layer.

    Only applicable if the layer has exactly one input,
    i.e. if it is connected to one incoming layer, or if all inputs
    have the same shape.

    Returns:
        Input shape, as an integer shape tuple
        (or list of shape tuples, one tuple per input tensor).

    Raises:
        AttributeError: if the layer has no defined input_shape.
        RuntimeError: if called in Eager mode.
    """
    if not self._inbound_nodes:
      raise AttributeError('The layer has never been called '
                           'and thus has no defined input shape.')
    all_input_shapes = set(
        [str(node.input_shapes) for node in self._inbound_nodes])
    if len(all_input_shapes) == 1:
      return self._inbound_nodes[0].input_shapes
    else:
      raise AttributeError('The layer "' + str(self.name) +
                           ' has multiple inbound nodes, '
                           'with different input shapes. Hence '
                           'the notion of "input shape" is '
                           'ill-defined for the layer. '
                           'Use `get_input_shape_at(node_index)` '
                           'instead.')

  def count_params(self):
    """Count the total number of scalars composing the weights.

    Returns:
        An integer count.

    Raises:
        ValueError: if the layer isn't yet built
          (in which case its weights aren't yet defined).
    """
    if not self.built:
      if getattr(self, '_is_graph_network', False):
        with tf_utils.maybe_init_scope(self):
          self._maybe_build(self.inputs)
      else:
        raise ValueError('You tried to call `count_params` on ' + self.name +
                         ', but the layer isn\'t built. '
                         'You can build it manually via: `' + self.name +
                         '.build(batch_input_shape)`.')
    return layer_utils.count_params(self.weights)

  @property
  @doc_controls.do_not_doc_inheritable
  def output_shape(self):
    """Retrieves the output shape(s) of a layer.

    Only applicable if the layer has one output,
    or if all outputs have the same shape.

    Returns:
        Output shape, as an integer shape tuple
        (or list of shape tuples, one tuple per output tensor).

    Raises:
        AttributeError: if the layer has no defined output shape.
        RuntimeError: if called in Eager mode.
    """
    if not self._inbound_nodes:
      raise AttributeError('The layer has never been called '
                           'and thus has no defined output shape.')
    all_output_shapes = set(
        [str(node.output_shapes) for node in self._inbound_nodes])
    if len(all_output_shapes) == 1:
      return self._inbound_nodes[0].output_shapes
    else:
      raise AttributeError('The layer "%s"'
                           ' has multiple inbound nodes, '
                           'with different output shapes. Hence '
                           'the notion of "output shape" is '
                           'ill-defined for the layer. '
                           'Use `get_output_shape_at(node_index)` '
                           'instead.' % self.name)

  @property
  @doc_controls.do_not_doc_inheritable
  def inbound_nodes(self):
    """Deprecated, do NOT use! Only for compatibility with external Keras."""
    return self._inbound_nodes

  @property
  @doc_controls.do_not_doc_inheritable
  def outbound_nodes(self):
    """Deprecated, do NOT use! Only for compatibility with external Keras."""
    return self._outbound_nodes

  ##############################################################################
  # Methods & attributes below are public aliases of other methods.            #
  ##############################################################################

  @doc_controls.do_not_doc_inheritable
  def apply(self, inputs, *args, **kwargs):
    """Deprecated, do NOT use!

    This is an alias of `self.__call__`.

    Args:
      inputs: Input tensor(s).
      *args: additional positional arguments to be passed to `self.call`.
      **kwargs: additional keyword arguments to be passed to `self.call`.

    Returns:
      Output tensor(s).
    """
    warnings.warn('`layer.apply` is deprecated and '
                  'will be removed in a future version. '
                  'Please use `layer.__call__` method instead.')
    return self.__call__(inputs, *args, **kwargs)

  @doc_controls.do_not_doc_inheritable
  def add_variable(self, *args, **kwargs):
    """Deprecated, do NOT use! Alias for `add_weight`."""
    warnings.warn('`layer.add_variable` is deprecated and '
                  'will be removed in a future version. '
                  'Please use `layer.add_weight` method instead.')
    return self.add_weight(*args, **kwargs)

  @property
  @doc_controls.do_not_generate_docs
  def variables(self):
    """Returns the list of all layer variables/weights.

    Alias of `self.weights`.

    Note: This will not track the weights of nested `tf.Modules` that are not
    themselves Keras layers.

    Returns:
      A list of variables.
    """
    return self.weights

  @property
  @doc_controls.do_not_generate_docs
  def trainable_variables(self):
    return self.trainable_weights

  @property
  @doc_controls.do_not_generate_docs
  def non_trainable_variables(self):
    return self.non_trainable_weights

  ##############################################################################
  # Methods & attributes below are all private and only used by the framework. #
  ##############################################################################

  @property
  def _inbound_nodes(self):
    return self._inbound_nodes_value

  @_inbound_nodes.setter
  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def _inbound_nodes(self, value):
    self._inbound_nodes_value = value

  @property
  def _outbound_nodes(self):
    return self._outbound_nodes_value

  @_outbound_nodes.setter
  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def _outbound_nodes(self, value):
    self._outbound_nodes_value = value

  def _set_dtype_policy(self, dtype):
    """Sets self._dtype_policy."""
    if isinstance(dtype, policy.Policy):
      self._dtype_policy = dtype
    elif isinstance(dtype, dict):
      self._dtype_policy = policy.deserialize(dtype)
    elif isinstance(dtype, str) and dtype in ('mixed_float16',
                                              'mixed_bfloat16'):
      # The isinstance check is required since np.dtype raises an error if
      # compared to a non-dtype string.
      self._dtype_policy = policy.Policy(dtype)
    elif dtype:
      self._dtype_policy = policy.Policy(tf.as_dtype(dtype).name)
    else:
      self._dtype_policy = policy.global_policy()
    if (self._dtype_policy.name == 'mixed_float16' and
        not loss_scale_optimizer.strategy_supports_loss_scaling()):
      # Although only loss scaling doesn't support certain strategies, to avoid
      # confusion, we disallow the 'mixed_float16' policy with unsupported
      # strategies. This is because 'mixed_float16' requires loss scaling for
      # numeric stability.
      strategy = tf.distribute.get_strategy()
      raise ValueError('Mixed precision is not supported with the '
                       'tf.distribute.Strategy: %s. Either stop using mixed '
                       'precision by removing the use of the "%s" policy or '
                       'use a different Strategy, e.g. a MirroredStrategy.' %
                       (strategy.__class__.__name__, self._dtype_policy.name))

    # Performance optimization: cache the compute dtype as a Dtype object or
    # None, so that str to Dtype conversion doesn't happen in Layer.__call__.
    # TODO(b/157486353): Investigate returning DTypes in Policy.
    if self._dtype_policy.compute_dtype:
      self._compute_dtype_object = tf.as_dtype(
          self._dtype_policy.compute_dtype)
    else:
      self._compute_dtype_object = None

  @property
  def dtype_policy(self):
    """The dtype policy associated with this layer.

    This is an instance of a `tf.keras.mixed_precision.Policy`.
    """
    return self._dtype_policy

  @property
  def compute_dtype(self):
    """The dtype of the layer's computations.

    This is equivalent to `Layer.dtype_policy.compute_dtype`. Unless
    mixed precision is used, this is the same as `Layer.dtype`, the dtype of
    the weights.

    Layers automatically cast their inputs to the compute dtype, which causes
    computations and the output to be in the compute dtype as well. This is done
    by the base Layer class in `Layer.__call__`, so you do not have to insert
    these casts if implementing your own layer.

    Layers often perform certain internal computations in higher precision when
    `compute_dtype` is float16 or bfloat16 for numeric stability. The output
    will still typically be float16 or bfloat16 in such cases.

    Returns:
      The layer's compute dtype.
    """
    return self._dtype_policy.compute_dtype

  @property
  def _compute_dtype(self):
    """Deprecated alias of `compute_dtype`."""
    return self._dtype_policy.compute_dtype

  @property
  def variable_dtype(self):
    """Alias of `Layer.dtype`, the dtype of the weights."""
    return self.dtype

  def _maybe_cast_inputs(self, inputs, input_list=None):
    """Maybe casts the inputs to the compute dtype.

    If self._compute_dtype is floating-point, and self_autocast is True,
    floating-point inputs are casted to self._compute_dtype.

    Args:
      inputs: Input tensor, or structure of input tensors.
      input_list: Flat list of input tensors.

    Returns:
      `inputs`, but tensors may have been casted to self._compute_dtype
    """
    if not input_list:
      input_list = tf.nest.flatten(inputs)

    compute_dtype_object = self._compute_dtype_object
    should_autocast = (
        self._autocast and compute_dtype_object and
        compute_dtype_object.is_floating)

    if (should_autocast and
        any(map(self._should_cast_single_input, input_list))):
      # Only perform expensive `nest` operation when needed.
      return tf.nest.map_structure(self._cast_single_input, inputs)
    else:
      return inputs

  def _should_cast_single_input(self, x):
    if isinstance(x, _AUTOCAST_TYPES):
      return (self._compute_dtype_object and
              x.dtype != self._compute_dtype_object and x.dtype.is_floating)
    return False

  def _cast_single_input(self, x):
    """Cast a single Tensor or TensorSpec to the compute dtype."""
    if self._should_cast_single_input(x):
      return tf.cast(x, self._compute_dtype_object)
    else:
      return x

  # _dtype used to be an attribute set in the constructor. We still expose it
  # because some clients still use it.
  # TODO(reedwm): Deprecate, then remove the _dtype property.
  @property
  def _dtype(self):
    # This is equivalent to returning self.dtype . We do not return self.dtype
    # as it would cause infinite recursion in a few subclasses, which override
    # "dtype" to return self._dtype.
    return self._dtype_policy.variable_dtype

  @_dtype.setter
  def _dtype(self, value):
    value = tf.as_dtype(value).name
    self._set_dtype_policy(policy.Policy(value))

  def _name_scope(self):  # pylint: disable=method-hidden
    if not tf.__internal__.tf2.enabled():
      return self.name
    name_scope = self.name
    if _is_name_scope_on_model_declaration_enabled and self._outer_name_scope:
      name_scope = self._outer_name_scope + '/' + name_scope
    current_name_scope = tf.__internal__.get_name_scope()
    if current_name_scope:
      name_scope = current_name_scope + '/' + name_scope
    if name_scope:
      # Note that the trailing `/` prevents autogenerated
      # numerical suffixes to get appended. It will also fully reset
      # nested name scope (i.e. the outer name scope has no effect).
      name_scope += '/'
    return name_scope

  def _init_set_name(self, name, zero_based=True):
    if not name:
      self._name = backend.unique_object_name(
          generic_utils.to_snake_case(self.__class__.__name__),
          zero_based=zero_based)
    else:
      backend.observe_object_name(name)
      self._name = name

  def _get_existing_metric(self, name=None):
    match = [m for m in self._metrics if m.name == name]
    if not match:
      return
    if len(match) > 1:
      raise ValueError(
          'Please provide different names for the metrics you have added. '
          'We found {} metrics with the name: "{}"'.format(len(match), name))
    return match[0]

  def _handle_weight_regularization(self, name, variable, regularizer):
    """Create lambdas which compute regularization losses."""

    def _loss_for_variable(v):
      """Creates a regularization loss `Tensor` for variable `v`."""
      with backend.name_scope(name + '/Regularizer'):
        regularization = regularizer(v)
      return regularization

    if base_layer_utils.is_split_variable(variable):
      for v in variable:
        self.add_loss(functools.partial(_loss_for_variable, v))
    else:
      self.add_loss(functools.partial(_loss_for_variable, variable))

  def _handle_activity_regularization(self, inputs, outputs):
    # Apply activity regularization.
    # Note that it should be applied every time the layer creates a new
    # output, since it is output-specific.
    if self._activity_regularizer:
      output_list = tf.nest.flatten(outputs)
      with backend.name_scope('ActivityRegularizer'):
        for output in output_list:
          activity_loss = self._activity_regularizer(output)
          batch_size = tf.cast(
              tf.shape(output)[0], activity_loss.dtype)
          # Make activity regularization strength batch-agnostic.
          mean_activity_loss = activity_loss / batch_size
          self.add_loss(mean_activity_loss)

  def _set_mask_metadata(self, inputs, outputs, previous_mask, build_graph):
    # Many `Layer`s don't need to call `compute_mask`.
    # This method is optimized to do as little work as needed for the common
    # case.
    if not self._supports_masking:
      return

    flat_outputs = tf.nest.flatten(outputs)

    mask_already_computed = (
        getattr(self, '_compute_output_and_mask_jointly', False) or
        all(getattr(x, '_keras_mask', None) is not None for x in flat_outputs))
    if mask_already_computed:
      if build_graph:
        self._set_mask_keras_history_checked(flat_outputs)
      return

    output_masks = self.compute_mask(inputs, previous_mask)
    if output_masks is None:
      return

    flat_masks = tf.nest.flatten(output_masks)
    for tensor, mask in zip(flat_outputs, flat_masks):
      try:
        tensor._keras_mask = mask
      except AttributeError:
        # C Type such as np.ndarray.
        pass

    if build_graph:
      self._set_mask_keras_history_checked(flat_outputs)

  def _set_mask_keras_history_checked(self, flat_outputs):
    for output in flat_outputs:
      if getattr(output, '_keras_mask', None) is not None:
        # Do not track masks for `TensorFlowOpLayer` construction.
        output._keras_mask._keras_history_checked = True

  def _get_input_masks(self, inputs, input_list, args, kwargs):
    if not self._supports_masking and not self._expects_mask_arg:
      # Input masks only need to be retrieved if they are needed for `call`
      # or `compute_mask`.
      input_masks = None
      implicit_mask = False
    elif self._call_arg_was_passed('mask', args, kwargs):
      input_masks = self._get_call_arg_value('mask', args, kwargs)
      implicit_mask = False
    else:
      input_masks = [getattr(t, '_keras_mask', None) for t in input_list]
      if all(mask is None for mask in input_masks):
        input_masks = None
        implicit_mask = False
      else:
        # Only do expensive `nest` op when masking is actually being used.
        input_masks = tf.nest.pack_sequence_as(inputs, input_masks)
        implicit_mask = True
    return input_masks, implicit_mask

  def _call_arg_was_passed(self, arg_name, args, kwargs, inputs_in_args=False):
    # Performance optimization: do no work in most common case.
    if not args and not kwargs:
      return False

    if arg_name in kwargs:
      return True
    call_fn_args = self._call_fn_args
    if not inputs_in_args:
      # Ignore `inputs` arg.
      call_fn_args = call_fn_args[1:]
    return arg_name in dict(zip(call_fn_args, args))

  def _get_call_arg_value(self, arg_name, args, kwargs, inputs_in_args=False):
    if arg_name in kwargs:
      return kwargs[arg_name]
    call_fn_args = self._call_fn_args
    if not inputs_in_args:
      # Ignore `inputs` arg.
      call_fn_args = call_fn_args[1:]
    args_dict = dict(zip(call_fn_args, args))
    return args_dict[arg_name]

  def _set_call_arg_value(
      self, arg_name, new_value, args,
      kwargs, inputs_in_args=False, pop_kwarg_if_none=False):
    arg_pos = self._call_fn_arg_positions.get(arg_name, None)
    if arg_pos is not None:
      if not inputs_in_args:
        # Ignore `inputs` arg.
        arg_pos = arg_pos - 1
      if len(args) > arg_pos:
        args = list(args)
        args[arg_pos] = new_value
        return tuple(args), kwargs
    if new_value is None and pop_kwarg_if_none:
      kwargs.pop(arg_name, None)
    else:
      kwargs[arg_name] = new_value
    return args, kwargs

  def _set_connectivity_metadata(self, args, kwargs, outputs):
    # If the layer returns tensors from its inputs unmodified,
    # we copy them to avoid loss of KerasHistory metadata.
    flat_outputs = tf.nest.flatten(outputs)
    flat_inputs = tf.nest.flatten((args, kwargs))
    input_ids_set = {id(i) for i in flat_inputs}
    outputs_copy = []
    for x in flat_outputs:
      if id(x) in input_ids_set:
        with backend.name_scope(self.name):
          x = tf.identity(x)
      outputs_copy.append(x)
    outputs = tf.nest.pack_sequence_as(outputs, outputs_copy)

    # Create node, Node wires itself to inbound and outbound layers.
    # The Node constructor actually updates this layer's self._inbound_nodes,
    # sets _keras_history on the outputs, and adds itself to the
    # `_outbound_nodes` of the layers that produced the inputs to this
    # layer call.
    node_module.Node(self, call_args=args, call_kwargs=kwargs, outputs=outputs)
    return outputs

  def _get_node_attribute_at_index(self, node_index, attr, attr_name):
    """Private utility to retrieves an attribute (e.g. inputs) from a node.

    This is used to implement the methods:
        - get_input_shape_at
        - get_output_shape_at
        - get_input_at
        etc...

    Args:
        node_index: Integer index of the node from which
            to retrieve the attribute.
        attr: Exact node attribute name.
        attr_name: Human-readable attribute name, for error messages.

    Returns:
        The layer's attribute `attr` at the node of index `node_index`.

    Raises:
        RuntimeError: If the layer has no inbound nodes, or if called in Eager
        mode.
        ValueError: If the index provided does not match any node.
    """
    if not self._inbound_nodes:
      raise RuntimeError('The layer has never been called '
                         'and thus has no defined ' + attr_name + '.')
    if not len(self._inbound_nodes) > node_index:
      raise ValueError('Asked to get ' + attr_name + ' at node ' +
                       str(node_index) + ', but the layer has only ' +
                       str(len(self._inbound_nodes)) + ' inbound nodes.')
    values = getattr(self._inbound_nodes[node_index], attr)
    if isinstance(values, list) and len(values) == 1:
      return values[0]
    else:
      return values

  def _maybe_build(self, inputs):
    # Check input assumptions set before layer building, e.g. input rank.
    if not self.built:
      input_spec.assert_input_compatibility(
          self.input_spec, inputs, self.name)
      input_list = tf.nest.flatten(inputs)
      if input_list and self._dtype_policy.compute_dtype is None:
        try:
          dtype = input_list[0].dtype.base_dtype.name
        except AttributeError:
          pass
        else:
          self._set_dtype_policy(policy.Policy(dtype))
      input_shapes = None
      # Converts Tensors / CompositeTensors to TensorShapes.
      if all(hasattr(x, 'shape') for x in input_list):
        input_shapes = tf_utils.get_shapes(inputs)
      else:
        # Converts input shape to TensorShapes.
        try:
          input_shapes = tf_utils.convert_shapes(inputs, to_tuples=False)
        except ValueError:
          pass
      # Only call `build` if the user has manually overridden the build method.
      if not hasattr(self.build, '_is_default'):
        # Any setup work performed only once should happen in an `init_scope`
        # to avoid creating symbolic Tensors that will later pollute any eager
        # operations.
        with tf_utils.maybe_init_scope(self):
          self.build(input_shapes)  # pylint:disable=not-callable
      # We must set also ensure that the layer is marked as built, and the build
      # shape is stored since user defined build functions may not be calling
      # `super.build()`
      Layer.build(self, input_shapes)

    # Optionally load weight values specified at layer instantiation.
    if self._initial_weights is not None:
      with tf.init_scope():
        # Using `init_scope` since we want variable assignment in
        # `set_weights` to be treated like variable initialization.
        self.set_weights(self._initial_weights)
      self._initial_weights = None

  def _symbolic_call(self, inputs):
    input_shapes = tf.nest.map_structure(lambda x: x.shape, inputs)
    output_shapes = self.compute_output_shape(input_shapes)
    # Convert to TensorShape so that nest.map_structure will not map into
    # individual dim of the shape.
    output_shapes = tf_utils.convert_shapes(output_shapes, to_tuples=False)

    def _make_placeholder_like(shape):
      ph = backend.placeholder(shape=shape, dtype=self.dtype)
      ph._keras_mask = None
      return ph
    return tf.nest.map_structure(_make_placeholder_like, output_shapes)

  def _get_trainable_state(self):
    """Get the `trainable` state of each sublayer.

    Returns:
      A dict mapping all sublayers to their `trainable` value.
    """
    trainable_state = weakref.WeakKeyDictionary()
    for layer in self._flatten_layers():
      trainable_state[layer] = layer.trainable
    return trainable_state

  def _set_trainable_state(self, trainable_state):
    """Set `trainable` state for each sublayer."""
    for layer in self._flatten_layers():
      if layer in trainable_state:
        layer.trainable = trainable_state[layer]

  @property
  def _obj_reference_counts(self):
    """A dictionary counting the number of attributes referencing an object."""
    self._maybe_create_attribute('_obj_reference_counts_dict',
                                 object_identity.ObjectIdentityDictionary())
    return self._obj_reference_counts_dict

  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def _maybe_create_attribute(self, name, default_value):
    """Create the attribute with the default value if it hasn't been created.

    This is useful for fields that is used for tracking purpose,
    _trainable_weights, or _layers. Note that user could create a layer subclass
    and assign an internal field before invoking the Layer.__init__(), the
    __setattr__() need to create the tracking fields and __init__() need to not
    override them.

    Args:
      name: String, the name of the attribute.
      default_value: Object, the default value of the attribute.
    """
    if not hasattr(self, name):
      self.__setattr__(name, default_value)

  def __delattr__(self, name):
    # For any super.__delattr__() call, we will directly use the implementation
    # in Trackable and skip the behavior in AutoTrackable. The Layer was
    # originally use Trackable as base class, the change of using Module as base
    # class forced us to have AutoTrackable in the class hierarchy.
    #
    # TODO(b/180760306) Keeping the status quo of skipping _delattr__ and
    # __setattr__ in AutoTrackable may be unsustainable.
    existing_value = getattr(self, name, None)

    # If this value is replacing an existing object assigned to an attribute, we
    # should clean it out to avoid leaking memory. First we check if there are
    # other attributes referencing it.
    reference_counts = self._obj_reference_counts
    if existing_value not in reference_counts:
      super(tf.__internal__.tracking.AutoTrackable, self).__delattr__(name)  # pylint: disable=bad-super-call
      return

    reference_count = reference_counts[existing_value]
    if reference_count > 1:
      # There are other remaining references. We can't remove this object from
      # _layers etc.
      reference_counts[existing_value] = reference_count - 1
      super(tf.__internal__.tracking.AutoTrackable, self).__delattr__(name)  # pylint: disable=bad-super-call
      return
    else:
      # This is the last remaining reference.
      del reference_counts[existing_value]

    super(tf.__internal__.tracking.AutoTrackable, self).__delattr__(name)  # pylint: disable=bad-super-call

    if (isinstance(existing_value, Layer)
        or base_layer_utils.has_weights(existing_value)):
      super(tf.__internal__.tracking.AutoTrackable, self).__setattr__(  # pylint: disable=bad-super-call
          '_self_tracked_trackables',
          [l for l in self._self_tracked_trackables if l is not existing_value])
    if isinstance(existing_value, tf.Variable):
      super(tf.__internal__.tracking.AutoTrackable, self).__setattr__(  # pylint: disable=bad-super-call
          '_trainable_weights',
          [w for w in self._trainable_weights if w is not existing_value])
      super(tf.__internal__.tracking.AutoTrackable, self).__setattr__(  # pylint: disable=bad-super-call
          '_non_trainable_weights',
          [w for w in self._non_trainable_weights if w is not existing_value])

  def __setattr__(self, name, value):
    if (name == '_self_setattr_tracking' or
        not getattr(self, '_self_setattr_tracking', True) or
        # Exclude @property.setters from tracking
        hasattr(self.__class__, name)):
      try:
        super(tf.__internal__.tracking.AutoTrackable, self).__setattr__(name, value)  # pylint: disable=bad-super-call
      except AttributeError:
        raise AttributeError(
            ('Can\'t set the attribute "{}", likely because it conflicts with '
             'an existing read-only @property of the object. Please choose a '
             'different name.').format(name))
      return

    # Wraps data structures in `Trackable`, unwraps `NoDependency` objects.
    value = tf.__internal__.tracking.sticky_attribute_assignment(
        trackable=self, value=value, name=name)

    reference_counts = self._obj_reference_counts
    reference_counts[value] = reference_counts.get(value, 0) + 1

    # Clean out the old attribute, which clears _layers and _trainable_weights
    # if necessary.
    try:
      self.__delattr__(name)
    except AttributeError:
      pass

    # Keep track of metric instance created in subclassed layer.
    for val in tf.nest.flatten(value):
      if isinstance(val, metrics_mod.Metric) and hasattr(self, '_metrics'):
        self._metrics.append(val)

    # Append value to self._self_tracked_trackables if relevant
    if (getattr(self, '_auto_track_sub_layers', True) and
        (isinstance(value, tf.Module) or
         base_layer_utils.has_weights(value))):
      self._maybe_create_attribute('_self_tracked_trackables', [])
      # We need to check object identity to avoid de-duplicating empty
      # container types which compare equal.
      if not any((layer is value for layer in self._self_tracked_trackables)):
        self._self_tracked_trackables.append(value)
        if hasattr(value, '_use_resource_variables'):
          # Legacy layers (V1 tf.layers) must always use
          # resource variables.
          value._use_resource_variables = True

    # Append value to list of trainable / non-trainable weights if relevant
    # TODO(b/125122625): This won't pick up on any variables added to a
    # list/dict after creation.
    for val in tf.nest.flatten(value, expand_composites=True):
      if not isinstance(val, tf.Variable):
        continue

      # Users may add extra weights/variables
      # simply by assigning them to attributes (invalid for graph networks)
      self._maybe_create_attribute('_trainable_weights', [])
      self._maybe_create_attribute('_non_trainable_weights', [])
      if val.trainable:
        if any(val is w for w in self._trainable_weights):
          continue
        self._trainable_weights.append(val)
      else:
        if any(val is w for w in self._non_trainable_weights):
          continue
        self._non_trainable_weights.append(val)

      backend.track_variable(val)

    # TODO(b/180760306) Skip the auto trackable from tf.Module to keep status
    # quo. See the comment at __delattr__.
    super(tf.__internal__.tracking.AutoTrackable, self).__setattr__(name, value)  # pylint: disable=bad-super-call

  def _gather_children_attribute(self, attribute):
    assert attribute in {
        'variables', 'trainable_variables', 'non_trainable_variables'
    }
    if hasattr(self, '_self_tracked_trackables'):
      nested_layers = self._flatten_modules(include_self=False, recursive=False)
      return list(
          itertools.chain.from_iterable(
              getattr(layer, attribute) for layer in nested_layers))
    return []

  def _flatten_layers(self, recursive=True, include_self=True):
    for m in self._flatten_modules(
        recursive=recursive, include_self=include_self):
      if isinstance(m, Layer):
        yield m

  def _flatten_modules(self, recursive=True, include_self=True):
    """Flattens `tf.Module` instances (excluding `Metrics`).

    Args:
      recursive: Whether to recursively flatten through submodules.
      include_self: Whether to include this `Layer` instance.

    Yields:
      `tf.Module` instance tracked by this `Layer`.
    """
    if include_self:
      yield self

    # Only instantiate set and deque if needed.
    trackables = getattr(self, '_self_tracked_trackables', None)
    if trackables:
      seen_object_ids = set()
      deque = collections.deque(trackables)
      while deque:
        trackable_obj = deque.popleft()
        trackable_id = id(trackable_obj)
        if trackable_id in seen_object_ids:
          continue
        seen_object_ids.add(trackable_id)

        # Metrics are not considered part of the Layer's topology.
        if (isinstance(trackable_obj, tf.Module) and
            not isinstance(trackable_obj, metrics_mod.Metric)):
          yield trackable_obj
          # Introspect recursively through sublayers.
          if recursive:
            subtrackables = getattr(trackable_obj, '_self_tracked_trackables',
                                    None)
            if subtrackables:
              deque.extendleft(reversed(subtrackables))
        elif isinstance(trackable_obj, tf.__internal__.tracking.TrackableDataStructure):
          # Data structures are introspected even with `recursive=False`.
          tracked_values = trackable_obj._values
          if tracked_values:
            deque.extendleft(reversed(tracked_values))

  # This is a hack so that the is_layer (within
  # training/trackable/layer_utils.py) check doesn't get the weights attr.
  # TODO(b/110718070): Remove when fixed.
  def _is_layer(self):
    return True

  def _init_call_fn_args(self, expects_training_arg=None):
    # Clear cached call function arguments.
    self.__class__._call_full_argspec.fget.cache.pop(self, None)
    self.__class__._call_fn_args.fget.cache.pop(self, None)
    self.__class__._call_accepts_kwargs.fget.cache.pop(self, None)

    call_fn_args = self._call_fn_args
    call_fn_args += self._call_full_argspec.kwonlyargs or []
    if expects_training_arg is None:
      self._expects_training_arg = ('training' in call_fn_args or
                                    self._call_accepts_kwargs)
    else:
      # Use value encoded into the metadata when loading from the SavedModel.
      self._expects_training_arg = expects_training_arg
    # The default training arg will be any (non-None) default specified in the
    # method signature, or None if no value is specified.
    call_fn_arg_defaults = self._call_fn_arg_defaults.copy()
    call_fn_arg_defaults.update(self._call_full_argspec.kwonlydefaults or {})
    self._default_training_arg = call_fn_arg_defaults.get('training')

    self._expects_mask_arg = ('mask' in call_fn_args or
                              self._call_accepts_kwargs)

  @property
  @layer_utils.cached_per_instance
  def _call_full_argspec(self):
    # Argspec inspection is expensive and the call spec is used often, so it
    # makes sense to cache the result.
    return tf_inspect.getfullargspec(self.call)

  @property
  @layer_utils.cached_per_instance
  def _call_fn_args(self):
    all_args = self._call_full_argspec.args
    # Scrub `self` that appears if a decorator was applied.
    if all_args and all_args[0] == 'self':
      return all_args[1:]
    return all_args

  @property
  @layer_utils.cached_per_instance
  def _call_fn_arg_defaults(self):
    call_fn_args = self._call_fn_args
    call_fn_defaults = self._call_full_argspec.defaults or []
    defaults = dict()

    # The call arg defaults are an n-tuple of the last n elements of the args
    # list. (n = # of elements that have a default argument)
    for i in range(-1 * len(call_fn_defaults), 0):
      defaults[call_fn_args[i]] = call_fn_defaults[i]
    return defaults

  @property
  @layer_utils.cached_per_instance
  def _call_fn_arg_positions(self):
    call_fn_arg_positions = dict()
    for pos, arg in enumerate(self._call_fn_args):
      call_fn_arg_positions[arg] = pos
    return call_fn_arg_positions

  @property
  @layer_utils.cached_per_instance
  def _call_accepts_kwargs(self):
    return self._call_full_argspec.varkw is not None

  @property
  def _eager_losses(self):
    # A list of loss values containing activity regularizers and losses
    # manually added through `add_loss` during eager execution. It is cleared
    # after every batch.
    # Because we plan on eventually allowing a same model instance to be trained
    # in eager mode or graph mode alternatively, we need to keep track of
    # eager losses and symbolic losses via separate attributes.
    if not hasattr(self._thread_local, '_eager_losses'):
      self._thread_local._eager_losses = []
    return self._thread_local._eager_losses

  @_eager_losses.setter
  def _eager_losses(self, losses):
    self._thread_local._eager_losses = losses

  def _dedup_weights(self, weights):
    """Dedupe weights while maintaining order as much as possible."""
    output, seen_ids = [], set()
    for w in weights:
      if id(w) not in seen_ids:
        output.append(w)
        # Track the Variable's identity to avoid __eq__ issues.
        seen_ids.add(id(w))

    return output

  def _split_out_first_arg(self, args, kwargs):
    # Grab the argument corresponding to the first argument in the
    # layer's `call` method spec. This will either be the first positional
    # argument, or it will be provided as a keyword argument.
    if args:
      inputs = args[0]
      args = args[1:]
    elif self._call_fn_args[0] in kwargs:
      kwargs = copy.copy(kwargs)
      inputs = kwargs.pop(self._call_fn_args[0])
    else:
      raise ValueError(
          'The first argument to `Layer.call` must always be passed.')
    return inputs, args, kwargs

  # SavedModel properties. Please see keras/saving/saved_model for details.

  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def _set_save_spec(self, inputs, args=None, kwargs=None):
    """Defines the save spec so that serialization is able to trace layer call.

    The TensorSpecs of the call function `inputs`, `args`, and `kwargs` are
    saved into a tuple of `([inputs] + args, kwargs)`.

    Args:
      inputs: possibly nested inputs passed into the call function.
      args: a list of positional arguments passed into call.
      kwargs: a dictionary of keyword arguments passed into call.
    """
    if self._saved_model_inputs_spec is not None:
      return  # Already set.
    args = args or []
    kwargs = kwargs or {}

    inputs_spec = tf.nest.map_structure(tf_utils.get_tensor_spec, inputs)

    # Filter out non-tensor arguments from args and kwargs.
    args_spec = []
    for arg in args:
      flat_arg = tf.nest.flatten(arg)
      flat_specs = [tf_utils.get_tensor_spec(x) for x in flat_arg]
      if any(s is None for s in flat_specs):
        break  # Stop recording positional args once a non-tensor has been found
      args_spec.append(tf.nest.pack_sequence_as(arg, flat_specs))
    kwargs_spec = {}
    for key, kwarg in kwargs.items():
      if key == 'training':
        continue
      flat_kwarg = tf.nest.flatten(kwarg)
      flat_specs = [tf_utils.get_tensor_spec(x) for x in flat_kwarg]
      if any(s is None for s in flat_specs):
        continue
      kwargs[key] = args_spec.append(
          tf.nest.pack_sequence_as(kwarg, flat_specs))

    self._saved_model_inputs_spec = inputs_spec
    self._saved_model_arg_spec = ([inputs_spec] + args_spec, kwargs_spec)

  def _get_save_spec(self, dynamic_batch=True, inputs_only=True):
    if self._saved_model_inputs_spec is None:
      return None

    spec = tf.nest.map_structure(
        lambda t: tf_utils.get_tensor_spec(t, dynamic_batch=dynamic_batch),
        self._saved_model_arg_spec)
    return spec[0][0] if inputs_only else spec

  @property
  def _trackable_saved_model_saver(self):
    return layer_serialization.LayerSavedModelSaver(self)

  @property
  def _object_identifier(self):
    return self._trackable_saved_model_saver.object_identifier

  @property
  def _tracking_metadata(self):
    """Info about this layer to be saved into the SavedModel."""
    return self._trackable_saved_model_saver.tracking_metadata

  def _list_extra_dependencies_for_serialization(self, serialization_cache):
    return (self._trackable_saved_model_saver
            .list_extra_dependencies_for_serialization(serialization_cache))

  def _list_functions_for_serialization(self, serialization_cache):
    return (self._trackable_saved_model_saver
            .list_functions_for_serialization(serialization_cache))

  @property
  def _use_input_spec_as_call_signature(self):
    # Whether input spec can be used as the call signature when tracing the
    # Layer for SavedModel. By default, this is set to `True` for layers
    # exported from the Keras library, because the layers more rigidly define
    # the `input_specs` property (many custom layers only set the `ndims`)
    return get_canonical_name_for_symbol(type(self),
                                         api_name='keras') is not None

  def __getstate__(self):
    # Override to support `copy.deepcopy` and pickling.
    # Thread-local objects cannot be copied in Python 3, so pop these.
    # Thread-local objects are used to cache losses in MirroredStrategy, and
    # so shouldn't be copied.
    state = self.__dict__.copy()
    state.pop('_thread_local', None)
    state.pop('_metrics_lock', None)
    return state

  def __setstate__(self, state):
    state['_thread_local'] = threading.local()
    state['_metrics_lock'] = threading.Lock()
    # Bypass Trackable logic as `__dict__` already contains this info.
    object.__setattr__(self, '__dict__', state)

Ancestors

  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Static methods

def from_config(config)

Creates a layer from its config.

This method is the reverse of get_config, capable of instantiating the same layer from the config dictionary. It does not handle layer connectivity (handled by Network), nor weights (handled by set_weights).

Args

config
A Python dictionary, typically the output of get_config.

Returns

A layer instance.

Expand source code
@classmethod
def from_config(cls, config):
  """Creates a layer from its config.

  This method is the reverse of `get_config`,
  capable of instantiating the same layer from the config
  dictionary. It does not handle layer connectivity
  (handled by Network), nor weights (handled by `set_weights`).

  Args:
      config: A Python dictionary, typically the
          output of get_config.

  Returns:
      A layer instance.
  """
  return cls(**config)

Instance variables

var activity_regularizer

Optional regularizer function for the output of this layer.

Expand source code
@property
def activity_regularizer(self):
  """Optional regularizer function for the output of this layer."""
  return self._activity_regularizer
var compute_dtype

The dtype of the layer's computations.

This is equivalent to Layer.dtype_policy.compute_dtype. Unless mixed precision is used, this is the same as Layer.dtype, the dtype of the weights.

Layers automatically cast their inputs to the compute dtype, which causes computations and the output to be in the compute dtype as well. This is done by the base Layer class in Layer.__call__, so you do not have to insert these casts if implementing your own layer.

Layers often perform certain internal computations in higher precision when compute_dtype is float16 or bfloat16 for numeric stability. The output will still typically be float16 or bfloat16 in such cases.

Returns

The layer's compute dtype.

Expand source code
@property
def compute_dtype(self):
  """The dtype of the layer's computations.

  This is equivalent to `Layer.dtype_policy.compute_dtype`. Unless
  mixed precision is used, this is the same as `Layer.dtype`, the dtype of
  the weights.

  Layers automatically cast their inputs to the compute dtype, which causes
  computations and the output to be in the compute dtype as well. This is done
  by the base Layer class in `Layer.__call__`, so you do not have to insert
  these casts if implementing your own layer.

  Layers often perform certain internal computations in higher precision when
  `compute_dtype` is float16 or bfloat16 for numeric stability. The output
  will still typically be float16 or bfloat16 in such cases.

  Returns:
    The layer's compute dtype.
  """
  return self._dtype_policy.compute_dtype
var dtype

The dtype of the layer weights.

This is equivalent to Layer.dtype_policy.variable_dtype. Unless mixed precision is used, this is the same as Layer.compute_dtype, the dtype of the layer's computations.

Expand source code
@property
def dtype(self):
  """The dtype of the layer weights.

  This is equivalent to `Layer.dtype_policy.variable_dtype`. Unless
  mixed precision is used, this is the same as `Layer.compute_dtype`, the
  dtype of the layer's computations.
  """
  return self._dtype_policy.variable_dtype
var dtype_policy

The dtype policy associated with this layer.

This is an instance of a tf.keras.mixed_precision.Policy.

Expand source code
@property
def dtype_policy(self):
  """The dtype policy associated with this layer.

  This is an instance of a `tf.keras.mixed_precision.Policy`.
  """
  return self._dtype_policy
var dynamic

Whether the layer is dynamic (eager-only); set in the constructor.

Expand source code
@property
def dynamic(self):
  """Whether the layer is dynamic (eager-only); set in the constructor."""
  return any(layer._dynamic for layer in self._flatten_layers())
var inbound_nodes

Deprecated, do NOT use! Only for compatibility with external Keras.

Expand source code
@property
@doc_controls.do_not_doc_inheritable
def inbound_nodes(self):
  """Deprecated, do NOT use! Only for compatibility with external Keras."""
  return self._inbound_nodes
var input

Retrieves the input tensor(s) of a layer.

Only applicable if the layer has exactly one input, i.e. if it is connected to one incoming layer.

Returns

Input tensor or list of input tensors.

Raises

RuntimeError
If called in Eager mode.
AttributeError
If no inbound nodes are found.
Expand source code
@property
def input(self):
  """Retrieves the input tensor(s) of a layer.

  Only applicable if the layer has exactly one input,
  i.e. if it is connected to one incoming layer.

  Returns:
      Input tensor or list of input tensors.

  Raises:
    RuntimeError: If called in Eager mode.
    AttributeError: If no inbound nodes are found.
  """
  if not self._inbound_nodes:
    raise AttributeError('Layer ' + self.name +
                         ' is not connected, no input to return.')
  return self._get_node_attribute_at_index(0, 'input_tensors', 'input')
var input_mask

Retrieves the input mask tensor(s) of a layer.

Only applicable if the layer has exactly one inbound node, i.e. if it is connected to one incoming layer.

Returns

Input mask tensor (potentially None) or list of input mask tensors.

Raises

AttributeError
if the layer is connected to

more than one incoming layers.

Expand source code
@property
@doc_controls.do_not_doc_inheritable
def input_mask(self):
  """Retrieves the input mask tensor(s) of a layer.

  Only applicable if the layer has exactly one inbound node,
  i.e. if it is connected to one incoming layer.

  Returns:
      Input mask tensor (potentially None) or list of input
      mask tensors.

  Raises:
      AttributeError: if the layer is connected to
      more than one incoming layers.
  """
  inputs = self.input
  if isinstance(inputs, list):
    return [getattr(x, '_keras_mask', None) for x in inputs]
  else:
    return getattr(inputs, '_keras_mask', None)
var input_shape

Retrieves the input shape(s) of a layer.

Only applicable if the layer has exactly one input, i.e. if it is connected to one incoming layer, or if all inputs have the same shape.

Returns

Input shape, as an integer shape tuple (or list of shape tuples, one tuple per input tensor).

Raises

AttributeError
if the layer has no defined input_shape.
RuntimeError
if called in Eager mode.
Expand source code
@property
@doc_controls.do_not_doc_inheritable
def input_shape(self):
  """Retrieves the input shape(s) of a layer.

  Only applicable if the layer has exactly one input,
  i.e. if it is connected to one incoming layer, or if all inputs
  have the same shape.

  Returns:
      Input shape, as an integer shape tuple
      (or list of shape tuples, one tuple per input tensor).

  Raises:
      AttributeError: if the layer has no defined input_shape.
      RuntimeError: if called in Eager mode.
  """
  if not self._inbound_nodes:
    raise AttributeError('The layer has never been called '
                         'and thus has no defined input shape.')
  all_input_shapes = set(
      [str(node.input_shapes) for node in self._inbound_nodes])
  if len(all_input_shapes) == 1:
    return self._inbound_nodes[0].input_shapes
  else:
    raise AttributeError('The layer "' + str(self.name) +
                         ' has multiple inbound nodes, '
                         'with different input shapes. Hence '
                         'the notion of "input shape" is '
                         'ill-defined for the layer. '
                         'Use `get_input_shape_at(node_index)` '
                         'instead.')
var input_spec

InputSpec instance(s) describing the input format for this layer.

When you create a layer subclass, you can set self.input_spec to enable the layer to run input compatibility checks when it is called. Consider a Conv2D layer: it can only be called on a single input tensor of rank 4. As such, you can set, in __init__():

self.input_spec = tf.keras.layers.InputSpec(ndim=4)

Now, if you try to call the layer on an input that isn't rank 4 (for instance, an input of shape (2,), it will raise a nicely-formatted error:

ValueError: Input 0 of layer conv2d is incompatible with the layer:
expected ndim=4, found ndim=1. Full shape received: [2]

Input checks that can be specified via input_spec include: - Structure (e.g. a single input, a list of 2 inputs, etc) - Shape - Rank (ndim) - Dtype

For more information, see tf.keras.layers.InputSpec.

Returns

A tf.keras.layers.InputSpec instance, or nested structure thereof.

Expand source code
@property
def input_spec(self):
  """`InputSpec` instance(s) describing the input format for this layer.

  When you create a layer subclass, you can set `self.input_spec` to enable
  the layer to run input compatibility checks when it is called.
  Consider a `Conv2D` layer: it can only be called on a single input tensor
  of rank 4. As such, you can set, in `__init__()`:

  ```python
  self.input_spec = tf.keras.layers.InputSpec(ndim=4)
  ```

  Now, if you try to call the layer on an input that isn't rank 4
  (for instance, an input of shape `(2,)`, it will raise a nicely-formatted
  error:

  ```
  ValueError: Input 0 of layer conv2d is incompatible with the layer:
  expected ndim=4, found ndim=1. Full shape received: [2]
  ```

  Input checks that can be specified via `input_spec` include:
  - Structure (e.g. a single input, a list of 2 inputs, etc)
  - Shape
  - Rank (ndim)
  - Dtype

  For more information, see `tf.keras.layers.InputSpec`.

  Returns:
    A `tf.keras.layers.InputSpec` instance, or nested structure thereof.
  """
  return self._input_spec
var losses

List of losses added using the add_loss() API.

Variable regularization tensors are created when this property is accessed, so it is eager safe: accessing losses under a tf.GradientTape will propagate gradients back to the corresponding variables.

Examples:

>>> class MyLayer(tf.keras.layers.Layer):
...   def call(self, inputs):
...     self.add_loss(tf.abs(tf.reduce_mean(inputs)))
...     return inputs
>>> l = MyLayer()
>>> l(np.ones((10, 1)))
>>> l.losses
[1.0]
>>> inputs = tf.keras.Input(shape=(10,))
>>> x = tf.keras.layers.Dense(10)(inputs)
>>> outputs = tf.keras.layers.Dense(1)(x)
>>> model = tf.keras.Model(inputs, outputs)
>>> # Activity regularization.
>>> len(model.losses)
0
>>> model.add_loss(tf.abs(tf.reduce_mean(x)))
>>> len(model.losses)
1
>>> inputs = tf.keras.Input(shape=(10,))
>>> d = tf.keras.layers.Dense(10, kernel_initializer='ones')
>>> x = d(inputs)
>>> outputs = tf.keras.layers.Dense(1)(x)
>>> model = tf.keras.Model(inputs, outputs)
>>> # Weight regularization.
>>> model.add_loss(lambda: tf.reduce_mean(d.kernel))
>>> model.losses
[<tf.Tensor: shape=(), dtype=float32, numpy=1.0>]

Returns

A list of tensors.

Expand source code
@property
def losses(self):
  """List of losses added using the `add_loss()` API.

  Variable regularization tensors are created when this property is accessed,
  so it is eager safe: accessing `losses` under a `tf.GradientTape` will
  propagate gradients back to the corresponding variables.

  Examples:

  >>> class MyLayer(tf.keras.layers.Layer):
  ...   def call(self, inputs):
  ...     self.add_loss(tf.abs(tf.reduce_mean(inputs)))
  ...     return inputs
  >>> l = MyLayer()
  >>> l(np.ones((10, 1)))
  >>> l.losses
  [1.0]

  >>> inputs = tf.keras.Input(shape=(10,))
  >>> x = tf.keras.layers.Dense(10)(inputs)
  >>> outputs = tf.keras.layers.Dense(1)(x)
  >>> model = tf.keras.Model(inputs, outputs)
  >>> # Activity regularization.
  >>> len(model.losses)
  0
  >>> model.add_loss(tf.abs(tf.reduce_mean(x)))
  >>> len(model.losses)
  1

  >>> inputs = tf.keras.Input(shape=(10,))
  >>> d = tf.keras.layers.Dense(10, kernel_initializer='ones')
  >>> x = d(inputs)
  >>> outputs = tf.keras.layers.Dense(1)(x)
  >>> model = tf.keras.Model(inputs, outputs)
  >>> # Weight regularization.
  >>> model.add_loss(lambda: tf.reduce_mean(d.kernel))
  >>> model.losses
  [<tf.Tensor: shape=(), dtype=float32, numpy=1.0>]

  Returns:
    A list of tensors.
  """
  collected_losses = []
  for layer in self._flatten_layers():
    # If any eager losses are present, we assume the model to be part of an
    # eager training loop (either a custom one or the one used when
    # `run_eagerly=True`) and so we always return just the eager losses.
    if layer._eager_losses:
      # Filter placeholder losses that may have been added by revived layers.
      # (see base_layer_utils for details).
      if (layer._eager_losses[0] is
          not base_layer_utils.REVIVED_LOSS_PLACEHOLDER):
        collected_losses.extend(layer._eager_losses)
    else:
      collected_losses.extend(layer._losses)
    for regularizer in layer._callable_losses:
      loss_tensor = regularizer()
      if loss_tensor is not None:
        collected_losses.append(loss_tensor)
  return collected_losses
var metrics

List of metrics added using the add_metric() API.

Example:

>>> input = tf.keras.layers.Input(shape=(3,))
>>> d = tf.keras.layers.Dense(2)
>>> output = d(input)
>>> d.add_metric(tf.reduce_max(output), name='max')
>>> d.add_metric(tf.reduce_min(output), name='min')
>>> [m.name for m in d.metrics]
['max', 'min']

Returns

A list of Metric objects.

Expand source code
@property
def metrics(self):
  """List of metrics added using the `add_metric()` API.

  Example:

  >>> input = tf.keras.layers.Input(shape=(3,))
  >>> d = tf.keras.layers.Dense(2)
  >>> output = d(input)
  >>> d.add_metric(tf.reduce_max(output), name='max')
  >>> d.add_metric(tf.reduce_min(output), name='min')
  >>> [m.name for m in d.metrics]
  ['max', 'min']

  Returns:
    A list of `Metric` objects.
  """
  collected_metrics = []
  for layer in self._flatten_layers():
    with layer._metrics_lock:
      collected_metrics.extend(layer._metrics)
  return collected_metrics
var name

Name of the layer (string), set in the constructor.

Expand source code
@property
def name(self):
  """Name of the layer (string), set in the constructor."""
  return self._name
var non_trainable_variables

Sequence of non-trainable variables owned by this module and its submodules.

Note: this method uses reflection to find variables on the current instance and submodules. For performance reasons you may wish to cache the result of calling this method if you don't expect the return value to change.

Returns

A sequence of variables for the current module (sorted by attribute name) followed by variables from all submodules recursively (breadth first).

Expand source code
@property
@doc_controls.do_not_generate_docs
def non_trainable_variables(self):
  return self.non_trainable_weights
var non_trainable_weights

List of all non-trainable weights tracked by this layer.

Non-trainable weights are not updated during training. They are expected to be updated manually in call().

Returns

A list of non-trainable variables.

Expand source code
@property
def non_trainable_weights(self):
  """List of all non-trainable weights tracked by this layer.

  Non-trainable weights are *not* updated during training. They are expected
  to be updated manually in `call()`.

  Returns:
    A list of non-trainable variables.
  """
  if self.trainable:
    children_weights = self._gather_children_attribute(
        'non_trainable_variables')
    non_trainable_weights = self._non_trainable_weights + children_weights
  else:
    children_weights = self._gather_children_attribute('variables')
    non_trainable_weights = (
        self._trainable_weights + self._non_trainable_weights +
        children_weights)
  return self._dedup_weights(non_trainable_weights)
var outbound_nodes

Deprecated, do NOT use! Only for compatibility with external Keras.

Expand source code
@property
@doc_controls.do_not_doc_inheritable
def outbound_nodes(self):
  """Deprecated, do NOT use! Only for compatibility with external Keras."""
  return self._outbound_nodes
var output

Retrieves the output tensor(s) of a layer.

Only applicable if the layer has exactly one output, i.e. if it is connected to one incoming layer.

Returns

Output tensor or list of output tensors.

Raises

AttributeError
if the layer is connected to more than one incoming layers.
RuntimeError
if called in Eager mode.
Expand source code
@property
def output(self):
  """Retrieves the output tensor(s) of a layer.

  Only applicable if the layer has exactly one output,
  i.e. if it is connected to one incoming layer.

  Returns:
    Output tensor or list of output tensors.

  Raises:
    AttributeError: if the layer is connected to more than one incoming
      layers.
    RuntimeError: if called in Eager mode.
  """
  if not self._inbound_nodes:
    raise AttributeError('Layer ' + self.name + ' has no inbound nodes.')
  return self._get_node_attribute_at_index(0, 'output_tensors', 'output')
var output_mask

Retrieves the output mask tensor(s) of a layer.

Only applicable if the layer has exactly one inbound node, i.e. if it is connected to one incoming layer.

Returns

Output mask tensor (potentially None) or list of output mask tensors.

Raises

AttributeError
if the layer is connected to

more than one incoming layers.

Expand source code
@property
@doc_controls.do_not_doc_inheritable
def output_mask(self):
  """Retrieves the output mask tensor(s) of a layer.

  Only applicable if the layer has exactly one inbound node,
  i.e. if it is connected to one incoming layer.

  Returns:
      Output mask tensor (potentially None) or list of output
      mask tensors.

  Raises:
      AttributeError: if the layer is connected to
      more than one incoming layers.
  """
  output = self.output
  if isinstance(output, list):
    return [getattr(x, '_keras_mask', None) for x in output]
  else:
    return getattr(output, '_keras_mask', None)
var output_shape

Retrieves the output shape(s) of a layer.

Only applicable if the layer has one output, or if all outputs have the same shape.

Returns

Output shape, as an integer shape tuple (or list of shape tuples, one tuple per output tensor).

Raises

AttributeError
if the layer has no defined output shape.
RuntimeError
if called in Eager mode.
Expand source code
@property
@doc_controls.do_not_doc_inheritable
def output_shape(self):
  """Retrieves the output shape(s) of a layer.

  Only applicable if the layer has one output,
  or if all outputs have the same shape.

  Returns:
      Output shape, as an integer shape tuple
      (or list of shape tuples, one tuple per output tensor).

  Raises:
      AttributeError: if the layer has no defined output shape.
      RuntimeError: if called in Eager mode.
  """
  if not self._inbound_nodes:
    raise AttributeError('The layer has never been called '
                         'and thus has no defined output shape.')
  all_output_shapes = set(
      [str(node.output_shapes) for node in self._inbound_nodes])
  if len(all_output_shapes) == 1:
    return self._inbound_nodes[0].output_shapes
  else:
    raise AttributeError('The layer "%s"'
                         ' has multiple inbound nodes, '
                         'with different output shapes. Hence '
                         'the notion of "output shape" is '
                         'ill-defined for the layer. '
                         'Use `get_output_shape_at(node_index)` '
                         'instead.' % self.name)
var stateful
Expand source code
@property
@doc_controls.do_not_doc_inheritable
def stateful(self):
  return any(layer._stateful for layer in self._flatten_layers())
var supports_masking

Whether this layer supports computing a mask using compute_mask.

Expand source code
@property
def supports_masking(self):
  """Whether this layer supports computing a mask using `compute_mask`."""
  return self._supports_masking
var trainable
Expand source code
@property
def trainable(self):
  return self._trainable
var trainable_variables

Sequence of trainable variables owned by this module and its submodules.

Note: this method uses reflection to find variables on the current instance and submodules. For performance reasons you may wish to cache the result of calling this method if you don't expect the return value to change.

Returns

A sequence of variables for the current module (sorted by attribute name) followed by variables from all submodules recursively (breadth first).

Expand source code
@property
@doc_controls.do_not_generate_docs
def trainable_variables(self):
  return self.trainable_weights
var trainable_weights

List of all trainable weights tracked by this layer.

Trainable weights are updated via gradient descent during training.

Returns

A list of trainable variables.

Expand source code
@property
def trainable_weights(self):
  """List of all trainable weights tracked by this layer.

  Trainable weights are updated via gradient descent during training.

  Returns:
    A list of trainable variables.
  """
  if self.trainable:
    children_weights = self._gather_children_attribute('trainable_variables')
    return self._dedup_weights(self._trainable_weights + children_weights)
  else:
    return []
var updates
Expand source code
@property
@doc_controls.do_not_generate_docs
def updates(self):
  warnings.warn('`layer.updates` will be removed in a future version. '
                'This property should not be used in TensorFlow 2.0, '
                'as `updates` are applied automatically.')
  return []
var variable_dtype

Alias of Layer.dtype, the dtype of the weights.

Expand source code
@property
def variable_dtype(self):
  """Alias of `Layer.dtype`, the dtype of the weights."""
  return self.dtype
var variables

Returns the list of all layer variables/weights.

Alias of self.weights.

Note: This will not track the weights of nested tf.Modules that are not themselves Keras layers.

Returns

A list of variables.

Expand source code
@property
@doc_controls.do_not_generate_docs
def variables(self):
  """Returns the list of all layer variables/weights.

  Alias of `self.weights`.

  Note: This will not track the weights of nested `tf.Modules` that are not
  themselves Keras layers.

  Returns:
    A list of variables.
  """
  return self.weights
var weights

Returns the list of all layer variables/weights.

Returns

A list of variables.

Expand source code
@property
def weights(self):
  """Returns the list of all layer variables/weights.

  Returns:
    A list of variables.
  """
  return self.trainable_weights + self.non_trainable_weights

Methods

def add_loss(self, losses, **kwargs)

Add loss tensor(s), potentially dependent on layer inputs.

Some losses (for instance, activity regularization losses) may be dependent on the inputs passed when calling a layer. Hence, when reusing the same layer on different inputs a and b, some entries in layer.losses may be dependent on a and some on b. This method automatically keeps track of dependencies.

This method can be used inside a subclassed layer or model's call function, in which case losses should be a Tensor or list of Tensors.

Example:

class MyLayer(tf.keras.layers.Layer):
  def call(self, inputs):
    self.add_loss(tf.abs(tf.reduce_mean(inputs)))
    return inputs

This method can also be called directly on a Functional Model during construction. In this case, any loss Tensors passed to this Model must be symbolic and be able to be traced back to the model's Input()s. These losses become part of the model's topology and are tracked in get_config.

Example:

inputs = tf.keras.Input(shape=(10,))
x = tf.keras.layers.Dense(10)(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
# Activity regularization.
model.add_loss(tf.abs(tf.reduce_mean(x)))

If this is not the case for your loss (if, for example, your loss references a Variable of one of the model's layers), you can wrap your loss in a zero-argument lambda. These losses are not tracked as part of the model's topology since they can't be serialized.

Example:

inputs = tf.keras.Input(shape=(10,))
d = tf.keras.layers.Dense(10)
x = d(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
# Weight regularization.
model.add_loss(lambda: tf.reduce_mean(d.kernel))

Args

losses
Loss tensor, or list/tuple of tensors. Rather than tensors, losses may also be zero-argument callables which create a loss tensor.
**kwargs
Additional keyword arguments for backward compatibility. Accepted values: inputs - Deprecated, will be automatically inferred.
Expand source code
def add_loss(self, losses, **kwargs):
  """Add loss tensor(s), potentially dependent on layer inputs.

  Some losses (for instance, activity regularization losses) may be dependent
  on the inputs passed when calling a layer. Hence, when reusing the same
  layer on different inputs `a` and `b`, some entries in `layer.losses` may
  be dependent on `a` and some on `b`. This method automatically keeps track
  of dependencies.

  This method can be used inside a subclassed layer or model's `call`
  function, in which case `losses` should be a Tensor or list of Tensors.

  Example:

  ```python
  class MyLayer(tf.keras.layers.Layer):
    def call(self, inputs):
      self.add_loss(tf.abs(tf.reduce_mean(inputs)))
      return inputs
  ```

  This method can also be called directly on a Functional Model during
  construction. In this case, any loss Tensors passed to this Model must
  be symbolic and be able to be traced back to the model's `Input`s. These
  losses become part of the model's topology and are tracked in `get_config`.

  Example:

  ```python
  inputs = tf.keras.Input(shape=(10,))
  x = tf.keras.layers.Dense(10)(inputs)
  outputs = tf.keras.layers.Dense(1)(x)
  model = tf.keras.Model(inputs, outputs)
  # Activity regularization.
  model.add_loss(tf.abs(tf.reduce_mean(x)))
  ```

  If this is not the case for your loss (if, for example, your loss references
  a `Variable` of one of the model's layers), you can wrap your loss in a
  zero-argument lambda. These losses are not tracked as part of the model's
  topology since they can't be serialized.

  Example:

  ```python
  inputs = tf.keras.Input(shape=(10,))
  d = tf.keras.layers.Dense(10)
  x = d(inputs)
  outputs = tf.keras.layers.Dense(1)(x)
  model = tf.keras.Model(inputs, outputs)
  # Weight regularization.
  model.add_loss(lambda: tf.reduce_mean(d.kernel))
  ```

  Args:
    losses: Loss tensor, or list/tuple of tensors. Rather than tensors, losses
      may also be zero-argument callables which create a loss tensor.
    **kwargs: Additional keyword arguments for backward compatibility.
      Accepted values:
        inputs - Deprecated, will be automatically inferred.
  """
  kwargs.pop('inputs', None)
  if kwargs:
    raise TypeError('Unknown keyword arguments: %s' % (kwargs.keys(),))

  def _tag_callable(loss):
    """Tags callable loss tensor as `_unconditional_loss`."""
    if callable(loss):
      # We run the loss without autocasting, as regularizers are often
      # numerically unstable in float16.
      with autocast_variable.enable_auto_cast_variables(None):
        loss = loss()
    if loss is None:
      return None  # Will be filtered out when computing the .losses property
    if not tf.is_tensor(loss):
      loss = tf.convert_to_tensor(
          loss, dtype=backend.floatx())
    loss._unconditional_loss = True  # pylint: disable=protected-access
    return loss

  losses = tf.nest.flatten(losses)

  callable_losses = []
  eager_losses = []
  symbolic_losses = []
  for loss in losses:
    if callable(loss):
      callable_losses.append(functools.partial(_tag_callable, loss))
      continue
    if loss is None:
      continue
    if not tf.is_tensor(loss) and not isinstance(
        loss, keras_tensor.KerasTensor):
      loss = tf.convert_to_tensor(
          loss, dtype=backend.floatx())
    # TF Functions should take the eager path.
    if ((tf_utils.is_symbolic_tensor(loss) or
         isinstance(loss, keras_tensor.KerasTensor)) and
        not base_layer_utils.is_in_tf_function()):
      symbolic_losses.append(loss)
    elif tf.is_tensor(loss):
      eager_losses.append(loss)

  self._callable_losses.extend(callable_losses)

  in_call_context = base_layer_utils.call_context().in_call
  if eager_losses and not in_call_context:
    raise ValueError(
        'Expected a symbolic Tensors or a callable for the loss value. '
        'Please wrap your loss computation in a zero argument `lambda`.')

  self._eager_losses.extend(eager_losses)

  for symbolic_loss in symbolic_losses:
    if getattr(self, '_is_graph_network', False):
      self._graph_network_add_loss(symbolic_loss)
    else:
      # Possible a loss was added in a Layer's `build`.
      self._losses.append(symbolic_loss)
def add_metric(self, value, name=None, **kwargs)

Adds metric tensor to the layer.

This method can be used inside the call() method of a subclassed layer or model.

class MyMetricLayer(tf.keras.layers.Layer):
  def __init__(self):
    super(MyMetricLayer, self).__init__(name='my_metric_layer')
    self.mean = tf.keras.metrics.Mean(name='metric_1')

  def call(self, inputs):
    self.add_metric(self.mean(inputs))
    self.add_metric(tf.reduce_sum(inputs), name='metric_2')
    return inputs

This method can also be called directly on a Functional Model during construction. In this case, any tensor passed to this Model must be symbolic and be able to be traced back to the model's Input()s. These metrics become part of the model's topology and are tracked when you save the model via save().

inputs = tf.keras.Input(shape=(10,))
x = tf.keras.layers.Dense(10)(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
model.add_metric(math_ops.reduce_sum(x), name='metric_1')

Note: Calling add_metric() with the result of a metric object on a Functional Model, as shown in the example below, is not supported. This is because we cannot trace the metric result tensor back to the model's inputs.

inputs = tf.keras.Input(shape=(10,))
x = tf.keras.layers.Dense(10)(inputs)
outputs = tf.keras.layers.Dense(1)(x)
model = tf.keras.Model(inputs, outputs)
model.add_metric(tf.keras.metrics.Mean()(x), name='metric_1')

Args

value
Metric tensor.
name
String metric name.
**kwargs
Additional keyword arguments for backward compatibility. Accepted values: aggregation - When the value tensor provided is not the result of calling a keras.Metric instance, it will be aggregated by default using a keras.Metric.Mean.
Expand source code
def add_metric(self, value, name=None, **kwargs):
  """Adds metric tensor to the layer.

  This method can be used inside the `call()` method of a subclassed layer
  or model.

  ```python
  class MyMetricLayer(tf.keras.layers.Layer):
    def __init__(self):
      super(MyMetricLayer, self).__init__(name='my_metric_layer')
      self.mean = tf.keras.metrics.Mean(name='metric_1')

    def call(self, inputs):
      self.add_metric(self.mean(inputs))
      self.add_metric(tf.reduce_sum(inputs), name='metric_2')
      return inputs
  ```

  This method can also be called directly on a Functional Model during
  construction. In this case, any tensor passed to this Model must
  be symbolic and be able to be traced back to the model's `Input`s. These
  metrics become part of the model's topology and are tracked when you
  save the model via `save()`.

  ```python
  inputs = tf.keras.Input(shape=(10,))
  x = tf.keras.layers.Dense(10)(inputs)
  outputs = tf.keras.layers.Dense(1)(x)
  model = tf.keras.Model(inputs, outputs)
  model.add_metric(math_ops.reduce_sum(x), name='metric_1')
  ```

  Note: Calling `add_metric()` with the result of a metric object on a
  Functional Model, as shown in the example below, is not supported. This is
  because we cannot trace the metric result tensor back to the model's inputs.

  ```python
  inputs = tf.keras.Input(shape=(10,))
  x = tf.keras.layers.Dense(10)(inputs)
  outputs = tf.keras.layers.Dense(1)(x)
  model = tf.keras.Model(inputs, outputs)
  model.add_metric(tf.keras.metrics.Mean()(x), name='metric_1')
  ```

  Args:
    value: Metric tensor.
    name: String metric name.
    **kwargs: Additional keyword arguments for backward compatibility.
      Accepted values:
      `aggregation` - When the `value` tensor provided is not the result of
      calling a `keras.Metric` instance, it will be aggregated by default
      using a `keras.Metric.Mean`.
  """
  kwargs_keys = list(kwargs.keys())
  if (len(kwargs_keys) > 1 or
      (len(kwargs_keys) == 1 and kwargs_keys[0] != 'aggregation')):
    raise TypeError('Unknown keyword arguments: ', str(kwargs.keys()))

  from_metric_obj = hasattr(value, '_metric_obj')
  is_symbolic = isinstance(value, keras_tensor.KerasTensor)
  in_call_context = base_layer_utils.call_context().in_call

  if name is None and not from_metric_obj:
    # Eg. `self.add_metric(math_ops.reduce_sum(x))`
    # In eager mode, we use metric name to lookup a metric. Without a name,
    # a new Mean metric wrapper will be created on every model/layer call.
    # So, we raise an error when no name is provided.
    # We will do the same for symbolic mode for consistency although a name
    # will be generated if no name is provided.

    # We will not raise this error in the foll use case for the sake of
    # consistency as name in provided in the metric constructor.
    # mean = metrics.Mean(name='my_metric')
    # model.add_metric(mean(outputs))
    raise ValueError('Please provide a name for your metric like '
                     '`self.add_metric(tf.reduce_sum(inputs), '
                     'name=\'mean_activation\')`')
  elif from_metric_obj:
    name = value._metric_obj.name

  if not in_call_context and not is_symbolic:
    raise ValueError('Expected a symbolic Tensor for the metric value, '
                     'received: ' + str(value))

  # If a metric was added in a Layer's `call` or `build`.
  if in_call_context or not getattr(self, '_is_graph_network', False):
    # TF Function path should take the eager path.

    # If the given metric is available in `metrics` list we just update state
    # on it, otherwise we create a new metric instance and
    # add it to the `metrics` list.
    metric_obj = getattr(value, '_metric_obj', None)
    # Tensors that come from a Metric object already updated the Metric state.
    should_update_state = not metric_obj
    name = metric_obj.name if metric_obj else name

    with self._metrics_lock:
      match = self._get_existing_metric(name)
      if match:
        metric_obj = match
      elif metric_obj:
        self._metrics.append(metric_obj)
      else:
        # Build the metric object with the value's dtype if it defines one
        metric_obj = metrics_mod.Mean(
            name=name, dtype=getattr(value, 'dtype', None))
        self._metrics.append(metric_obj)

    if should_update_state:
      metric_obj(value)
  else:
    if from_metric_obj:
      raise ValueError('Using the result of calling a `Metric` object '
                       'when calling `add_metric` on a Functional '
                       'Model is not supported. Please pass the '
                       'Tensor to monitor directly.')

    # Insert layers into the Keras Graph Network.
    aggregation = None if from_metric_obj else 'mean'
    self._graph_network_add_metric(value, aggregation, name)
def add_update(self, updates, inputs=None)

Add update op(s), potentially dependent on layer inputs.

Weight updates (for instance, the updates of the moving mean and variance in a BatchNormalization layer) may be dependent on the inputs passed when calling a layer. Hence, when reusing the same layer on different inputs a and b, some entries in layer.updates may be dependent on a and some on b. This method automatically keeps track of dependencies.

This call is ignored when eager execution is enabled (in that case, variable updates are run on the fly and thus do not need to be tracked for later execution).

Args

updates
Update op, or list/tuple of update ops, or zero-arg callable that returns an update op. A zero-arg callable should be passed in order to disable running the updates by setting trainable=False on this Layer, when executing in Eager mode.
inputs
Deprecated, will be automatically inferred.
Expand source code
@doc_controls.do_not_doc_inheritable
def add_update(self, updates, inputs=None):
  """Add update op(s), potentially dependent on layer inputs.

  Weight updates (for instance, the updates of the moving mean and variance
  in a BatchNormalization layer) may be dependent on the inputs passed
  when calling a layer. Hence, when reusing the same layer on
  different inputs `a` and `b`, some entries in `layer.updates` may be
  dependent on `a` and some on `b`. This method automatically keeps track
  of dependencies.

  This call is ignored when eager execution is enabled (in that case, variable
  updates are run on the fly and thus do not need to be tracked for later
  execution).

  Args:
    updates: Update op, or list/tuple of update ops, or zero-arg callable
      that returns an update op. A zero-arg callable should be passed in
      order to disable running the updates by setting `trainable=False`
      on this Layer, when executing in Eager mode.
    inputs: Deprecated, will be automatically inferred.
  """
  if inputs is not None:
    tf_logging.warning(
        '`add_update` `inputs` kwarg has been deprecated. You no longer need '
        'to pass a value to `inputs` as it is being automatically inferred.')
  call_context = base_layer_utils.call_context()
  # No need to run updates during Functional API construction.
  if call_context.in_keras_graph:
    return

  # Callable updates are disabled by setting `trainable=False`.
  if not call_context.frozen:
    for update in tf.nest.flatten(updates):
      if callable(update):
        update()  # pylint: disable=not-callable
def add_variable(self, *args, **kwargs)

Deprecated, do NOT use! Alias for add_weight.

Expand source code
@doc_controls.do_not_doc_inheritable
def add_variable(self, *args, **kwargs):
  """Deprecated, do NOT use! Alias for `add_weight`."""
  warnings.warn('`layer.add_variable` is deprecated and '
                'will be removed in a future version. '
                'Please use `layer.add_weight` method instead.')
  return self.add_weight(*args, **kwargs)
def add_weight(self, name=None, shape=None, dtype=None, initializer=None, regularizer=None, trainable=None, constraint=None, use_resource=None, synchronization=VariableSynchronization.AUTO, aggregation=VariableAggregationV2.NONE, **kwargs)

Adds a new variable to the layer.

Args

name
Variable name.
shape
Variable shape. Defaults to scalar if unspecified.
dtype
The type of the variable. Defaults to self.dtype.
initializer
Initializer instance (callable).
regularizer
Regularizer instance (callable).
trainable
Boolean, whether the variable should be part of the layer's "trainable_variables" (e.g. variables, biases) or "non_trainable_variables" (e.g. BatchNorm mean and variance). Note that trainable cannot be True if synchronization is set to ON_READ.
constraint
Constraint instance (callable).
use_resource
Whether to use ResourceVariable.
synchronization
Indicates when a distributed a variable will be aggregated. Accepted values are constants defined in the class tf.VariableSynchronization. By default the synchronization is set to AUTO and the current DistributionStrategy chooses when to synchronize. If synchronization is set to ON_READ, trainable must not be set to True.
aggregation
Indicates how a distributed variable will be aggregated. Accepted values are constants defined in the class tf.VariableAggregation.
**kwargs
Additional keyword arguments. Accepted values are getter, collections, experimental_autocast and caching_device.

Returns

The variable created.

Raises

ValueError
When giving unsupported dtype and no initializer or when trainable has been set to True with synchronization set as ON_READ.
Expand source code
@doc_controls.for_subclass_implementers
def add_weight(self,
               name=None,
               shape=None,
               dtype=None,
               initializer=None,
               regularizer=None,
               trainable=None,
               constraint=None,
               use_resource=None,
               synchronization=tf.VariableSynchronization.AUTO,
               aggregation=tf.VariableAggregation.NONE,
               **kwargs):
  """Adds a new variable to the layer.

  Args:
    name: Variable name.
    shape: Variable shape. Defaults to scalar if unspecified.
    dtype: The type of the variable. Defaults to `self.dtype`.
    initializer: Initializer instance (callable).
    regularizer: Regularizer instance (callable).
    trainable: Boolean, whether the variable should be part of the layer's
      "trainable_variables" (e.g. variables, biases)
      or "non_trainable_variables" (e.g. BatchNorm mean and variance).
      Note that `trainable` cannot be `True` if `synchronization`
      is set to `ON_READ`.
    constraint: Constraint instance (callable).
    use_resource: Whether to use `ResourceVariable`.
    synchronization: Indicates when a distributed a variable will be
      aggregated. Accepted values are constants defined in the class
      `tf.VariableSynchronization`. By default the synchronization is set to
      `AUTO` and the current `DistributionStrategy` chooses
      when to synchronize. If `synchronization` is set to `ON_READ`,
      `trainable` must not be set to `True`.
    aggregation: Indicates how a distributed variable will be aggregated.
      Accepted values are constants defined in the class
      `tf.VariableAggregation`.
    **kwargs: Additional keyword arguments. Accepted values are `getter`,
      `collections`, `experimental_autocast` and `caching_device`.

  Returns:
    The variable created.

  Raises:
    ValueError: When giving unsupported dtype and no initializer or when
      trainable has been set to True with synchronization set as `ON_READ`.
  """
  if shape is None:
    shape = ()
  kwargs.pop('partitioner', None)  # Ignored.
  # Validate optional keyword arguments.
  for kwarg in kwargs:
    if kwarg not in ['collections', 'experimental_autocast',
                     'caching_device', 'getter']:
      raise TypeError('Unknown keyword argument:', kwarg)
  collections_arg = kwargs.pop('collections', None)
  # 'experimental_autocast' can be set to False by the caller to indicate an
  # AutoCastVariable should never be created.
  autocast = kwargs.pop('experimental_autocast', True)
  # See the docstring for tf.Variable about the details for caching_device.
  caching_device = kwargs.pop('caching_device', None)

  if dtype is None:
    dtype = self.dtype or backend.floatx()
  dtype = tf.as_dtype(dtype)
  if self._dtype_policy.variable_dtype is None:
    # The policy is "_infer", so we infer the policy from the variable dtype.
    self._set_dtype_policy(policy.Policy(dtype.base_dtype.name))
  initializer = initializers.get(initializer)
  regularizer = regularizers.get(regularizer)
  constraint = constraints.get(constraint)

  if synchronization == tf.VariableSynchronization.ON_READ:
    if trainable:
      raise ValueError(
          'Synchronization value can be set to '
          'VariableSynchronization.ON_READ only for non-trainable variables. '
          'You have specified trainable=True and '
          'synchronization=VariableSynchronization.ON_READ.')
    else:
      # Set trainable to be false when variable is to be synced on read.
      trainable = False
  elif trainable is None:
    trainable = True

  # Initialize variable when no initializer provided
  if initializer is None:
    # If dtype is DT_FLOAT, provide a uniform unit scaling initializer
    if dtype.is_floating:
      initializer = initializers.get('glorot_uniform')
    # If dtype is DT_INT/DT_UINT, provide a default value `zero`
    # If dtype is DT_BOOL, provide a default value `FALSE`
    elif dtype.is_integer or dtype.is_unsigned or dtype.is_bool:
      initializer = initializers.get('zeros')
    # NOTES:Do we need to support for handling DT_STRING and DT_COMPLEX here?
    elif 'getter' not in kwargs:
      # When `getter` is specified, it's possibly fine for `initializer` to be
      # None since it's up to the custom `getter` to raise error in case it
      # indeed needs `initializer`.
      raise ValueError('An initializer for variable %s of type %s is required'
                       ' for layer %s' % (name, dtype.base_dtype, self.name))

  getter = kwargs.pop('getter', base_layer_utils.make_variable)
  if (autocast and
      self._dtype_policy.compute_dtype != self._dtype_policy.variable_dtype
      and dtype.is_floating):
    old_getter = getter
    # Wrap variable constructor to return an AutoCastVariable.
    def getter(*args, **kwargs):  # pylint: disable=function-redefined
      variable = old_getter(*args, **kwargs)
      return autocast_variable.create_autocast_variable(variable)
    # Also the caching_device does not work with the mixed precision API,
    # disable it if it is specified.
    # TODO(b/142020079): Reenable it once the bug is fixed.
    if caching_device is not None:
      tf_logging.warning(
          '`caching_device` does not work with mixed precision API. Ignoring '
          'user specified `caching_device`.')
      caching_device = None

  variable = self._add_variable_with_custom_getter(
      name=name,
      shape=shape,
      # TODO(allenl): a `make_variable` equivalent should be added as a
      # `Trackable` method.
      getter=getter,
      # Manage errors in Layer rather than Trackable.
      overwrite=True,
      initializer=initializer,
      dtype=dtype,
      constraint=constraint,
      trainable=trainable,
      use_resource=use_resource,
      collections=collections_arg,
      synchronization=synchronization,
      aggregation=aggregation,
      caching_device=caching_device)
  if regularizer is not None:
    # TODO(fchollet): in the future, this should be handled at the
    # level of variable creation, and weight regularization losses
    # should be variable attributes.
    name_in_scope = variable.name[:variable.name.find(':')]
    self._handle_weight_regularization(name_in_scope,
                                       variable,
                                       regularizer)
  if base_layer_utils.is_split_variable(variable):
    for v in variable:
      backend.track_variable(v)
      if trainable:
        self._trainable_weights.append(v)
      else:
        self._non_trainable_weights.append(v)
  else:
    backend.track_variable(variable)
    if trainable:
      self._trainable_weights.append(variable)
    else:
      self._non_trainable_weights.append(variable)
  return variable
def apply(self, inputs, *args, **kwargs)

Deprecated, do NOT use!

This is an alias of self.__call__.

Args

inputs
Input tensor(s).
*args
additional positional arguments to be passed to self.call.
**kwargs
additional keyword arguments to be passed to self.call.

Returns

Output tensor(s).

Expand source code
@doc_controls.do_not_doc_inheritable
def apply(self, inputs, *args, **kwargs):
  """Deprecated, do NOT use!

  This is an alias of `self.__call__`.

  Args:
    inputs: Input tensor(s).
    *args: additional positional arguments to be passed to `self.call`.
    **kwargs: additional keyword arguments to be passed to `self.call`.

  Returns:
    Output tensor(s).
  """
  warnings.warn('`layer.apply` is deprecated and '
                'will be removed in a future version. '
                'Please use `layer.__call__` method instead.')
  return self.__call__(inputs, *args, **kwargs)
def build(self, input_shape)

Creates the variables of the layer (optional, for subclass implementers).

This is a method that implementers of subclasses of Layer or Model can override if they need a state-creation step in-between layer instantiation and layer call.

This is typically used to create the weights of Layer subclasses.

Args

input_shape
Instance of TensorShape, or list of instances of TensorShape if the layer expects a list of inputs (one instance per input).
Expand source code
@tf.__internal__.tracking.no_automatic_dependency_tracking
@generic_utils.default
def build(self, input_shape):
  """Creates the variables of the layer (optional, for subclass implementers).

  This is a method that implementers of subclasses of `Layer` or `Model`
  can override if they need a state-creation step in-between
  layer instantiation and layer call.

  This is typically used to create the weights of `Layer` subclasses.

  Args:
    input_shape: Instance of `TensorShape`, or list of instances of
      `TensorShape` if the layer expects a list of inputs
      (one instance per input).
  """
  # Only record the build input shapes of overridden build methods.
  if not hasattr(self.build, '_is_default'):
    self._build_input_shape = input_shape
  self.built = True
def call(self, inputs, *args, **kwargs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
@doc_controls.for_subclass_implementers
def call(self, inputs, *args, **kwargs):  # pylint: disable=unused-argument
  """This is where the layer's logic lives.

  Note here that `call()` method in `tf.keras` is little bit different
  from `keras` API. In `keras` API, you can pass support masking for
  layers as additional arguments. Whereas `tf.keras` has `compute_mask()`
  method to support masking.

  Args:
    inputs: Input tensor, or dict/list/tuple of input tensors.
      The first positional `inputs` argument is subject to special rules:
      - `inputs` must be explicitly passed. A layer cannot have zero
        arguments, and `inputs` cannot be provided via the default value
        of a keyword argument.
      - NumPy array or Python scalar values in `inputs` get cast as tensors.
      - Keras mask metadata is only collected from `inputs`.
      - Layers are built (`build(input_shape)` method)
        using shape info from `inputs` only.
      - `input_spec` compatibility is only checked against `inputs`.
      - Mixed precision input casting is only applied to `inputs`.
        If a layer has tensor arguments in `*args` or `**kwargs`, their
        casting behavior in mixed precision should be handled manually.
      - The SavedModel input specification is generated using `inputs` only.
      - Integration with various ecosystem packages like TFMOT, TFLite,
        TF.js, etc is only supported for `inputs` and not for tensors in
        positional and keyword arguments.
    *args: Additional positional arguments. May contain tensors, although
      this is not recommended, for the reasons above.
    **kwargs: Additional keyword arguments. May contain tensors, although
      this is not recommended, for the reasons above.
      The following optional keyword arguments are reserved:
      - `training`: Boolean scalar tensor of Python boolean indicating
        whether the `call` is meant for training or inference.
      - `mask`: Boolean input mask. If the layer's `call()` method takes a
        `mask` argument, its default value will be set to the mask generated
        for `inputs` by the previous layer (if `input` did come from a layer
        that generated a corresponding mask, i.e. if it came from a Keras
        layer with masking support).

  Returns:
    A tensor or list/tuple of tensors.
  """
  return inputs
def compute_mask(self, inputs, mask=None)

Computes an output mask tensor.

Args

inputs
Tensor or list of tensors.
mask
Tensor or list of tensors.

Returns

None or a tensor (or list of tensors, one per output tensor of the layer).

Expand source code
@generic_utils.default
def compute_mask(self, inputs, mask=None):  # pylint: disable=unused-argument
  """Computes an output mask tensor.

  Args:
      inputs: Tensor or list of tensors.
      mask: Tensor or list of tensors.

  Returns:
      None or a tensor (or list of tensors,
          one per output tensor of the layer).
  """
  if not self._supports_masking:
    if any(m is not None for m in tf.nest.flatten(mask)):
      raise TypeError('Layer ' + self.name + ' does not support masking, '
                      'but was passed an input_mask: ' + str(mask))
    # masking not explicitly supported: return None as mask.
    return None
  # if masking is explicitly supported, by default
  # carry over the input mask
  return mask
def compute_output_shape(self, input_shape)

Computes the output shape of the layer.

If the layer has not been built, this method will call build on the layer. This assumes that the layer will later be used with inputs that match the input shape provided here.

Args

input_shape
Shape tuple (tuple of integers) or list of shape tuples (one per output tensor of the layer). Shape tuples can include None for free dimensions, instead of an integer.

Returns

An input shape tuple.

Expand source code
def compute_output_shape(self, input_shape):
  """Computes the output shape of the layer.

  If the layer has not been built, this method will call `build` on the
  layer. This assumes that the layer will later be used with inputs that
  match the input shape provided here.

  Args:
      input_shape: Shape tuple (tuple of integers)
          or list of shape tuples (one per output tensor of the layer).
          Shape tuples can include None for free dimensions,
          instead of an integer.

  Returns:
      An input shape tuple.
  """
  if tf.executing_eagerly():
    # In this case we build the model first in order to do shape inference.
    # This is acceptable because the framework only calls
    # `compute_output_shape` on shape values that the layer would later be
    # built for. It would however cause issues in case a user attempts to
    # use `compute_output_shape` manually with shapes that are incompatible
    # with the shape the Layer will be called on (these users will have to
    # implement `compute_output_shape` themselves).
    self._maybe_build(input_shape)
    with tf.__internal__.FuncGraph(str(self.name) + '_scratch_graph').as_default():
      input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
      def _make_placeholder_like(shape):
        ph = backend.placeholder(shape=shape, dtype=self.dtype)
        ph._keras_mask = None
        return ph
      inputs = tf.nest.map_structure(_make_placeholder_like, input_shape)
      try:
        outputs = self(inputs, training=False)
      except TypeError as e:
        raise NotImplementedError(
            'We could not automatically infer the static shape of the '
            'layer\'s output. Please implement the '
            '`compute_output_shape` method on your layer (%s).' %
            self.__class__.__name__) from e
    return tf.nest.map_structure(lambda t: t.shape, outputs)
  raise NotImplementedError(
      'Please run in eager mode or implement the `compute_output_shape` '
      'method on your layer (%s).' % self.__class__.__name__)
def compute_output_signature(self, input_signature)

Compute the output tensor signature of the layer based on the inputs.

Unlike a TensorShape object, a TensorSpec object contains both shape and dtype information for a tensor. This method allows layers to provide output dtype information if it is different from the input dtype. For any layer that doesn't implement this function, the framework will fall back to use compute_output_shape, and will assume that the output dtype matches the input dtype.

Args

input_signature
Single TensorSpec or nested structure of TensorSpec objects, describing a candidate input for the layer.

Returns

Single TensorSpec or nested structure of TensorSpec objects, describing how the layer would transform the provided input.

Raises

TypeError
If input_signature contains a non-TensorSpec object.
Expand source code
@doc_controls.for_subclass_implementers
def compute_output_signature(self, input_signature):
  """Compute the output tensor signature of the layer based on the inputs.

  Unlike a TensorShape object, a TensorSpec object contains both shape
  and dtype information for a tensor. This method allows layers to provide
  output dtype information if it is different from the input dtype.
  For any layer that doesn't implement this function,
  the framework will fall back to use `compute_output_shape`, and will
  assume that the output dtype matches the input dtype.

  Args:
    input_signature: Single TensorSpec or nested structure of TensorSpec
      objects, describing a candidate input for the layer.

  Returns:
    Single TensorSpec or nested structure of TensorSpec objects, describing
      how the layer would transform the provided input.

  Raises:
    TypeError: If input_signature contains a non-TensorSpec object.
  """
  def check_type_return_shape(s):
    if not isinstance(s, tf.TensorSpec):
      raise TypeError('Only TensorSpec signature types are supported, '
                      'but saw signature entry: {}.'.format(s))
    return s.shape
  input_shape = tf.nest.map_structure(check_type_return_shape, input_signature)
  output_shape = self.compute_output_shape(input_shape)
  dtype = self._compute_dtype
  if dtype is None:
    input_dtypes = [s.dtype for s in tf.nest.flatten(input_signature)]
    # Default behavior when self.dtype is None, is to use the first input's
    # dtype.
    dtype = input_dtypes[0]
  return tf.nest.map_structure(
      lambda s: tf.TensorSpec(dtype=dtype, shape=s),
      output_shape)
def count_params(self)

Count the total number of scalars composing the weights.

Returns

An integer count.

Raises

ValueError
if the layer isn't yet built (in which case its weights aren't yet defined).
Expand source code
def count_params(self):
  """Count the total number of scalars composing the weights.

  Returns:
      An integer count.

  Raises:
      ValueError: if the layer isn't yet built
        (in which case its weights aren't yet defined).
  """
  if not self.built:
    if getattr(self, '_is_graph_network', False):
      with tf_utils.maybe_init_scope(self):
        self._maybe_build(self.inputs)
    else:
      raise ValueError('You tried to call `count_params` on ' + self.name +
                       ', but the layer isn\'t built. '
                       'You can build it manually via: `' + self.name +
                       '.build(batch_input_shape)`.')
  return layer_utils.count_params(self.weights)
def finalize_state(self)

Finalizes the layers state after updating layer weights.

This function can be subclassed in a layer and will be called after updating a layer weights. It can be overridden to finalize any additional layer state after a weight update.

Expand source code
@doc_controls.do_not_generate_docs
def finalize_state(self):
  """Finalizes the layers state after updating layer weights.

  This function can be subclassed in a layer and will be called after updating
  a layer weights. It can be overridden to finalize any additional layer state
  after a weight update.
  """
  pass
def get_config(self)

Returns the config of the layer.

A layer config is a Python dictionary (serializable) containing the configuration of a layer. The same layer can be reinstantiated later (without its trained weights) from this configuration.

The config of a layer does not include connectivity information, nor the layer class name. These are handled by Network (one layer of abstraction above).

Note that get_config() does not guarantee to return a fresh copy of dict every time it is called. The callers should make a copy of the returned dict if they want to modify it.

Returns

Python dictionary.

Expand source code
@generic_utils.default
def get_config(self):
  """Returns the config of the layer.

  A layer config is a Python dictionary (serializable)
  containing the configuration of a layer.
  The same layer can be reinstantiated later
  (without its trained weights) from this configuration.

  The config of a layer does not include connectivity
  information, nor the layer class name. These are handled
  by `Network` (one layer of abstraction above).

  Note that `get_config()` does not guarantee to return a fresh copy of dict
  every time it is called. The callers should make a copy of the returned dict
  if they want to modify it.

  Returns:
      Python dictionary.
  """
  all_args = tf_inspect.getfullargspec(self.__init__).args
  config = {
      'name': self.name,
      'trainable': self.trainable,
  }
  if hasattr(self, '_batch_input_shape'):
    config['batch_input_shape'] = self._batch_input_shape
  config['dtype'] = policy.serialize(self._dtype_policy)
  if hasattr(self, 'dynamic'):
    # Only include `dynamic` in the `config` if it is `True`
    if self.dynamic:
      config['dynamic'] = self.dynamic
    elif 'dynamic' in all_args:
      all_args.remove('dynamic')
  expected_args = config.keys()
  # Finds all arguments in the `__init__` that are not in the config:
  extra_args = [arg for arg in all_args if arg not in expected_args]
  # Check that either the only argument in the `__init__` is  `self`,
  # or that `get_config` has been overridden:
  if len(extra_args) > 1 and hasattr(self.get_config, '_is_default'):
    raise NotImplementedError('Layer %s has arguments in `__init__` and '
                              'therefore must override `get_config`.' %
                              self.__class__.__name__)
  return config
def get_input_at(self, node_index)

Retrieves the input tensor(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first input node of the layer.

Returns

A tensor (or list of tensors if the layer has multiple inputs).

Raises

RuntimeError
If called in Eager mode.
Expand source code
@doc_controls.do_not_doc_inheritable
def get_input_at(self, node_index):
  """Retrieves the input tensor(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first input node of the layer.

  Returns:
      A tensor (or list of tensors if the layer has multiple inputs).

  Raises:
    RuntimeError: If called in Eager mode.
  """
  return self._get_node_attribute_at_index(node_index, 'input_tensors',
                                           'input')
def get_input_mask_at(self, node_index)

Retrieves the input mask tensor(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first time the layer was called.

Returns

A mask tensor (or list of tensors if the layer has multiple inputs).

Expand source code
@doc_controls.do_not_doc_inheritable
def get_input_mask_at(self, node_index):
  """Retrieves the input mask tensor(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first time the layer was called.

  Returns:
      A mask tensor
      (or list of tensors if the layer has multiple inputs).
  """
  inputs = self.get_input_at(node_index)
  if isinstance(inputs, list):
    return [getattr(x, '_keras_mask', None) for x in inputs]
  else:
    return getattr(inputs, '_keras_mask', None)
def get_input_shape_at(self, node_index)

Retrieves the input shape(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first time the layer was called.

Returns

A shape tuple (or list of shape tuples if the layer has multiple inputs).

Raises

RuntimeError
If called in Eager mode.
Expand source code
@doc_controls.do_not_doc_inheritable
def get_input_shape_at(self, node_index):
  """Retrieves the input shape(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first time the layer was called.

  Returns:
      A shape tuple
      (or list of shape tuples if the layer has multiple inputs).

  Raises:
    RuntimeError: If called in Eager mode.
  """
  return self._get_node_attribute_at_index(node_index, 'input_shapes',
                                           'input shape')
def get_losses_for(self, inputs)

Deprecated, do NOT use!

Retrieves losses relevant to a specific set of inputs.

Args

inputs
Input tensor or list/tuple of input tensors.

Returns

List of loss tensors of the layer that depend on inputs.

Expand source code
@doc_controls.do_not_generate_docs
def get_losses_for(self, inputs):
  """Deprecated, do NOT use!

  Retrieves losses relevant to a specific set of inputs.

  Args:
    inputs: Input tensor or list/tuple of input tensors.

  Returns:
    List of loss tensors of the layer that depend on `inputs`.
  """
  warnings.warn('`layer.get_losses_for` is deprecated and '
                'will be removed in a future version. '
                'Please use `layer.losses` instead.')
  return self.losses
def get_output_at(self, node_index)

Retrieves the output tensor(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first output node of the layer.

Returns

A tensor (or list of tensors if the layer has multiple outputs).

Raises

RuntimeError
If called in Eager mode.
Expand source code
@doc_controls.do_not_doc_inheritable
def get_output_at(self, node_index):
  """Retrieves the output tensor(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first output node of the layer.

  Returns:
      A tensor (or list of tensors if the layer has multiple outputs).

  Raises:
    RuntimeError: If called in Eager mode.
  """
  return self._get_node_attribute_at_index(node_index, 'output_tensors',
                                           'output')
def get_output_mask_at(self, node_index)

Retrieves the output mask tensor(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first time the layer was called.

Returns

A mask tensor (or list of tensors if the layer has multiple outputs).

Expand source code
@doc_controls.do_not_doc_inheritable
def get_output_mask_at(self, node_index):
  """Retrieves the output mask tensor(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first time the layer was called.

  Returns:
      A mask tensor
      (or list of tensors if the layer has multiple outputs).
  """
  output = self.get_output_at(node_index)
  if isinstance(output, list):
    return [getattr(x, '_keras_mask', None) for x in output]
  else:
    return getattr(output, '_keras_mask', None)
def get_output_shape_at(self, node_index)

Retrieves the output shape(s) of a layer at a given node.

Args

node_index
Integer, index of the node from which to retrieve the attribute. E.g. node_index=0 will correspond to the first time the layer was called.

Returns

A shape tuple (or list of shape tuples if the layer has multiple outputs).

Raises

RuntimeError
If called in Eager mode.
Expand source code
@doc_controls.do_not_doc_inheritable
def get_output_shape_at(self, node_index):
  """Retrieves the output shape(s) of a layer at a given node.

  Args:
      node_index: Integer, index of the node
          from which to retrieve the attribute.
          E.g. `node_index=0` will correspond to the
          first time the layer was called.

  Returns:
      A shape tuple
      (or list of shape tuples if the layer has multiple outputs).

  Raises:
    RuntimeError: If called in Eager mode.
  """
  return self._get_node_attribute_at_index(node_index, 'output_shapes',
                                           'output shape')
def get_updates_for(self, inputs)

Deprecated, do NOT use!

Retrieves updates relevant to a specific set of inputs.

Args

inputs
Input tensor or list/tuple of input tensors.

Returns

List of update ops of the layer that depend on inputs.

Expand source code
@doc_controls.do_not_generate_docs
def get_updates_for(self, inputs):
  """Deprecated, do NOT use!

  Retrieves updates relevant to a specific set of inputs.

  Args:
    inputs: Input tensor or list/tuple of input tensors.

  Returns:
    List of update ops of the layer that depend on `inputs`.
  """
  warnings.warn('`layer.get_updates_for` is deprecated and '
                'will be removed in a future version. '
                'Please use `layer.updates` method instead.')
  return self.updates
def get_weights(self)

Returns the current weights of the layer, as NumPy arrays.

The weights of a layer represent the state of the layer. This function returns both trainable and non-trainable weight values associated with this layer as a list of NumPy arrays, which can in turn be used to load state into similarly parameterized layers.

For example, a Dense layer returns a list of two values: the kernel matrix and the bias vector. These can be used to set the weights of another Dense layer:

>>> layer_a = tf.keras.layers.Dense(1,
...   kernel_initializer=tf.constant_initializer(1.))
>>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
>>> layer_a.get_weights()
[array([[1.],
       [1.],
       [1.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b = tf.keras.layers.Dense(1,
...   kernel_initializer=tf.constant_initializer(2.))
>>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
>>> layer_b.get_weights()
[array([[2.],
       [2.],
       [2.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b.set_weights(layer_a.get_weights())
>>> layer_b.get_weights()
[array([[1.],
       [1.],
       [1.]], dtype=float32), array([0.], dtype=float32)]

Returns

Weights values as a list of NumPy arrays.

Expand source code
def get_weights(self):
  """Returns the current weights of the layer, as NumPy arrays.

  The weights of a layer represent the state of the layer. This function
  returns both trainable and non-trainable weight values associated with this
  layer as a list of NumPy arrays, which can in turn be used to load state
  into similarly parameterized layers.

  For example, a `Dense` layer returns a list of two values: the kernel matrix
  and the bias vector. These can be used to set the weights of another
  `Dense` layer:

  >>> layer_a = tf.keras.layers.Dense(1,
  ...   kernel_initializer=tf.constant_initializer(1.))
  >>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
  >>> layer_a.get_weights()
  [array([[1.],
         [1.],
         [1.]], dtype=float32), array([0.], dtype=float32)]
  >>> layer_b = tf.keras.layers.Dense(1,
  ...   kernel_initializer=tf.constant_initializer(2.))
  >>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
  >>> layer_b.get_weights()
  [array([[2.],
         [2.],
         [2.]], dtype=float32), array([0.], dtype=float32)]
  >>> layer_b.set_weights(layer_a.get_weights())
  >>> layer_b.get_weights()
  [array([[1.],
         [1.],
         [1.]], dtype=float32), array([0.], dtype=float32)]

  Returns:
      Weights values as a list of NumPy arrays.
  """
  weights = self.weights
  output_weights = []
  for weight in weights:
    if isinstance(weight, base_layer_utils.TrackableWeightHandler):
      output_weights.extend(weight.get_tensors())
    else:
      output_weights.append(weight)
  return backend.batch_get_value(output_weights)
def set_weights(self, weights)

Sets the weights of the layer, from NumPy arrays.

The weights of a layer represent the state of the layer. This function sets the weight values from numpy arrays. The weight values should be passed in the order they are created by the layer. Note that the layer's weights must be instantiated before calling this function, by calling the layer.

For example, a Dense layer returns a list of two values: the kernel matrix and the bias vector. These can be used to set the weights of another Dense layer:

>>> layer_a = tf.keras.layers.Dense(1,
...   kernel_initializer=tf.constant_initializer(1.))
>>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
>>> layer_a.get_weights()
[array([[1.],
       [1.],
       [1.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b = tf.keras.layers.Dense(1,
...   kernel_initializer=tf.constant_initializer(2.))
>>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
>>> layer_b.get_weights()
[array([[2.],
       [2.],
       [2.]], dtype=float32), array([0.], dtype=float32)]
>>> layer_b.set_weights(layer_a.get_weights())
>>> layer_b.get_weights()
[array([[1.],
       [1.],
       [1.]], dtype=float32), array([0.], dtype=float32)]

Args

weights
a list of NumPy arrays. The number of arrays and their shape must match number of the dimensions of the weights of the layer (i.e. it should match the output of get_weights).

Raises

ValueError
If the provided weights list does not match the layer's specifications.
Expand source code
def set_weights(self, weights):
  """Sets the weights of the layer, from NumPy arrays.

  The weights of a layer represent the state of the layer. This function
  sets the weight values from numpy arrays. The weight values should be
  passed in the order they are created by the layer. Note that the layer's
  weights must be instantiated before calling this function, by calling
  the layer.

  For example, a `Dense` layer returns a list of two values: the kernel matrix
  and the bias vector. These can be used to set the weights of another
  `Dense` layer:

  >>> layer_a = tf.keras.layers.Dense(1,
  ...   kernel_initializer=tf.constant_initializer(1.))
  >>> a_out = layer_a(tf.convert_to_tensor([[1., 2., 3.]]))
  >>> layer_a.get_weights()
  [array([[1.],
         [1.],
         [1.]], dtype=float32), array([0.], dtype=float32)]
  >>> layer_b = tf.keras.layers.Dense(1,
  ...   kernel_initializer=tf.constant_initializer(2.))
  >>> b_out = layer_b(tf.convert_to_tensor([[10., 20., 30.]]))
  >>> layer_b.get_weights()
  [array([[2.],
         [2.],
         [2.]], dtype=float32), array([0.], dtype=float32)]
  >>> layer_b.set_weights(layer_a.get_weights())
  >>> layer_b.get_weights()
  [array([[1.],
         [1.],
         [1.]], dtype=float32), array([0.], dtype=float32)]

  Args:
    weights: a list of NumPy arrays. The number
      of arrays and their shape must match
      number of the dimensions of the weights
      of the layer (i.e. it should match the
      output of `get_weights`).

  Raises:
    ValueError: If the provided weights list does not match the
      layer's specifications.
  """
  params = self.weights

  expected_num_weights = 0
  for param in params:
    if isinstance(param, base_layer_utils.TrackableWeightHandler):
      expected_num_weights += param.num_tensors
    else:
      expected_num_weights += 1

  if expected_num_weights != len(weights):
    raise ValueError(
        'You called `set_weights(weights)` on layer "%s" '
        'with a weight list of length %s, but the layer was '
        'expecting %s weights. Provided weights: %s...' %
        (self.name, len(weights), expected_num_weights, str(weights)[:50]))

  weight_index = 0
  weight_value_tuples = []
  for param in params:
    if isinstance(param, base_layer_utils.TrackableWeightHandler):
      num_tensors = param.num_tensors
      tensors = weights[weight_index:weight_index + num_tensors]
      param.set_weights(tensors)
      weight_index += num_tensors
    else:
      weight = weights[weight_index]
      weight_shape = weight.shape if hasattr(weight, 'shape') else ()
      ref_shape = param.shape
      if not ref_shape.is_compatible_with(weight_shape):
        raise ValueError(
            'Layer weight shape %s not compatible with provided weight '
            'shape %s' % (ref_shape, weight_shape))
      weight_value_tuples.append((param, weight))
      weight_index += 1

  backend.batch_set_value(weight_value_tuples)

  # Perform any layer defined finalization of the layer state.
  for layer in self._flatten_layers():
    layer.finalize_state()
class LayerNormalization (axis=-1, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None, **kwargs)

Layer normalization layer (Ba et al., 2016).

Normalize the activations of the previous layer for each given example in a batch independently, rather than across a batch like Batch Normalization. i.e. applies a transformation that maintains the mean activation within each example close to 0 and the activation standard deviation close to 1.

Given a tensor inputs, moments are calculated and normalization is performed across the axes specified in axis.

Example:

>>> data = tf.constant(np.arange(10).reshape(5, 2) * 10, dtype=tf.float32)
>>> print(data)
tf.Tensor(
[[ 0. 10.]
 [20. 30.]
 [40. 50.]
 [60. 70.]
 [80. 90.]], shape=(5, 2), dtype=float32)
>>> layer = tf.keras.layers.LayerNormalization(axis=1)
>>> output = layer(data)
>>> print(output)
tf.Tensor(
[[-1. 1.]
 [-1. 1.]
 [-1. 1.]
 [-1. 1.]
 [-1. 1.]], shape=(5, 2), dtype=float32)

Notice that with Layer Normalization the normalization happens across the axes within each example, rather than across different examples in the batch.

If scale or center are enabled, the layer will scale the normalized outputs by broadcasting them with a trainable variable gamma, and center the outputs by broadcasting with a trainable variable beta. gamma will default to a ones tensor and beta will default to a zeros tensor, so that centering and scaling are no-ops before training has begun.

So, with scaling and centering enabled the normalization equations are as follows:

Let the intermediate activations for a mini-batch to be the inputs.

For each sample x_i in inputs with k features, we compute the mean and variance of the sample:

mean_i = sum(x_i[j] for j in range(k)) / k
var_i = sum((x_i[j] - mean_i) ** 2 for j in range(k)) / k

and then compute a normalized x_i_normalized, including a small factor epsilon for numerical stability.

x_i_normalized = (x_i - mean_i) / sqrt(var_i + epsilon)

And finally x_i_normalized is linearly transformed by gamma and beta, which are learned parameters:

output_i = x_i_normalized * gamma + beta

gamma and beta will span the axes of inputs specified in axis, and this part of the inputs' shape must be fully defined.

For example:

>>> layer = tf.keras.layers.LayerNormalization(axis=[1, 2, 3])
>>> layer.build([5, 20, 30, 40])
>>> print(layer.beta.shape)
(20, 30, 40)
>>> print(layer.gamma.shape)
(20, 30, 40)

Note that other implementations of layer normalization may choose to define gamma and beta over a separate set of axes from the axes being normalized across. For example, Group Normalization (Wu et al. 2018) with group size of 1 corresponds to a Layer Normalization that normalizes across height, width, and channel and has gamma and beta span only the channel dimension. So, this Layer Normalization implementation will not match a Group Normalization layer with group size set to 1.

Args

axis
Integer or List/Tuple. The axis or axes to normalize across. Typically this is the features axis/axes. The left-out axes are typically the batch axis/axes. This argument defaults to -1, the last dimension in the input.
epsilon
Small float added to variance to avoid dividing by zero. Defaults to 1e-3
center
If True, add offset of beta to normalized tensor. If False, beta is ignored. Defaults to True.
scale
If True, multiply by gamma. If False, gamma is not used. Defaults to True. When the next layer is linear (also e.g. nn.relu), this can be disabled since the scaling will be done by the next layer.
beta_initializer
Initializer for the beta weight. Defaults to zeros.
gamma_initializer
Initializer for the gamma weight. Defaults to ones.
beta_regularizer
Optional regularizer for the beta weight. None by default.
gamma_regularizer
Optional regularizer for the gamma weight. None by default.
beta_constraint
Optional constraint for the beta weight. None by default.
gamma_constraint
Optional constraint for the gamma weight. None by default.

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as input.

Reference

Expand source code
class LayerNormalization(Layer):
  """Layer normalization layer (Ba et al., 2016).

  Normalize the activations of the previous layer for each given example in a
  batch independently, rather than across a batch like Batch Normalization.
  i.e. applies a transformation that maintains the mean activation within each
  example close to 0 and the activation standard deviation close to 1.

  Given a tensor `inputs`, moments are calculated and normalization
  is performed across the axes specified in `axis`.

  Example:

  >>> data = tf.constant(np.arange(10).reshape(5, 2) * 10, dtype=tf.float32)
  >>> print(data)
  tf.Tensor(
  [[ 0. 10.]
   [20. 30.]
   [40. 50.]
   [60. 70.]
   [80. 90.]], shape=(5, 2), dtype=float32)

  >>> layer = tf.keras.layers.LayerNormalization(axis=1)
  >>> output = layer(data)
  >>> print(output)
  tf.Tensor(
  [[-1. 1.]
   [-1. 1.]
   [-1. 1.]
   [-1. 1.]
   [-1. 1.]], shape=(5, 2), dtype=float32)

  Notice that with Layer Normalization the normalization happens across the
  axes *within* each example, rather than across different examples in the
  batch.

  If `scale` or `center` are enabled, the layer will scale the normalized
  outputs by broadcasting them with a trainable variable `gamma`, and center
  the outputs by broadcasting with a trainable variable `beta`. `gamma` will
  default to a ones tensor and `beta` will default to a zeros tensor, so that
  centering and scaling are no-ops before training has begun.

  So, with scaling and centering enabled the normalization equations
  are as follows:

  Let the intermediate activations for a mini-batch to be the `inputs`.

  For each sample `x_i` in `inputs` with `k` features, we compute the mean and
  variance of the sample:

  ```python
  mean_i = sum(x_i[j] for j in range(k)) / k
  var_i = sum((x_i[j] - mean_i) ** 2 for j in range(k)) / k
  ```

  and then compute a normalized `x_i_normalized`, including a small factor
  `epsilon` for numerical stability.

  ```python
  x_i_normalized = (x_i - mean_i) / sqrt(var_i + epsilon)
  ```

  And finally `x_i_normalized ` is linearly transformed by `gamma` and `beta`,
  which are learned parameters:

  ```python
  output_i = x_i_normalized * gamma + beta
  ```

  `gamma` and `beta` will span the axes of `inputs` specified in `axis`, and
  this part of the inputs' shape must be fully defined.

  For example:

  >>> layer = tf.keras.layers.LayerNormalization(axis=[1, 2, 3])
  >>> layer.build([5, 20, 30, 40])
  >>> print(layer.beta.shape)
  (20, 30, 40)
  >>> print(layer.gamma.shape)
  (20, 30, 40)

  Note that other implementations of layer normalization may choose to define
  `gamma` and `beta` over a separate set of axes from the axes being
  normalized across. For example, Group Normalization
  ([Wu et al. 2018](https://arxiv.org/abs/1803.08494)) with group size of 1
  corresponds to a Layer Normalization that normalizes across height, width,
  and channel and has `gamma` and `beta` span only the channel dimension.
  So, this Layer Normalization implementation will not match a Group
  Normalization layer with group size set to 1.

  Args:
    axis: Integer or List/Tuple. The axis or axes to normalize across. Typically
      this is the features axis/axes. The left-out axes are typically the batch
      axis/axes. This argument defaults to `-1`, the last dimension in the
      input.
    epsilon: Small float added to variance to avoid dividing by zero. Defaults
      to 1e-3
    center: If True, add offset of `beta` to normalized tensor. If False, `beta`
      is ignored. Defaults to True.
    scale: If True, multiply by `gamma`. If False, `gamma` is not used. Defaults
      to True. When the next layer is linear (also e.g. `nn.relu`), this can be
      disabled since the scaling will be done by the next layer.
    beta_initializer: Initializer for the beta weight. Defaults to zeros.
    gamma_initializer: Initializer for the gamma weight. Defaults to ones.
    beta_regularizer: Optional regularizer for the beta weight. None by default.
    gamma_regularizer: Optional regularizer for the gamma weight. None by
      default.
    beta_constraint: Optional constraint for the beta weight. None by default.
    gamma_constraint: Optional constraint for the gamma weight. None by default.

  Input shape:
    Arbitrary. Use the keyword argument `input_shape` (tuple of
    integers, does not include the samples axis) when using this layer as the
    first layer in a model.

  Output shape:
    Same shape as input.

  Reference:
    - [Lei Ba et al., 2016](https://arxiv.org/abs/1607.06450).
  """

  def __init__(self,
               axis=-1,
               epsilon=1e-3,
               center=True,
               scale=True,
               beta_initializer='zeros',
               gamma_initializer='ones',
               beta_regularizer=None,
               gamma_regularizer=None,
               beta_constraint=None,
               gamma_constraint=None,
               **kwargs):
    super(LayerNormalization, self).__init__(**kwargs)
    if isinstance(axis, (list, tuple)):
      self.axis = axis[:]
    elif isinstance(axis, int):
      self.axis = axis
    else:
      raise TypeError('Expected an int or a list/tuple of ints for the '
                      'argument \'axis\', but received: %r' % axis)

    self.epsilon = epsilon
    self.center = center
    self.scale = scale
    self.beta_initializer = initializers.get(beta_initializer)
    self.gamma_initializer = initializers.get(gamma_initializer)
    self.beta_regularizer = regularizers.get(beta_regularizer)
    self.gamma_regularizer = regularizers.get(gamma_regularizer)
    self.beta_constraint = constraints.get(beta_constraint)
    self.gamma_constraint = constraints.get(gamma_constraint)

    self.supports_masking = True

    # Indicates whether a faster fused implementation can be used. This will be
    # set to True or False in build()"
    self._fused = None

  def _fused_can_be_used(self, ndims):
    """Returns false if fused implementation cannot be used.

    Check if the axis is contiguous and can be collapsed into the last axis.
    The self.axis is assumed to have no duplicates.
    """
    axis = sorted(self.axis)
    can_use_fused = False

    if axis[-1] == ndims - 1 and axis[-1] - axis[0] == len(axis) - 1:
      can_use_fused = True

    # fused_batch_norm will silently raise epsilon to be at least 1.001e-5, so
    # we cannot used the fused version if epsilon is below that value. Also, the
    # variable dtype must be float32, as fused_batch_norm only supports float32
    # variables.
    if self.epsilon < 1.001e-5 or self.dtype != 'float32':
      can_use_fused = False

    return can_use_fused

  def build(self, input_shape):
    ndims = len(input_shape)
    if ndims is None:
      raise ValueError('Input shape %s has undefined rank.' % input_shape)

    # Convert axis to list and resolve negatives
    if isinstance(self.axis, int):
      self.axis = [self.axis]
    elif isinstance(self.axis, tuple):
      self.axis = list(self.axis)
    for idx, x in enumerate(self.axis):
      if x < 0:
        self.axis[idx] = ndims + x

    # Validate axes
    for x in self.axis:
      if x < 0 or x >= ndims:
        raise ValueError('Invalid axis: %d' % x)
    if len(self.axis) != len(set(self.axis)):
      raise ValueError('Duplicate axis: {}'.format(tuple(self.axis)))

    param_shape = [input_shape[dim] for dim in self.axis]
    if self.scale:
      self.gamma = self.add_weight(
          name='gamma',
          shape=param_shape,
          initializer=self.gamma_initializer,
          regularizer=self.gamma_regularizer,
          constraint=self.gamma_constraint,
          trainable=True,
          experimental_autocast=False)
    else:
      self.gamma = None

    if self.center:
      self.beta = self.add_weight(
          name='beta',
          shape=param_shape,
          initializer=self.beta_initializer,
          regularizer=self.beta_regularizer,
          constraint=self.beta_constraint,
          trainable=True,
          experimental_autocast=False)
    else:
      self.beta = None

    self._fused = self._fused_can_be_used(ndims)

    self.built = True

  def call(self, inputs):
    # Compute the axes along which to reduce the mean / variance
    input_shape = inputs.shape
    ndims = len(input_shape)

    # Broadcasting only necessary for norm when the axis is not just
    # the last dimension
    broadcast_shape = [1] * ndims
    for dim in self.axis:
      broadcast_shape[dim] = input_shape.dims[dim].value

    def _broadcast(v):
      if (v is not None and len(v.shape) != ndims and self.axis != [ndims - 1]):
        return tf.reshape(v, broadcast_shape)
      return v

    if not self._fused:
      input_dtype = inputs.dtype
      if input_dtype in ('float16', 'bfloat16') and self.dtype == 'float32':
        # If mixed precision is used, cast inputs to float32 so that this is at
        # least as numerically stable as the fused version.
        inputs = tf.cast(inputs, 'float32')

      # Calculate the moments on the last axis (layer activations).
      mean, variance = tf.nn.moments(inputs, self.axis, keepdims=True)

      scale, offset = _broadcast(self.gamma), _broadcast(self.beta)

      # Compute layer normalization using the batch_normalization function.
      outputs = tf.nn.batch_normalization(
          inputs,
          mean,
          variance,
          offset=offset,
          scale=scale,
          variance_epsilon=self.epsilon)
      outputs = tf.cast(outputs, input_dtype)
    else:
      # Collapse dims before self.axis, and dims in self.axis
      pre_dim, in_dim = (1, 1)
      axis = sorted(self.axis)
      tensor_shape = tf.shape(inputs)
      for dim in range(0, ndims):
        dim_tensor = tensor_shape[dim]
        if dim < axis[0]:
          pre_dim = pre_dim * dim_tensor
        else:
          assert dim in axis
          in_dim = in_dim * dim_tensor

      squeezed_shape = [1, pre_dim, in_dim, 1]
      # This fused operation requires reshaped inputs to be NCHW.
      data_format = 'NCHW'

      inputs = tf.reshape(inputs, squeezed_shape)

      # self.gamma and self.beta have the wrong shape for fused_batch_norm, so
      # we cannot pass them as the scale and offset parameters. Therefore, we
      # create two constant tensors in correct shapes for fused_batch_norm and
      # later construct a separate calculation on the scale and offset.
      scale = tf.ones([pre_dim], dtype=self.dtype)
      offset = tf.zeros([pre_dim], dtype=self.dtype)

      # Compute layer normalization using the fused_batch_norm function.
      outputs, _, _ = tf.compat.v1.nn.fused_batch_norm(
          inputs,
          scale=scale,
          offset=offset,
          epsilon=self.epsilon,
          data_format=data_format)

      outputs = tf.reshape(outputs, tensor_shape)

      scale, offset = _broadcast(self.gamma), _broadcast(self.beta)

      if scale is not None:
        outputs = outputs * tf.cast(scale, outputs.dtype)
      if offset is not None:
        outputs = outputs + tf.cast(offset, outputs.dtype)

    # If some components of the shape got lost due to adjustments, fix that.
    outputs.set_shape(input_shape)

    return outputs

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'axis': self.axis,
        'epsilon': self.epsilon,
        'center': self.center,
        'scale': self.scale,
        'beta_initializer': initializers.serialize(self.beta_initializer),
        'gamma_initializer': initializers.serialize(self.gamma_initializer),
        'beta_regularizer': regularizers.serialize(self.beta_regularizer),
        'gamma_regularizer': regularizers.serialize(self.gamma_regularizer),
        'beta_constraint': constraints.serialize(self.beta_constraint),
        'gamma_constraint': constraints.serialize(self.gamma_constraint)
    }
    base_config = super(LayerNormalization, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class LeakyReLU (alpha=0.3, **kwargs)

Leaky version of a Rectified Linear Unit.

It allows a small gradient when the unit is not active:

  f(x) = alpha * x if x < 0
  f(x) = x if x >= 0

Usage:

>>> layer = tf.keras.layers.LeakyReLU()
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[-0.9, -0.3, 0.0, 2.0]
>>> layer = tf.keras.layers.LeakyReLU(alpha=0.1)
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[-0.3, -0.1, 0.0, 2.0]

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the batch axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

alpha
Float >= 0. Negative slope coefficient. Default to 0.3.
Expand source code
class LeakyReLU(Layer):
  """Leaky version of a Rectified Linear Unit.

  It allows a small gradient when the unit is not active:

  ```
    f(x) = alpha * x if x < 0
    f(x) = x if x >= 0
  ```

  Usage:

  >>> layer = tf.keras.layers.LeakyReLU()
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [-0.9, -0.3, 0.0, 2.0]
  >>> layer = tf.keras.layers.LeakyReLU(alpha=0.1)
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [-0.3, -0.1, 0.0, 2.0]

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the batch axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    alpha: Float >= 0. Negative slope coefficient. Default to 0.3.

  """

  def __init__(self, alpha=0.3, **kwargs):
    super(LeakyReLU, self).__init__(**kwargs)
    if alpha is None:
      raise ValueError('The alpha value of a Leaky ReLU layer '
                       'cannot be None, needs a float. '
                       'Got %s' % alpha)
    self.supports_masking = True
    self.alpha = backend.cast_to_floatx(alpha)

  def call(self, inputs):
    return backend.relu(inputs, alpha=self.alpha)

  def get_config(self):
    config = {'alpha': float(self.alpha)}
    base_config = super(LeakyReLU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class LocallyConnected1D (filters, kernel_size, strides=1, padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, implementation=1, **kwargs)

Locally-connected layer for 1D inputs.

The LocallyConnected1D layer works similarly to the Conv1D layer, except that weights are unshared, that is, a different set of filters is applied at each different patch of the input.

Note: layer attributes cannot be modified after the layer has been called once (except the trainable attribute).

Example:

    # apply a unshared weight convolution 1d of length 3 to a sequence with
    # 10 timesteps, with 64 output filters
    model = Sequential()
    model.add(LocallyConnected1D(64, 3, input_shape=(10, 32)))
    # now model.output_shape == (None, 8, 64)
    # add a new conv1d on top
    model.add(LocallyConnected1D(32, 3))
    # now model.output_shape == (None, 6, 32)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of a single integer, specifying the length of the 1D convolution window.
strides
An integer or tuple/list of a single integer, specifying the stride length of the convolution.
padding
Currently only supports "valid" (case-insensitive). "same" may be supported in the future. "valid" means no padding.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, length, channels)<code> while </code>channels_first corresponds to inputs with shape (batch, channels, length). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
activation
Activation function to use. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation")..
kernel_constraint
Constraint function applied to the kernel matrix.
bias_constraint
Constraint function applied to the bias vector.
implementation
implementation mode, either 1, 2, or 3. 1 loops over input spatial locations to perform the forward pass. It is memory-efficient but performs a lot of (small) ops. 2 stores layer weights in a dense but sparsely-populated 2D matrix and implements the forward pass as a single matrix-multiply. It uses a lot of RAM but performs few (large) ops. 3 stores layer weights in a sparse tensor and implements the forward pass as a single sparse matrix-multiply. How to choose: 1: large, dense models, 2: small models, 3: large, sparse models, where "large" stands for large input/output activations (i.e. many filters, input_filters, large input_size, output_size), and "sparse" stands for few connections between inputs and outputs, i.e. small ratio filters * input_filters * kernel_size / (input_size * strides), where inputs to and outputs of the layer are assumed to have shapes (input_size, input_filters)<code>, </code>(output_size, filters) respectively. It is recommended to benchmark each in the setting of interest to pick the most efficient one (in terms of speed and memory usage). Correct choice of implementation can lead to dramatic speed improvements (e.g. 50X), potentially at the expense of RAM. Also, only padding="valid" is supported by implementation=1.

Input shape: 3D tensor with shape: (batch_size, steps, input_dim) Output shape: 3D tensor with shape: (batch_size, new_steps, filters) steps value might have changed due to padding or strides.

Expand source code
class LocallyConnected1D(Layer):
  """Locally-connected layer for 1D inputs.

  The `LocallyConnected1D` layer works similarly to
  the `Conv1D` layer, except that weights are unshared,
  that is, a different set of filters is applied at each different patch
  of the input.

  Note: layer attributes cannot be modified after the layer has been called
  once (except the `trainable` attribute).

  Example:
  ```python
      # apply a unshared weight convolution 1d of length 3 to a sequence with
      # 10 timesteps, with 64 output filters
      model = Sequential()
      model.add(LocallyConnected1D(64, 3, input_shape=(10, 32)))
      # now model.output_shape == (None, 8, 64)
      # add a new conv1d on top
      model.add(LocallyConnected1D(32, 3))
      # now model.output_shape == (None, 6, 32)
  ```

  Args:
      filters: Integer, the dimensionality of the output space (i.e. the number
        of output filters in the convolution).
      kernel_size: An integer or tuple/list of a single integer, specifying the
        length of the 1D convolution window.
      strides: An integer or tuple/list of a single integer, specifying the
        stride length of the convolution.
      padding: Currently only supports `"valid"` (case-insensitive). `"same"`
        may be supported in the future. `"valid"` means no padding.
      data_format: A string, one of `channels_last` (default) or
        `channels_first`. The ordering of the dimensions in the inputs.
        `channels_last` corresponds to inputs with shape `(batch, length,
        channels)` while `channels_first` corresponds to inputs with shape
        `(batch, channels, length)`. It defaults to the `image_data_format`
        value found in your Keras config file at `~/.keras/keras.json`. If you
        never set it, then it will be "channels_last".
      activation: Activation function to use. If you don't specify anything, no
        activation is applied
          (ie. "linear" activation: `a(x) = x`).
      use_bias: Boolean, whether the layer uses a bias vector.
      kernel_initializer: Initializer for the `kernel` weights matrix.
      bias_initializer: Initializer for the bias vector.
      kernel_regularizer: Regularizer function applied to the `kernel` weights
        matrix.
      bias_regularizer: Regularizer function applied to the bias vector.
      activity_regularizer: Regularizer function applied to the output of the
        layer (its "activation")..
      kernel_constraint: Constraint function applied to the kernel matrix.
      bias_constraint: Constraint function applied to the bias vector.
      implementation: implementation mode, either `1`, `2`, or `3`. `1` loops
        over input spatial locations to perform the forward pass. It is
        memory-efficient but performs a lot of (small) ops.  `2` stores layer
        weights in a dense but sparsely-populated 2D matrix and implements the
        forward pass as a single matrix-multiply. It uses a lot of RAM but
        performs few (large) ops.  `3` stores layer weights in a sparse tensor
        and implements the forward pass as a single sparse matrix-multiply.
          How to choose:
          `1`: large, dense models,
          `2`: small models,
          `3`: large, sparse models,  where "large" stands for large
            input/output activations (i.e. many `filters`, `input_filters`,
            large `input_size`, `output_size`), and "sparse" stands for few
            connections between inputs and outputs, i.e. small ratio `filters *
            input_filters * kernel_size / (input_size * strides)`, where inputs
            to and outputs of the layer are assumed to have shapes `(input_size,
            input_filters)`, `(output_size, filters)` respectively.  It is
            recommended to benchmark each in the setting of interest to pick the
            most efficient one (in terms of speed and memory usage). Correct
            choice of implementation can lead to dramatic speed improvements
            (e.g. 50X), potentially at the expense of RAM.  Also, only
            `padding="valid"` is supported by `implementation=1`.
  Input shape:
      3D tensor with shape: `(batch_size, steps, input_dim)`
  Output shape:
      3D tensor with shape: `(batch_size, new_steps, filters)` `steps` value
        might have changed due to padding or strides.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format=None,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               implementation=1,
               **kwargs):
    super(LocallyConnected1D, self).__init__(**kwargs)
    self.filters = filters
    self.kernel_size = conv_utils.normalize_tuple(kernel_size, 1, 'kernel_size')
    self.strides = conv_utils.normalize_tuple(strides, 1, 'strides')
    self.padding = conv_utils.normalize_padding(padding)
    if self.padding != 'valid' and implementation == 1:
      raise ValueError('Invalid border mode for LocallyConnected1D '
                       '(only "valid" is supported if implementation is 1): ' +
                       padding)
    self.data_format = conv_utils.normalize_data_format(data_format)
    self.activation = activations.get(activation)
    self.use_bias = use_bias
    self.kernel_initializer = initializers.get(kernel_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.kernel_constraint = constraints.get(kernel_constraint)
    self.bias_constraint = constraints.get(bias_constraint)
    self.implementation = implementation
    self.input_spec = InputSpec(ndim=3)

  @property
  def _use_input_spec_as_call_signature(self):
    return False

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    if self.data_format == 'channels_first':
      input_dim, input_length = input_shape[1], input_shape[2]
    else:
      input_dim, input_length = input_shape[2], input_shape[1]

    if input_dim is None:
      raise ValueError(
          'Axis 2 of input should be fully-defined. '
          'Found shape:', input_shape)
    self.output_length = conv_utils.conv_output_length(input_length,
                                                       self.kernel_size[0],
                                                       self.padding,
                                                       self.strides[0])

    if self.implementation == 1:
      self.kernel_shape = (self.output_length, self.kernel_size[0] * input_dim,
                           self.filters)

      self.kernel = self.add_weight(
          shape=self.kernel_shape,
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

    elif self.implementation == 2:
      if self.data_format == 'channels_first':
        self.kernel_shape = (input_dim, input_length, self.filters,
                             self.output_length)
      else:
        self.kernel_shape = (input_length, input_dim, self.output_length,
                             self.filters)

      self.kernel = self.add_weight(
          shape=self.kernel_shape,
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

      self.kernel_mask = get_locallyconnected_mask(
          input_shape=(input_length,),
          kernel_shape=self.kernel_size,
          strides=self.strides,
          padding=self.padding,
          data_format=self.data_format,
      )

    elif self.implementation == 3:
      self.kernel_shape = (self.output_length * self.filters,
                           input_length * input_dim)

      self.kernel_idxs = sorted(
          conv_utils.conv_kernel_idxs(
              input_shape=(input_length,),
              kernel_shape=self.kernel_size,
              strides=self.strides,
              padding=self.padding,
              filters_in=input_dim,
              filters_out=self.filters,
              data_format=self.data_format))

      self.kernel = self.add_weight(
          shape=(len(self.kernel_idxs),),
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

    else:
      raise ValueError('Unrecognized implementation mode: %d.' %
                       self.implementation)

    if self.use_bias:
      self.bias = self.add_weight(
          shape=(self.output_length, self.filters),
          initializer=self.bias_initializer,
          name='bias',
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint)
    else:
      self.bias = None

    if self.data_format == 'channels_first':
      self.input_spec = InputSpec(ndim=3, axes={1: input_dim})
    else:
      self.input_spec = InputSpec(ndim=3, axes={-1: input_dim})
    self.built = True

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if self.data_format == 'channels_first':
      input_length = input_shape[2]
    else:
      input_length = input_shape[1]

    length = conv_utils.conv_output_length(input_length, self.kernel_size[0],
                                           self.padding, self.strides[0])

    if self.data_format == 'channels_first':
      return (input_shape[0], self.filters, length)
    elif self.data_format == 'channels_last':
      return (input_shape[0], length, self.filters)

  def call(self, inputs):
    if self.implementation == 1:
      output = backend.local_conv(
          inputs, self.kernel, self.kernel_size, self.strides,
          (self.output_length,), self.data_format)

    elif self.implementation == 2:
      output = local_conv_matmul(inputs, self.kernel, self.kernel_mask,
                                 self.compute_output_shape(inputs.shape))

    elif self.implementation == 3:
      output = local_conv_sparse_matmul(inputs, self.kernel, self.kernel_idxs,
                                        self.kernel_shape,
                                        self.compute_output_shape(inputs.shape))

    else:
      raise ValueError('Unrecognized implementation mode: %d.' %
                       self.implementation)

    if self.use_bias:
      output = backend.bias_add(output, self.bias, data_format=self.data_format)

    output = self.activation(output)
    return output

  def get_config(self):
    config = {
        'filters':
            self.filters,
        'kernel_size':
            self.kernel_size,
        'strides':
            self.strides,
        'padding':
            self.padding,
        'data_format':
            self.data_format,
        'activation':
            activations.serialize(self.activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'implementation':
            self.implementation
    }
    base_config = super(LocallyConnected1D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class LocallyConnected2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, implementation=1, **kwargs)

Locally-connected layer for 2D inputs.

The LocallyConnected2D layer works similarly to the Conv2D layer, except that weights are unshared, that is, a different set of filters is applied at each different patch of the input.

Note: layer attributes cannot be modified after the layer has been called once (except the trainable attribute).

Examples:

    # apply a 3x3 unshared weights convolution with 64 output filters on a
    32x32 image
    # with `data_format="channels_last"`:
    model = Sequential()
    model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3)))
    # now model.output_shape == (None, 30, 30, 64)
    # notice that this layer will consume (30*30)*(3*3*3*64) + (30*30)*64
    parameters

    # add a 3x3 unshared weights convolution on top, with 32 output filters:
    model.add(LocallyConnected2D(32, (3, 3)))
    # now model.output_shape == (None, 28, 28, 32)

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the width and height of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the width and height. Can be a single integer to specify the same value for all spatial dimensions.
padding
Currently only support "valid" (case-insensitive). "same" will be supported in future. "valid" means no padding.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels)<code> while </code>channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
activation
Activation function to use. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix.
bias_initializer
Initializer for the bias vector.
kernel_regularizer
Regularizer function applied to the kernel weights matrix.
bias_regularizer
Regularizer function applied to the bias vector.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation").
kernel_constraint
Constraint function applied to the kernel matrix.
bias_constraint
Constraint function applied to the bias vector.
implementation
implementation mode, either 1, 2, or 3. 1 loops over input spatial locations to perform the forward pass. It is memory-efficient but performs a lot of (small) ops. 2 stores layer weights in a dense but sparsely-populated 2D matrix and implements the forward pass as a single matrix-multiply. It uses a lot of RAM but performs few (large) ops. 3 stores layer weights in a sparse tensor and implements the forward pass as a single sparse matrix-multiply. How to choose: 1: large, dense models, 2: small models, 3: large, sparse models, where "large" stands for large input/output activations (i.e. many filters, input_filters, large np.prod(input_size), np.prod(output_size)), and "sparse" stands for few connections between inputs and outputs, i.e. small ratio filters * input_filters * np.prod(kernel_size) / (np.prod(input_size) * np.prod(strides)), where inputs to and outputs of the layer are assumed to have shapes input_size + (input_filters,)<code>, </code>output_size + (filters,) respectively. It is recommended to benchmark each in the setting of interest to pick the most efficient one (in terms of speed and memory usage). Correct choice of implementation can lead to dramatic speed improvements (e.g. 50X), potentially at the expense of RAM. Also, only padding="valid" is supported by implementation=1.

Input shape: 4D tensor with shape: (samples, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (samples, rows, cols, channels) if data_format='channels_last'. Output shape: 4D tensor with shape: (samples, filters, new_rows, new_cols) if data_format='channels_first' or 4D tensor with shape: (samples, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding.

Expand source code
class LocallyConnected2D(Layer):
  """Locally-connected layer for 2D inputs.

  The `LocallyConnected2D` layer works similarly
  to the `Conv2D` layer, except that weights are unshared,
  that is, a different set of filters is applied at each
  different patch of the input.

  Note: layer attributes cannot be modified after the layer has been called
  once (except the `trainable` attribute).

  Examples:
  ```python
      # apply a 3x3 unshared weights convolution with 64 output filters on a
      32x32 image
      # with `data_format="channels_last"`:
      model = Sequential()
      model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3)))
      # now model.output_shape == (None, 30, 30, 64)
      # notice that this layer will consume (30*30)*(3*3*3*64) + (30*30)*64
      parameters

      # add a 3x3 unshared weights convolution on top, with 32 output filters:
      model.add(LocallyConnected2D(32, (3, 3)))
      # now model.output_shape == (None, 28, 28, 32)
  ```

  Args:
      filters: Integer, the dimensionality of the output space (i.e. the number
        of output filters in the convolution).
      kernel_size: An integer or tuple/list of 2 integers, specifying the width
        and height of the 2D convolution window. Can be a single integer to
        specify the same value for all spatial dimensions.
      strides: An integer or tuple/list of 2 integers, specifying the strides of
        the convolution along the width and height. Can be a single integer to
        specify the same value for all spatial dimensions.
      padding: Currently only support `"valid"` (case-insensitive). `"same"`
        will be supported in future. `"valid"` means no padding.
      data_format: A string, one of `channels_last` (default) or
        `channels_first`. The ordering of the dimensions in the inputs.
        `channels_last` corresponds to inputs with shape `(batch, height, width,
        channels)` while `channels_first` corresponds to inputs with shape
        `(batch, channels, height, width)`. It defaults to the
        `image_data_format` value found in your Keras config file at
        `~/.keras/keras.json`. If you never set it, then it will be
        "channels_last".
      activation: Activation function to use. If you don't specify anything, no
        activation is applied
          (ie. "linear" activation: `a(x) = x`).
      use_bias: Boolean, whether the layer uses a bias vector.
      kernel_initializer: Initializer for the `kernel` weights matrix.
      bias_initializer: Initializer for the bias vector.
      kernel_regularizer: Regularizer function applied to the `kernel` weights
        matrix.
      bias_regularizer: Regularizer function applied to the bias vector.
      activity_regularizer: Regularizer function applied to the output of the
        layer (its "activation").
      kernel_constraint: Constraint function applied to the kernel matrix.
      bias_constraint: Constraint function applied to the bias vector.
      implementation: implementation mode, either `1`, `2`, or `3`. `1` loops
        over input spatial locations to perform the forward pass. It is
        memory-efficient but performs a lot of (small) ops.  `2` stores layer
        weights in a dense but sparsely-populated 2D matrix and implements the
        forward pass as a single matrix-multiply. It uses a lot of RAM but
        performs few (large) ops.  `3` stores layer weights in a sparse tensor
        and implements the forward pass as a single sparse matrix-multiply.
          How to choose:
          `1`: large, dense models,
          `2`: small models,
          `3`: large, sparse models,  where "large" stands for large
            input/output activations (i.e. many `filters`, `input_filters`,
            large `np.prod(input_size)`, `np.prod(output_size)`), and "sparse"
            stands for few connections between inputs and outputs, i.e. small
            ratio `filters * input_filters * np.prod(kernel_size) /
            (np.prod(input_size) * np.prod(strides))`, where inputs to and
            outputs of the layer are assumed to have shapes `input_size +
            (input_filters,)`, `output_size + (filters,)` respectively.  It is
            recommended to benchmark each in the setting of interest to pick the
            most efficient one (in terms of speed and memory usage). Correct
            choice of implementation can lead to dramatic speed improvements
            (e.g. 50X), potentially at the expense of RAM.  Also, only
            `padding="valid"` is supported by `implementation=1`.
  Input shape:
      4D tensor with shape: `(samples, channels, rows, cols)` if
        data_format='channels_first'
      or 4D tensor with shape: `(samples, rows, cols, channels)` if
        data_format='channels_last'.
  Output shape:
      4D tensor with shape: `(samples, filters, new_rows, new_cols)` if
        data_format='channels_first'
      or 4D tensor with shape: `(samples, new_rows, new_cols, filters)` if
        data_format='channels_last'. `rows` and `cols` values might have changed
        due to padding.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               activation=None,
               use_bias=True,
               kernel_initializer='glorot_uniform',
               bias_initializer='zeros',
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               implementation=1,
               **kwargs):
    super(LocallyConnected2D, self).__init__(**kwargs)
    self.filters = filters
    self.kernel_size = conv_utils.normalize_tuple(kernel_size, 2, 'kernel_size')
    self.strides = conv_utils.normalize_tuple(strides, 2, 'strides')
    self.padding = conv_utils.normalize_padding(padding)
    if self.padding != 'valid' and implementation == 1:
      raise ValueError('Invalid border mode for LocallyConnected2D '
                       '(only "valid" is supported if implementation is 1): ' +
                       padding)
    self.data_format = conv_utils.normalize_data_format(data_format)
    self.activation = activations.get(activation)
    self.use_bias = use_bias
    self.kernel_initializer = initializers.get(kernel_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.kernel_constraint = constraints.get(kernel_constraint)
    self.bias_constraint = constraints.get(bias_constraint)
    self.implementation = implementation
    self.input_spec = InputSpec(ndim=4)

  @property
  def _use_input_spec_as_call_signature(self):
    return False

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    if self.data_format == 'channels_last':
      input_row, input_col = input_shape[1:-1]
      input_filter = input_shape[3]
    else:
      input_row, input_col = input_shape[2:]
      input_filter = input_shape[1]
    if input_row is None or input_col is None:
      raise ValueError('The spatial dimensions of the inputs to '
                       ' a LocallyConnected2D layer '
                       'should be fully-defined, but layer received '
                       'the inputs shape ' + str(input_shape))
    output_row = conv_utils.conv_output_length(input_row, self.kernel_size[0],
                                               self.padding, self.strides[0])
    output_col = conv_utils.conv_output_length(input_col, self.kernel_size[1],
                                               self.padding, self.strides[1])
    self.output_row = output_row
    self.output_col = output_col

    if self.implementation == 1:
      self.kernel_shape = (output_row * output_col, self.kernel_size[0] *
                           self.kernel_size[1] * input_filter, self.filters)

      self.kernel = self.add_weight(
          shape=self.kernel_shape,
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

    elif self.implementation == 2:
      if self.data_format == 'channels_first':
        self.kernel_shape = (input_filter, input_row, input_col, self.filters,
                             self.output_row, self.output_col)
      else:
        self.kernel_shape = (input_row, input_col, input_filter,
                             self.output_row, self.output_col, self.filters)

      self.kernel = self.add_weight(
          shape=self.kernel_shape,
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

      self.kernel_mask = get_locallyconnected_mask(
          input_shape=(input_row, input_col),
          kernel_shape=self.kernel_size,
          strides=self.strides,
          padding=self.padding,
          data_format=self.data_format,
      )

    elif self.implementation == 3:
      self.kernel_shape = (self.output_row * self.output_col * self.filters,
                           input_row * input_col * input_filter)

      self.kernel_idxs = sorted(
          conv_utils.conv_kernel_idxs(
              input_shape=(input_row, input_col),
              kernel_shape=self.kernel_size,
              strides=self.strides,
              padding=self.padding,
              filters_in=input_filter,
              filters_out=self.filters,
              data_format=self.data_format))

      self.kernel = self.add_weight(
          shape=(len(self.kernel_idxs),),
          initializer=self.kernel_initializer,
          name='kernel',
          regularizer=self.kernel_regularizer,
          constraint=self.kernel_constraint)

    else:
      raise ValueError('Unrecognized implementation mode: %d.' %
                       self.implementation)

    if self.use_bias:
      self.bias = self.add_weight(
          shape=(output_row, output_col, self.filters),
          initializer=self.bias_initializer,
          name='bias',
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint)
    else:
      self.bias = None
    if self.data_format == 'channels_first':
      self.input_spec = InputSpec(ndim=4, axes={1: input_filter})
    else:
      self.input_spec = InputSpec(ndim=4, axes={-1: input_filter})
    self.built = True

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    if self.data_format == 'channels_first':
      rows = input_shape[2]
      cols = input_shape[3]
    elif self.data_format == 'channels_last':
      rows = input_shape[1]
      cols = input_shape[2]

    rows = conv_utils.conv_output_length(rows, self.kernel_size[0],
                                         self.padding, self.strides[0])
    cols = conv_utils.conv_output_length(cols, self.kernel_size[1],
                                         self.padding, self.strides[1])

    if self.data_format == 'channels_first':
      return (input_shape[0], self.filters, rows, cols)
    elif self.data_format == 'channels_last':
      return (input_shape[0], rows, cols, self.filters)

  def call(self, inputs):
    if self.implementation == 1:
      output = backend.local_conv(
          inputs, self.kernel, self.kernel_size, self.strides,
          (self.output_row, self.output_col),
          self.data_format)

    elif self.implementation == 2:
      output = local_conv_matmul(inputs, self.kernel, self.kernel_mask,
                                 self.compute_output_shape(inputs.shape))

    elif self.implementation == 3:
      output = local_conv_sparse_matmul(inputs, self.kernel, self.kernel_idxs,
                                        self.kernel_shape,
                                        self.compute_output_shape(inputs.shape))

    else:
      raise ValueError('Unrecognized implementation mode: %d.' %
                       self.implementation)

    if self.use_bias:
      output = backend.bias_add(output, self.bias, data_format=self.data_format)

    output = self.activation(output)
    return output

  def get_config(self):
    config = {
        'filters':
            self.filters,
        'kernel_size':
            self.kernel_size,
        'strides':
            self.strides,
        'padding':
            self.padding,
        'data_format':
            self.data_format,
        'activation':
            activations.serialize(self.activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'implementation':
            self.implementation
    }
    base_config = super(LocallyConnected2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Masking (mask_value=0.0, **kwargs)

Masks a sequence by using a mask value to skip timesteps.

For each timestep in the input tensor (dimension #1 in the tensor), if all values in the input tensor at that timestep are equal to mask_value, then the timestep will be masked (skipped) in all downstream layers (as long as they support masking).

If any downstream layer does not support masking yet receives such an input mask, an exception will be raised.

Example:

Consider a Numpy data array x of shape (samples, timesteps, features), to be fed to an LSTM layer. You want to mask timestep #3 and #5 because you lack data for these timesteps. You can:

  • Set x[:, 3, :] = 0. and x[:, 5, :] = 0.
  • Insert a Masking layer with mask_value=0. before the LSTM layer:
samples, timesteps, features = 32, 10, 8
inputs = np.random.random([samples, timesteps, features]).astype(np.float32)
inputs[:, 3, :] = 0.
inputs[:, 5, :] = 0.

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Masking(mask_value=0.,
                                  input_shape=(timesteps, features)))
model.add(tf.keras.layers.LSTM(32))

output = model(inputs)
# The time step 3 and 5 will be skipped from LSTM calculation.

See the masking and padding guide for more details.

Expand source code
class Masking(Layer):
  """Masks a sequence by using a mask value to skip timesteps.

  For each timestep in the input tensor (dimension #1 in the tensor),
  if all values in the input tensor at that timestep
  are equal to `mask_value`, then the timestep will be masked (skipped)
  in all downstream layers (as long as they support masking).

  If any downstream layer does not support masking yet receives such
  an input mask, an exception will be raised.

  Example:

  Consider a Numpy data array `x` of shape `(samples, timesteps, features)`,
  to be fed to an LSTM layer. You want to mask timestep #3 and #5 because you
  lack data for these timesteps. You can:

  - Set `x[:, 3, :] = 0.` and `x[:, 5, :] = 0.`
  - Insert a `Masking` layer with `mask_value=0.` before the LSTM layer:

  ```python
  samples, timesteps, features = 32, 10, 8
  inputs = np.random.random([samples, timesteps, features]).astype(np.float32)
  inputs[:, 3, :] = 0.
  inputs[:, 5, :] = 0.

  model = tf.keras.models.Sequential()
  model.add(tf.keras.layers.Masking(mask_value=0.,
                                    input_shape=(timesteps, features)))
  model.add(tf.keras.layers.LSTM(32))

  output = model(inputs)
  # The time step 3 and 5 will be skipped from LSTM calculation.
  ```

  See [the masking and padding guide](
    https://www.tensorflow.org/guide/keras/masking_and_padding)
  for more details.
  """

  def __init__(self, mask_value=0., **kwargs):
    super(Masking, self).__init__(**kwargs)
    self.supports_masking = True
    self.mask_value = mask_value
    self._compute_output_and_mask_jointly = True

  def compute_mask(self, inputs, mask=None):
    return K.any(tf.not_equal(inputs, self.mask_value), axis=-1)

  def call(self, inputs):
    boolean_mask = K.any(
        tf.not_equal(inputs, self.mask_value), axis=-1, keepdims=True)
    outputs = inputs * tf.cast(boolean_mask, inputs.dtype)
    # Compute the mask and outputs simultaneously.
    outputs._keras_mask = tf.squeeze(boolean_mask, axis=-1)  # pylint: disable=protected-access
    return outputs

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {'mask_value': self.mask_value}
    base_config = super(Masking, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class MaxPool1D (pool_size=2, strides=None, padding='valid', data_format='channels_last', **kwargs)

Max pooling operation for 1D temporal data.

Downsamples the input representation by taking the maximum value over a spatial window of size pool_size. The window is shifted by strides. The resulting output, when using the "valid" padding option, has a shape of: output_shape = (input_shape - pool_size + 1) / strides)

The resulting output shape when using the "same" padding option is: output_shape = input_shape / strides

For example, for strides=1 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=1, padding='valid')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
array([[[2.],
        [3.],
        [4.],
        [5.]]], dtype=float32)>

For example, for strides=2 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=2, padding='valid')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
array([[[2.],
        [4.]]], dtype=float32)>

For example, for strides=1 and padding="same":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=1, padding='same')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[2.],
        [3.],
        [4.],
        [5.],
        [5.]]], dtype=float32)>

Args

pool_size
Integer, size of the max pooling window.
strides
Integer, or None. Specifies how much the pooling window moves for each pooling step. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).

Input shape: - If data_format='channels_last': 3D tensor with shape (batch_size, steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, steps).

Output shape: - If data_format='channels_last': 3D tensor with shape (batch_size, downsampled_steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, downsampled_steps).

Expand source code
class MaxPooling1D(Pooling1D):
  """Max pooling operation for 1D temporal data.

  Downsamples the input representation by taking the maximum value over a
  spatial window of size `pool_size`. The window is shifted by `strides`.  The
  resulting output, when using the `"valid"` padding option, has a shape of:
  `output_shape = (input_shape - pool_size + 1) / strides)`

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = input_shape / strides`

  For example, for `strides=1` and `padding="valid"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=1, padding='valid')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
  array([[[2.],
          [3.],
          [4.],
          [5.]]], dtype=float32)>

  For example, for `strides=2` and `padding="valid"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=2, padding='valid')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
  array([[[2.],
          [4.]]], dtype=float32)>

  For example, for `strides=1` and `padding="same"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=1, padding='same')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[2.],
          [3.],
          [4.],
          [5.],
          [5.]]], dtype=float32)>

  Args:
    pool_size: Integer, size of the max pooling window.
    strides: Integer, or None. Specifies how much the pooling window moves
      for each pooling step.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, steps)`.

  Output shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, downsampled_steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, downsampled_steps)`.
  """

  def __init__(self, pool_size=2, strides=None,
               padding='valid', data_format='channels_last', **kwargs):

    super(MaxPooling1D, self).__init__(
        functools.partial(backend.pool2d, pool_mode='max'),
        pool_size=pool_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        **kwargs)

Ancestors

  • Pooling1D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class MaxPooling1D (pool_size=2, strides=None, padding='valid', data_format='channels_last', **kwargs)

Max pooling operation for 1D temporal data.

Downsamples the input representation by taking the maximum value over a spatial window of size pool_size. The window is shifted by strides. The resulting output, when using the "valid" padding option, has a shape of: output_shape = (input_shape - pool_size + 1) / strides)

The resulting output shape when using the "same" padding option is: output_shape = input_shape / strides

For example, for strides=1 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=1, padding='valid')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
array([[[2.],
        [3.],
        [4.],
        [5.]]], dtype=float32)>

For example, for strides=2 and padding="valid":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=2, padding='valid')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
array([[[2.],
        [4.]]], dtype=float32)>

For example, for strides=1 and padding="same":

>>> x = tf.constant([1., 2., 3., 4., 5.])
>>> x = tf.reshape(x, [1, 5, 1])
>>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
...    strides=1, padding='same')
>>> max_pool_1d(x)
<tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
array([[[2.],
        [3.],
        [4.],
        [5.],
        [5.]]], dtype=float32)>

Args

pool_size
Integer, size of the max pooling window.
strides
Integer, or None. Specifies how much the pooling window moves for each pooling step. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, steps, features) while channels_first corresponds to inputs with shape (batch, features, steps).

Input shape: - If data_format='channels_last': 3D tensor with shape (batch_size, steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, steps).

Output shape: - If data_format='channels_last': 3D tensor with shape (batch_size, downsampled_steps, features). - If data_format='channels_first': 3D tensor with shape (batch_size, features, downsampled_steps).

Expand source code
class MaxPooling1D(Pooling1D):
  """Max pooling operation for 1D temporal data.

  Downsamples the input representation by taking the maximum value over a
  spatial window of size `pool_size`. The window is shifted by `strides`.  The
  resulting output, when using the `"valid"` padding option, has a shape of:
  `output_shape = (input_shape - pool_size + 1) / strides)`

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = input_shape / strides`

  For example, for `strides=1` and `padding="valid"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=1, padding='valid')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 4, 1), dtype=float32, numpy=
  array([[[2.],
          [3.],
          [4.],
          [5.]]], dtype=float32)>

  For example, for `strides=2` and `padding="valid"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=2, padding='valid')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 2, 1), dtype=float32, numpy=
  array([[[2.],
          [4.]]], dtype=float32)>

  For example, for `strides=1` and `padding="same"`:

  >>> x = tf.constant([1., 2., 3., 4., 5.])
  >>> x = tf.reshape(x, [1, 5, 1])
  >>> max_pool_1d = tf.keras.layers.MaxPooling1D(pool_size=2,
  ...    strides=1, padding='same')
  >>> max_pool_1d(x)
  <tf.Tensor: shape=(1, 5, 1), dtype=float32, numpy=
  array([[[2.],
          [3.],
          [4.],
          [5.],
          [5.]]], dtype=float32)>

  Args:
    pool_size: Integer, size of the max pooling window.
    strides: Integer, or None. Specifies how much the pooling window moves
      for each pooling step.
      If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, steps, features)` while `channels_first`
      corresponds to inputs with shape
      `(batch, features, steps)`.

  Input shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, steps)`.

  Output shape:
    - If `data_format='channels_last'`:
      3D tensor with shape `(batch_size, downsampled_steps, features)`.
    - If `data_format='channels_first'`:
      3D tensor with shape `(batch_size, features, downsampled_steps)`.
  """

  def __init__(self, pool_size=2, strides=None,
               padding='valid', data_format='channels_last', **kwargs):

    super(MaxPooling1D, self).__init__(
        functools.partial(backend.pool2d, pool_mode='max'),
        pool_size=pool_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        **kwargs)

Ancestors

  • Pooling1D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class MaxPool2D (pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Max pooling operation for 2D spatial data.

Downsamples the input along its spatial dimensions (height and width) by taking the maximum value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

The resulting output, when using the "valid" padding option, has a spatial shape (number of rows or columns) of: output_shape = math.floor((input_shape - pool_size) / strides) + 1 (when input_shape >= pool_size)

The resulting output shape when using the "same" padding option is: output_shape = math.floor((input_shape - 1) / strides) + 1

For example, for strides=(1, 1) and padding="valid":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='valid')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
  array([[[[5.],
           [6.]],
          [[8.],
           [9.]]]], dtype=float32)>

For example, for strides=(2, 2) and padding="valid":

>>> x = tf.constant([[1., 2., 3., 4.],
...                  [5., 6., 7., 8.],
...                  [9., 10., 11., 12.]])
>>> x = tf.reshape(x, [1, 3, 4, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(2, 2), padding='valid')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
  array([[[[6.],
           [8.]]]], dtype=float32)>

Usage Example:

>>> input_image = tf.constant([[[[1.], [1.], [2.], [4.]],
...                            [[2.], [2.], [3.], [2.]],
...                            [[4.], [1.], [1.], [1.]],
...                            [[2.], [2.], [1.], [4.]]]])
>>> output = tf.constant([[[[1], [0]],
...                       [[0], [1]]]])
>>> model = tf.keras.models.Sequential()
>>> model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    input_shape=(4, 4, 1)))
>>> model.compile('adam', 'mean_squared_error')
>>> model.predict(input_image, steps=1)
array([[[[2.],
         [4.]],
        [[4.],
         [4.]]]], dtype=float32)

For example, for stride=(1, 1) and padding="same":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='same')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
  array([[[[5.],
           [6.],
           [6.]],
          [[8.],
           [9.],
           [9.]],
          [[8.],
           [9.],
           [9.]]]], dtype=float32)>

Args

pool_size
integer or tuple of 2 integers, window size over which to take the maximum. (2, 2) will take the max value over a 2x2 pooling window. If only one integer is specified, the same window length will be used for both dimensions.
strides
Integer, tuple of 2 integers, or None. Strides values. Specifies how far the pooling window moves for each pooling step. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If data_format='channels_last': 4D tensor with shape (batch_size, pooled_rows, pooled_cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, pooled_rows, pooled_cols).

Returns

A tensor of rank 4 representing the maximum pooled values. See above for output shape.

Expand source code
class MaxPooling2D(Pooling2D):
  """Max pooling operation for 2D spatial data.

  Downsamples the input along its spatial dimensions (height and width)
  by taking the maximum value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  The resulting output,
  when using the `"valid"` padding option, has a spatial shape
  (number of rows or columns) of:
  `output_shape = math.floor((input_shape - pool_size) / strides) + 1`
  (when `input_shape >= pool_size`)

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = math.floor((input_shape - 1) / strides) + 1`

  For example, for `strides=(1, 1)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='valid')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
    array([[[[5.],
             [6.]],
            [[8.],
             [9.]]]], dtype=float32)>

  For example, for `strides=(2, 2)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3., 4.],
  ...                  [5., 6., 7., 8.],
  ...                  [9., 10., 11., 12.]])
  >>> x = tf.reshape(x, [1, 3, 4, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(2, 2), padding='valid')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
    array([[[[6.],
             [8.]]]], dtype=float32)>

  Usage Example:

  >>> input_image = tf.constant([[[[1.], [1.], [2.], [4.]],
  ...                            [[2.], [2.], [3.], [2.]],
  ...                            [[4.], [1.], [1.], [1.]],
  ...                            [[2.], [2.], [1.], [4.]]]])
  >>> output = tf.constant([[[[1], [0]],
  ...                       [[0], [1]]]])
  >>> model = tf.keras.models.Sequential()
  >>> model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    input_shape=(4, 4, 1)))
  >>> model.compile('adam', 'mean_squared_error')
  >>> model.predict(input_image, steps=1)
  array([[[[2.],
           [4.]],
          [[4.],
           [4.]]]], dtype=float32)

  For example, for stride=(1, 1) and padding="same":

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='same')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
    array([[[[5.],
             [6.],
             [6.]],
            [[8.],
             [9.],
             [9.]],
            [[8.],
             [9.],
             [9.]]]], dtype=float32)>

  Args:
    pool_size: integer or tuple of 2 integers,
      window size over which to take the maximum.
      `(2, 2)` will take the max value over a 2x2 pooling window.
      If only one integer is specified, the same window length
      will be used for both dimensions.
    strides: Integer, tuple of 2 integers, or None.
      Strides values.  Specifies how far the pooling window moves
      for each pooling step. If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, pooled_rows, pooled_cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, pooled_rows, pooled_cols)`.

  Returns:
    A tensor of rank 4 representing the maximum pooled values.  See above for
    output shape.
  """

  def __init__(self,
               pool_size=(2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(MaxPooling2D, self).__init__(
        tf.compat.v1.nn.max_pool,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling2D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class MaxPooling2D (pool_size=(2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Max pooling operation for 2D spatial data.

Downsamples the input along its spatial dimensions (height and width) by taking the maximum value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

The resulting output, when using the "valid" padding option, has a spatial shape (number of rows or columns) of: output_shape = math.floor((input_shape - pool_size) / strides) + 1 (when input_shape >= pool_size)

The resulting output shape when using the "same" padding option is: output_shape = math.floor((input_shape - 1) / strides) + 1

For example, for strides=(1, 1) and padding="valid":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='valid')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
  array([[[[5.],
           [6.]],
          [[8.],
           [9.]]]], dtype=float32)>

For example, for strides=(2, 2) and padding="valid":

>>> x = tf.constant([[1., 2., 3., 4.],
...                  [5., 6., 7., 8.],
...                  [9., 10., 11., 12.]])
>>> x = tf.reshape(x, [1, 3, 4, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(2, 2), padding='valid')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
  array([[[[6.],
           [8.]]]], dtype=float32)>

Usage Example:

>>> input_image = tf.constant([[[[1.], [1.], [2.], [4.]],
...                            [[2.], [2.], [3.], [2.]],
...                            [[4.], [1.], [1.], [1.]],
...                            [[2.], [2.], [1.], [4.]]]])
>>> output = tf.constant([[[[1], [0]],
...                       [[0], [1]]]])
>>> model = tf.keras.models.Sequential()
>>> model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    input_shape=(4, 4, 1)))
>>> model.compile('adam', 'mean_squared_error')
>>> model.predict(input_image, steps=1)
array([[[[2.],
         [4.]],
        [[4.],
         [4.]]]], dtype=float32)

For example, for stride=(1, 1) and padding="same":

>>> x = tf.constant([[1., 2., 3.],
...                  [4., 5., 6.],
...                  [7., 8., 9.]])
>>> x = tf.reshape(x, [1, 3, 3, 1])
>>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
...    strides=(1, 1), padding='same')
>>> max_pool_2d(x)
<tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
  array([[[[5.],
           [6.],
           [6.]],
          [[8.],
           [9.],
           [9.]],
          [[8.],
           [9.],
           [9.]]]], dtype=float32)>

Args

pool_size
integer or tuple of 2 integers, window size over which to take the maximum. (2, 2) will take the max value over a 2x2 pooling window. If only one integer is specified, the same window length will be used for both dimensions.
strides
Integer, tuple of 2 integers, or None. Strides values. Specifies how far the pooling window moves for each pooling step. If None, it will default to pool_size.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, height, width, channels) while channels_first corresponds to inputs with shape (batch, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 4D tensor with shape (batch_size, rows, cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, rows, cols).

Output shape: - If data_format='channels_last': 4D tensor with shape (batch_size, pooled_rows, pooled_cols, channels). - If data_format='channels_first': 4D tensor with shape (batch_size, channels, pooled_rows, pooled_cols).

Returns

A tensor of rank 4 representing the maximum pooled values. See above for output shape.

Expand source code
class MaxPooling2D(Pooling2D):
  """Max pooling operation for 2D spatial data.

  Downsamples the input along its spatial dimensions (height and width)
  by taking the maximum value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  The resulting output,
  when using the `"valid"` padding option, has a spatial shape
  (number of rows or columns) of:
  `output_shape = math.floor((input_shape - pool_size) / strides) + 1`
  (when `input_shape >= pool_size`)

  The resulting output shape when using the `"same"` padding option is:
  `output_shape = math.floor((input_shape - 1) / strides) + 1`

  For example, for `strides=(1, 1)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='valid')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 2, 2, 1), dtype=float32, numpy=
    array([[[[5.],
             [6.]],
            [[8.],
             [9.]]]], dtype=float32)>

  For example, for `strides=(2, 2)` and `padding="valid"`:

  >>> x = tf.constant([[1., 2., 3., 4.],
  ...                  [5., 6., 7., 8.],
  ...                  [9., 10., 11., 12.]])
  >>> x = tf.reshape(x, [1, 3, 4, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(2, 2), padding='valid')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 1, 2, 1), dtype=float32, numpy=
    array([[[[6.],
             [8.]]]], dtype=float32)>

  Usage Example:

  >>> input_image = tf.constant([[[[1.], [1.], [2.], [4.]],
  ...                            [[2.], [2.], [3.], [2.]],
  ...                            [[4.], [1.], [1.], [1.]],
  ...                            [[2.], [2.], [1.], [4.]]]])
  >>> output = tf.constant([[[[1], [0]],
  ...                       [[0], [1]]]])
  >>> model = tf.keras.models.Sequential()
  >>> model.add(tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    input_shape=(4, 4, 1)))
  >>> model.compile('adam', 'mean_squared_error')
  >>> model.predict(input_image, steps=1)
  array([[[[2.],
           [4.]],
          [[4.],
           [4.]]]], dtype=float32)

  For example, for stride=(1, 1) and padding="same":

  >>> x = tf.constant([[1., 2., 3.],
  ...                  [4., 5., 6.],
  ...                  [7., 8., 9.]])
  >>> x = tf.reshape(x, [1, 3, 3, 1])
  >>> max_pool_2d = tf.keras.layers.MaxPooling2D(pool_size=(2, 2),
  ...    strides=(1, 1), padding='same')
  >>> max_pool_2d(x)
  <tf.Tensor: shape=(1, 3, 3, 1), dtype=float32, numpy=
    array([[[[5.],
             [6.],
             [6.]],
            [[8.],
             [9.],
             [9.]],
            [[8.],
             [9.],
             [9.]]]], dtype=float32)>

  Args:
    pool_size: integer or tuple of 2 integers,
      window size over which to take the maximum.
      `(2, 2)` will take the max value over a 2x2 pooling window.
      If only one integer is specified, the same window length
      will be used for both dimensions.
    strides: Integer, tuple of 2 integers, or None.
      Strides values.  Specifies how far the pooling window moves
      for each pooling step. If None, it will default to `pool_size`.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, rows, cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, rows, cols)`.

  Output shape:
    - If `data_format='channels_last'`:
      4D tensor with shape `(batch_size, pooled_rows, pooled_cols, channels)`.
    - If `data_format='channels_first'`:
      4D tensor with shape `(batch_size, channels, pooled_rows, pooled_cols)`.

  Returns:
    A tensor of rank 4 representing the maximum pooled values.  See above for
    output shape.
  """

  def __init__(self,
               pool_size=(2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(MaxPooling2D, self).__init__(
        tf.compat.v1.nn.max_pool,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling2D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class MaxPool3D (pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Max pooling operation for 3D data (spatial or spatio-temporal).

Downsamples the input along its spatial dimensions (depth, height, and width) by taking the maximum value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

Args

pool_size
Tuple of 3 integers, factors by which to downscale (dim1, dim2, dim3). (2, 2, 2) will halve the size of the 3D input in each dimension.
strides
tuple of 3 integers, or None. Strides values.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)

Example:

depth = 30
height = 30
width = 30
input_channels = 3

inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
layer = tf.keras.layers.MaxPooling3D(pool_size=3)
outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
Expand source code
class MaxPooling3D(Pooling3D):
  """Max pooling operation for 3D data (spatial or spatio-temporal).

  Downsamples the input along its spatial dimensions (depth, height, and width)
  by taking the maximum value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  Args:
    pool_size: Tuple of 3 integers,
      factors by which to downscale (dim1, dim2, dim3).
      `(2, 2, 2)` will halve the size of the 3D input in each dimension.
    strides: tuple of 3 integers, or None. Strides values.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`

  Example:

  ```python
  depth = 30
  height = 30
  width = 30
  input_channels = 3

  inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
  layer = tf.keras.layers.MaxPooling3D(pool_size=3)
  outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
  ```
  """

  def __init__(self,
               pool_size=(2, 2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(MaxPooling3D, self).__init__(
        tf.nn.max_pool3d,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling3D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

class MaxPooling3D (pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None, **kwargs)

Max pooling operation for 3D data (spatial or spatio-temporal).

Downsamples the input along its spatial dimensions (depth, height, and width) by taking the maximum value over an input window (of size defined by pool_size) for each channel of the input. The window is shifted by strides along each dimension.

Args

pool_size
Tuple of 3 integers, factors by which to downscale (dim1, dim2, dim3). (2, 2, 2) will halve the size of the 3D input in each dimension.
strides
tuple of 3 integers, or None. Strides values.
padding
One of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)

Output shape: - If data_format='channels_last': 5D tensor with shape: (batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels) - If data_format='channels_first': 5D tensor with shape: (batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)

Example:

depth = 30
height = 30
width = 30
input_channels = 3

inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
layer = tf.keras.layers.MaxPooling3D(pool_size=3)
outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
Expand source code
class MaxPooling3D(Pooling3D):
  """Max pooling operation for 3D data (spatial or spatio-temporal).

  Downsamples the input along its spatial dimensions (depth, height, and width)
  by taking the maximum value over an input window
  (of size defined by `pool_size`) for each channel of the input.
  The window is shifted by `strides` along each dimension.

  Args:
    pool_size: Tuple of 3 integers,
      factors by which to downscale (dim1, dim2, dim3).
      `(2, 2, 2)` will halve the size of the 3D input in each dimension.
    strides: tuple of 3 integers, or None. Strides values.
    padding: One of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding evenly to
      the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`

  Output shape:
    - If `data_format='channels_last'`:
      5D tensor with shape:
      `(batch_size, pooled_dim1, pooled_dim2, pooled_dim3, channels)`
    - If `data_format='channels_first'`:
      5D tensor with shape:
      `(batch_size, channels, pooled_dim1, pooled_dim2, pooled_dim3)`

  Example:

  ```python
  depth = 30
  height = 30
  width = 30
  input_channels = 3

  inputs = tf.keras.Input(shape=(depth, height, width, input_channels))
  layer = tf.keras.layers.MaxPooling3D(pool_size=3)
  outputs = layer(inputs)  # Shape: (batch_size, 10, 10, 10, 3)
  ```
  """

  def __init__(self,
               pool_size=(2, 2, 2),
               strides=None,
               padding='valid',
               data_format=None,
               **kwargs):
    super(MaxPooling3D, self).__init__(
        tf.nn.max_pool3d,
        pool_size=pool_size, strides=strides,
        padding=padding, data_format=data_format, **kwargs)

Ancestors

  • Pooling3D
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class Maximum (**kwargs)

Layer that computes the maximum (element-wise) a list of inputs.

It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).

>>> tf.keras.layers.Maximum()([np.arange(5).reshape(5, 1),
...                            np.arange(5, 10).reshape(5, 1)])
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
array([[5],
     [6],
     [7],
     [8],
     [9]])>
>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> maxed = tf.keras.layers.Maximum()([x1, x2])
>>> maxed.shape
TensorShape([5, 8])

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Maximum(_Merge):
  """Layer that computes the maximum (element-wise) a list of inputs.

  It takes as input a list of tensors, all of the same shape, and returns
  a single tensor (also of the same shape).

  >>> tf.keras.layers.Maximum()([np.arange(5).reshape(5, 1),
  ...                            np.arange(5, 10).reshape(5, 1)])
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[5],
       [6],
       [7],
       [8],
       [9]])>

  >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
  >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
  >>> maxed = tf.keras.layers.Maximum()([x1, x2])
  >>> maxed.shape
  TensorShape([5, 8])
  """

  def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
      output = tf.maximum(output, inputs[i])
    return output

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Minimum (**kwargs)

Layer that computes the minimum (element-wise) a list of inputs.

It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).

>>> tf.keras.layers.Minimum()([np.arange(5).reshape(5, 1),
...                            np.arange(5, 10).reshape(5, 1)])
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
array([[0],
     [1],
     [2],
     [3],
     [4]])>
>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> minned = tf.keras.layers.Minimum()([x1, x2])
>>> minned.shape
TensorShape([5, 8])

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Minimum(_Merge):
  """Layer that computes the minimum (element-wise) a list of inputs.

  It takes as input a list of tensors, all of the same shape, and returns
  a single tensor (also of the same shape).

  >>> tf.keras.layers.Minimum()([np.arange(5).reshape(5, 1),
  ...                            np.arange(5, 10).reshape(5, 1)])
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[0],
       [1],
       [2],
       [3],
       [4]])>

  >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
  >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
  >>> minned = tf.keras.layers.Minimum()([x1, x2])
  >>> minned.shape
  TensorShape([5, 8])
  """

  def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
      output = tf.minimum(output, inputs[i])
    return output

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class MultiHeadAttention (num_heads, key_dim, value_dim=None, dropout=0.0, use_bias=True, output_shape=None, attention_axes=None, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None, **kwargs)

MultiHeadAttention layer.

This is an implementation of multi-headed attention as described in the paper "Attention is all you Need" (Vaswani et al., 2017). If query, key, value are the same, then this is self-attention. Each timestep in query attends to the corresponding sequence in key, and returns a fixed-width vector.

This layer first projects query, key and value. These are (effectively) a list of tensors of length num_attention_heads, where the corresponding shapes are (batch_size, <query dimensions>, key_dim), (batch_size, <key/value dimensions>, key_dim), (batch_size, <key/value dimensions>, value_dim).

Then, the query and key tensors are dot-producted and scaled. These are softmaxed to obtain attention probabilities. The value tensors are then interpolated by these probabilities, then concatenated back to a single tensor.

Finally, the result tensor with the last dimension as value_dim can take an linear projection and return.

Examples:

Performs 1D cross-attention over two sequence inputs with an attention mask. Returns the additional attention weights over heads.

>>> layer = MultiHeadAttention(num_heads=2, key_dim=2)
>>> target = tf.keras.Input(shape=[8, 16])
>>> source = tf.keras.Input(shape=[4, 16])
>>> output_tensor, weights = layer(target, source,
...                                return_attention_scores=True)
>>> print(output_tensor.shape)
(None, 8, 16)
>>> print(weights.shape)
(None, 2, 8, 4)

Performs 2D self-attention over a 5D input tensor on axes 2 and 3.

>>> layer = MultiHeadAttention(num_heads=2, key_dim=2, attention_axes=(2, 3))
>>> input_tensor = tf.keras.Input(shape=[5, 3, 4, 16])
>>> output_tensor = layer(input_tensor, input_tensor)
>>> print(output_tensor.shape)
(None, 5, 3, 4, 16)

Args

num_heads
Number of attention heads.
key_dim
Size of each attention head for query and key.
value_dim
Size of each attention head for value.
dropout
Dropout probability.
use_bias
Boolean, whether the dense layers use bias vectors/matrices.
output_shape
The expected shape of an output tensor, besides the batch and sequence dims. If not specified, projects back to the key feature dim.
attention_axes
axes over which the attention is applied. None means attention over all axes, but batch, heads, and features.
kernel_initializer
Initializer for dense layer kernels.
bias_initializer
Initializer for dense layer biases.
kernel_regularizer
Regularizer for dense layer kernels.
bias_regularizer
Regularizer for dense layer biases.
activity_regularizer
Regularizer for dense layer activity.
kernel_constraint
Constraint for dense layer kernels.
bias_constraint
Constraint for dense layer kernels.

Call arguments: query: Query Tensor of shape (B, T, dim). value: Value Tensor of shape (B, S, dim). key: Optional key Tensor of shape (B, S, dim). If not given, will use value for both key and value, which is the most common case. attention_mask: a boolean mask of shape (B, T, S), that prevents attention to certain positions. The boolean mask specifies which query elements can attend to which key elements, 1 indicates attention and 0 indicates no attention. Broadcasting can happen for the missing batch dimensions and the head dimension. return_attention_scores: A boolean to indicate whether the output should be attention output if True, or (attention_output, attention_scores) if False. Defaults to False. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (no dropout). Defaults to either using the training mode of the parent layer/model, or False (inference) if there is no parent layer.

Returns

attention_output
The result of the computation, of shape (B, T, E), where T is for target sequence shapes and E is the query input last dimension if output_shape is None. Otherwise, the multi-head outputs are project to the shape specified by output_shape.
attention_scores
[Optional] multi-head attention coeffients over attention axes.
Expand source code
class MultiHeadAttention(Layer):
  """MultiHeadAttention layer.

  This is an implementation of multi-headed attention as described in the paper
  "Attention is all you Need" (Vaswani et al., 2017).
  If `query`, `key,` `value` are the same, then
  this is self-attention. Each timestep in `query` attends to the
  corresponding sequence in `key`, and returns a fixed-width vector.

  This layer first projects `query`, `key` and `value`. These are
  (effectively) a list of tensors of length `num_attention_heads`, where the
  corresponding shapes are `(batch_size, <query dimensions>, key_dim)`,
  `(batch_size, <key/value dimensions>, key_dim)`,
  `(batch_size, <key/value dimensions>, value_dim)`.

  Then, the query and key tensors are dot-producted and scaled. These are
  softmaxed to obtain attention probabilities. The value tensors are then
  interpolated by these probabilities, then concatenated back to a single
  tensor.

  Finally, the result tensor with the last dimension as value_dim can take an
  linear projection and return.

  Examples:

  Performs 1D cross-attention over two sequence inputs with an attention mask.
  Returns the additional attention weights over heads.

  >>> layer = MultiHeadAttention(num_heads=2, key_dim=2)
  >>> target = tf.keras.Input(shape=[8, 16])
  >>> source = tf.keras.Input(shape=[4, 16])
  >>> output_tensor, weights = layer(target, source,
  ...                                return_attention_scores=True)
  >>> print(output_tensor.shape)
  (None, 8, 16)
  >>> print(weights.shape)
  (None, 2, 8, 4)

  Performs 2D self-attention over a 5D input tensor on axes 2 and 3.

  >>> layer = MultiHeadAttention(num_heads=2, key_dim=2, attention_axes=(2, 3))
  >>> input_tensor = tf.keras.Input(shape=[5, 3, 4, 16])
  >>> output_tensor = layer(input_tensor, input_tensor)
  >>> print(output_tensor.shape)
  (None, 5, 3, 4, 16)

  Args:
    num_heads: Number of attention heads.
    key_dim: Size of each attention head for query and key.
    value_dim: Size of each attention head for value.
    dropout: Dropout probability.
    use_bias: Boolean, whether the dense layers use bias vectors/matrices.
    output_shape: The expected shape of an output tensor, besides the batch and
      sequence dims. If not specified, projects back to the key feature dim.
    attention_axes: axes over which the attention is applied. `None` means
      attention over all axes, but batch, heads, and features.
    kernel_initializer: Initializer for dense layer kernels.
    bias_initializer: Initializer for dense layer biases.
    kernel_regularizer: Regularizer for dense layer kernels.
    bias_regularizer: Regularizer for dense layer biases.
    activity_regularizer: Regularizer for dense layer activity.
    kernel_constraint: Constraint for dense layer kernels.
    bias_constraint: Constraint for dense layer kernels.

  Call arguments:
    query: Query `Tensor` of shape `(B, T, dim)`.
    value: Value `Tensor` of shape `(B, S, dim)`.
    key: Optional key `Tensor` of shape `(B, S, dim)`. If not given, will use
      `value` for both `key` and `value`, which is the most common case.
    attention_mask: a boolean mask of shape `(B, T, S)`, that prevents
      attention to certain positions. The boolean mask specifies which query
      elements can attend to which key elements, 1 indicates attention and 0
      indicates no attention. Broadcasting can happen for the missing batch
      dimensions and the head dimension.
    return_attention_scores: A boolean to indicate whether the output should
      be attention output if True, or (attention_output, attention_scores) if
      False. Defaults to False.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (no dropout).
      Defaults to either using the training mode of the parent layer/model,
      or False (inference) if there is no parent layer.

  Returns:
    attention_output: The result of the computation, of shape `(B, T, E)`,
      where `T` is for target sequence shapes and `E` is the query input last
      dimension if `output_shape` is `None`. Otherwise, the multi-head outputs
      are project to the shape specified by `output_shape`.
    attention_scores: [Optional] multi-head attention coeffients over
      attention axes.
  """

  def __init__(self,
               num_heads,
               key_dim,
               value_dim=None,
               dropout=0.0,
               use_bias=True,
               output_shape=None,
               attention_axes=None,
               kernel_initializer="glorot_uniform",
               bias_initializer="zeros",
               kernel_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(MultiHeadAttention, self).__init__(**kwargs)
    self._num_heads = num_heads
    self._key_dim = key_dim
    self._value_dim = value_dim if value_dim else key_dim
    self._dropout = dropout
    self._use_bias = use_bias
    self._output_shape = output_shape
    self._kernel_initializer = initializers.get(kernel_initializer)
    self._bias_initializer = initializers.get(bias_initializer)
    self._kernel_regularizer = regularizers.get(kernel_regularizer)
    self._bias_regularizer = regularizers.get(bias_regularizer)
    self._kernel_constraint = constraints.get(kernel_constraint)
    self._bias_constraint = constraints.get(bias_constraint)
    if attention_axes is not None and not isinstance(attention_axes,
                                                     collections.abc.Sized):
      self._attention_axes = (attention_axes,)
    else:
      self._attention_axes = attention_axes
    self._built_from_signature = False
    self._query_shape, self._key_shape, self._value_shape = None, None, None

  def get_config(self):
    config = {
        "num_heads": self._num_heads,
        "key_dim": self._key_dim,
        "value_dim": self._value_dim,
        "dropout": self._dropout,
        "use_bias": self._use_bias,
        "output_shape": self._output_shape,
        "attention_axes": self._attention_axes,
        "kernel_initializer":
            initializers.serialize(self._kernel_initializer),
        "bias_initializer":
            initializers.serialize(self._bias_initializer),
        "kernel_regularizer":
            regularizers.serialize(self._kernel_regularizer),
        "bias_regularizer":
            regularizers.serialize(self._bias_regularizer),
        "activity_regularizer":
            regularizers.serialize(self._activity_regularizer),
        "kernel_constraint":
            constraints.serialize(self._kernel_constraint),
        "bias_constraint":
            constraints.serialize(self._bias_constraint),
        "query_shape": self._query_shape,
        "key_shape": self._key_shape,
        "value_shape": self._value_shape,
    }
    base_config = super(MultiHeadAttention, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config):
    # If the layer has a different build() function from the Keras default,
    # we need to trigger the customized build to create weights.
    query_shape = config.pop("query_shape")
    key_shape = config.pop("key_shape")
    value_shape = config.pop("value_shape")
    layer = cls(**config)
    if None in [query_shape, key_shape, value_shape]:
      logging.warning(
          "One of dimensions of the input shape is missing. It should have been"
          " memorized when the layer was serialized. "
          "%s is created without weights.",
          str(cls))
    else:
      layer._build_from_signature(query_shape, value_shape, key_shape)  # pylint: disable=protected-access
    return layer

  def _build_from_signature(self, query, value, key=None):
    """Builds layers and variables.

    Once the method is called, self._built_from_signature will be set to True.

    Args:
      query: Query tensor or TensorShape.
      value: Value tensor or TensorShape.
      key: Key tensor or TensorShape.
    """
    self._built_from_signature = True
    if hasattr(query, "shape"):
      self._query_shape = tf.TensorShape(query.shape)
    else:
      self._query_shape = tf.TensorShape(query)
    if hasattr(value, "shape"):
      self._value_shape = tf.TensorShape(value.shape)
    else:
      self._value_shape = tf.TensorShape(value)
    if key is None:
      self._key_shape = self._value_shape
    elif hasattr(key, "shape"):
      self._key_shape = tf.TensorShape(key.shape)
    else:
      self._key_shape = tf.TensorShape(key)

    common_kwargs = dict(
        kernel_initializer=self._kernel_initializer,
        bias_initializer=self._bias_initializer,
        kernel_regularizer=self._kernel_regularizer,
        bias_regularizer=self._bias_regularizer,
        activity_regularizer=self._activity_regularizer,
        kernel_constraint=self._kernel_constraint,
        bias_constraint=self._bias_constraint)
    # Any setup work performed only once should happen in an `init_scope`
    # to avoid creating symbolic Tensors that will later pollute any eager
    # operations.
    with tf_utils.maybe_init_scope(self):
      free_dims = self._query_shape.rank - 1
      einsum_equation, bias_axes, output_rank = _build_proj_equation(
          free_dims, bound_dims=1, output_dims=2)
      self._query_dense = einsum_dense.EinsumDense(
          einsum_equation,
          output_shape=_get_output_shape(output_rank - 1,
                                         [self._num_heads, self._key_dim]),
          bias_axes=bias_axes if self._use_bias else None,
          name="query",
          **common_kwargs)
      einsum_equation, bias_axes, output_rank = _build_proj_equation(
          self._key_shape.rank - 1, bound_dims=1, output_dims=2)
      self._key_dense = einsum_dense.EinsumDense(
          einsum_equation,
          output_shape=_get_output_shape(output_rank - 1,
                                         [self._num_heads, self._key_dim]),
          bias_axes=bias_axes if self._use_bias else None,
          name="key",
          **common_kwargs)
      einsum_equation, bias_axes, output_rank = _build_proj_equation(
          self._value_shape.rank - 1, bound_dims=1, output_dims=2)
      self._value_dense = einsum_dense.EinsumDense(
          einsum_equation,
          output_shape=_get_output_shape(output_rank - 1,
                                         [self._num_heads, self._value_dim]),
          bias_axes=bias_axes if self._use_bias else None,
          name="value",
          **common_kwargs)

      # Builds the attention computations for multi-head dot product attention.
      # These computations could be wrapped into the keras attention layer once
      # it support mult-head einsum computations.
      self._build_attention(output_rank)
      self._output_dense = self._make_output_dense(
          free_dims, common_kwargs, "attention_output")

  def _make_output_dense(self, free_dims, common_kwargs, name=None):
    """Builds the output projection matrix.

    Args:
      free_dims: Number of free dimensions for einsum equation building.
      common_kwargs: Common keyword arguments for einsum layer.
      name: Name for the projection layer.

    Returns:
      Projection layer.
    """
    if self._output_shape:
      if not isinstance(self._output_shape, collections.abc.Sized):
        output_shape = [self._output_shape]
      else:
        output_shape = self._output_shape
    else:
      output_shape = [self._query_shape[-1]]
    einsum_equation, bias_axes, output_rank = _build_proj_equation(
        free_dims, bound_dims=2, output_dims=len(output_shape))
    return einsum_dense.EinsumDense(
        einsum_equation,
        output_shape=_get_output_shape(output_rank - 1, output_shape),
        bias_axes=bias_axes if self._use_bias else None,
        name=name,
        **common_kwargs)

  def _build_attention(self, rank):
    """Builds multi-head dot-product attention computations.

    This function builds attributes necessary for `_compute_attention` to
    costomize attention computation to replace the default dot-product
    attention.

    Args:
      rank: the rank of query, key, value tensors.
    """
    if self._attention_axes is None:
      self._attention_axes = tuple(range(1, rank - 2))
    else:
      self._attention_axes = tuple(self._attention_axes)
    self._dot_product_equation, self._combine_equation, attn_scores_rank = (
        _build_attention_equation(rank, attn_axes=self._attention_axes))
    norm_axes = tuple(
        range(attn_scores_rank - len(self._attention_axes), attn_scores_rank))
    self._softmax = advanced_activations.Softmax(axis=norm_axes)
    self._dropout_layer = core.Dropout(rate=self._dropout)

  def _masked_softmax(self, attention_scores, attention_mask=None):
    # Normalize the attention scores to probabilities.
    # `attention_scores` = [B, N, T, S]
    if attention_mask is not None:
      # The expand dim happens starting from the `num_heads` dimension,
      # (<batch_dims>, num_heads, <query_attention_dims, key_attention_dims>)
      mask_expansion_axis = -len(self._attention_axes) * 2 - 1
      for _ in range(len(attention_scores.shape) - len(attention_mask.shape)):
        attention_mask = tf.expand_dims(
            attention_mask, axis=mask_expansion_axis)
    return self._softmax(attention_scores, attention_mask)

  def _compute_attention(self,
                         query,
                         key,
                         value,
                         attention_mask=None,
                         training=None):
    """Applies Dot-product attention with query, key, value tensors.

    This function defines the computation inside `call` with projected
    multi-head Q, K, V inputs. Users can override this function for customized
    attention implementation.

    Args:
      query: Projected query `Tensor` of shape `(B, T, N, key_dim)`.
      key: Projected key `Tensor` of shape `(B, T, N, key_dim)`.
      value: Projected value `Tensor` of shape `(B, T, N, value_dim)`.
      attention_mask: a boolean mask of shape `(B, T, S)`, that prevents
        attention to certain positions.
      training: Python boolean indicating whether the layer should behave in
        training mode (adding dropout) or in inference mode (doing nothing).

    Returns:
      attention_output: Multi-headed outputs of attention computation.
      attention_scores: Multi-headed attention weights.
    """
    # Note: Applying scalar multiply at the smaller end of einsum improves
    # XLA performance, but may introduce slight numeric differences in
    # the Transformer attention head.
    query = tf.multiply(query, 1.0 / math.sqrt(float(self._key_dim)))

    # Take the dot product between "query" and "key" to get the raw
    # attention scores.
    attention_scores = tf.einsum(self._dot_product_equation, key,
                                               query)

    attention_scores = self._masked_softmax(attention_scores, attention_mask)

    # This is actually dropping out entire tokens to attend to, which might
    # seem a bit unusual, but is taken from the original Transformer paper.
    attention_scores_dropout = self._dropout_layer(
        attention_scores, training=training)

    # `context_layer` = [B, T, N, H]
    attention_output = tf.einsum(self._combine_equation,
                                               attention_scores_dropout, value)
    return attention_output, attention_scores

  def call(self,
           query,
           value,
           key=None,
           attention_mask=None,
           return_attention_scores=False,
           training=None):
    if not self._built_from_signature:
      self._build_from_signature(query=query, value=value, key=key)
    if key is None:
      key = value

    #   N = `num_attention_heads`
    #   H = `size_per_head`
    # `query` = [B, T, N ,H]
    query = self._query_dense(query)

    # `key` = [B, S, N, H]
    key = self._key_dense(key)

    # `value` = [B, S, N, H]
    value = self._value_dense(value)

    attention_output, attention_scores = self._compute_attention(
        query, key, value, attention_mask, training)
    attention_output = self._output_dense(attention_output)

    if return_attention_scores:
      return attention_output, attention_scores
    return attention_output

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Multiply (**kwargs)

Layer that multiplies (element-wise) a list of inputs.

It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).

>>> tf.keras.layers.Multiply()([np.arange(5).reshape(5, 1),
...                             np.arange(5, 10).reshape(5, 1)])
<tf.Tensor: shape=(5, 1), dtype=int64, numpy=
array([[ 0],
     [ 6],
     [14],
     [24],
     [36]])>
>>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
>>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
>>> multiplied = tf.keras.layers.Multiply()([x1, x2])
>>> multiplied.shape
TensorShape([5, 8])

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Multiply(_Merge):
  """Layer that multiplies (element-wise) a list of inputs.

  It takes as input a list of tensors, all of the same shape, and returns
  a single tensor (also of the same shape).

  >>> tf.keras.layers.Multiply()([np.arange(5).reshape(5, 1),
  ...                             np.arange(5, 10).reshape(5, 1)])
  <tf.Tensor: shape=(5, 1), dtype=int64, numpy=
  array([[ 0],
       [ 6],
       [14],
       [24],
       [36]])>

  >>> x1 = tf.keras.layers.Dense(8)(np.arange(10).reshape(5, 2))
  >>> x2 = tf.keras.layers.Dense(8)(np.arange(10, 20).reshape(5, 2))
  >>> multiplied = tf.keras.layers.Multiply()([x1, x2])
  >>> multiplied.shape
  TensorShape([5, 8])
  """

  def _merge_function(self, inputs):
    output = inputs[0]
    for i in range(1, len(inputs)):
      output = output * inputs[i]
    return output

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Normalization (axis=-1, mean=None, variance=None, **kwargs)

Feature-wise normalization of the data.

This layer will coerce its inputs into a distribution centered around 0 with standard deviation 1. It accomplishes this by precomputing the mean and variance of the data, and calling (input - mean) / sqrt(var) at runtime.

What happens in adapt(): Compute mean and variance of the data and store them as the layer's weights. adapt() should be called before fit(), evaluate(), or predict().

Args

axis
Integer, tuple of integers, or None. The axis or axes that should have a separate mean and variance for each index in the shape. For example, if shape is (None, 5) and axis=1, the layer will track 5 separate mean and variance values for the last axis. If axis is set to None, the layer will normalize all elements in the input by a scalar mean and variance. Defaults to -1, where the last axis of the input is assumed to be a feature dimension and is normalized per index. Note that in the specific case of batched scalar inputs where the only axis is the batch axis, the default will normalize each index in the batch separately. In this case, consider passing axis=None.
mean
The mean value(s) to use during normalization. The passed value(s) will be broadcast to the shape of the kept axes above; if the value(s) cannot be broadcast, an error will be raised when this layer's build() method is called.
variance
The variance value(s) to use during normalization. The passed value(s) will be broadcast to the shape of the kept axes above; if the value(s) cannot be broadcast, an error will be raised when this layer's build() method is called.

Examples:

Calculate a global mean and variance by analyzing the dataset in adapt().

>>> adapt_data = np.array([1., 2., 3., 4., 5.], dtype='float32')
>>> input_data = np.array([1., 2., 3.], dtype='float32')
>>> layer = tf.keras.layers.Normalization(axis=None)
>>> layer.adapt(adapt_data)
>>> layer(input_data)
<tf.Tensor: shape=(3,), dtype=float32, numpy=
array([-1.4142135, -0.70710677, 0.], dtype=float32)>

Calculate a mean and variance for each index on the last axis.

>>> adapt_data = np.array([[0., 7., 4.],
...                        [2., 9., 6.],
...                        [0., 7., 4.],
...                        [2., 9., 6.]], dtype='float32')
>>> input_data = np.array([[0., 7., 4.]], dtype='float32')
>>> layer = tf.keras.layers.Normalization(axis=-1)
>>> layer.adapt(adapt_data)
>>> layer(input_data)
<tf.Tensor: shape=(1, 3), dtype=float32, numpy=
array([0., 0., 0.], dtype=float32)>

Pass the mean and variance directly.

>>> input_data = np.array([[1.], [2.], [3.]], dtype='float32')
>>> layer = tf.keras.layers.Normalization(mean=3., variance=2.)
>>> layer(input_data)
<tf.Tensor: shape=(3, 1), dtype=float32, numpy=
array([[-1.4142135 ],
       [-0.70710677],
       [ 0.        ]], dtype=float32)>
Expand source code
class Normalization(base_preprocessing_layer.PreprocessingLayer):
  """Feature-wise normalization of the data.

  This layer will coerce its inputs into a distribution centered around
  0 with standard deviation 1. It accomplishes this by precomputing the mean and
  variance of the data, and calling `(input - mean) / sqrt(var)` at runtime.

  What happens in `adapt()`: Compute mean and variance of the data and store
  them as the layer's weights. `adapt()` should be called before `fit()`,
  `evaluate()`, or `predict()`.

  Args:
      axis: Integer, tuple of integers, or None. The axis or axes that should
        have a separate mean and variance for each index in the shape. For
        example, if shape is `(None, 5)` and `axis=1`, the layer will track 5
        separate mean and variance values for the last axis. If `axis` is set to
        `None`, the layer will normalize all elements in the input by a scalar
        mean and variance. Defaults to -1, where the last axis of the input is
        assumed to be a feature dimension and is normalized per index. Note that
        in the specific case of batched scalar inputs where the only axis is the
        batch axis, the default will normalize each index in the batch
        separately. In this case, consider passing `axis=None`.
      mean: The mean value(s) to use during normalization. The passed value(s)
        will be broadcast to the shape of the kept axes above; if the value(s)
        cannot be broadcast, an error will be raised when this layer's `build()`
        method is called.
      variance: The variance value(s) to use during normalization. The passed
        value(s) will be broadcast to the shape of the kept axes above; if the
        value(s) cannot be broadcast, an error will be raised when this layer's
        `build()` method is called.

  Examples:

  Calculate a global mean and variance by analyzing the dataset in `adapt()`.

  >>> adapt_data = np.array([1., 2., 3., 4., 5.], dtype='float32')
  >>> input_data = np.array([1., 2., 3.], dtype='float32')
  >>> layer = tf.keras.layers.Normalization(axis=None)
  >>> layer.adapt(adapt_data)
  >>> layer(input_data)
  <tf.Tensor: shape=(3,), dtype=float32, numpy=
  array([-1.4142135, -0.70710677, 0.], dtype=float32)>

  Calculate a mean and variance for each index on the last axis.

  >>> adapt_data = np.array([[0., 7., 4.],
  ...                        [2., 9., 6.],
  ...                        [0., 7., 4.],
  ...                        [2., 9., 6.]], dtype='float32')
  >>> input_data = np.array([[0., 7., 4.]], dtype='float32')
  >>> layer = tf.keras.layers.Normalization(axis=-1)
  >>> layer.adapt(adapt_data)
  >>> layer(input_data)
  <tf.Tensor: shape=(1, 3), dtype=float32, numpy=
  array([0., 0., 0.], dtype=float32)>

  Pass the mean and variance directly.

  >>> input_data = np.array([[1.], [2.], [3.]], dtype='float32')
  >>> layer = tf.keras.layers.Normalization(mean=3., variance=2.)
  >>> layer(input_data)
  <tf.Tensor: shape=(3, 1), dtype=float32, numpy=
  array([[-1.4142135 ],
         [-0.70710677],
         [ 0.        ]], dtype=float32)>
  """

  def __init__(self, axis=-1, mean=None, variance=None, **kwargs):
    super().__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('Normalization').set(True)

    # Standardize `axis` to a tuple.
    if axis is None:
      axis = ()
    elif isinstance(axis, int):
      axis = (axis,)
    else:
      axis = tuple(axis)
    self.axis = axis

    # Set `mean` and `variance` if passed.
    if isinstance(mean, tf.Variable):
      raise ValueError('Normalization does not support passing a Variable '
                       'for the `mean` init arg.')
    if isinstance(variance, tf.Variable):
      raise ValueError('Normalization does not support passing a Variable '
                       'for the `variance` init arg.')
    if (mean is not None) != (variance is not None):
      raise ValueError(
          'When setting values directly, both `mean` and `variance` '
          'must be set. Got mean: {} and variance: {}'.format(mean, variance))
    self.input_mean = mean
    self.input_variance = variance

  def build(self, input_shape):
    super().build(input_shape)

    if (isinstance(input_shape, (list, tuple)) and
        all(isinstance(shape, tf.TensorShape) for shape in input_shape)):
      raise ValueError('Normalization only accepts a single input. If you are '
                       'passing a python list or tuple as a single input, '
                       'please convert to a numpy array or `tf.Tensor`.')

    input_shape = tf.TensorShape(input_shape).as_list()
    ndim = len(input_shape)

    if any(a < -ndim or a >= ndim for a in self.axis):
      raise ValueError('All `axis` values must be in the range [-ndim, ndim). '
                       'Found ndim: `{}`, axis: {}'.format(ndim, self.axis))

    # Axes to be kept, replacing negative values with positive equivalents.
    # Sorted to avoid transposing axes.
    self._keep_axis = sorted([d if d >= 0 else d + ndim for d in self.axis])
    # All axes to be kept should have known shape.
    for d in self._keep_axis:
      if input_shape[d] is None:
        raise ValueError(
            'All `axis` values to be kept must have known shape. Got axis: {}, '
            'input shape: {}, with unknown axis at index: {}'.format(
                self.axis, input_shape, d))
    # Axes to be reduced.
    self._reduce_axis = [d for d in range(ndim) if d not in self._keep_axis]
    # 1 if an axis should be reduced, 0 otherwise.
    self._reduce_axis_mask = [
        0 if d in self._keep_axis else 1 for d in range(ndim)
    ]
    # Broadcast any reduced axes.
    self._broadcast_shape = [
        input_shape[d] if d in self._keep_axis else 1 for d in range(ndim)
    ]
    mean_and_var_shape = tuple(input_shape[d] for d in self._keep_axis)

    if self.input_mean is None:
      self.adapt_mean = self.add_weight(
          name='mean',
          shape=mean_and_var_shape,
          dtype=self.dtype,
          initializer='zeros',
          trainable=False)
      self.adapt_variance = self.add_weight(
          name='variance',
          shape=mean_and_var_shape,
          dtype=self.dtype,
          initializer='ones',
          trainable=False)
      self.count = self.add_weight(
          name='count',
          shape=(),
          dtype=tf.int64,
          initializer='zeros',
          trainable=False)
      self.finalize_state()
    else:
      # In the no adapt case, make constant tensors for mean and variance with
      # proper broadcast shape for use during call.
      mean = self.input_mean * np.ones(mean_and_var_shape)
      variance = self.input_variance * np.ones(mean_and_var_shape)
      mean = tf.reshape(mean, self._broadcast_shape)
      variance = tf.reshape(variance, self._broadcast_shape)
      self.mean = tf.cast(mean, self.compute_dtype)
      self.variance = tf.cast(variance, self.compute_dtype)

  def update_state(self, data):
    if self.input_mean is not None:
      raise ValueError(
          'Cannot `adapt` a Normalization layer that is initialized with '
          'static `mean` and `variance`, you passed mean {} and variance {}.'
          .format(self.input_mean, self.input_variance))

    if not self.built:
      raise RuntimeError('`build` must be called before `update_state`.')

    data = self._standardize_inputs(data)
    data = tf.cast(data, self.adapt_mean.dtype)
    batch_mean, batch_variance = tf.nn.moments(data, axes=self._reduce_axis)
    batch_shape = tf.shape(data, out_type=self.count.dtype)
    if self._reduce_axis:
      batch_reduce_shape = tf.gather(batch_shape, self._reduce_axis)
      batch_count = tf.reduce_prod(batch_reduce_shape)
    else:
      batch_count = 1

    total_count = batch_count + self.count
    batch_weight = (
        tf.cast(batch_count, dtype=self.dtype) /
        tf.cast(total_count, dtype=self.dtype))
    existing_weight = 1. - batch_weight

    total_mean = self.adapt_mean * existing_weight + batch_mean * batch_weight
    # The variance is computed using the lack-of-fit sum of squares
    # formula (see https://en.wikipedia.org/wiki/Lack-of-fit_sum_of_squares).
    total_variance = ((self.adapt_variance +
                       (self.adapt_mean - total_mean)**2) * existing_weight +
                      (batch_variance +
                       (batch_mean - total_mean)**2) * batch_weight)
    self.adapt_mean.assign(total_mean)
    self.adapt_variance.assign(total_variance)
    self.count.assign(total_count)

  def reset_state(self):  # pylint: disable=method-hidden
    if self.input_mean is not None or not self.built:
      return

    self.adapt_mean.assign(tf.zeros_like(self.adapt_mean))
    self.adapt_variance.assign(tf.ones_like(self.adapt_variance))
    self.count.assign(tf.zeros_like(self.count))

  def finalize_state(self):
    if self.input_mean is not None or not self.built:
      return

    # In the adapt case, we make constant tensors for mean and variance with
    # proper broadcast shape and dtype each time `finalize_state` is called.
    self.mean = tf.reshape(self.adapt_mean, self._broadcast_shape)
    self.mean = tf.cast(self.mean, self.compute_dtype)
    self.variance = tf.reshape(self.adapt_variance, self._broadcast_shape)
    self.variance = tf.cast(self.variance, self.compute_dtype)

  def call(self, inputs):
    inputs = self._standardize_inputs(inputs)
    # The base layer automatically casts floating-point inputs, but we
    # explicitly cast here to also allow integer inputs to be passed
    inputs = tf.cast(inputs, self.compute_dtype)
    return ((inputs - self.mean) /
            tf.maximum(tf.sqrt(self.variance), backend.epsilon()))

  def compute_output_shape(self, input_shape):
    return input_shape

  def compute_output_signature(self, input_spec):
    return input_spec

  def get_config(self):
    config = super().get_config()
    config.update({
        'axis': self.axis,
        'mean': self._convert_to_list(self.input_mean),
        'variance': self._convert_to_list(self.input_variance),
    })
    return config

  def _standardize_inputs(self, inputs):
    inputs = tf.convert_to_tensor(inputs)
    if inputs.dtype != self.dtype:
      inputs = tf.cast(inputs, self.dtype)
    return inputs

  def _convert_to_list(self, inputs):
    if tf.is_tensor(inputs):
      inputs = inputs.numpy()
    if isinstance(inputs, (np.ndarray)):
      inputs = inputs.tolist()
      inputs = list(inputs)
    return inputs

Ancestors

Inherited members

class PReLU (alpha_initializer='zeros', alpha_regularizer=None, alpha_constraint=None, shared_axes=None, **kwargs)

Parametric Rectified Linear Unit.

It follows:

  f(x) = alpha * x for x < 0
  f(x) = x for x >= 0

where alpha is a learned array with the same shape as x.

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

alpha_initializer
Initializer function for the weights.
alpha_regularizer
Regularizer for the weights.
alpha_constraint
Constraint for the weights.
shared_axes
The axes along which to share learnable parameters for the activation function. For example, if the incoming feature maps are from a 2D convolution with output shape (batch, height, width, channels), and you wish to share parameters across space so that each filter only has one set of parameters, set shared_axes=[1, 2].
Expand source code
class PReLU(Layer):
  """Parametric Rectified Linear Unit.

  It follows:

  ```
    f(x) = alpha * x for x < 0
    f(x) = x for x >= 0
  ```

  where `alpha` is a learned array with the same shape as x.

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    alpha_initializer: Initializer function for the weights.
    alpha_regularizer: Regularizer for the weights.
    alpha_constraint: Constraint for the weights.
    shared_axes: The axes along which to share learnable
      parameters for the activation function.
      For example, if the incoming feature maps
      are from a 2D convolution
      with output shape `(batch, height, width, channels)`,
      and you wish to share parameters across space
      so that each filter only has one set of parameters,
      set `shared_axes=[1, 2]`.
  """

  def __init__(self,
               alpha_initializer='zeros',
               alpha_regularizer=None,
               alpha_constraint=None,
               shared_axes=None,
               **kwargs):
    super(PReLU, self).__init__(**kwargs)
    self.supports_masking = True
    self.alpha_initializer = initializers.get(alpha_initializer)
    self.alpha_regularizer = regularizers.get(alpha_regularizer)
    self.alpha_constraint = constraints.get(alpha_constraint)
    if shared_axes is None:
      self.shared_axes = None
    elif not isinstance(shared_axes, (list, tuple)):
      self.shared_axes = [shared_axes]
    else:
      self.shared_axes = list(shared_axes)

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    param_shape = list(input_shape[1:])
    if self.shared_axes is not None:
      for i in self.shared_axes:
        param_shape[i - 1] = 1
    self.alpha = self.add_weight(
        shape=param_shape,
        name='alpha',
        initializer=self.alpha_initializer,
        regularizer=self.alpha_regularizer,
        constraint=self.alpha_constraint)
    # Set input spec
    axes = {}
    if self.shared_axes:
      for i in range(1, len(input_shape)):
        if i not in self.shared_axes:
          axes[i] = input_shape[i]
    self.input_spec = InputSpec(ndim=len(input_shape), axes=axes)
    self.built = True

  def call(self, inputs):
    pos = backend.relu(inputs)
    neg = -self.alpha * backend.relu(-inputs)
    return pos + neg

  def get_config(self):
    config = {
        'alpha_initializer': initializers.serialize(self.alpha_initializer),
        'alpha_regularizer': regularizers.serialize(self.alpha_regularizer),
        'alpha_constraint': constraints.serialize(self.alpha_constraint),
        'shared_axes': self.shared_axes
    }
    base_config = super(PReLU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Permute (dims, **kwargs)

Permutes the dimensions of the input according to a given pattern.

Useful e.g. connecting RNNs and convnets.

Example:

model = Sequential()
model.add(Permute((2, 1), input_shape=(10, 64)))
# now: model.output_shape == (None, 64, 10)
# note: `None` is the batch dimension

Args

dims
Tuple of integers. Permutation pattern does not include the samples dimension. Indexing starts at 1. For instance, (2, 1) permutes the first and second dimensions of the input.

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same as the input shape, but with the dimensions re-ordered according to the specified pattern.

Expand source code
class Permute(Layer):
  """Permutes the dimensions of the input according to a given pattern.

  Useful e.g. connecting RNNs and convnets.

  Example:

  ```python
  model = Sequential()
  model.add(Permute((2, 1), input_shape=(10, 64)))
  # now: model.output_shape == (None, 64, 10)
  # note: `None` is the batch dimension
  ```

  Args:
    dims: Tuple of integers. Permutation pattern does not include the
      samples dimension. Indexing starts at 1.
      For instance, `(2, 1)` permutes the first and second dimensions
      of the input.

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same as the input shape, but with the dimensions re-ordered according
    to the specified pattern.
  """

  def __init__(self, dims, **kwargs):
    super(Permute, self).__init__(**kwargs)
    self.dims = tuple(dims)
    if sorted(dims) != list(range(1, len(dims) + 1)):
      raise ValueError(
          'Invalid permutation `dims` for Permute Layer: %s. '
          'The set of indices in `dims` must be consecutive and start from 1.' %
          (dims,))
    self.input_spec = InputSpec(ndim=len(self.dims) + 1)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    output_shape = copy.copy(input_shape)
    for i, dim in enumerate(self.dims):
      target_dim = input_shape[dim]
      output_shape[i + 1] = target_dim
    return tf.TensorShape(output_shape)

  def call(self, inputs):
    return tf.transpose(inputs, perm=(0,) + self.dims)

  def get_config(self):
    config = {'dims': self.dims}
    base_config = super(Permute, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RNN (cell, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False, time_major=False, **kwargs)

Base class for recurrent layers.

See the Keras RNN API guide for details about the usage of RNN API.

Args

cell
A RNN cell instance or a list of RNN cell instances. A RNN cell is a class that has: - A call(input_at_t, states_at_t) method, returning (output_at_t, states_at_t_plus_1). The call method of the cell can also take the optional argument constants, see section "Note on passing external constants" below. - A state_size attribute. This can be a single integer (single state) in which case it is the size of the recurrent state. This can also be a list/tuple of integers (one size per state). The state_size can also be TensorShape or tuple/list of TensorShape, to represent high dimension state. - A output_size attribute. This can be a single integer or a TensorShape, which represent the shape of the output. For backward compatible reason, if this attribute is not available for the cell, the value will be inferred by the first element of the state_size. - A get_initial_state(inputs=None, batch_size=None, dtype=None) method that creates a tensor meant to be fed to call() as the initial state, if the user didn't specify any initial state via other means. The returned initial state should have a shape of [batch_size, cell.state_size]. The cell might choose to create a tensor full of zeros, or full of other values based on the cell's implementation. inputs is the input tensor to the RNN layer, which should contain the batch size as its shape[0], and also dtype. Note that the shape[0] might be None during the graph construction. Either the inputs or the pair of batch_size and dtype are provided. batch_size is a scalar tensor that represents the batch size of the inputs. dtype is tf.DType that represents the dtype of the inputs. For backward compatibility, if this method is not implemented by the cell, the RNN layer will create a zero filled tensor with the size of [batch_size, cell.state_size]. In the case that cell is a list of RNN cell instances, the cells will be stacked on top of each other in the RNN, resulting in an efficient stacked RNN.
return_sequences
Boolean (default False). Whether to return the last output in the output sequence, or the full sequence.
return_state
Boolean (default False). Whether to return the last state in addition to the output.
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
unroll
Boolean (default False). If True, the network will be unrolled, else a symbolic loop will be used. Unrolling can speed-up a RNN, although it tends to be more memory-intensive. Unrolling is only suitable for short sequences.
time_major
The shape format of the inputs and outputs tensors. If True, the inputs and outputs will be in shape (timesteps, batch, …), whereas in the False case, it will be (batch, timesteps, …). Using time_major = True is a bit more efficient because it avoids transposes at the beginning and end of the RNN calculation. However, most TensorFlow data is batch-major, so by default this function accepts input and emits output in batch-major form.
zero_output_for_mask
Boolean (default False). Whether the output should use zeros for the masked timesteps. Note that this field is only used when return_sequences is True and mask is provided. It can useful if you want to reuse the raw output sequence of the RNN without interference from the masked timesteps, eg, merging bidirectional RNNs.

Call arguments: inputs: Input tensor. mask: Binary tensor of shape [batch_size, timesteps] indicating whether a given timestep should be masked. An individual True entry indicates that the corresponding timestep should be utilized, while a False entry indicates that the corresponding timestep should be ignored. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is for use with cells that use dropout. initial_state: List of initial state tensors to be passed to the first call of the cell. constants: List of constant tensors to be passed to the cell at each timestep.

Input shape: N-D tensor with shape [batch_size, timesteps, …] or [timesteps, batch_size, …] when time_major is True.

Output shape: - If return_state: a list of tensors. The first tensor is the output. The remaining tensors are the last states, each with shape [batch_size, state_size], where state_size could be a high dimension tensor shape. - If return_sequences: N-D tensor with shape [batch_size, timesteps, output_size], where output_size could be a high dimension tensor shape, or [timesteps, batch_size, output_size] when time_major is True. - Else, N-D tensor with shape [batch_size, output_size], where output_size could be a high dimension tensor shape.

Masking

This layer supports masking for input data with a variable number of timesteps. To introduce masks to your data, use an [tf.keras.layers.Embedding] layer with the mask_zero parameter set to True.

Note on using statefulness in RNNs: You can set RNN layers to be 'stateful', which means that the states computed for the samples in one batch will be reused as initial states for the samples in the next batch. This assumes a one-to-one mapping between samples in different successive batches.

To enable statefulness: - Specify stateful=True in the layer constructor. - Specify a fixed batch size for your model, by passing If sequential model: batch_input_shape=(...) to the first layer in your model. Else for functional model with 1 or more Input layers: batch_shape=(...) to all the first layers in your model. This is the expected shape of your inputs including the batch size. It should be a tuple of integers, e.g. (32, 10, 100). - Specify shuffle=False when calling fit().

To reset the states of your model, call .reset_states() on either a specific layer, or on your entire model.

Note on specifying the initial state of RNNs: You can specify the initial state of RNN layers symbolically by calling them with the keyword argument initial_state. The value of initial_state should be a tensor or list of tensors representing the initial state of the RNN layer.

You can specify the initial state of RNN layers numerically by calling reset_states with the keyword argument states. The value of states should be a numpy array or list of numpy arrays representing the initial state of the RNN layer.

Note on passing external constants to RNNs: You can pass "external" constants to the cell using the constants keyword argument of RNN.__call__ (as well as RNN.call()) method. This requires that the cell.call method accepts the same keyword argument constants. Such constants can be used to condition the cell transformation on additional static inputs (not changing over time), a.k.a. an attention mechanism.

Examples:

# First, let's define a RNN Cell, as a layer subclass.

class MinimalRNNCell(keras.layers.Layer):

    def __init__(self, units, **kwargs):
        self.units = units
        self.state_size = units
        super(MinimalRNNCell, self).__init__(**kwargs)

    def build(self, input_shape):
        self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                                      initializer='uniform',
                                      name='kernel')
        self.recurrent_kernel = self.add_weight(
            shape=(self.units, self.units),
            initializer='uniform',
            name='recurrent_kernel')
        self.built = True

    def call(self, inputs, states):
        prev_output = states[0]
        h = backend.dot(inputs, self.kernel)
        output = h + backend.dot(prev_output, self.recurrent_kernel)
        return output, [output]

# Let's use this cell in a RNN layer:

cell = MinimalRNNCell(32)
x = keras.Input((None, 5))
layer = RNN(cell)
y = layer(x)

# Here's how to use the cell to build a stacked RNN:

cells = [MinimalRNNCell(32), MinimalRNNCell(64)]
x = keras.Input((None, 5))
layer = RNN(cells)
y = layer(x)
Expand source code
class RNN(Layer):
  """Base class for recurrent layers.

  See [the Keras RNN API guide](https://www.tensorflow.org/guide/keras/rnn)
  for details about the usage of RNN API.

  Args:
    cell: A RNN cell instance or a list of RNN cell instances.
      A RNN cell is a class that has:
      - A `call(input_at_t, states_at_t)` method, returning
        `(output_at_t, states_at_t_plus_1)`. The call method of the
        cell can also take the optional argument `constants`, see
        section "Note on passing external constants" below.
      - A `state_size` attribute. This can be a single integer
        (single state) in which case it is the size of the recurrent
        state. This can also be a list/tuple of integers (one size per state).
        The `state_size` can also be TensorShape or tuple/list of
        TensorShape, to represent high dimension state.
      - A `output_size` attribute. This can be a single integer or a
        TensorShape, which represent the shape of the output. For backward
        compatible reason, if this attribute is not available for the
        cell, the value will be inferred by the first element of the
        `state_size`.
      - A `get_initial_state(inputs=None, batch_size=None, dtype=None)`
        method that creates a tensor meant to be fed to `call()` as the
        initial state, if the user didn't specify any initial state via other
        means. The returned initial state should have a shape of
        [batch_size, cell.state_size]. The cell might choose to create a
        tensor full of zeros, or full of other values based on the cell's
        implementation.
        `inputs` is the input tensor to the RNN layer, which should
        contain the batch size as its shape[0], and also dtype. Note that
        the shape[0] might be `None` during the graph construction. Either
        the `inputs` or the pair of `batch_size` and `dtype` are provided.
        `batch_size` is a scalar tensor that represents the batch size
        of the inputs. `dtype` is `tf.DType` that represents the dtype of
        the inputs.
        For backward compatibility, if this method is not implemented
        by the cell, the RNN layer will create a zero filled tensor with the
        size of [batch_size, cell.state_size].
      In the case that `cell` is a list of RNN cell instances, the cells
      will be stacked on top of each other in the RNN, resulting in an
      efficient stacked RNN.
    return_sequences: Boolean (default `False`). Whether to return the last
      output in the output sequence, or the full sequence.
    return_state: Boolean (default `False`). Whether to return the last state
      in addition to the output.
    go_backwards: Boolean (default `False`).
      If True, process the input sequence backwards and return the
      reversed sequence.
    stateful: Boolean (default `False`). If True, the last state
      for each sample at index i in a batch will be used as initial
      state for the sample of index i in the following batch.
    unroll: Boolean (default `False`).
      If True, the network will be unrolled, else a symbolic loop will be used.
      Unrolling can speed-up a RNN, although it tends to be more
      memory-intensive. Unrolling is only suitable for short sequences.
    time_major: The shape format of the `inputs` and `outputs` tensors.
      If True, the inputs and outputs will be in shape
      `(timesteps, batch, ...)`, whereas in the False case, it will be
      `(batch, timesteps, ...)`. Using `time_major = True` is a bit more
      efficient because it avoids transposes at the beginning and end of the
      RNN calculation. However, most TensorFlow data is batch-major, so by
      default this function accepts input and emits output in batch-major
      form.
    zero_output_for_mask: Boolean (default `False`).
      Whether the output should use zeros for the masked timesteps. Note that
      this field is only used when `return_sequences` is True and mask is
      provided. It can useful if you want to reuse the raw output sequence of
      the RNN without interference from the masked timesteps, eg, merging
      bidirectional RNNs.

  Call arguments:
    inputs: Input tensor.
    mask: Binary tensor of shape `[batch_size, timesteps]` indicating whether
      a given timestep should be masked. An individual `True` entry indicates
      that the corresponding timestep should be utilized, while a `False`
      entry indicates that the corresponding timestep should be ignored.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is for use with cells that use dropout.
    initial_state: List of initial state tensors to be passed to the first
      call of the cell.
    constants: List of constant tensors to be passed to the cell at each
      timestep.

  Input shape:
    N-D tensor with shape `[batch_size, timesteps, ...]` or
    `[timesteps, batch_size, ...]` when time_major is True.

  Output shape:
    - If `return_state`: a list of tensors. The first tensor is
      the output. The remaining tensors are the last states,
      each with shape `[batch_size, state_size]`, where `state_size` could
      be a high dimension tensor shape.
    - If `return_sequences`: N-D tensor with shape
      `[batch_size, timesteps, output_size]`, where `output_size` could
      be a high dimension tensor shape, or
      `[timesteps, batch_size, output_size]` when `time_major` is True.
    - Else, N-D tensor with shape `[batch_size, output_size]`, where
      `output_size` could be a high dimension tensor shape.

  Masking:
    This layer supports masking for input data with a variable number
    of timesteps. To introduce masks to your data,
    use an [tf.keras.layers.Embedding] layer with the `mask_zero` parameter
    set to `True`.

  Note on using statefulness in RNNs:
    You can set RNN layers to be 'stateful', which means that the states
    computed for the samples in one batch will be reused as initial states
    for the samples in the next batch. This assumes a one-to-one mapping
    between samples in different successive batches.

    To enable statefulness:
      - Specify `stateful=True` in the layer constructor.
      - Specify a fixed batch size for your model, by passing
        If sequential model:
          `batch_input_shape=(...)` to the first layer in your model.
        Else for functional model with 1 or more Input layers:
          `batch_shape=(...)` to all the first layers in your model.
        This is the expected shape of your inputs
        *including the batch size*.
        It should be a tuple of integers, e.g. `(32, 10, 100)`.
      - Specify `shuffle=False` when calling `fit()`.

    To reset the states of your model, call `.reset_states()` on either
    a specific layer, or on your entire model.

  Note on specifying the initial state of RNNs:
    You can specify the initial state of RNN layers symbolically by
    calling them with the keyword argument `initial_state`. The value of
    `initial_state` should be a tensor or list of tensors representing
    the initial state of the RNN layer.

    You can specify the initial state of RNN layers numerically by
    calling `reset_states` with the keyword argument `states`. The value of
    `states` should be a numpy array or list of numpy arrays representing
    the initial state of the RNN layer.

  Note on passing external constants to RNNs:
    You can pass "external" constants to the cell using the `constants`
    keyword argument of `RNN.__call__` (as well as `RNN.call`) method. This
    requires that the `cell.call` method accepts the same keyword argument
    `constants`. Such constants can be used to condition the cell
    transformation on additional static inputs (not changing over time),
    a.k.a. an attention mechanism.

  Examples:

  ```python
  # First, let's define a RNN Cell, as a layer subclass.

  class MinimalRNNCell(keras.layers.Layer):

      def __init__(self, units, **kwargs):
          self.units = units
          self.state_size = units
          super(MinimalRNNCell, self).__init__(**kwargs)

      def build(self, input_shape):
          self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
                                        initializer='uniform',
                                        name='kernel')
          self.recurrent_kernel = self.add_weight(
              shape=(self.units, self.units),
              initializer='uniform',
              name='recurrent_kernel')
          self.built = True

      def call(self, inputs, states):
          prev_output = states[0]
          h = backend.dot(inputs, self.kernel)
          output = h + backend.dot(prev_output, self.recurrent_kernel)
          return output, [output]

  # Let's use this cell in a RNN layer:

  cell = MinimalRNNCell(32)
  x = keras.Input((None, 5))
  layer = RNN(cell)
  y = layer(x)

  # Here's how to use the cell to build a stacked RNN:

  cells = [MinimalRNNCell(32), MinimalRNNCell(64)]
  x = keras.Input((None, 5))
  layer = RNN(cells)
  y = layer(x)
  ```
  """

  def __init__(self,
               cell,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               unroll=False,
               time_major=False,
               **kwargs):
    if isinstance(cell, (list, tuple)):
      cell = StackedRNNCells(cell)
    if not 'call' in dir(cell):
      raise ValueError('`cell` should have a `call` method. '
                       'The RNN was passed:', cell)
    if not 'state_size' in dir(cell):
      raise ValueError('The RNN cell should have '
                       'an attribute `state_size` '
                       '(tuple of integers, '
                       'one integer per RNN state).')
    # If True, the output for masked timestep will be zeros, whereas in the
    # False case, output from previous timestep is returned for masked timestep.
    self.zero_output_for_mask = kwargs.pop('zero_output_for_mask', False)

    if 'input_shape' not in kwargs and (
        'input_dim' in kwargs or 'input_length' in kwargs):
      input_shape = (kwargs.pop('input_length', None),
                     kwargs.pop('input_dim', None))
      kwargs['input_shape'] = input_shape

    super(RNN, self).__init__(**kwargs)
    self.cell = cell
    self.return_sequences = return_sequences
    self.return_state = return_state
    self.go_backwards = go_backwards
    self.stateful = stateful
    self.unroll = unroll
    self.time_major = time_major

    self.supports_masking = True
    # The input shape is unknown yet, it could have nested tensor inputs, and
    # the input spec will be the list of specs for nested inputs, the structure
    # of the input_spec will be the same as the input.
    self.input_spec = None
    self.state_spec = None
    self._states = None
    self.constants_spec = None
    self._num_constants = 0

    if stateful:
      if tf.distribute.has_strategy():
        raise ValueError('RNNs with stateful=True not yet supported with '
                         'tf.distribute.Strategy.')

  @property
  def _use_input_spec_as_call_signature(self):
    if self.unroll:
      # When the RNN layer is unrolled, the time step shape cannot be unknown.
      # The input spec does not define the time step (because this layer can be
      # called with any time step value, as long as it is not None), so it
      # cannot be used as the call function signature when saving to SavedModel.
      return False
    return super(RNN, self)._use_input_spec_as_call_signature

  @property
  def states(self):
    if self._states is None:
      state = tf.nest.map_structure(lambda _: None, self.cell.state_size)
      return state if tf.nest.is_nested(self.cell.state_size) else [state]
    return self._states

  @states.setter
  # Automatic tracking catches "self._states" which adds an extra weight and
  # breaks HDF5 checkpoints.
  @tf.__internal__.tracking.no_automatic_dependency_tracking
  def states(self, states):
    self._states = states

  def compute_output_shape(self, input_shape):
    if isinstance(input_shape, list):
      input_shape = input_shape[0]
    # Check whether the input shape contains any nested shapes. It could be
    # (tensor_shape(1, 2), tensor_shape(3, 4)) or (1, 2, 3) which is from numpy
    # inputs.
    try:
      input_shape = tf.TensorShape(input_shape)
    except (ValueError, TypeError):
      # A nested tensor input
      input_shape = tf.nest.flatten(input_shape)[0]

    batch = input_shape[0]
    time_step = input_shape[1]
    if self.time_major:
      batch, time_step = time_step, batch

    if _is_multiple_state(self.cell.state_size):
      state_size = self.cell.state_size
    else:
      state_size = [self.cell.state_size]

    def _get_output_shape(flat_output_size):
      output_dim = tf.TensorShape(flat_output_size).as_list()
      if self.return_sequences:
        if self.time_major:
          output_shape = tf.TensorShape(
              [time_step, batch] + output_dim)
        else:
          output_shape = tf.TensorShape(
              [batch, time_step] + output_dim)
      else:
        output_shape = tf.TensorShape([batch] + output_dim)
      return output_shape

    if getattr(self.cell, 'output_size', None) is not None:
      # cell.output_size could be nested structure.
      output_shape = tf.nest.flatten(tf.nest.map_structure(
          _get_output_shape, self.cell.output_size))
      output_shape = output_shape[0] if len(output_shape) == 1 else output_shape
    else:
      # Note that state_size[0] could be a tensor_shape or int.
      output_shape = _get_output_shape(state_size[0])

    if self.return_state:
      def _get_state_shape(flat_state):
        state_shape = [batch] + tf.TensorShape(flat_state).as_list()
        return tf.TensorShape(state_shape)
      state_shape = tf.nest.map_structure(_get_state_shape, state_size)
      return generic_utils.to_list(output_shape) + tf.nest.flatten(state_shape)
    else:
      return output_shape

  def compute_mask(self, inputs, mask):
    # Time step masks must be the same for each input.
    # This is because the mask for an RNN is of size [batch, time_steps, 1],
    # and specifies which time steps should be skipped, and a time step
    # must be skipped for all inputs.
    # TODO(scottzhu): Should we accept multiple different masks?
    mask = tf.nest.flatten(mask)[0]
    output_mask = mask if self.return_sequences else None
    if self.return_state:
      state_mask = [None for _ in self.states]
      return [output_mask] + state_mask
    else:
      return output_mask

  def build(self, input_shape):
    if isinstance(input_shape, list):
      input_shape = input_shape[0]
      # The input_shape here could be a nest structure.

    # do the tensor_shape to shapes here. The input could be single tensor, or a
    # nested structure of tensors.
    def get_input_spec(shape):
      """Convert input shape to InputSpec."""
      if isinstance(shape, tf.TensorShape):
        input_spec_shape = shape.as_list()
      else:
        input_spec_shape = list(shape)
      batch_index, time_step_index = (1, 0) if self.time_major else (0, 1)
      if not self.stateful:
        input_spec_shape[batch_index] = None
      input_spec_shape[time_step_index] = None
      return InputSpec(shape=tuple(input_spec_shape))

    def get_step_input_shape(shape):
      if isinstance(shape, tf.TensorShape):
        shape = tuple(shape.as_list())
      # remove the timestep from the input_shape
      return shape[1:] if self.time_major else (shape[0],) + shape[2:]

    # Check whether the input shape contains any nested shapes. It could be
    # (tensor_shape(1, 2), tensor_shape(3, 4)) or (1, 2, 3) which is from numpy
    # inputs.
    try:
      input_shape = tf.TensorShape(input_shape)
    except (ValueError, TypeError):
      # A nested tensor input
      pass

    if not tf.nest.is_nested(input_shape):
      # This indicates the there is only one input.
      if self.input_spec is not None:
        self.input_spec[0] = get_input_spec(input_shape)
      else:
        self.input_spec = [get_input_spec(input_shape)]
      step_input_shape = get_step_input_shape(input_shape)
    else:
      if self.input_spec is not None:
        self.input_spec[0] = tf.nest.map_structure(get_input_spec, input_shape)
      else:
        self.input_spec = generic_utils.to_list(
            tf.nest.map_structure(get_input_spec, input_shape))
      step_input_shape = tf.nest.map_structure(get_step_input_shape, input_shape)

    # allow cell (if layer) to build before we set or validate state_spec.
    if isinstance(self.cell, Layer) and not self.cell.built:
      with backend.name_scope(self.cell.name):
        self.cell.build(step_input_shape)
        self.cell.built = True

    # set or validate state_spec
    if _is_multiple_state(self.cell.state_size):
      state_size = list(self.cell.state_size)
    else:
      state_size = [self.cell.state_size]

    if self.state_spec is not None:
      # initial_state was passed in call, check compatibility
      self._validate_state_spec(state_size, self.state_spec)
    else:
      self.state_spec = [
          InputSpec(shape=[None] + tf.TensorShape(dim).as_list())
          for dim in state_size
      ]
    if self.stateful:
      self.reset_states()
    self.built = True

  @staticmethod
  def _validate_state_spec(cell_state_sizes, init_state_specs):
    """Validate the state spec between the initial_state and the state_size.

    Args:
      cell_state_sizes: list, the `state_size` attribute from the cell.
      init_state_specs: list, the `state_spec` from the initial_state that is
        passed in `call()`.

    Raises:
      ValueError: When initial state spec is not compatible with the state size.
    """
    validation_error = ValueError(
        'An `initial_state` was passed that is not compatible with '
        '`cell.state_size`. Received `state_spec`={}; '
        'however `cell.state_size` is '
        '{}'.format(init_state_specs, cell_state_sizes))
    flat_cell_state_sizes = tf.nest.flatten(cell_state_sizes)
    flat_state_specs = tf.nest.flatten(init_state_specs)

    if len(flat_cell_state_sizes) != len(flat_state_specs):
      raise validation_error
    for cell_state_spec, cell_state_size in zip(flat_state_specs,
                                                flat_cell_state_sizes):
      if not tf.TensorShape(
          # Ignore the first axis for init_state which is for batch
          cell_state_spec.shape[1:]).is_compatible_with(
              tf.TensorShape(cell_state_size)):
        raise validation_error

  @doc_controls.do_not_doc_inheritable
  def get_initial_state(self, inputs):
    get_initial_state_fn = getattr(self.cell, 'get_initial_state', None)

    if tf.nest.is_nested(inputs):
      # The input are nested sequences. Use the first element in the seq to get
      # batch size and dtype.
      inputs = tf.nest.flatten(inputs)[0]

    input_shape = tf.shape(inputs)
    batch_size = input_shape[1] if self.time_major else input_shape[0]
    dtype = inputs.dtype
    if get_initial_state_fn:
      init_state = get_initial_state_fn(
          inputs=None, batch_size=batch_size, dtype=dtype)
    else:
      init_state = _generate_zero_filled_state(batch_size, self.cell.state_size,
                                               dtype)
    # Keras RNN expect the states in a list, even if it's a single state tensor.
    if not tf.nest.is_nested(init_state):
      init_state = [init_state]
    # Force the state to be a list in case it is a namedtuple eg LSTMStateTuple.
    return list(init_state)

  def __call__(self, inputs, initial_state=None, constants=None, **kwargs):
    inputs, initial_state, constants = _standardize_args(inputs,
                                                         initial_state,
                                                         constants,
                                                         self._num_constants)

    if initial_state is None and constants is None:
      return super(RNN, self).__call__(inputs, **kwargs)

    # If any of `initial_state` or `constants` are specified and are Keras
    # tensors, then add them to the inputs and temporarily modify the
    # input_spec to include them.

    additional_inputs = []
    additional_specs = []
    if initial_state is not None:
      additional_inputs += initial_state
      self.state_spec = tf.nest.map_structure(
          lambda s: InputSpec(shape=backend.int_shape(s)), initial_state)
      additional_specs += self.state_spec
    if constants is not None:
      additional_inputs += constants
      self.constants_spec = [
          InputSpec(shape=backend.int_shape(constant)) for constant in constants
      ]
      self._num_constants = len(constants)
      additional_specs += self.constants_spec
    # additional_inputs can be empty if initial_state or constants are provided
    # but empty (e.g. the cell is stateless).
    flat_additional_inputs = tf.nest.flatten(additional_inputs)
    is_keras_tensor = backend.is_keras_tensor(
        flat_additional_inputs[0]) if flat_additional_inputs else True
    for tensor in flat_additional_inputs:
      if backend.is_keras_tensor(tensor) != is_keras_tensor:
        raise ValueError('The initial state or constants of an RNN'
                         ' layer cannot be specified with a mix of'
                         ' Keras tensors and non-Keras tensors'
                         ' (a "Keras tensor" is a tensor that was'
                         ' returned by a Keras layer, or by `Input`)')

    if is_keras_tensor:
      # Compute the full input spec, including state and constants
      full_input = [inputs] + additional_inputs
      if self.built:
        # Keep the input_spec since it has been populated in build() method.
        full_input_spec = self.input_spec + additional_specs
      else:
        # The original input_spec is None since there could be a nested tensor
        # input. Update the input_spec to match the inputs.
        full_input_spec = generic_utils.to_list(
            tf.nest.map_structure(lambda _: None, inputs)) + additional_specs
      # Perform the call with temporarily replaced input_spec
      self.input_spec = full_input_spec
      output = super(RNN, self).__call__(full_input, **kwargs)
      # Remove the additional_specs from input spec and keep the rest. It is
      # important to keep since the input spec was populated by build(), and
      # will be reused in the stateful=True.
      self.input_spec = self.input_spec[:-len(additional_specs)]
      return output
    else:
      if initial_state is not None:
        kwargs['initial_state'] = initial_state
      if constants is not None:
        kwargs['constants'] = constants
      return super(RNN, self).__call__(inputs, **kwargs)

  def call(self,
           inputs,
           mask=None,
           training=None,
           initial_state=None,
           constants=None):
    # The input should be dense, padded with zeros. If a ragged input is fed
    # into the layer, it is padded and the row lengths are used for masking.
    inputs, row_lengths = backend.convert_inputs_if_ragged(inputs)
    is_ragged_input = (row_lengths is not None)
    self._validate_args_if_ragged(is_ragged_input, mask)

    inputs, initial_state, constants = self._process_inputs(
        inputs, initial_state, constants)

    self._maybe_reset_cell_dropout_mask(self.cell)
    if isinstance(self.cell, StackedRNNCells):
      for cell in self.cell.cells:
        self._maybe_reset_cell_dropout_mask(cell)

    if mask is not None:
      # Time step masks must be the same for each input.
      # TODO(scottzhu): Should we accept multiple different masks?
      mask = tf.nest.flatten(mask)[0]

    if tf.nest.is_nested(inputs):
      # In the case of nested input, use the first element for shape check.
      input_shape = backend.int_shape(tf.nest.flatten(inputs)[0])
    else:
      input_shape = backend.int_shape(inputs)
    timesteps = input_shape[0] if self.time_major else input_shape[1]
    if self.unroll and timesteps is None:
      raise ValueError('Cannot unroll a RNN if the '
                       'time dimension is undefined. \n'
                       '- If using a Sequential model, '
                       'specify the time dimension by passing '
                       'an `input_shape` or `batch_input_shape` '
                       'argument to your first layer. If your '
                       'first layer is an Embedding, you can '
                       'also use the `input_length` argument.\n'
                       '- If using the functional API, specify '
                       'the time dimension by passing a `shape` '
                       'or `batch_shape` argument to your Input layer.')

    kwargs = {}
    if generic_utils.has_arg(self.cell.call, 'training'):
      kwargs['training'] = training

    # TF RNN cells expect single tensor as state instead of list wrapped tensor.
    is_tf_rnn_cell = getattr(self.cell, '_is_tf_rnn_cell', None) is not None
    # Use the __call__ function for callable objects, eg layers, so that it
    # will have the proper name scopes for the ops, etc.
    cell_call_fn = self.cell.__call__ if callable(self.cell) else self.cell.call
    if constants:
      if not generic_utils.has_arg(self.cell.call, 'constants'):
        raise ValueError('RNN cell does not support constants')

      def step(inputs, states):
        constants = states[-self._num_constants:]  # pylint: disable=invalid-unary-operand-type
        states = states[:-self._num_constants]  # pylint: disable=invalid-unary-operand-type

        states = states[0] if len(states) == 1 and is_tf_rnn_cell else states
        output, new_states = cell_call_fn(
            inputs, states, constants=constants, **kwargs)
        if not tf.nest.is_nested(new_states):
          new_states = [new_states]
        return output, new_states
    else:

      def step(inputs, states):
        states = states[0] if len(states) == 1 and is_tf_rnn_cell else states
        output, new_states = cell_call_fn(inputs, states, **kwargs)
        if not tf.nest.is_nested(new_states):
          new_states = [new_states]
        return output, new_states
    last_output, outputs, states = backend.rnn(
        step,
        inputs,
        initial_state,
        constants=constants,
        go_backwards=self.go_backwards,
        mask=mask,
        unroll=self.unroll,
        input_length=row_lengths if row_lengths is not None else timesteps,
        time_major=self.time_major,
        zero_output_for_mask=self.zero_output_for_mask)

    if self.stateful:
      updates = [
          tf.compat.v1.assign(self_state, state) for self_state, state in zip(
              tf.nest.flatten(self.states), tf.nest.flatten(states))
      ]
      self.add_update(updates)

    if self.return_sequences:
      output = backend.maybe_convert_to_ragged(
          is_ragged_input, outputs, row_lengths, go_backwards=self.go_backwards)
    else:
      output = last_output

    if self.return_state:
      if not isinstance(states, (list, tuple)):
        states = [states]
      else:
        states = list(states)
      return generic_utils.to_list(output) + states
    else:
      return output

  def _process_inputs(self, inputs, initial_state, constants):
    # input shape: `(samples, time (padded with zeros), input_dim)`
    # note that the .build() method of subclasses MUST define
    # self.input_spec and self.state_spec with complete input shapes.
    if (isinstance(inputs, collections.abc.Sequence)
        and not isinstance(inputs, tuple)):
      # get initial_state from full input spec
      # as they could be copied to multiple GPU.
      if not self._num_constants:
        initial_state = inputs[1:]
      else:
        initial_state = inputs[1:-self._num_constants]
        constants = inputs[-self._num_constants:]
      if len(initial_state) == 0:
        initial_state = None
      inputs = inputs[0]

    if self.stateful:
      if initial_state is not None:
        # When layer is stateful and initial_state is provided, check if the
        # recorded state is same as the default value (zeros). Use the recorded
        # state if it is not same as the default.
        non_zero_count = tf.add_n([tf.math.count_nonzero(s)
                                   for s in tf.nest.flatten(self.states)])
        # Set strict = True to keep the original structure of the state.
        initial_state = tf.compat.v1.cond(non_zero_count > 0,
                                          true_fn=lambda: self.states,
                                          false_fn=lambda: initial_state,
                                          strict=True)
      else:
        initial_state = self.states
    elif initial_state is None:
      initial_state = self.get_initial_state(inputs)

    if len(initial_state) != len(self.states):
      raise ValueError('Layer has ' + str(len(self.states)) +
                       ' states but was passed ' + str(len(initial_state)) +
                       ' initial states.')
    return inputs, initial_state, constants

  def _validate_args_if_ragged(self, is_ragged_input, mask):
    if not is_ragged_input:
      return

    if mask is not None:
      raise ValueError('The mask that was passed in was ' + str(mask) +
                       ' and cannot be applied to RaggedTensor inputs. Please '
                       'make sure that there is no mask passed in by upstream '
                       'layers.')
    if self.unroll:
      raise ValueError('The input received contains RaggedTensors and does '
                       'not support unrolling. Disable unrolling by passing '
                       '`unroll=False` in the RNN Layer constructor.')

  def _maybe_reset_cell_dropout_mask(self, cell):
    if isinstance(cell, DropoutRNNCellMixin):
      cell.reset_dropout_mask()
      cell.reset_recurrent_dropout_mask()

  def reset_states(self, states=None):
    """Reset the recorded states for the stateful RNN layer.

    Can only be used when RNN layer is constructed with `stateful` = `True`.
    Args:
      states: Numpy arrays that contains the value for the initial state, which
        will be feed to cell at the first time step. When the value is None,
        zero filled numpy array will be created based on the cell state size.

    Raises:
      AttributeError: When the RNN layer is not stateful.
      ValueError: When the batch size of the RNN layer is unknown.
      ValueError: When the input numpy array is not compatible with the RNN
        layer state, either size wise or dtype wise.
    """
    if not self.stateful:
      raise AttributeError('Layer must be stateful.')
    spec_shape = None
    if self.input_spec is not None:
      spec_shape = tf.nest.flatten(self.input_spec[0])[0].shape
    if spec_shape is None:
      # It is possible to have spec shape to be None, eg when construct a RNN
      # with a custom cell, or standard RNN layers (LSTM/GRU) which we only know
      # it has 3 dim input, but not its full shape spec before build().
      batch_size = None
    else:
      batch_size = spec_shape[1] if self.time_major else spec_shape[0]
    if not batch_size:
      raise ValueError('If a RNN is stateful, it needs to know '
                       'its batch size. Specify the batch size '
                       'of your input tensors: \n'
                       '- If using a Sequential model, '
                       'specify the batch size by passing '
                       'a `batch_input_shape` '
                       'argument to your first layer.\n'
                       '- If using the functional API, specify '
                       'the batch size by passing a '
                       '`batch_shape` argument to your Input layer.')
    # initialize state if None
    if tf.nest.flatten(self.states)[0] is None:
      if getattr(self.cell, 'get_initial_state', None):
        flat_init_state_values = tf.nest.flatten(self.cell.get_initial_state(
            inputs=None, batch_size=batch_size,
            dtype=self.dtype or backend.floatx()))
      else:
        flat_init_state_values = tf.nest.flatten(_generate_zero_filled_state(
            batch_size, self.cell.state_size, self.dtype or backend.floatx()))
      flat_states_variables = tf.nest.map_structure(
          backend.variable, flat_init_state_values)
      self.states = tf.nest.pack_sequence_as(self.cell.state_size,
                                             flat_states_variables)
      if not tf.nest.is_nested(self.states):
        self.states = [self.states]
    elif states is None:
      for state, size in zip(tf.nest.flatten(self.states),
                             tf.nest.flatten(self.cell.state_size)):
        backend.set_value(
            state,
            np.zeros([batch_size] + tf.TensorShape(size).as_list()))
    else:
      flat_states = tf.nest.flatten(self.states)
      flat_input_states = tf.nest.flatten(states)
      if len(flat_input_states) != len(flat_states):
        raise ValueError('Layer ' + self.name + ' expects ' +
                         str(len(flat_states)) + ' states, '
                         'but it received ' + str(len(flat_input_states)) +
                         ' state values. Input received: ' + str(states))
      set_value_tuples = []
      for i, (value, state) in enumerate(zip(flat_input_states,
                                             flat_states)):
        if value.shape != state.shape:
          raise ValueError(
              'State ' + str(i) + ' is incompatible with layer ' +
              self.name + ': expected shape=' + str(
                  (batch_size, state)) + ', found shape=' + str(value.shape))
        set_value_tuples.append((state, value))
      backend.batch_set_value(set_value_tuples)

  def get_config(self):
    config = {
        'return_sequences': self.return_sequences,
        'return_state': self.return_state,
        'go_backwards': self.go_backwards,
        'stateful': self.stateful,
        'unroll': self.unroll,
        'time_major': self.time_major
    }
    if self._num_constants:
      config['num_constants'] = self._num_constants
    if self.zero_output_for_mask:
      config['zero_output_for_mask'] = self.zero_output_for_mask

    config['cell'] = generic_utils.serialize_keras_object(self.cell)
    base_config = super(RNN, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config, custom_objects=None):
    from keras.layers import deserialize as deserialize_layer  # pylint: disable=g-import-not-at-top
    cell = deserialize_layer(config.pop('cell'), custom_objects=custom_objects)
    num_constants = config.pop('num_constants', 0)
    layer = cls(cell, **config)
    layer._num_constants = num_constants
    return layer

  @property
  def _trackable_saved_model_saver(self):
    return layer_serialization.RNNSavedModelSaver(self)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Instance variables

var states
Expand source code
@property
def states(self):
  if self._states is None:
    state = tf.nest.map_structure(lambda _: None, self.cell.state_size)
    return state if tf.nest.is_nested(self.cell.state_size) else [state]
  return self._states

Methods

def get_initial_state(self, inputs)
Expand source code
@doc_controls.do_not_doc_inheritable
def get_initial_state(self, inputs):
  get_initial_state_fn = getattr(self.cell, 'get_initial_state', None)

  if tf.nest.is_nested(inputs):
    # The input are nested sequences. Use the first element in the seq to get
    # batch size and dtype.
    inputs = tf.nest.flatten(inputs)[0]

  input_shape = tf.shape(inputs)
  batch_size = input_shape[1] if self.time_major else input_shape[0]
  dtype = inputs.dtype
  if get_initial_state_fn:
    init_state = get_initial_state_fn(
        inputs=None, batch_size=batch_size, dtype=dtype)
  else:
    init_state = _generate_zero_filled_state(batch_size, self.cell.state_size,
                                             dtype)
  # Keras RNN expect the states in a list, even if it's a single state tensor.
  if not tf.nest.is_nested(init_state):
    init_state = [init_state]
  # Force the state to be a list in case it is a namedtuple eg LSTMStateTuple.
  return list(init_state)
def reset_states(self, states=None)

Reset the recorded states for the stateful RNN layer.

Can only be used when RNN layer is constructed with stateful = True.

Args

states
Numpy arrays that contains the value for the initial state, which will be feed to cell at the first time step. When the value is None, zero filled numpy array will be created based on the cell state size.

Raises

AttributeError
When the RNN layer is not stateful.
ValueError
When the batch size of the RNN layer is unknown.
ValueError
When the input numpy array is not compatible with the RNN layer state, either size wise or dtype wise.
Expand source code
def reset_states(self, states=None):
  """Reset the recorded states for the stateful RNN layer.

  Can only be used when RNN layer is constructed with `stateful` = `True`.
  Args:
    states: Numpy arrays that contains the value for the initial state, which
      will be feed to cell at the first time step. When the value is None,
      zero filled numpy array will be created based on the cell state size.

  Raises:
    AttributeError: When the RNN layer is not stateful.
    ValueError: When the batch size of the RNN layer is unknown.
    ValueError: When the input numpy array is not compatible with the RNN
      layer state, either size wise or dtype wise.
  """
  if not self.stateful:
    raise AttributeError('Layer must be stateful.')
  spec_shape = None
  if self.input_spec is not None:
    spec_shape = tf.nest.flatten(self.input_spec[0])[0].shape
  if spec_shape is None:
    # It is possible to have spec shape to be None, eg when construct a RNN
    # with a custom cell, or standard RNN layers (LSTM/GRU) which we only know
    # it has 3 dim input, but not its full shape spec before build().
    batch_size = None
  else:
    batch_size = spec_shape[1] if self.time_major else spec_shape[0]
  if not batch_size:
    raise ValueError('If a RNN is stateful, it needs to know '
                     'its batch size. Specify the batch size '
                     'of your input tensors: \n'
                     '- If using a Sequential model, '
                     'specify the batch size by passing '
                     'a `batch_input_shape` '
                     'argument to your first layer.\n'
                     '- If using the functional API, specify '
                     'the batch size by passing a '
                     '`batch_shape` argument to your Input layer.')
  # initialize state if None
  if tf.nest.flatten(self.states)[0] is None:
    if getattr(self.cell, 'get_initial_state', None):
      flat_init_state_values = tf.nest.flatten(self.cell.get_initial_state(
          inputs=None, batch_size=batch_size,
          dtype=self.dtype or backend.floatx()))
    else:
      flat_init_state_values = tf.nest.flatten(_generate_zero_filled_state(
          batch_size, self.cell.state_size, self.dtype or backend.floatx()))
    flat_states_variables = tf.nest.map_structure(
        backend.variable, flat_init_state_values)
    self.states = tf.nest.pack_sequence_as(self.cell.state_size,
                                           flat_states_variables)
    if not tf.nest.is_nested(self.states):
      self.states = [self.states]
  elif states is None:
    for state, size in zip(tf.nest.flatten(self.states),
                           tf.nest.flatten(self.cell.state_size)):
      backend.set_value(
          state,
          np.zeros([batch_size] + tf.TensorShape(size).as_list()))
  else:
    flat_states = tf.nest.flatten(self.states)
    flat_input_states = tf.nest.flatten(states)
    if len(flat_input_states) != len(flat_states):
      raise ValueError('Layer ' + self.name + ' expects ' +
                       str(len(flat_states)) + ' states, '
                       'but it received ' + str(len(flat_input_states)) +
                       ' state values. Input received: ' + str(states))
    set_value_tuples = []
    for i, (value, state) in enumerate(zip(flat_input_states,
                                           flat_states)):
      if value.shape != state.shape:
        raise ValueError(
            'State ' + str(i) + ' is incompatible with layer ' +
            self.name + ': expected shape=' + str(
                (batch_size, state)) + ', found shape=' + str(value.shape))
      set_value_tuples.append((state, value))
    backend.batch_set_value(set_value_tuples)

Inherited members

class RandomContrast (factor, seed=None, **kwargs)

Adjust the contrast of an image or images by a random factor.

Contrast is adjusted independently for each channel of each image during training.

For each channel, this layer computes the mean of the image pixels in the channel and then adjusts each component x of each pixel to (x - mean) * contrast_factor + mean.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Attributes

factor
a positive float represented as fraction of value, or a tuple of size 2 representing lower and upper bound. When represented as a single float, lower = upper. The contrast factor will be randomly picked between [1.0 - lower, 1.0 + upper].
seed
Integer. Used to create a random seed.
Expand source code
class RandomContrast(base_layer.Layer):
  """Adjust the contrast of an image or images by a random factor.

  Contrast is adjusted independently for each channel of each image during
  training.

  For each channel, this layer computes the mean of the image pixels in the
  channel and then adjusts each component `x` of each pixel to
  `(x - mean) * contrast_factor + mean`.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Attributes:
    factor: a positive float represented as fraction of value, or a tuple of
      size 2 representing lower and upper bound. When represented as a single
      float, lower = upper. The contrast factor will be randomly picked between
      `[1.0 - lower, 1.0 + upper]`.
    seed: Integer. Used to create a random seed.
  """

  def __init__(self, factor, seed=None, **kwargs):
    self.factor = factor
    if isinstance(factor, (tuple, list)):
      self.lower = factor[0]
      self.upper = factor[1]
    else:
      self.lower = self.upper = factor
    if self.lower < 0. or self.upper < 0. or self.lower > 1.:
      raise ValueError('Factor cannot have negative values or greater than 1.0,'
                       ' got {}'.format(factor))
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomContrast, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomContrast').set(
        True)

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

    def random_contrasted_inputs():
      return tf.image.stateless_random_contrast(inputs, 1. - self.lower,
                                                1. + self.upper,
                                                self._rng.make_seeds()[:, 0])

    output = control_flow_util.smart_cond(training, random_contrasted_inputs,
                                          lambda: inputs)
    output.set_shape(inputs.shape)
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'factor': self.factor,
        'seed': self.seed,
    }
    base_config = super(RandomContrast, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomCrop (height, width, seed=None, **kwargs)

Randomly crop the images to target height and width.

This layer will crop all the images in the same batch to the same cropping location. By default, random cropping is only applied during training. At inference time, the images will be first rescaled to preserve the shorter side, and center cropped. If you need to apply random cropping at inference time, set training to True when calling the layer.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, target_height, target_width, channels).

Args

height
Integer, the height of the output shape.
width
Integer, the width of the output shape.
seed
Integer. Used to create a random seed.
Expand source code
class RandomCrop(base_layer.Layer):
  """Randomly crop the images to target height and width.

  This layer will crop all the images in the same batch to the same cropping
  location.
  By default, random cropping is only applied during training. At inference
  time, the images will be first rescaled to preserve the shorter side, and
  center cropped. If you need to apply random cropping at inference time,
  set `training` to True when calling the layer.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., target_height, target_width, channels)`.

  Args:
    height: Integer, the height of the output shape.
    width: Integer, the width of the output shape.
    seed: Integer. Used to create a random seed.
  """

  def __init__(self, height, width, seed=None, **kwargs):
    self.height = height
    self.width = width
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomCrop, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomCrop').set(True)

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

    inputs = tf.convert_to_tensor(inputs)
    unbatched = inputs.shape.rank == 3

    def random_cropped_inputs():
      """Cropped inputs with stateless random ops."""
      shape = tf.shape(inputs)
      if unbatched:
        crop_size = tf.stack([self.height, self.width, shape[-1]])
      else:
        crop_size = tf.stack([shape[0], self.height, self.width, shape[-1]])
      check = tf.Assert(
          tf.reduce_all(shape >= crop_size),
          [self.height, self.width])
      with tf.control_dependencies([check]):
        limit = shape - crop_size + 1
        offset = stateless_random_ops.stateless_random_uniform(
            tf.shape(shape),
            dtype=crop_size.dtype,
            maxval=crop_size.dtype.max,
            seed=self._rng.make_seeds()[:, 0]) % limit
        return tf.slice(inputs, offset, crop_size)

    # TODO(b/143885775): Share logic with Resize and CenterCrop.
    def resize_and_center_cropped_inputs():
      """Deterministically resize to shorter side and center crop."""
      input_shape = tf.shape(inputs)
      input_height_t = input_shape[H_AXIS]
      input_width_t = input_shape[W_AXIS]
      ratio_cond = (input_height_t / input_width_t > (self.height / self.width))
      # pylint: disable=g-long-lambda
      resized_height = control_flow_util.smart_cond(
          ratio_cond,
          lambda: tf.cast(self.width * input_height_t / input_width_t,
                          input_height_t.dtype), lambda: self.height)
      resized_width = control_flow_util.smart_cond(
          ratio_cond, lambda: self.width,
          lambda: tf.cast(self.height * input_width_t / input_height_t,
                          input_width_t.dtype))
      # pylint: enable=g-long-lambda
      resized_inputs = tf.image.resize(
          images=inputs, size=tf.stack([resized_height, resized_width]))

      img_hd_diff = resized_height - self.height
      img_wd_diff = resized_width - self.width
      bbox_h_start = tf.cast(img_hd_diff / 2, tf.int32)
      bbox_w_start = tf.cast(img_wd_diff / 2, tf.int32)
      if unbatched:
        bbox_begin = tf.stack([bbox_h_start, bbox_w_start, 0])
        bbox_size = tf.stack([self.height, self.width, -1])
      else:
        bbox_begin = tf.stack([0, bbox_h_start, bbox_w_start, 0])
        bbox_size = tf.stack([-1, self.height, self.width, -1])
      outputs = tf.slice(resized_inputs, bbox_begin, bbox_size)
      return outputs

    output = control_flow_util.smart_cond(training, random_cropped_inputs,
                                          resize_and_center_cropped_inputs)
    input_shape = inputs.shape.as_list()
    if unbatched:
      output_shape = [self.height, self.width, input_shape[-1]]
    else:
      output_shape = [input_shape[0], self.height, self.width, input_shape[-1]]
    output.set_shape(output_shape)
    return output

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    input_shape[H_AXIS] = self.height
    input_shape[W_AXIS] = self.width
    return tf.TensorShape(input_shape)

  def get_config(self):
    config = {
        'height': self.height,
        'width': self.width,
        'seed': self.seed,
    }
    base_config = super(RandomCrop, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomFlip (mode='horizontal_and_vertical', seed=None, **kwargs)

Randomly flip each image horizontally and vertically.

This layer will flip the images based on the mode attribute. During inference time, the output will be identical to input. Call the layer with training=True to flip the input.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Attributes

mode
String indicating which flip mode to use. Can be "horizontal", "vertical", or "horizontal_and_vertical". Defaults to "horizontal_and_vertical". "horizontal" is a left-right flip and "vertical" is a top-bottom flip.
seed
Integer. Used to create a random seed.
Expand source code
class RandomFlip(base_layer.Layer):
  """Randomly flip each image horizontally and vertically.

  This layer will flip the images based on the `mode` attribute.
  During inference time, the output will be identical to input. Call the layer
  with `training=True` to flip the input.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Attributes:
    mode: String indicating which flip mode to use. Can be `"horizontal"`,
      `"vertical"`, or `"horizontal_and_vertical"`. Defaults to
      `"horizontal_and_vertical"`. `"horizontal"` is a left-right flip and
      `"vertical"` is a top-bottom flip.
    seed: Integer. Used to create a random seed.
  """

  def __init__(self,
               mode=HORIZONTAL_AND_VERTICAL,
               seed=None,
               **kwargs):
    super(RandomFlip, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomFlip').set(True)
    self.mode = mode
    if mode == HORIZONTAL:
      self.horizontal = True
      self.vertical = False
    elif mode == VERTICAL:
      self.horizontal = False
      self.vertical = True
    elif mode == HORIZONTAL_AND_VERTICAL:
      self.horizontal = True
      self.vertical = True
    else:
      raise ValueError('RandomFlip layer {name} received an unknown mode '
                       'argument {arg}'.format(name=self.name, arg=mode))
    self.seed = seed
    self._rng = make_generator(self.seed)

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

    def random_flipped_inputs():
      flipped_outputs = inputs
      if self.horizontal:
        flipped_outputs = tf.image.stateless_random_flip_left_right(
            flipped_outputs,
            self._rng.make_seeds()[:, 0])
      if self.vertical:
        flipped_outputs = tf.image.stateless_random_flip_up_down(
            flipped_outputs,
            self._rng.make_seeds()[:, 0])
      return flipped_outputs

    output = control_flow_util.smart_cond(training, random_flipped_inputs,
                                          lambda: inputs)
    output.set_shape(inputs.shape)
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'mode': self.mode,
        'seed': self.seed,
    }
    base_config = super(RandomFlip, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomHeight (factor, interpolation='bilinear', seed=None, **kwargs)

Randomly vary the height of a batch of images during training.

Adjusts the height of a batch of images by a random factor. The input should be a 3D (unbatched) or 4D (batched) tensor in the "channels_last" image data format.

By default, this layer is inactive during inference.

Args

factor
A positive float (fraction of original height), or a tuple of size 2 representing lower and upper bound for resizing vertically. When represented as a single float, this value is used for both the upper and lower bound. For instance, factor=(0.2, 0.3) results in an output with height changed by a random amount in the range [20%, 30%]. factor=(-0.2, 0.3) results in an output with height changed by a random amount in the range [-20%, +30%].factor=0.2results in an output with height changed by a random amount in the range[-20%, +20%]`.
interpolation
String, the interpolation method. Defaults to "bilinear". Supports "bilinear", "nearest", "bicubic", "area", "lanczos3", "lanczos5", "gaussian", "mitchellcubic".
seed
Integer. Used to create a random seed.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, random_height, width, channels).

Expand source code
class RandomHeight(base_layer.Layer):
  """Randomly vary the height of a batch of images during training.

  Adjusts the height of a batch of images by a random factor. The input
  should be a 3D (unbatched) or 4D (batched) tensor in the `"channels_last"`
  image data format.

  By default, this layer is inactive during inference.

  Args:
    factor: A positive float (fraction of original height), or a tuple of size 2
      representing lower and upper bound for resizing vertically. When
      represented as a single float, this value is used for both the upper and
      lower bound. For instance, `factor=(0.2, 0.3)` results in an output with
      height changed by a random amount in the range `[20%, 30%]`.
      `factor=(-0.2, 0.3)` results in an output with height changed by a random
      amount in the range `[-20%, +30%]. `factor=0.2` results in an output with
      height changed by a random amount in the range `[-20%, +20%]`.
    interpolation: String, the interpolation method. Defaults to `"bilinear"`.
      Supports `"bilinear"`, `"nearest"`, `"bicubic"`, `"area"`,
      `"lanczos3"`, `"lanczos5"`, `"gaussian"`, `"mitchellcubic"`.
    seed: Integer. Used to create a random seed.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., random_height, width, channels)`.
  """

  def __init__(self,
               factor,
               interpolation='bilinear',
               seed=None,
               **kwargs):
    self.factor = factor
    if isinstance(factor, (tuple, list)):
      self.height_lower = factor[0]
      self.height_upper = factor[1]
    else:
      self.height_lower = -factor
      self.height_upper = factor

    if self.height_upper < self.height_lower:
      raise ValueError('`factor` cannot have upper bound less than '
                       'lower bound, got {}'.format(factor))
    if self.height_lower < -1. or self.height_upper < -1.:
      raise ValueError('`factor` must have values larger than -1, '
                       'got {}'.format(factor))
    self.interpolation = interpolation
    self._interpolation_method = get_interpolation(interpolation)
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomHeight, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomHeight').set(True)

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

    def random_height_inputs():
      """Inputs height-adjusted with random ops."""
      inputs_shape = tf.shape(inputs)
      img_hd = tf.cast(inputs_shape[H_AXIS], tf.float32)
      img_wd = inputs_shape[W_AXIS]
      height_factor = self._rng.uniform(
          shape=[],
          minval=(1.0 + self.height_lower),
          maxval=(1.0 + self.height_upper))
      adjusted_height = tf.cast(height_factor * img_hd, tf.int32)
      adjusted_size = tf.stack([adjusted_height, img_wd])
      output = tf.image.resize(
          images=inputs, size=adjusted_size, method=self._interpolation_method)
      output_shape = inputs.shape.as_list()
      output_shape[H_AXIS] = None
      output.set_shape(output_shape)
      return output

    return control_flow_util.smart_cond(training, random_height_inputs,
                                        lambda: inputs)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    input_shape[H_AXIS] = None
    return tf.TensorShape(input_shape)

  def get_config(self):
    config = {
        'factor': self.factor,
        'interpolation': self.interpolation,
        'seed': self.seed,
    }
    base_config = super(RandomHeight, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomRotation (factor, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs)

Randomly rotate each image.

By default, random rotations are only applied during training. At inference time, the layer does nothing. If you need to apply random rotations at inference time, set training to True when calling the layer.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format

Attributes

factor
a float represented as fraction of 2 Pi, or a tuple of size 2 representing lower and upper bound for rotating clockwise and counter-clockwise. A positive values means rotating counter clock-wise, while a negative value means clock-wise. When represented as a single float, this value is used for both the upper and lower bound. For instance, factor=(-0.2, 0.3) results in an output rotation by a random amount in the range [-20% * 2pi, 30% * 2pi]. factor=0.2 results in an output rotating by a random amount in the range [-20% * 2pi, 20% * 2pi].
fill_mode
Points outside the boundaries of the input are filled according to the given mode (one of {"constant", "reflect", "wrap", "nearest"}). - reflect: (d c b a | a b c d | d c b a) The input is extended by reflecting about the edge of the last pixel. - constant: (k k k k | a b c d | k k k k) The input is extended by filling all values beyond the edge with the same constant value k = 0. - wrap: (a b c d | a b c d | a b c d) The input is extended by wrapping around to the opposite edge. - nearest: (a a a a | a b c d | d d d d) The input is extended by the nearest pixel.
interpolation
Interpolation mode. Supported values: "nearest", "bilinear".
seed
Integer. Used to create a random seed.
fill_value
a float represents the value to be filled outside the boundaries when fill_mode="constant".
Expand source code
class RandomRotation(base_layer.Layer):
  """Randomly rotate each image.

  By default, random rotations are only applied during training.
  At inference time, the layer does nothing. If you need to apply random
  rotations at inference time, set `training` to True when calling the layer.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format

  Attributes:
    factor: a float represented as fraction of 2 Pi, or a tuple of size 2
      representing lower and upper bound for rotating clockwise and
      counter-clockwise. A positive values means rotating counter clock-wise,
      while a negative value means clock-wise. When represented as a single
      float, this value is used for both the upper and lower bound. For
      instance, `factor=(-0.2, 0.3)` results in an output rotation by a random
      amount in the range `[-20% * 2pi, 30% * 2pi]`. `factor=0.2` results in an
      output rotating by a random amount in the range `[-20% * 2pi, 20% * 2pi]`.
    fill_mode: Points outside the boundaries of the input are filled according
      to the given mode (one of `{"constant", "reflect", "wrap", "nearest"}`).
      - *reflect*: `(d c b a | a b c d | d c b a)` The input is extended by
        reflecting about the edge of the last pixel.
      - *constant*: `(k k k k | a b c d | k k k k)` The input is extended by
        filling all values beyond the edge with the same constant value k = 0.
      - *wrap*: `(a b c d | a b c d | a b c d)` The input is extended by
        wrapping around to the opposite edge.
      - *nearest*: `(a a a a | a b c d | d d d d)` The input is extended by the
        nearest pixel.
    interpolation: Interpolation mode. Supported values: `"nearest"`,
      `"bilinear"`.
    seed: Integer. Used to create a random seed.
    fill_value: a float represents the value to be filled outside the boundaries
      when `fill_mode="constant"`.
  """

  def __init__(self,
               factor,
               fill_mode='reflect',
               interpolation='bilinear',
               seed=None,
               fill_value=0.0,
               **kwargs):
    self.factor = factor
    if isinstance(factor, (tuple, list)):
      self.lower = factor[0]
      self.upper = factor[1]
    else:
      self.lower = -factor
      self.upper = factor
    if self.upper < self.lower:
      raise ValueError('Factor cannot have negative values, '
                       'got {}'.format(factor))
    check_fill_mode_and_interpolation(fill_mode, interpolation)
    self.fill_mode = fill_mode
    self.fill_value = fill_value
    self.interpolation = interpolation
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomRotation, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomRotation').set(
        True)

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

    inputs = tf.convert_to_tensor(inputs)
    original_shape = inputs.shape
    unbatched = inputs.shape.rank == 3
    # The transform op only accepts rank 4 inputs, so if we have an unbatched
    # image, we need to temporarily expand dims to a batch.
    if unbatched:
      inputs = tf.expand_dims(inputs, 0)

    def random_rotated_inputs():
      """Rotated inputs with random ops."""
      inputs_shape = tf.shape(inputs)
      batch_size = inputs_shape[0]
      img_hd = tf.cast(inputs_shape[H_AXIS], tf.float32)
      img_wd = tf.cast(inputs_shape[W_AXIS], tf.float32)
      min_angle = self.lower * 2. * np.pi
      max_angle = self.upper * 2. * np.pi
      angles = self._rng.uniform(
          shape=[batch_size], minval=min_angle, maxval=max_angle)
      return transform(
          inputs,
          get_rotation_matrix(angles, img_hd, img_wd),
          fill_mode=self.fill_mode,
          fill_value=self.fill_value,
          interpolation=self.interpolation)

    output = control_flow_util.smart_cond(training, random_rotated_inputs,
                                          lambda: inputs)
    if unbatched:
      output = tf.squeeze(output, 0)
    output.set_shape(original_shape)
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'factor': self.factor,
        'fill_mode': self.fill_mode,
        'fill_value': self.fill_value,
        'interpolation': self.interpolation,
        'seed': self.seed,
    }
    base_config = super(RandomRotation, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomTranslation (height_factor, width_factor, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs)

Randomly translate each image during training.

Args

height_factor
a float represented as fraction of value, or a tuple of size 2 representing lower and upper bound for shifting vertically. A negative value means shifting image up, while a positive value means shifting image down. When represented as a single positive float, this value is used for both the upper and lower bound. For instance, height_factor=(-0.2, 0.3) results in an output shifted by a random amount in the range [-20%, +30%]. height_factor=0.2 results in an output height shifted by a random amount in the range [-20%, +20%].
width_factor
a float represented as fraction of value, or a tuple of size 2 representing lower and upper bound for shifting horizontally. A negative value means shifting image left, while a positive value means shifting image right. When represented as a single positive float, this value is used for both the upper and lower bound. For instance, width_factor=(-0.2, 0.3) results in an output shifted left by 20%, and shifted right by 30%. width_factor=0.2 results in an output height shifted left or right by 20%.
fill_mode
Points outside the boundaries of the input are filled according to the given mode (one of {"constant", "reflect", "wrap", "nearest"}). - reflect: (d c b a | a b c d | d c b a) The input is extended by reflecting about the edge of the last pixel. - constant: (k k k k | a b c d | k k k k) The input is extended by filling all values beyond the edge with the same constant value k = 0. - wrap: (a b c d | a b c d | a b c d) The input is extended by wrapping around to the opposite edge. - nearest: (a a a a | a b c d | d d d d) The input is extended by the nearest pixel.
interpolation
Interpolation mode. Supported values: "nearest", "bilinear".
seed
Integer. Used to create a random seed.
fill_value
a float represents the value to be filled outside the boundaries when fill_mode="constant".

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Expand source code
class RandomTranslation(base_layer.Layer):
  """Randomly translate each image during training.

  Args:
    height_factor: a float represented as fraction of value, or a tuple of size
      2 representing lower and upper bound for shifting vertically. A negative
      value means shifting image up, while a positive value means shifting image
      down. When represented as a single positive float, this value is used for
      both the upper and lower bound. For instance, `height_factor=(-0.2, 0.3)`
      results in an output shifted by a random amount in the range
      `[-20%, +30%]`.
      `height_factor=0.2` results in an output height shifted by a random amount
      in the range `[-20%, +20%]`.
    width_factor: a float represented as fraction of value, or a tuple of size 2
      representing lower and upper bound for shifting horizontally. A negative
      value means shifting image left, while a positive value means shifting
      image right. When represented as a single positive float, this value is
      used for both the upper and lower bound. For instance,
      `width_factor=(-0.2, 0.3)` results in an output shifted left by 20%, and
      shifted right by 30%. `width_factor=0.2` results in an output height
      shifted left or right by 20%.
    fill_mode: Points outside the boundaries of the input are filled according
      to the given mode (one of `{"constant", "reflect", "wrap", "nearest"}`).
      - *reflect*: `(d c b a | a b c d | d c b a)` The input is extended by
        reflecting about the edge of the last pixel.
      - *constant*: `(k k k k | a b c d | k k k k)` The input is extended by
        filling all values beyond the edge with the same constant value k = 0.
      - *wrap*: `(a b c d | a b c d | a b c d)` The input is extended by
        wrapping around to the opposite edge.
      - *nearest*: `(a a a a | a b c d | d d d d)` The input is extended by the
        nearest pixel.
    interpolation: Interpolation mode. Supported values: `"nearest"`,
      `"bilinear"`.
    seed: Integer. Used to create a random seed.
    fill_value: a float represents the value to be filled outside the boundaries
      when `fill_mode="constant"`.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`,  in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`,  in `"channels_last"` format.
  """

  def __init__(self,
               height_factor,
               width_factor,
               fill_mode='reflect',
               interpolation='bilinear',
               seed=None,
               fill_value=0.0,
               **kwargs):
    self.height_factor = height_factor
    if isinstance(height_factor, (tuple, list)):
      self.height_lower = height_factor[0]
      self.height_upper = height_factor[1]
    else:
      self.height_lower = -height_factor
      self.height_upper = height_factor
    if self.height_upper < self.height_lower:
      raise ValueError('`height_factor` cannot have upper bound less than '
                       'lower bound, got {}'.format(height_factor))
    if abs(self.height_lower) > 1. or abs(self.height_upper) > 1.:
      raise ValueError('`height_factor` must have values between [-1, 1], '
                       'got {}'.format(height_factor))

    self.width_factor = width_factor
    if isinstance(width_factor, (tuple, list)):
      self.width_lower = width_factor[0]
      self.width_upper = width_factor[1]
    else:
      self.width_lower = -width_factor
      self.width_upper = width_factor
    if self.width_upper < self.width_lower:
      raise ValueError('`width_factor` cannot have upper bound less than '
                       'lower bound, got {}'.format(width_factor))
    if abs(self.width_lower) > 1. or abs(self.width_upper) > 1.:
      raise ValueError('`width_factor` must have values between [-1, 1], '
                       'got {}'.format(width_factor))

    check_fill_mode_and_interpolation(fill_mode, interpolation)

    self.fill_mode = fill_mode
    self.fill_value = fill_value
    self.interpolation = interpolation
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomTranslation, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomTranslation').set(
        True)

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

    inputs = tf.convert_to_tensor(inputs)
    original_shape = inputs.shape
    unbatched = inputs.shape.rank == 3
    # The transform op only accepts rank 4 inputs, so if we have an unbatched
    # image, we need to temporarily expand dims to a batch.
    if unbatched:
      inputs = tf.expand_dims(inputs, 0)

    def random_translated_inputs():
      """Translated inputs with random ops."""
      inputs_shape = tf.shape(inputs)
      batch_size = inputs_shape[0]
      img_hd = tf.cast(inputs_shape[H_AXIS], tf.float32)
      img_wd = tf.cast(inputs_shape[W_AXIS], tf.float32)
      height_translate = self._rng.uniform(
          shape=[batch_size, 1],
          minval=self.height_lower,
          maxval=self.height_upper,
          dtype=tf.float32)
      height_translate = height_translate * img_hd
      width_translate = self._rng.uniform(
          shape=[batch_size, 1],
          minval=self.width_lower,
          maxval=self.width_upper,
          dtype=tf.float32)
      width_translate = width_translate * img_wd
      translations = tf.cast(
          tf.concat([width_translate, height_translate], axis=1),
          dtype=tf.float32)
      return transform(
          inputs,
          get_translation_matrix(translations),
          interpolation=self.interpolation,
          fill_mode=self.fill_mode,
          fill_value=self.fill_value)

    output = control_flow_util.smart_cond(training, random_translated_inputs,
                                          lambda: inputs)
    if unbatched:
      output = tf.squeeze(output, 0)
    output.set_shape(original_shape)
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'height_factor': self.height_factor,
        'width_factor': self.width_factor,
        'fill_mode': self.fill_mode,
        'fill_value': self.fill_value,
        'interpolation': self.interpolation,
        'seed': self.seed,
    }
    base_config = super(RandomTranslation, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomWidth (factor, interpolation='bilinear', seed=None, **kwargs)

Randomly vary the width of a batch of images during training.

Adjusts the width of a batch of images by a random factor. The input should be a 3D (unbatched) or 4D (batched) tensor in the "channels_last" image data format.

By default, this layer is inactive during inference.

Args

factor
A positive float (fraction of original height), or a tuple of size 2 representing lower and upper bound for resizing vertically. When represented as a single float, this value is used for both the upper and lower bound. For instance, factor=(0.2, 0.3) results in an output with width changed by a random amount in the range [20%, 30%]. factor=(-0.2, 0.3) results in an output with width changed by a random amount in the range [-20%, +30%]. factor=0.2 results in an output with width changed by a random amount in the range [-20%, +20%].
interpolation
String, the interpolation method. Defaults to bilinear. Supports "bilinear", "nearest", "bicubic", "area", "lanczos3", "lanczos5", "gaussian", "mitchellcubic".
seed
Integer. Used to create a random seed.

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, random_height, width, channels).

Expand source code
class RandomWidth(base_layer.Layer):
  """Randomly vary the width of a batch of images during training.

  Adjusts the width of a batch of images by a random factor. The input
  should be a 3D (unbatched) or 4D (batched) tensor in the `"channels_last"`
  image data format.

  By default, this layer is inactive during inference.

  Args:
    factor: A positive float (fraction of original height), or a tuple of size 2
      representing lower and upper bound for resizing vertically. When
      represented as a single float, this value is used for both the upper and
      lower bound. For instance, `factor=(0.2, 0.3)` results in an output with
      width changed by a random amount in the range `[20%, 30%]`. `factor=(-0.2,
      0.3)` results in an output with width changed by a random amount in the
      range `[-20%, +30%]`. `factor=0.2` results in an output with width changed
      by a random amount in the range `[-20%, +20%]`.
    interpolation: String, the interpolation method. Defaults to `bilinear`.
      Supports `"bilinear"`, `"nearest"`, `"bicubic"`, `"area"`, `"lanczos3"`,
      `"lanczos5"`, `"gaussian"`, `"mitchellcubic"`.
    seed: Integer. Used to create a random seed.

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., random_height, width, channels)`.
  """

  def __init__(self,
               factor,
               interpolation='bilinear',
               seed=None,
               **kwargs):
    self.factor = factor
    if isinstance(factor, (tuple, list)):
      self.width_lower = factor[0]
      self.width_upper = factor[1]
    else:
      self.width_lower = -factor
      self.width_upper = factor
    if self.width_upper < self.width_lower:
      raise ValueError('`factor` cannot have upper bound less than '
                       'lower bound, got {}'.format(factor))
    if self.width_lower < -1. or self.width_upper < -1.:
      raise ValueError('`factor` must have values larger than -1, '
                       'got {}'.format(factor))
    self.interpolation = interpolation
    self._interpolation_method = get_interpolation(interpolation)
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomWidth, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomWidth').set(True)

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

    def random_width_inputs():
      """Inputs width-adjusted with random ops."""
      inputs_shape = tf.shape(inputs)
      img_hd = inputs_shape[H_AXIS]
      img_wd = tf.cast(inputs_shape[W_AXIS], tf.float32)
      width_factor = self._rng.uniform(
          shape=[],
          minval=(1.0 + self.width_lower),
          maxval=(1.0 + self.width_upper))
      adjusted_width = tf.cast(width_factor * img_wd, tf.int32)
      adjusted_size = tf.stack([img_hd, adjusted_width])
      output = tf.image.resize(
          images=inputs, size=adjusted_size, method=self._interpolation_method)
      output_shape = inputs.shape.as_list()
      output_shape[W_AXIS] = None
      output.set_shape(output_shape)
      return output

    return control_flow_util.smart_cond(training, random_width_inputs,
                                        lambda: inputs)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    input_shape[W_AXIS] = None
    return tf.TensorShape(input_shape)

  def get_config(self):
    config = {
        'factor': self.factor,
        'interpolation': self.interpolation,
        'seed': self.seed,
    }
    base_config = super(RandomWidth, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RandomZoom (height_factor, width_factor=None, fill_mode='reflect', interpolation='bilinear', seed=None, fill_value=0.0, **kwargs)

Randomly zoom each image during training.

Args

height_factor
a float represented as fraction of value, or a tuple of size 2 representing lower and upper bound for zooming vertically. When represented as a single float, this value is used for both the upper and lower bound. A positive value means zooming out, while a negative value means zooming in. For instance, height_factor=(0.2, 0.3) result in an output zoomed out by a random amount in the range [+20%, +30%]. height_factor=(-0.3, -0.2) result in an output zoomed in by a random amount in the range [+20%, +30%].
width_factor
a float represented as fraction of value, or a tuple of size 2 representing lower and upper bound for zooming horizontally. When represented as a single float, this value is used for both the upper and lower bound. For instance, width_factor=(0.2, 0.3) result in an output zooming out between 20% to 30%. width_factor=(-0.3, -0.2) result in an output zooming in between 20% to 30%. Defaults to None, i.e., zooming vertical and horizontal directions by preserving the aspect ratio.
fill_mode
Points outside the boundaries of the input are filled according to the given mode (one of {"constant", "reflect", "wrap", "nearest"}). - reflect: (d c b a | a b c d | d c b a) The input is extended by reflecting about the edge of the last pixel. - constant: (k k k k | a b c d | k k k k) The input is extended by filling all values beyond the edge with the same constant value k = 0. - wrap: (a b c d | a b c d | a b c d) The input is extended by wrapping around to the opposite edge. - nearest: (a a a a | a b c d | d d d d) The input is extended by the nearest pixel.
interpolation
Interpolation mode. Supported values: "nearest", "bilinear".
seed
Integer. Used to create a random seed.
fill_value
a float represents the value to be filled outside the boundaries when fill_mode="constant".

Example:

>>> input_img = np.random.random((32, 224, 224, 3))
>>> layer = tf.keras.layers.RandomZoom(.5, .2)
>>> out_img = layer(input_img)
>>> out_img.shape
TensorShape([32, 224, 224, 3])

Input shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Output shape: 3D (unbatched) or 4D (batched) tensor with shape: (…, height, width, channels), in "channels_last" format.

Expand source code
class RandomZoom(base_layer.Layer):
  """Randomly zoom each image during training.

  Args:
    height_factor: a float represented as fraction of value, or a tuple of size
      2 representing lower and upper bound for zooming vertically. When
      represented as a single float, this value is used for both the upper and
      lower bound. A positive value means zooming out, while a negative value
      means zooming in. For instance, `height_factor=(0.2, 0.3)` result in an
      output zoomed out by a random amount in the range `[+20%, +30%]`.
      `height_factor=(-0.3, -0.2)` result in an output zoomed in by a random
      amount in the range `[+20%, +30%]`.
    width_factor: a float represented as fraction of value, or a tuple of size 2
      representing lower and upper bound for zooming horizontally. When
      represented as a single float, this value is used for both the upper and
      lower bound. For instance, `width_factor=(0.2, 0.3)` result in an output
      zooming out between 20% to 30%. `width_factor=(-0.3, -0.2)` result in an
      output zooming in between 20% to 30%. Defaults to `None`, i.e., zooming
      vertical and horizontal directions by preserving the aspect ratio.
    fill_mode: Points outside the boundaries of the input are filled according
      to the given mode (one of `{"constant", "reflect", "wrap", "nearest"}`).
      - *reflect*: `(d c b a | a b c d | d c b a)` The input is extended by
        reflecting about the edge of the last pixel.
      - *constant*: `(k k k k | a b c d | k k k k)` The input is extended by
        filling all values beyond the edge with the same constant value k = 0.
      - *wrap*: `(a b c d | a b c d | a b c d)` The input is extended by
        wrapping around to the opposite edge.
      - *nearest*: `(a a a a | a b c d | d d d d)` The input is extended by the
        nearest pixel.
    interpolation: Interpolation mode. Supported values: `"nearest"`,
      `"bilinear"`.
    seed: Integer. Used to create a random seed.
    fill_value: a float represents the value to be filled outside the boundaries
      when `fill_mode="constant"`.

  Example:

  >>> input_img = np.random.random((32, 224, 224, 3))
  >>> layer = tf.keras.layers.RandomZoom(.5, .2)
  >>> out_img = layer(input_img)
  >>> out_img.shape
  TensorShape([32, 224, 224, 3])

  Input shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.

  Output shape:
    3D (unbatched) or 4D (batched) tensor with shape:
    `(..., height, width, channels)`, in `"channels_last"` format.
  """

  def __init__(self,
               height_factor,
               width_factor=None,
               fill_mode='reflect',
               interpolation='bilinear',
               seed=None,
               fill_value=0.0,
               **kwargs):
    self.height_factor = height_factor
    if isinstance(height_factor, (tuple, list)):
      self.height_lower = height_factor[0]
      self.height_upper = height_factor[1]
    else:
      self.height_lower = -height_factor
      self.height_upper = height_factor

    if abs(self.height_lower) > 1. or abs(self.height_upper) > 1.:
      raise ValueError('`height_factor` must have values between [-1, 1], '
                       'got {}'.format(height_factor))

    self.width_factor = width_factor
    if width_factor is not None:
      if isinstance(width_factor, (tuple, list)):
        self.width_lower = width_factor[0]
        self.width_upper = width_factor[1]
      else:
        self.width_lower = -width_factor  # pylint: disable=invalid-unary-operand-type
        self.width_upper = width_factor

      if self.width_lower < -1. or self.width_upper < -1.:
        raise ValueError('`width_factor` must have values larger than -1, '
                         'got {}'.format(width_factor))

    check_fill_mode_and_interpolation(fill_mode, interpolation)

    self.fill_mode = fill_mode
    self.fill_value = fill_value
    self.interpolation = interpolation
    self.seed = seed
    self._rng = make_generator(self.seed)
    super(RandomZoom, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('RandomZoom').set(True)

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

    inputs = tf.convert_to_tensor(inputs)
    original_shape = inputs.shape
    unbatched = inputs.shape.rank == 3
    # The transform op only accepts rank 4 inputs, so if we have an unbatched
    # image, we need to temporarily expand dims to a batch.
    if unbatched:
      inputs = tf.expand_dims(inputs, 0)

    def random_zoomed_inputs():
      """Zoomed inputs with random ops."""
      inputs_shape = tf.shape(inputs)
      batch_size = inputs_shape[0]
      img_hd = tf.cast(inputs_shape[H_AXIS], tf.float32)
      img_wd = tf.cast(inputs_shape[W_AXIS], tf.float32)
      height_zoom = self._rng.uniform(
          shape=[batch_size, 1],
          minval=1. + self.height_lower,
          maxval=1. + self.height_upper)
      if self.width_factor is not None:
        width_zoom = self._rng.uniform(
            shape=[batch_size, 1],
            minval=1. + self.width_lower,
            maxval=1. + self.width_upper)
      else:
        width_zoom = height_zoom
      zooms = tf.cast(
          tf.concat([width_zoom, height_zoom], axis=1),
          dtype=tf.float32)
      return transform(
          inputs,
          get_zoom_matrix(zooms, img_hd, img_wd),
          fill_mode=self.fill_mode,
          fill_value=self.fill_value,
          interpolation=self.interpolation)

    output = control_flow_util.smart_cond(training, random_zoomed_inputs,
                                          lambda: inputs)
    if unbatched:
      output = tf.squeeze(output, 0)
    output.set_shape(original_shape)
    return output

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'height_factor': self.height_factor,
        'width_factor': self.width_factor,
        'fill_mode': self.fill_mode,
        'fill_value': self.fill_value,
        'interpolation': self.interpolation,
        'seed': self.seed,
    }
    base_config = super(RandomZoom, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class ReLU (max_value=None, negative_slope=0, threshold=0, **kwargs)

Rectified Linear Unit activation function.

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

Otherwise, it follows:

  f(x) = max_value if x >= max_value
  f(x) = x if threshold <= x < max_value
  f(x) = negative_slope * (x - threshold) otherwise

Usage:

>>> layer = tf.keras.layers.ReLU()
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[0.0, 0.0, 0.0, 2.0]
>>> layer = tf.keras.layers.ReLU(max_value=1.0)
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[0.0, 0.0, 0.0, 1.0]
>>> layer = tf.keras.layers.ReLU(negative_slope=1.0)
>>> output = layer([-3.0, -1.0, 0.0, 2.0])
>>> list(output.numpy())
[-3.0, -1.0, 0.0, 2.0]
>>> layer = tf.keras.layers.ReLU(threshold=1.5)
>>> output = layer([-3.0, -1.0, 1.0, 2.0])
>>> list(output.numpy())
[0.0, 0.0, 0.0, 2.0]

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the batch axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

max_value
Float >= 0. Maximum activation value. Default to None, which means unlimited.
negative_slope
Float >= 0. Negative slope coefficient. Default to 0.
threshold
Float >= 0. Threshold value for thresholded activation. Default to 0.
Expand source code
class ReLU(Layer):
  """Rectified Linear Unit activation function.

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

  Otherwise, it follows:

  ```
    f(x) = max_value if x >= max_value
    f(x) = x if threshold <= x < max_value
    f(x) = negative_slope * (x - threshold) otherwise
  ```

  Usage:

  >>> layer = tf.keras.layers.ReLU()
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [0.0, 0.0, 0.0, 2.0]
  >>> layer = tf.keras.layers.ReLU(max_value=1.0)
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [0.0, 0.0, 0.0, 1.0]
  >>> layer = tf.keras.layers.ReLU(negative_slope=1.0)
  >>> output = layer([-3.0, -1.0, 0.0, 2.0])
  >>> list(output.numpy())
  [-3.0, -1.0, 0.0, 2.0]
  >>> layer = tf.keras.layers.ReLU(threshold=1.5)
  >>> output = layer([-3.0, -1.0, 1.0, 2.0])
  >>> list(output.numpy())
  [0.0, 0.0, 0.0, 2.0]

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the batch axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    max_value: Float >= 0. Maximum activation value. Default to None, which
      means unlimited.
    negative_slope: Float >= 0. Negative slope coefficient. Default to 0.
    threshold: Float >= 0. Threshold value for thresholded activation. Default
      to 0.
  """

  def __init__(self, max_value=None, negative_slope=0, threshold=0, **kwargs):
    super(ReLU, self).__init__(**kwargs)
    if max_value is not None and max_value < 0.:
      raise ValueError('max_value of a ReLU layer cannot be a negative '
                       'value. Got: %s' % max_value)
    if negative_slope is None or negative_slope < 0.:
      raise ValueError('negative_slope of a ReLU layer cannot be a negative '
                       'value. Got: %s' % negative_slope)
    if threshold is None or threshold < 0.:
      raise ValueError('threshold of a ReLU layer cannot be a negative '
                       'value. Got: %s' % threshold)

    self.supports_masking = True
    if max_value is not None:
      max_value = backend.cast_to_floatx(max_value)
    self.max_value = max_value
    self.negative_slope = backend.cast_to_floatx(negative_slope)
    self.threshold = backend.cast_to_floatx(threshold)

  def call(self, inputs):
    # alpha is used for leaky relu slope in activations instead of
    # negative_slope.
    return backend.relu(inputs,
                        alpha=self.negative_slope,
                        max_value=self.max_value,
                        threshold=self.threshold)

  def get_config(self):
    config = {
        'max_value': self.max_value,
        'negative_slope': self.negative_slope,
        'threshold': self.threshold
    }
    base_config = super(ReLU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class RepeatVector (n, **kwargs)

Repeats the input n times.

Example:

model = Sequential()
model.add(Dense(32, input_dim=32))
# now: model.output_shape == (None, 32)
# note: `None` is the batch dimension

model.add(RepeatVector(3))
# now: model.output_shape == (None, 3, 32)

Args

n
Integer, repetition factor.

Input shape: 2D tensor of shape (num_samples, features).

Output shape: 3D tensor of shape (num_samples, n, features).

Expand source code
class RepeatVector(Layer):
  """Repeats the input n times.

  Example:

  ```python
  model = Sequential()
  model.add(Dense(32, input_dim=32))
  # now: model.output_shape == (None, 32)
  # note: `None` is the batch dimension

  model.add(RepeatVector(3))
  # now: model.output_shape == (None, 3, 32)
  ```

  Args:
    n: Integer, repetition factor.

  Input shape:
    2D tensor of shape `(num_samples, features)`.

  Output shape:
    3D tensor of shape `(num_samples, n, features)`.
  """

  def __init__(self, n, **kwargs):
    super(RepeatVector, self).__init__(**kwargs)
    self.n = n
    if not isinstance(n, int):
      raise TypeError(f'Expected an integer value for `n`, got {type(n)}.')
    self.input_spec = InputSpec(ndim=2)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    return tf.TensorShape([input_shape[0], self.n, input_shape[1]])

  def call(self, inputs):
    return K.repeat(inputs, self.n)

  def get_config(self):
    config = {'n': self.n}
    base_config = super(RepeatVector, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Rescaling (scale, offset=0.0, **kwargs)

Multiply inputs by scale and adds offset.

For instance:

  1. To rescale an input in the [0, 255] range to be in the [0, 1] range, you would pass scale=1./255.

  2. To rescale an input in the [0, 255] range to be in the [-1, 1] range, you would pass scale=1./127.5, offset=-1.

The rescaling is applied both during training and inference.

Input shape: Arbitrary.

Output shape: Same as input.

Args

scale
Float, the scale to apply to the inputs.
offset
Float, the offset to apply to the inputs.
Expand source code
class Rescaling(base_layer.Layer):
  """Multiply inputs by `scale` and adds `offset`.

  For instance:

  1. To rescale an input in the `[0, 255]` range
  to be in the `[0, 1]` range, you would pass `scale=1./255`.

  2. To rescale an input in the `[0, 255]` range to be in the `[-1, 1]` range,
  you would pass `scale=1./127.5, offset=-1`.

  The rescaling is applied both during training and inference.

  Input shape:
    Arbitrary.

  Output shape:
    Same as input.

  Args:
    scale: Float, the scale to apply to the inputs.
    offset: Float, the offset to apply to the inputs.
  """

  def __init__(self, scale, offset=0., **kwargs):
    self.scale = scale
    self.offset = offset
    super(Rescaling, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('Rescaling').set(True)

  def call(self, inputs):
    dtype = self._compute_dtype
    scale = tf.cast(self.scale, dtype)
    offset = tf.cast(self.offset, dtype)
    return tf.cast(inputs, dtype) * scale + offset

  def compute_output_shape(self, input_shape):
    return input_shape

  def get_config(self):
    config = {
        'scale': self.scale,
        'offset': self.offset,
    }
    base_config = super(Rescaling, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Reshape (target_shape, **kwargs)

Layer that reshapes inputs into the given shape.

Input shape: Arbitrary, although all dimensions in the input shape must be known/fixed. Use the keyword argument input_shape (tuple of integers, does not include the samples/batch size axis) when using this layer as the first layer in a model.

Output shape: (batch_size,) + target_shape

Example:

>>> # as first layer in a Sequential model
>>> model = tf.keras.Sequential()
>>> model.add(tf.keras.layers.Reshape((3, 4), input_shape=(12,)))
>>> # model.output_shape == (None, 3, 4), <code>None</code> is the batch size.
>>> model.output_shape
(None, 3, 4)
>>> # as intermediate layer in a Sequential model
>>> model.add(tf.keras.layers.Reshape((6, 2)))
>>> model.output_shape
(None, 6, 2)
>>> # also supports shape inference using `-1` as dimension
>>> model.add(tf.keras.layers.Reshape((-1, 2, 2)))
>>> model.output_shape
(None, 3, 2, 2)

Creates a tf.keras.layers.Reshape layer instance.

Args

target_shape
Target shape. Tuple of integers, does not include the samples dimension (batch size).
**kwargs
Any additional layer keyword arguments.
Expand source code
class Reshape(Layer):
  """Layer that reshapes inputs into the given shape.

  Input shape:
    Arbitrary, although all dimensions in the input shape must be known/fixed.
    Use the keyword argument `input_shape` (tuple of integers, does not include
    the samples/batch size axis) when using this layer as the first layer
    in a model.

  Output shape:
    `(batch_size,) + target_shape`

  Example:

  >>> # as first layer in a Sequential model
  >>> model = tf.keras.Sequential()
  >>> model.add(tf.keras.layers.Reshape((3, 4), input_shape=(12,)))
  >>> # model.output_shape == (None, 3, 4), `None` is the batch size.
  >>> model.output_shape
  (None, 3, 4)

  >>> # as intermediate layer in a Sequential model
  >>> model.add(tf.keras.layers.Reshape((6, 2)))
  >>> model.output_shape
  (None, 6, 2)

  >>> # also supports shape inference using `-1` as dimension
  >>> model.add(tf.keras.layers.Reshape((-1, 2, 2)))
  >>> model.output_shape
  (None, 3, 2, 2)
  """

  def __init__(self, target_shape, **kwargs):
    """Creates a `tf.keras.layers.Reshape`  layer instance.

    Args:
      target_shape: Target shape. Tuple of integers, does not include the
        samples dimension (batch size).
      **kwargs: Any additional layer keyword arguments.
    """
    super(Reshape, self).__init__(**kwargs)
    self.target_shape = tuple(target_shape)

  def _fix_unknown_dimension(self, input_shape, output_shape):
    """Find and replace a missing dimension in an output shape.

    This is a near direct port of the internal Numpy function
    `_fix_unknown_dimension` in `numpy/core/src/multiarray/shape.c`

    Args:
      input_shape: Shape of array being reshaped
      output_shape: Desired shape of the array with at most
        a single -1 which indicates a dimension that should be
        derived from the input shape.

    Returns:
      The new output shape with a -1 replaced with its computed value.

    Raises:
      ValueError: If the total array size of the output_shape is
      different than the input_shape, or more than one unknown dimension
      is specified.
    """
    output_shape = list(output_shape)
    msg = ('total size of new array must be unchanged, '
           'input_shape = {}, output_shape = {}'
           .format(input_shape, output_shape))

    known, unknown = 1, None
    for index, dim in enumerate(output_shape):
      if dim < 0:
        if unknown is None:
          unknown = index
        else:
          raise ValueError('Can only specify one unknown dimension.')
      else:
        known *= dim

    original = np.prod(input_shape, dtype=int)
    if unknown is not None:
      if known == 0 or original % known != 0:
        raise ValueError(msg)
      output_shape[unknown] = original // known
    elif original != known:
      raise ValueError(msg)
    return output_shape

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if None in input_shape[1:]:
      output_shape = [input_shape[0]]
      # input shape (partially) unknown? replace -1's with None's
      output_shape += tuple(s if s != -1 else None for s in self.target_shape)
    else:
      output_shape = [input_shape[0]]
      output_shape += self._fix_unknown_dimension(input_shape[1:],
                                                  self.target_shape)
    return tf.TensorShape(output_shape)

  def call(self, inputs):
    result = tf.reshape(
        inputs, (tf.shape(inputs)[0],) + self.target_shape)
    if not tf.executing_eagerly():
      # Set the static shape for the result since it might lost during array_ops
      # reshape, eg, some `None` dim in the result could be inferred.
      result.set_shape(self.compute_output_shape(inputs.shape))
    return result

  def get_config(self):
    config = {'target_shape': self.target_shape}
    base_config = super(Reshape, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Resizing (height, width, interpolation='bilinear', crop_to_aspect_ratio=False, **kwargs)

Image resizing layer.

Resize the batched image input to target height and width. The input should be a 4D (batched) or 3D (unbatched) tensor in "channels_last" format.

Args

height
Integer, the height of the output shape.
width
Integer, the width of the output shape.
interpolation
String, the interpolation method. Defaults to "bilinear". Supports "bilinear", "nearest", "bicubic", "area", "lanczos3", "lanczos5", "gaussian", "mitchellcubic".
crop_to_aspect_ratio
If True, resize the images without aspect ratio distortion. When the original aspect ratio differs from the target aspect ratio, the output image will be cropped so as to return the largest possible window in the image (of size (height, width)) that matches the target aspect ratio. By default (crop_to_aspect_ratio=False), aspect ratio may not be preserved.
Expand source code
class Resizing(base_layer.Layer):
  """Image resizing layer.

  Resize the batched image input to target height and width. The input should
  be a 4D (batched) or 3D (unbatched) tensor in `"channels_last"` format.

  Args:
    height: Integer, the height of the output shape.
    width: Integer, the width of the output shape.
    interpolation: String, the interpolation method. Defaults to `"bilinear"`.
      Supports `"bilinear"`, `"nearest"`, `"bicubic"`, `"area"`, `"lanczos3"`,
      `"lanczos5"`, `"gaussian"`, `"mitchellcubic"`.
    crop_to_aspect_ratio: If True, resize the images without aspect
      ratio distortion. When the original aspect ratio differs from the target
      aspect ratio, the output image will be cropped so as to return the largest
      possible window in the image (of size `(height, width)`) that matches
      the target aspect ratio. By default (`crop_to_aspect_ratio=False`),
      aspect ratio may not be preserved.
  """

  def __init__(self,
               height,
               width,
               interpolation='bilinear',
               crop_to_aspect_ratio=False,
               **kwargs):
    self.target_height = height
    self.target_width = width
    self.interpolation = interpolation
    self.crop_to_aspect_ratio = crop_to_aspect_ratio
    self._interpolation_method = get_interpolation(interpolation)
    super(Resizing, self).__init__(**kwargs)
    base_preprocessing_layer.keras_kpl_gauge.get_cell('Resizing').set(True)

  def call(self, inputs):
    if self.crop_to_aspect_ratio:
      outputs = image_preprocessing.smart_resize(
          inputs,
          size=[self.target_height, self.target_width],
          interpolation=self._interpolation_method)
    else:
      outputs = tf.image.resize(
          inputs,
          size=[self.target_height, self.target_width],
          method=self._interpolation_method)
    return outputs

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    input_shape[H_AXIS] = self.target_height
    input_shape[W_AXIS] = self.target_width
    return tf.TensorShape(input_shape)

  def get_config(self):
    config = {
        'height': self.target_height,
        'width': self.target_width,
        'interpolation': self.interpolation,
        'crop_to_aspect_ratio': self.crop_to_aspect_ratio,
    }
    base_config = super(Resizing, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class SeparableConv1D (filters, kernel_size, strides=1, padding='valid', data_format=None, dilation_rate=1, depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None, **kwargs)

Depthwise separable 1D convolution.

This layer performs a depthwise convolution that acts separately on channels, followed by a pointwise convolution that mixes channels. If use_bias is True and a bias initializer is provided, it adds a bias vector to the output. It then optionally applies an activation function to produce the final output.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of filters in the convolution).
kernel_size
A single integer specifying the spatial dimensions of the filters.
strides
A single integer specifying the strides of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid", "same", or "causal" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input. "causal" results in causal (dilated) convolutions, e.g. output[t] does not depend on input[t+1:].
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, length, channels) while channels_first corresponds to inputs with shape (batch_size, channels, length).
dilation_rate
A single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
depth_multiplier
The number of depthwise convolution output channels for each input channel. The total number of depthwise convolution output channels will be equal to num_filters_in * depth_multiplier.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias.
depthwise_initializer
An initializer for the depthwise convolution kernel ( see keras.initializers). If None, then the default initializer ( 'glorot_uniform') will be used.
pointwise_initializer
An initializer for the pointwise convolution kernel ( see keras.initializers). If None, then the default initializer ('glorot_uniform') will be used.
bias_initializer
An initializer for the bias vector. If None, the default initializer ('zeros') will be used (see keras.initializers).
depthwise_regularizer
Optional regularizer for the depthwise convolution kernel (see keras.regularizers).
pointwise_regularizer
Optional regularizer for the pointwise convolution kernel (see keras.regularizers).
bias_regularizer
Optional regularizer for the bias vector ( see keras.regularizers).
activity_regularizer
Optional regularizer function for the output ( see keras.regularizers).
depthwise_constraint
Optional projection function to be applied to the depthwise kernel after being updated by an Optimizer (e.g. used for norm constraints or value constraints for layer weights). The function must take as input the unprojected variable and must return the projected variable (which must have the same shape). Constraints are not safe to use when doing asynchronous distributed training ( see keras.constraints).
pointwise_constraint
Optional projection function to be applied to the pointwise kernel after being updated by an Optimizer ( see keras.constraints).
bias_constraint
Optional projection function to be applied to the bias after being updated by an Optimizer ( see keras.constraints).
trainable
Boolean, if True the weights of this layer will be marked as trainable (and listed in layer.trainable_weights).

Input shape: 3D tensor with shape: (batch_size, channels, steps) if data_format='channels_first' or 5D tensor with shape: (batch_size, steps, channels) if data_format='channels_last'.

Output shape: 3D tensor with shape: (batch_size, filters, new_steps) if data_format='channels_first' or 3D tensor with shape: (batch_size, new_steps, filters) if data_format='channels_last'. new_steps value might have changed due to padding or strides.

Returns

A tensor of rank 3 representing activation(separableconv1d(inputs, kernel) + bias).

Raises

ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class SeparableConv1D(SeparableConv):
  """Depthwise separable 1D convolution.

  This layer performs a depthwise convolution that acts separately on
  channels, followed by a pointwise convolution that mixes channels.
  If `use_bias` is True and a bias initializer is provided,
  it adds a bias vector to the output.
  It then optionally applies an activation function to produce the final output.

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number
      of filters in the convolution).
    kernel_size: A single integer specifying the spatial
      dimensions of the filters.
    strides: A single integer specifying the strides
      of the convolution.
      Specifying any `stride` value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input. `"causal"` results in causal
      (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, length, channels)` while `channels_first` corresponds to
      inputs with shape `(batch_size, channels, length)`.
    dilation_rate: A single integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    depth_multiplier: The number of depthwise convolution output channels for
      each input channel. The total number of depthwise convolution output
      channels will be equal to `num_filters_in * depth_multiplier`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias.
    depthwise_initializer: An initializer for the depthwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer (
      'glorot_uniform') will be used.
    pointwise_initializer: An initializer for the pointwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer 
      ('glorot_uniform') will be used.
    bias_initializer: An initializer for the bias vector. If None, the default
      initializer ('zeros') will be used (see `keras.initializers`).
    depthwise_regularizer: Optional regularizer for the depthwise
      convolution kernel (see `keras.regularizers`).
    pointwise_regularizer: Optional regularizer for the pointwise
      convolution kernel (see `keras.regularizers`).
    bias_regularizer: Optional regularizer for the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Optional regularizer function for the output (
      see `keras.regularizers`).
    depthwise_constraint: Optional projection function to be applied to the
      depthwise kernel after being updated by an `Optimizer` (e.g. used for
      norm constraints or value constraints for layer weights). The function
      must take as input the unprojected variable and must return the
      projected variable (which must have the same shape). Constraints are
      not safe to use when doing asynchronous distributed training (
      see `keras.constraints`).
    pointwise_constraint: Optional projection function to be applied to the
      pointwise kernel after being updated by an `Optimizer` (
      see `keras.constraints`).
    bias_constraint: Optional projection function to be applied to the
      bias after being updated by an `Optimizer` (
      see `keras.constraints`).
    trainable: Boolean, if `True` the weights of this layer will be marked as
      trainable (and listed in `layer.trainable_weights`).

  Input shape:
    3D tensor with shape:
    `(batch_size, channels, steps)` if data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, steps, channels)` if data_format='channels_last'.

  Output shape:
    3D tensor with shape:
    `(batch_size, filters, new_steps)` if data_format='channels_first'
    or 3D tensor with shape:
    `(batch_size,  new_steps, filters)` if data_format='channels_last'.
    `new_steps` value might have changed due to padding or strides.

  Returns:
    A tensor of rank 3 representing
    `activation(separableconv1d(inputs, kernel) + bias)`.

  Raises:
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format=None,
               dilation_rate=1,
               depth_multiplier=1,
               activation=None,
               use_bias=True,
               depthwise_initializer='glorot_uniform',
               pointwise_initializer='glorot_uniform',
               bias_initializer='zeros',
               depthwise_regularizer=None,
               pointwise_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               depthwise_constraint=None,
               pointwise_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(SeparableConv1D, self).__init__(
        rank=1,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        depth_multiplier=depth_multiplier,
        activation=activations.get(activation),
        use_bias=use_bias,
        depthwise_initializer=initializers.get(depthwise_initializer),
        pointwise_initializer=initializers.get(pointwise_initializer),
        bias_initializer=initializers.get(bias_initializer),
        depthwise_regularizer=regularizers.get(depthwise_regularizer),
        pointwise_regularizer=regularizers.get(pointwise_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        depthwise_constraint=constraints.get(depthwise_constraint),
        pointwise_constraint=constraints.get(pointwise_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

  def call(self, inputs):
    if self.padding == 'causal':
      inputs = tf.pad(inputs, self._compute_causal_padding(inputs))
    if self.data_format == 'channels_last':
      strides = (1,) + self.strides * 2 + (1,)
      spatial_start_dim = 1
    else:
      strides = (1, 1) + self.strides * 2
      spatial_start_dim = 2

    # Explicitly broadcast inputs and kernels to 4D.
    # TODO(fchollet): refactor when a native separable_conv1d op is available.
    inputs = tf.expand_dims(inputs, spatial_start_dim)
    depthwise_kernel = tf.expand_dims(self.depthwise_kernel, 0)
    pointwise_kernel = tf.expand_dims(self.pointwise_kernel, 0)
    dilation_rate = (1,) + self.dilation_rate

    if self.padding == 'causal':
      op_padding = 'valid'
    else:
      op_padding = self.padding
    outputs = tf.compat.v1.nn.separable_conv2d(
        inputs,
        depthwise_kernel,
        pointwise_kernel,
        strides=strides,
        padding=op_padding.upper(),
        rate=dilation_rate,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    outputs = tf.squeeze(outputs, [spatial_start_dim])

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

Ancestors

Subclasses

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  if self.padding == 'causal':
    inputs = tf.pad(inputs, self._compute_causal_padding(inputs))
  if self.data_format == 'channels_last':
    strides = (1,) + self.strides * 2 + (1,)
    spatial_start_dim = 1
  else:
    strides = (1, 1) + self.strides * 2
    spatial_start_dim = 2

  # Explicitly broadcast inputs and kernels to 4D.
  # TODO(fchollet): refactor when a native separable_conv1d op is available.
  inputs = tf.expand_dims(inputs, spatial_start_dim)
  depthwise_kernel = tf.expand_dims(self.depthwise_kernel, 0)
  pointwise_kernel = tf.expand_dims(self.pointwise_kernel, 0)
  dilation_rate = (1,) + self.dilation_rate

  if self.padding == 'causal':
    op_padding = 'valid'
  else:
    op_padding = self.padding
  outputs = tf.compat.v1.nn.separable_conv2d(
      inputs,
      depthwise_kernel,
      pointwise_kernel,
      strides=strides,
      padding=op_padding.upper(),
      rate=dilation_rate,
      data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  if self.use_bias:
    outputs = tf.nn.bias_add(
        outputs,
        self.bias,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  outputs = tf.squeeze(outputs, [spatial_start_dim])

  if self.activation is not None:
    return self.activation(outputs)
  return outputs
class SeparableConvolution1D (filters, kernel_size, strides=1, padding='valid', data_format=None, dilation_rate=1, depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None, **kwargs)

Depthwise separable 1D convolution.

This layer performs a depthwise convolution that acts separately on channels, followed by a pointwise convolution that mixes channels. If use_bias is True and a bias initializer is provided, it adds a bias vector to the output. It then optionally applies an activation function to produce the final output.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of filters in the convolution).
kernel_size
A single integer specifying the spatial dimensions of the filters.
strides
A single integer specifying the strides of the convolution. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
One of "valid", "same", or "causal" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input. "causal" results in causal (dilated) convolutions, e.g. output[t] does not depend on input[t+1:].
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, length, channels) while channels_first corresponds to inputs with shape (batch_size, channels, length).
dilation_rate
A single integer, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.
depth_multiplier
The number of depthwise convolution output channels for each input channel. The total number of depthwise convolution output channels will be equal to num_filters_in * depth_multiplier.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias.
depthwise_initializer
An initializer for the depthwise convolution kernel ( see keras.initializers). If None, then the default initializer ( 'glorot_uniform') will be used.
pointwise_initializer
An initializer for the pointwise convolution kernel ( see keras.initializers). If None, then the default initializer ('glorot_uniform') will be used.
bias_initializer
An initializer for the bias vector. If None, the default initializer ('zeros') will be used (see keras.initializers).
depthwise_regularizer
Optional regularizer for the depthwise convolution kernel (see keras.regularizers).
pointwise_regularizer
Optional regularizer for the pointwise convolution kernel (see keras.regularizers).
bias_regularizer
Optional regularizer for the bias vector ( see keras.regularizers).
activity_regularizer
Optional regularizer function for the output ( see keras.regularizers).
depthwise_constraint
Optional projection function to be applied to the depthwise kernel after being updated by an Optimizer (e.g. used for norm constraints or value constraints for layer weights). The function must take as input the unprojected variable and must return the projected variable (which must have the same shape). Constraints are not safe to use when doing asynchronous distributed training ( see keras.constraints).
pointwise_constraint
Optional projection function to be applied to the pointwise kernel after being updated by an Optimizer ( see keras.constraints).
bias_constraint
Optional projection function to be applied to the bias after being updated by an Optimizer ( see keras.constraints).
trainable
Boolean, if True the weights of this layer will be marked as trainable (and listed in layer.trainable_weights).

Input shape: 3D tensor with shape: (batch_size, channels, steps) if data_format='channels_first' or 5D tensor with shape: (batch_size, steps, channels) if data_format='channels_last'.

Output shape: 3D tensor with shape: (batch_size, filters, new_steps) if data_format='channels_first' or 3D tensor with shape: (batch_size, new_steps, filters) if data_format='channels_last'. new_steps value might have changed due to padding or strides.

Returns

A tensor of rank 3 representing activation(separableconv1d(inputs, kernel) + bias).

Raises

ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class SeparableConv1D(SeparableConv):
  """Depthwise separable 1D convolution.

  This layer performs a depthwise convolution that acts separately on
  channels, followed by a pointwise convolution that mixes channels.
  If `use_bias` is True and a bias initializer is provided,
  it adds a bias vector to the output.
  It then optionally applies an activation function to produce the final output.

  Args:
    filters: Integer, the dimensionality of the output space (i.e. the number
      of filters in the convolution).
    kernel_size: A single integer specifying the spatial
      dimensions of the filters.
    strides: A single integer specifying the strides
      of the convolution.
      Specifying any `stride` value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: One of `"valid"`, `"same"`, or `"causal"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input. `"causal"` results in causal
      (dilated) convolutions, e.g. `output[t]` does not depend on `input[t+1:]`.
    data_format: A string, one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, length, channels)` while `channels_first` corresponds to
      inputs with shape `(batch_size, channels, length)`.
    dilation_rate: A single integer, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any stride value != 1.
    depth_multiplier: The number of depthwise convolution output channels for
      each input channel. The total number of depthwise convolution output
      channels will be equal to `num_filters_in * depth_multiplier`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias.
    depthwise_initializer: An initializer for the depthwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer (
      'glorot_uniform') will be used.
    pointwise_initializer: An initializer for the pointwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer 
      ('glorot_uniform') will be used.
    bias_initializer: An initializer for the bias vector. If None, the default
      initializer ('zeros') will be used (see `keras.initializers`).
    depthwise_regularizer: Optional regularizer for the depthwise
      convolution kernel (see `keras.regularizers`).
    pointwise_regularizer: Optional regularizer for the pointwise
      convolution kernel (see `keras.regularizers`).
    bias_regularizer: Optional regularizer for the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Optional regularizer function for the output (
      see `keras.regularizers`).
    depthwise_constraint: Optional projection function to be applied to the
      depthwise kernel after being updated by an `Optimizer` (e.g. used for
      norm constraints or value constraints for layer weights). The function
      must take as input the unprojected variable and must return the
      projected variable (which must have the same shape). Constraints are
      not safe to use when doing asynchronous distributed training (
      see `keras.constraints`).
    pointwise_constraint: Optional projection function to be applied to the
      pointwise kernel after being updated by an `Optimizer` (
      see `keras.constraints`).
    bias_constraint: Optional projection function to be applied to the
      bias after being updated by an `Optimizer` (
      see `keras.constraints`).
    trainable: Boolean, if `True` the weights of this layer will be marked as
      trainable (and listed in `layer.trainable_weights`).

  Input shape:
    3D tensor with shape:
    `(batch_size, channels, steps)` if data_format='channels_first'
    or 5D tensor with shape:
    `(batch_size, steps, channels)` if data_format='channels_last'.

  Output shape:
    3D tensor with shape:
    `(batch_size, filters, new_steps)` if data_format='channels_first'
    or 3D tensor with shape:
    `(batch_size,  new_steps, filters)` if data_format='channels_last'.
    `new_steps` value might have changed due to padding or strides.

  Returns:
    A tensor of rank 3 representing
    `activation(separableconv1d(inputs, kernel) + bias)`.

  Raises:
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=1,
               padding='valid',
               data_format=None,
               dilation_rate=1,
               depth_multiplier=1,
               activation=None,
               use_bias=True,
               depthwise_initializer='glorot_uniform',
               pointwise_initializer='glorot_uniform',
               bias_initializer='zeros',
               depthwise_regularizer=None,
               pointwise_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               depthwise_constraint=None,
               pointwise_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(SeparableConv1D, self).__init__(
        rank=1,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        depth_multiplier=depth_multiplier,
        activation=activations.get(activation),
        use_bias=use_bias,
        depthwise_initializer=initializers.get(depthwise_initializer),
        pointwise_initializer=initializers.get(pointwise_initializer),
        bias_initializer=initializers.get(bias_initializer),
        depthwise_regularizer=regularizers.get(depthwise_regularizer),
        pointwise_regularizer=regularizers.get(pointwise_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        depthwise_constraint=constraints.get(depthwise_constraint),
        pointwise_constraint=constraints.get(pointwise_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

  def call(self, inputs):
    if self.padding == 'causal':
      inputs = tf.pad(inputs, self._compute_causal_padding(inputs))
    if self.data_format == 'channels_last':
      strides = (1,) + self.strides * 2 + (1,)
      spatial_start_dim = 1
    else:
      strides = (1, 1) + self.strides * 2
      spatial_start_dim = 2

    # Explicitly broadcast inputs and kernels to 4D.
    # TODO(fchollet): refactor when a native separable_conv1d op is available.
    inputs = tf.expand_dims(inputs, spatial_start_dim)
    depthwise_kernel = tf.expand_dims(self.depthwise_kernel, 0)
    pointwise_kernel = tf.expand_dims(self.pointwise_kernel, 0)
    dilation_rate = (1,) + self.dilation_rate

    if self.padding == 'causal':
      op_padding = 'valid'
    else:
      op_padding = self.padding
    outputs = tf.compat.v1.nn.separable_conv2d(
        inputs,
        depthwise_kernel,
        pointwise_kernel,
        strides=strides,
        padding=op_padding.upper(),
        rate=dilation_rate,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    outputs = tf.squeeze(outputs, [spatial_start_dim])

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

Ancestors

Subclasses

Inherited members

class SeparableConv2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None, **kwargs)

Depthwise separable 2D convolution.

Separable convolutions consist of first performing a depthwise spatial convolution (which acts on each input channel separately) followed by a pointwise convolution which mixes the resulting output channels. The depth_multiplier argument controls how many output channels are generated per input channel in the depthwise step.

Intuitively, separable convolutions can be understood as a way to factorize a convolution kernel into two smaller kernels, or as an extreme version of an Inception block.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Current implementation only supports equal length strides in the row and column dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
An integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
depth_multiplier
The number of depthwise convolution output channels for each input channel. The total number of depthwise convolution output channels will be equal to filters_in * depth_multiplier.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
depthwise_initializer
An initializer for the depthwise convolution kernel ( see keras.initializers). If None, then the default initializer ( 'glorot_uniform') will be used.
pointwise_initializer
An initializer for the pointwise convolution kernel ( see keras.initializers). If None, then the default initializer ('glorot_uniform') will be used.
bias_initializer
An initializer for the bias vector. If None, the default initializer ('zeros') will be used (see keras.initializers).
depthwise_regularizer
Regularizer function applied to the depthwise kernel matrix (see keras.regularizers).
pointwise_regularizer
Regularizer function applied to the pointwise kernel matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
depthwise_constraint
Constraint function applied to the depthwise kernel matrix ( see keras.constraints).
pointwise_constraint
Constraint function applied to the pointwise kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 4D tensor with shape: (batch_size, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, rows, cols, channels) if data_format='channels_last'.

Output shape: 4D tensor with shape: (batch_size, filters, new_rows, new_cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding.

Returns

A tensor of rank 4 representing activation(separableconv2d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class SeparableConv2D(SeparableConv):
  """Depthwise separable 2D convolution.

  Separable convolutions consist of first performing
  a depthwise spatial convolution
  (which acts on each input channel separately)
  followed by a pointwise convolution which mixes the resulting
  output channels. The `depth_multiplier` argument controls how many
  output channels are generated per input channel in the depthwise step.

  Intuitively, separable convolutions can be understood as
  a way to factorize a convolution kernel into two smaller kernels,
  or as an extreme version of an Inception block.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions. Current implementation only supports equal 
      length strides in the row and column dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: An integer or tuple/list of 2 integers, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any `strides` value != 1.
    depth_multiplier: The number of depthwise convolution output channels
      for each input channel.
      The total number of depthwise convolution output
      channels will be equal to `filters_in * depth_multiplier`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    depthwise_initializer: An initializer for the depthwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer (
      'glorot_uniform') will be used.
    pointwise_initializer: An initializer for the pointwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer 
      ('glorot_uniform') will be used.
    bias_initializer: An initializer for the bias vector. If None, the default
      initializer ('zeros') will be used (see `keras.initializers`).
    depthwise_regularizer: Regularizer function applied to
      the depthwise kernel matrix (see `keras.regularizers`).
    pointwise_regularizer: Regularizer function applied to
      the pointwise kernel matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    depthwise_constraint: Constraint function applied to
      the depthwise kernel matrix (
      see `keras.constraints`).
    pointwise_constraint: Constraint function applied to
      the pointwise kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    4D tensor with shape:
    `(batch_size, channels, rows, cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    4D tensor with shape:
    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
    `rows` and `cols` values might have changed due to padding.

  Returns:
    A tensor of rank 4 representing
    `activation(separableconv2d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1),
               depth_multiplier=1,
               activation=None,
               use_bias=True,
               depthwise_initializer='glorot_uniform',
               pointwise_initializer='glorot_uniform',
               bias_initializer='zeros',
               depthwise_regularizer=None,
               pointwise_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               depthwise_constraint=None,
               pointwise_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(SeparableConv2D, self).__init__(
        rank=2,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        depth_multiplier=depth_multiplier,
        activation=activations.get(activation),
        use_bias=use_bias,
        depthwise_initializer=initializers.get(depthwise_initializer),
        pointwise_initializer=initializers.get(pointwise_initializer),
        bias_initializer=initializers.get(bias_initializer),
        depthwise_regularizer=regularizers.get(depthwise_regularizer),
        pointwise_regularizer=regularizers.get(pointwise_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        depthwise_constraint=constraints.get(depthwise_constraint),
        pointwise_constraint=constraints.get(pointwise_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

  def call(self, inputs):
    # Apply the actual ops.
    if self.data_format == 'channels_last':
      strides = (1,) + self.strides + (1,)
    else:
      strides = (1, 1) + self.strides
    outputs = tf.compat.v1.nn.separable_conv2d(
        inputs,
        self.depthwise_kernel,
        self.pointwise_kernel,
        strides=strides,
        padding=self.padding.upper(),
        rate=self.dilation_rate,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

Ancestors

Subclasses

Methods

def call(self, inputs)

This is where the layer's logic lives.

Note here that call() method in tf.keras is little bit different from keras API. In keras API, you can pass support masking for layers as additional arguments. Whereas tf.keras has compute_mask() method to support masking.

Args

inputs
Input tensor, or dict/list/tuple of input tensors. The first positional inputs argument is subject to special rules: - inputs must be explicitly passed. A layer cannot have zero arguments, and inputs cannot be provided via the default value of a keyword argument. - NumPy array or Python scalar values in inputs get cast as tensors. - Keras mask metadata is only collected from inputs. - Layers are built (build(input_shape) method) using shape info from inputs only. - input_spec compatibility is only checked against inputs. - Mixed precision input casting is only applied to inputs. If a layer has tensor arguments in *args or **kwargs, their casting behavior in mixed precision should be handled manually. - The SavedModel input specification is generated using inputs only. - Integration with various ecosystem packages like TFMOT, TFLite, TF.js, etc is only supported for inputs and not for tensors in positional and keyword arguments.
*args
Additional positional arguments. May contain tensors, although this is not recommended, for the reasons above.
**kwargs
Additional keyword arguments. May contain tensors, although this is not recommended, for the reasons above. The following optional keyword arguments are reserved: - training: Boolean scalar tensor of Python boolean indicating whether the call is meant for training or inference. - mask: Boolean input mask. If the layer's call() method takes a mask argument, its default value will be set to the mask generated for inputs by the previous layer (if input did come from a layer that generated a corresponding mask, i.e. if it came from a Keras layer with masking support).

Returns

A tensor or list/tuple of tensors.

Expand source code
def call(self, inputs):
  # Apply the actual ops.
  if self.data_format == 'channels_last':
    strides = (1,) + self.strides + (1,)
  else:
    strides = (1, 1) + self.strides
  outputs = tf.compat.v1.nn.separable_conv2d(
      inputs,
      self.depthwise_kernel,
      self.pointwise_kernel,
      strides=strides,
      padding=self.padding.upper(),
      rate=self.dilation_rate,
      data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  if self.use_bias:
    outputs = tf.nn.bias_add(
        outputs,
        self.bias,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

  if self.activation is not None:
    return self.activation(outputs)
  return outputs
class SeparableConvolution2D (filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None, **kwargs)

Depthwise separable 2D convolution.

Separable convolutions consist of first performing a depthwise spatial convolution (which acts on each input channel separately) followed by a pointwise convolution which mixes the resulting output channels. The depth_multiplier argument controls how many output channels are generated per input channel in the depthwise step.

Intuitively, separable convolutions can be understood as a way to factorize a convolution kernel into two smaller kernels, or as an extreme version of an Inception block.

Args

filters
Integer, the dimensionality of the output space (i.e. the number of output filters in the convolution).
kernel_size
An integer or tuple/list of 2 integers, specifying the height and width of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.
strides
An integer or tuple/list of 2 integers, specifying the strides of the convolution along the height and width. Can be a single integer to specify the same value for all spatial dimensions. Current implementation only supports equal length strides in the row and column dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.
padding
one of "valid" or "same" (case-insensitive). "valid" means no padding. "same" results in padding with zeros evenly to the left/right or up/down of the input such that output has the same height/width dimension as the input.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
dilation_rate
An integer or tuple/list of 2 integers, specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.
depth_multiplier
The number of depthwise convolution output channels for each input channel. The total number of depthwise convolution output channels will be equal to filters_in * depth_multiplier.
activation
Activation function to use. If you don't specify anything, no activation is applied ( see keras.activations).
use_bias
Boolean, whether the layer uses a bias vector.
depthwise_initializer
An initializer for the depthwise convolution kernel ( see keras.initializers). If None, then the default initializer ( 'glorot_uniform') will be used.
pointwise_initializer
An initializer for the pointwise convolution kernel ( see keras.initializers). If None, then the default initializer ('glorot_uniform') will be used.
bias_initializer
An initializer for the bias vector. If None, the default initializer ('zeros') will be used (see keras.initializers).
depthwise_regularizer
Regularizer function applied to the depthwise kernel matrix (see keras.regularizers).
pointwise_regularizer
Regularizer function applied to the pointwise kernel matrix (see keras.regularizers).
bias_regularizer
Regularizer function applied to the bias vector ( see keras.regularizers).
activity_regularizer
Regularizer function applied to the output of the layer (its "activation") ( see keras.regularizers).
depthwise_constraint
Constraint function applied to the depthwise kernel matrix ( see keras.constraints).
pointwise_constraint
Constraint function applied to the pointwise kernel matrix ( see keras.constraints).
bias_constraint
Constraint function applied to the bias vector ( see keras.constraints).

Input shape: 4D tensor with shape: (batch_size, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, rows, cols, channels) if data_format='channels_last'.

Output shape: 4D tensor with shape: (batch_size, filters, new_rows, new_cols) if data_format='channels_first' or 4D tensor with shape: (batch_size, new_rows, new_cols, filters) if data_format='channels_last'. rows and cols values might have changed due to padding.

Returns

A tensor of rank 4 representing activation(separableconv2d(inputs, kernel) + bias).

Raises

ValueError
if padding is "causal".
ValueError
when both strides > 1 and dilation_rate > 1.
Expand source code
class SeparableConv2D(SeparableConv):
  """Depthwise separable 2D convolution.

  Separable convolutions consist of first performing
  a depthwise spatial convolution
  (which acts on each input channel separately)
  followed by a pointwise convolution which mixes the resulting
  output channels. The `depth_multiplier` argument controls how many
  output channels are generated per input channel in the depthwise step.

  Intuitively, separable convolutions can be understood as
  a way to factorize a convolution kernel into two smaller kernels,
  or as an extreme version of an Inception block.

  Args:
    filters: Integer, the dimensionality of the output space
      (i.e. the number of output filters in the convolution).
    kernel_size: An integer or tuple/list of 2 integers, specifying the
      height and width of the 2D convolution window.
      Can be a single integer to specify the same value for
      all spatial dimensions.
    strides: An integer or tuple/list of 2 integers,
      specifying the strides of the convolution along the height and width.
      Can be a single integer to specify the same value for
      all spatial dimensions. Current implementation only supports equal 
      length strides in the row and column dimensions.
      Specifying any stride value != 1 is incompatible with specifying
      any `dilation_rate` value != 1.
    padding: one of `"valid"` or `"same"` (case-insensitive).
      `"valid"` means no padding. `"same"` results in padding with zeros evenly
      to the left/right or up/down of the input such that output has the same
      height/width dimension as the input.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    dilation_rate: An integer or tuple/list of 2 integers, specifying
      the dilation rate to use for dilated convolution.
      Currently, specifying any `dilation_rate` value != 1 is
      incompatible with specifying any `strides` value != 1.
    depth_multiplier: The number of depthwise convolution output channels
      for each input channel.
      The total number of depthwise convolution output
      channels will be equal to `filters_in * depth_multiplier`.
    activation: Activation function to use.
      If you don't specify anything, no activation is applied (
      see `keras.activations`).
    use_bias: Boolean, whether the layer uses a bias vector.
    depthwise_initializer: An initializer for the depthwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer (
      'glorot_uniform') will be used.
    pointwise_initializer: An initializer for the pointwise convolution kernel (
      see `keras.initializers`). If None, then the default initializer 
      ('glorot_uniform') will be used.
    bias_initializer: An initializer for the bias vector. If None, the default
      initializer ('zeros') will be used (see `keras.initializers`).
    depthwise_regularizer: Regularizer function applied to
      the depthwise kernel matrix (see `keras.regularizers`).
    pointwise_regularizer: Regularizer function applied to
      the pointwise kernel matrix (see `keras.regularizers`).
    bias_regularizer: Regularizer function applied to the bias vector (
      see `keras.regularizers`).
    activity_regularizer: Regularizer function applied to
      the output of the layer (its "activation") (
      see `keras.regularizers`).
    depthwise_constraint: Constraint function applied to
      the depthwise kernel matrix (
      see `keras.constraints`).
    pointwise_constraint: Constraint function applied to
      the pointwise kernel matrix (
      see `keras.constraints`).
    bias_constraint: Constraint function applied to the bias vector (
      see `keras.constraints`).

  Input shape:
    4D tensor with shape:
    `(batch_size, channels, rows, cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    4D tensor with shape:
    `(batch_size, filters, new_rows, new_cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(batch_size, new_rows, new_cols, filters)` if data_format='channels_last'.
    `rows` and `cols` values might have changed due to padding.

  Returns:
    A tensor of rank 4 representing
    `activation(separableconv2d(inputs, kernel) + bias)`.

  Raises:
    ValueError: if `padding` is "causal".
    ValueError: when both `strides` > 1 and `dilation_rate` > 1.
  """

  def __init__(self,
               filters,
               kernel_size,
               strides=(1, 1),
               padding='valid',
               data_format=None,
               dilation_rate=(1, 1),
               depth_multiplier=1,
               activation=None,
               use_bias=True,
               depthwise_initializer='glorot_uniform',
               pointwise_initializer='glorot_uniform',
               bias_initializer='zeros',
               depthwise_regularizer=None,
               pointwise_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               depthwise_constraint=None,
               pointwise_constraint=None,
               bias_constraint=None,
               **kwargs):
    super(SeparableConv2D, self).__init__(
        rank=2,
        filters=filters,
        kernel_size=kernel_size,
        strides=strides,
        padding=padding,
        data_format=data_format,
        dilation_rate=dilation_rate,
        depth_multiplier=depth_multiplier,
        activation=activations.get(activation),
        use_bias=use_bias,
        depthwise_initializer=initializers.get(depthwise_initializer),
        pointwise_initializer=initializers.get(pointwise_initializer),
        bias_initializer=initializers.get(bias_initializer),
        depthwise_regularizer=regularizers.get(depthwise_regularizer),
        pointwise_regularizer=regularizers.get(pointwise_regularizer),
        bias_regularizer=regularizers.get(bias_regularizer),
        activity_regularizer=regularizers.get(activity_regularizer),
        depthwise_constraint=constraints.get(depthwise_constraint),
        pointwise_constraint=constraints.get(pointwise_constraint),
        bias_constraint=constraints.get(bias_constraint),
        **kwargs)

  def call(self, inputs):
    # Apply the actual ops.
    if self.data_format == 'channels_last':
      strides = (1,) + self.strides + (1,)
    else:
      strides = (1, 1) + self.strides
    outputs = tf.compat.v1.nn.separable_conv2d(
        inputs,
        self.depthwise_kernel,
        self.pointwise_kernel,
        strides=strides,
        padding=self.padding.upper(),
        rate=self.dilation_rate,
        data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.use_bias:
      outputs = tf.nn.bias_add(
          outputs,
          self.bias,
          data_format=conv_utils.convert_data_format(self.data_format, ndim=4))

    if self.activation is not None:
      return self.activation(outputs)
    return outputs

Ancestors

Subclasses

Inherited members

class SimpleRNN (units, activation='tanh', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, return_sequences=False, return_state=False, go_backwards=False, stateful=False, unroll=False, **kwargs)

Fully-connected RNN where the output is to be fed back to input.

See the Keras RNN API guide for details about the usage of RNN API.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, (default True), whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs. Default: glorot_uniform.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state. Default: orthogonal.
bias_initializer
Initializer for the bias vector. Default: zeros.
kernel_regularizer
Regularizer function applied to the kernel weights matrix. Default: None.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix. Default: None.
bias_regularizer
Regularizer function applied to the bias vector. Default: None.
activity_regularizer
Regularizer function applied to the output of the layer (its "activation"). Default: None.
kernel_constraint
Constraint function applied to the kernel weights matrix. Default: None.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix. Default: None.
bias_constraint
Constraint function applied to the bias vector. Default: None.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs. Default: 0.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state. Default: 0.
return_sequences
Boolean. Whether to return the last output in the output sequence, or the full sequence. Default: False.
return_state
Boolean. Whether to return the last state in addition to the output. Default: False
go_backwards
Boolean (default False). If True, process the input sequence backwards and return the reversed sequence.
stateful
Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
unroll
Boolean (default False). If True, the network will be unrolled, else a symbolic loop will be used. Unrolling can speed-up a RNN, although it tends to be more memory-intensive. Unrolling is only suitable for short sequences.

Call arguments: inputs: A 3D tensor, with shape [batch, timesteps, feature]. mask: Binary tensor of shape [batch, timesteps] indicating whether a given timestep should be masked. An individual True entry indicates that the corresponding timestep should be utilized, while a False entry indicates that the corresponding timestep should be ignored. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the cell when calling it. This is only relevant if dropout or recurrent_dropout is used. initial_state: List of initial state tensors to be passed to the first call of the cell.

Examples:

inputs = np.random.random([32, 10, 8]).astype(np.float32)
simple_rnn = tf.keras.layers.SimpleRNN(4)

output = simple_rnn(inputs)  # The output has shape `[32, 4]`.

simple_rnn = tf.keras.layers.SimpleRNN(
    4, return_sequences=True, return_state=True)

# whole_sequence_output has shape `[32, 10, 4]`.
# final_state has shape `[32, 4]`.
whole_sequence_output, final_state = simple_rnn(inputs)
Expand source code
class SimpleRNN(RNN):
  """Fully-connected RNN where the output is to be fed back to input.

  See [the Keras RNN API guide](https://www.tensorflow.org/guide/keras/rnn)
  for details about the usage of RNN API.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass None, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, (default `True`), whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs. Default:
      `glorot_uniform`.
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix, used for the linear transformation of the recurrent state.
      Default: `orthogonal`.
    bias_initializer: Initializer for the bias vector. Default: `zeros`.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix. Default: `None`.
    recurrent_regularizer: Regularizer function applied to the
      `recurrent_kernel` weights matrix. Default: `None`.
    bias_regularizer: Regularizer function applied to the bias vector. Default:
      `None`.
    activity_regularizer: Regularizer function applied to the output of the
      layer (its "activation"). Default: `None`.
    kernel_constraint: Constraint function applied to the `kernel` weights
      matrix. Default: `None`.
    recurrent_constraint: Constraint function applied to the `recurrent_kernel`
      weights matrix.  Default: `None`.
    bias_constraint: Constraint function applied to the bias vector. Default:
      `None`.
    dropout: Float between 0 and 1.
      Fraction of the units to drop for the linear transformation of the inputs.
      Default: 0.
    recurrent_dropout: Float between 0 and 1.
      Fraction of the units to drop for the linear transformation of the
      recurrent state. Default: 0.
    return_sequences: Boolean. Whether to return the last output
      in the output sequence, or the full sequence. Default: `False`.
    return_state: Boolean. Whether to return the last state
      in addition to the output. Default: `False`
    go_backwards: Boolean (default False).
      If True, process the input sequence backwards and return the
      reversed sequence.
    stateful: Boolean (default False). If True, the last state
      for each sample at index i in a batch will be used as initial
      state for the sample of index i in the following batch.
    unroll: Boolean (default False).
      If True, the network will be unrolled,
      else a symbolic loop will be used.
      Unrolling can speed-up a RNN,
      although it tends to be more memory-intensive.
      Unrolling is only suitable for short sequences.

  Call arguments:
    inputs: A 3D tensor, with shape `[batch, timesteps, feature]`.
    mask: Binary tensor of shape `[batch, timesteps]` indicating whether
      a given timestep should be masked. An individual `True` entry indicates
      that the corresponding timestep should be utilized, while a `False` entry
      indicates that the corresponding timestep should be ignored.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the cell
      when calling it. This is only relevant if `dropout` or
      `recurrent_dropout` is used.
    initial_state: List of initial state tensors to be passed to the first
      call of the cell.

  Examples:

  ```python
  inputs = np.random.random([32, 10, 8]).astype(np.float32)
  simple_rnn = tf.keras.layers.SimpleRNN(4)

  output = simple_rnn(inputs)  # The output has shape `[32, 4]`.

  simple_rnn = tf.keras.layers.SimpleRNN(
      4, return_sequences=True, return_state=True)

  # whole_sequence_output has shape `[32, 10, 4]`.
  # final_state has shape `[32, 4]`.
  whole_sequence_output, final_state = simple_rnn(inputs)
  ```
  """

  def __init__(self,
               units,
               activation='tanh',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               activity_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               return_sequences=False,
               return_state=False,
               go_backwards=False,
               stateful=False,
               unroll=False,
               **kwargs):
    if 'implementation' in kwargs:
      kwargs.pop('implementation')
      logging.warning('The `implementation` argument '
                      'in `SimpleRNN` has been deprecated. '
                      'Please remove it from your layer call.')
    if 'enable_caching_device' in kwargs:
      cell_kwargs = {'enable_caching_device':
                     kwargs.pop('enable_caching_device')}
    else:
      cell_kwargs = {}
    cell = SimpleRNNCell(
        units,
        activation=activation,
        use_bias=use_bias,
        kernel_initializer=kernel_initializer,
        recurrent_initializer=recurrent_initializer,
        bias_initializer=bias_initializer,
        kernel_regularizer=kernel_regularizer,
        recurrent_regularizer=recurrent_regularizer,
        bias_regularizer=bias_regularizer,
        kernel_constraint=kernel_constraint,
        recurrent_constraint=recurrent_constraint,
        bias_constraint=bias_constraint,
        dropout=dropout,
        recurrent_dropout=recurrent_dropout,
        dtype=kwargs.get('dtype'),
        trainable=kwargs.get('trainable', True),
        **cell_kwargs)
    super(SimpleRNN, self).__init__(
        cell,
        return_sequences=return_sequences,
        return_state=return_state,
        go_backwards=go_backwards,
        stateful=stateful,
        unroll=unroll,
        **kwargs)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    self.input_spec = [InputSpec(ndim=3)]

  def call(self, inputs, mask=None, training=None, initial_state=None):
    return super(SimpleRNN, self).call(
        inputs, mask=mask, training=training, initial_state=initial_state)

  @property
  def units(self):
    return self.cell.units

  @property
  def activation(self):
    return self.cell.activation

  @property
  def use_bias(self):
    return self.cell.use_bias

  @property
  def kernel_initializer(self):
    return self.cell.kernel_initializer

  @property
  def recurrent_initializer(self):
    return self.cell.recurrent_initializer

  @property
  def bias_initializer(self):
    return self.cell.bias_initializer

  @property
  def kernel_regularizer(self):
    return self.cell.kernel_regularizer

  @property
  def recurrent_regularizer(self):
    return self.cell.recurrent_regularizer

  @property
  def bias_regularizer(self):
    return self.cell.bias_regularizer

  @property
  def kernel_constraint(self):
    return self.cell.kernel_constraint

  @property
  def recurrent_constraint(self):
    return self.cell.recurrent_constraint

  @property
  def bias_constraint(self):
    return self.cell.bias_constraint

  @property
  def dropout(self):
    return self.cell.dropout

  @property
  def recurrent_dropout(self):
    return self.cell.recurrent_dropout

  def get_config(self):
    config = {
        'units':
            self.units,
        'activation':
            activations.serialize(self.activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'activity_regularizer':
            regularizers.serialize(self.activity_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'dropout':
            self.dropout,
        'recurrent_dropout':
            self.recurrent_dropout
    }
    base_config = super(SimpleRNN, self).get_config()
    config.update(_config_for_enable_caching_device(self.cell))
    del base_config['cell']
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config):
    if 'implementation' in config:
      config.pop('implementation')
    return cls(**config)

Ancestors

  • RNN
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Instance variables

var activation
Expand source code
@property
def activation(self):
  return self.cell.activation
var bias_constraint
Expand source code
@property
def bias_constraint(self):
  return self.cell.bias_constraint
var bias_initializer
Expand source code
@property
def bias_initializer(self):
  return self.cell.bias_initializer
var bias_regularizer
Expand source code
@property
def bias_regularizer(self):
  return self.cell.bias_regularizer
var dropout
Expand source code
@property
def dropout(self):
  return self.cell.dropout
var kernel_constraint
Expand source code
@property
def kernel_constraint(self):
  return self.cell.kernel_constraint
var kernel_initializer
Expand source code
@property
def kernel_initializer(self):
  return self.cell.kernel_initializer
var kernel_regularizer
Expand source code
@property
def kernel_regularizer(self):
  return self.cell.kernel_regularizer
var recurrent_constraint
Expand source code
@property
def recurrent_constraint(self):
  return self.cell.recurrent_constraint
var recurrent_dropout
Expand source code
@property
def recurrent_dropout(self):
  return self.cell.recurrent_dropout
var recurrent_initializer
Expand source code
@property
def recurrent_initializer(self):
  return self.cell.recurrent_initializer
var recurrent_regularizer
Expand source code
@property
def recurrent_regularizer(self):
  return self.cell.recurrent_regularizer
var units
Expand source code
@property
def units(self):
  return self.cell.units
var use_bias
Expand source code
@property
def use_bias(self):
  return self.cell.use_bias

Inherited members

class SimpleRNNCell (units, activation='tanh', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0, **kwargs)

Cell class for SimpleRNN.

See the Keras RNN API guide for details about the usage of RNN API.

This class processes one step within the whole time sequence input, whereas tf.keras.layer.SimpleRNN processes the whole sequence.

Args

units
Positive integer, dimensionality of the output space.
activation
Activation function to use. Default: hyperbolic tangent (tanh). If you pass None, no activation is applied (ie. "linear" activation: a(x) = x).
use_bias
Boolean, (default True), whether the layer uses a bias vector.
kernel_initializer
Initializer for the kernel weights matrix, used for the linear transformation of the inputs. Default: glorot_uniform.
recurrent_initializer
Initializer for the recurrent_kernel weights matrix, used for the linear transformation of the recurrent state. Default: orthogonal.
bias_initializer
Initializer for the bias vector. Default: zeros.
kernel_regularizer
Regularizer function applied to the kernel weights matrix. Default: None.
recurrent_regularizer
Regularizer function applied to the recurrent_kernel weights matrix. Default: None.
bias_regularizer
Regularizer function applied to the bias vector. Default: None.
kernel_constraint
Constraint function applied to the kernel weights matrix. Default: None.
recurrent_constraint
Constraint function applied to the recurrent_kernel weights matrix. Default: None.
bias_constraint
Constraint function applied to the bias vector. Default: None.
dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the inputs. Default: 0.
recurrent_dropout
Float between 0 and 1. Fraction of the units to drop for the linear transformation of the recurrent state. Default: 0.

Call arguments: inputs: A 2D tensor, with shape of [batch, feature]. states: A 2D tensor with shape of [batch, units], which is the state from the previous time step. For timestep 0, the initial state provided by user will be feed to cell. training: Python boolean indicating whether the layer should behave in training mode or in inference mode. Only relevant when dropout or recurrent_dropout is used.

Examples:

inputs = np.random.random([32, 10, 8]).astype(np.float32)
rnn = tf.keras.layers.RNN(tf.keras.layers.SimpleRNNCell(4))

output = rnn(inputs)  # The output has shape `[32, 4]`.

rnn = tf.keras.layers.RNN(
    tf.keras.layers.SimpleRNNCell(4),
    return_sequences=True,
    return_state=True)

# whole_sequence_output has shape `[32, 10, 4]`.
# final_state has shape `[32, 4]`.
whole_sequence_output, final_state = rnn(inputs)
Expand source code
class SimpleRNNCell(DropoutRNNCellMixin, Layer):
  """Cell class for SimpleRNN.

  See [the Keras RNN API guide](https://www.tensorflow.org/guide/keras/rnn)
  for details about the usage of RNN API.

  This class processes one step within the whole time sequence input, whereas
  `tf.keras.layer.SimpleRNN` processes the whole sequence.

  Args:
    units: Positive integer, dimensionality of the output space.
    activation: Activation function to use.
      Default: hyperbolic tangent (`tanh`).
      If you pass `None`, no activation is applied
      (ie. "linear" activation: `a(x) = x`).
    use_bias: Boolean, (default `True`), whether the layer uses a bias vector.
    kernel_initializer: Initializer for the `kernel` weights matrix,
      used for the linear transformation of the inputs. Default:
      `glorot_uniform`.
    recurrent_initializer: Initializer for the `recurrent_kernel`
      weights matrix, used for the linear transformation of the recurrent state.
      Default: `orthogonal`.
    bias_initializer: Initializer for the bias vector. Default: `zeros`.
    kernel_regularizer: Regularizer function applied to the `kernel` weights
      matrix. Default: `None`.
    recurrent_regularizer: Regularizer function applied to the
      `recurrent_kernel` weights matrix. Default: `None`.
    bias_regularizer: Regularizer function applied to the bias vector. Default:
      `None`.
    kernel_constraint: Constraint function applied to the `kernel` weights
      matrix. Default: `None`.
    recurrent_constraint: Constraint function applied to the `recurrent_kernel`
      weights matrix. Default: `None`.
    bias_constraint: Constraint function applied to the bias vector. Default:
      `None`.
    dropout: Float between 0 and 1. Fraction of the units to drop for the linear
      transformation of the inputs. Default: 0.
    recurrent_dropout: Float between 0 and 1. Fraction of the units to drop for
      the linear transformation of the recurrent state. Default: 0.

  Call arguments:
    inputs: A 2D tensor, with shape of `[batch, feature]`.
    states: A 2D tensor with shape of `[batch, units]`, which is the state from
      the previous time step. For timestep 0, the initial state provided by user
      will be feed to cell.
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. Only relevant when `dropout` or
      `recurrent_dropout` is used.

  Examples:

  ```python
  inputs = np.random.random([32, 10, 8]).astype(np.float32)
  rnn = tf.keras.layers.RNN(tf.keras.layers.SimpleRNNCell(4))

  output = rnn(inputs)  # The output has shape `[32, 4]`.

  rnn = tf.keras.layers.RNN(
      tf.keras.layers.SimpleRNNCell(4),
      return_sequences=True,
      return_state=True)

  # whole_sequence_output has shape `[32, 10, 4]`.
  # final_state has shape `[32, 4]`.
  whole_sequence_output, final_state = rnn(inputs)
  ```
  """

  def __init__(self,
               units,
               activation='tanh',
               use_bias=True,
               kernel_initializer='glorot_uniform',
               recurrent_initializer='orthogonal',
               bias_initializer='zeros',
               kernel_regularizer=None,
               recurrent_regularizer=None,
               bias_regularizer=None,
               kernel_constraint=None,
               recurrent_constraint=None,
               bias_constraint=None,
               dropout=0.,
               recurrent_dropout=0.,
               **kwargs):
    if units < 0:
      raise ValueError(f'Received an invalid value for units, expected '
                       f'a positive integer, got {units}.')
    # By default use cached variable under v2 mode, see b/143699808.
    if tf.compat.v1.executing_eagerly_outside_functions():
      self._enable_caching_device = kwargs.pop('enable_caching_device', True)
    else:
      self._enable_caching_device = kwargs.pop('enable_caching_device', False)
    super(SimpleRNNCell, self).__init__(**kwargs)
    self.units = units
    self.activation = activations.get(activation)
    self.use_bias = use_bias

    self.kernel_initializer = initializers.get(kernel_initializer)
    self.recurrent_initializer = initializers.get(recurrent_initializer)
    self.bias_initializer = initializers.get(bias_initializer)

    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.recurrent_regularizer = regularizers.get(recurrent_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)

    self.kernel_constraint = constraints.get(kernel_constraint)
    self.recurrent_constraint = constraints.get(recurrent_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

    self.dropout = min(1., max(0., dropout))
    self.recurrent_dropout = min(1., max(0., recurrent_dropout))
    self.state_size = self.units
    self.output_size = self.units

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    default_caching_device = _caching_device(self)
    self.kernel = self.add_weight(
        shape=(input_shape[-1], self.units),
        name='kernel',
        initializer=self.kernel_initializer,
        regularizer=self.kernel_regularizer,
        constraint=self.kernel_constraint,
        caching_device=default_caching_device)
    self.recurrent_kernel = self.add_weight(
        shape=(self.units, self.units),
        name='recurrent_kernel',
        initializer=self.recurrent_initializer,
        regularizer=self.recurrent_regularizer,
        constraint=self.recurrent_constraint,
        caching_device=default_caching_device)
    if self.use_bias:
      self.bias = self.add_weight(
          shape=(self.units,),
          name='bias',
          initializer=self.bias_initializer,
          regularizer=self.bias_regularizer,
          constraint=self.bias_constraint,
          caching_device=default_caching_device)
    else:
      self.bias = None
    self.built = True

  def call(self, inputs, states, training=None):
    prev_output = states[0] if tf.nest.is_nested(states) else states
    dp_mask = self.get_dropout_mask_for_cell(inputs, training)
    rec_dp_mask = self.get_recurrent_dropout_mask_for_cell(
        prev_output, training)

    if dp_mask is not None:
      h = backend.dot(inputs * dp_mask, self.kernel)
    else:
      h = backend.dot(inputs, self.kernel)
    if self.bias is not None:
      h = backend.bias_add(h, self.bias)

    if rec_dp_mask is not None:
      prev_output = prev_output * rec_dp_mask
    output = h + backend.dot(prev_output, self.recurrent_kernel)
    if self.activation is not None:
      output = self.activation(output)

    new_state = [output] if tf.nest.is_nested(states) else output
    return output, new_state

  def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
    return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

  def get_config(self):
    config = {
        'units':
            self.units,
        'activation':
            activations.serialize(self.activation),
        'use_bias':
            self.use_bias,
        'kernel_initializer':
            initializers.serialize(self.kernel_initializer),
        'recurrent_initializer':
            initializers.serialize(self.recurrent_initializer),
        'bias_initializer':
            initializers.serialize(self.bias_initializer),
        'kernel_regularizer':
            regularizers.serialize(self.kernel_regularizer),
        'recurrent_regularizer':
            regularizers.serialize(self.recurrent_regularizer),
        'bias_regularizer':
            regularizers.serialize(self.bias_regularizer),
        'kernel_constraint':
            constraints.serialize(self.kernel_constraint),
        'recurrent_constraint':
            constraints.serialize(self.recurrent_constraint),
        'bias_constraint':
            constraints.serialize(self.bias_constraint),
        'dropout':
            self.dropout,
        'recurrent_dropout':
            self.recurrent_dropout
    }
    config.update(_config_for_enable_caching_device(self))
    base_config = super(SimpleRNNCell, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

Methods

def get_initial_state(self, inputs=None, batch_size=None, dtype=None)
Expand source code
def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
  return _generate_zero_filled_state_for_cell(self, inputs, batch_size, dtype)

Inherited members

class Softmax (axis=-1, **kwargs)

Softmax activation function.

Example without mask:

>>> inp = np.asarray([1., 2., 1.])
>>> layer = tf.keras.layers.Softmax()
>>> layer(inp).numpy()
array([0.21194157, 0.5761169 , 0.21194157], dtype=float32)
>>> mask = np.asarray([True, False, True], dtype=bool)
>>> layer(inp, mask).numpy()
array([0.5, 0. , 0.5], dtype=float32)

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

axis
Integer, or list of Integers, axis along which the softmax normalization is applied.

Call arguments: inputs: The inputs, or logits to the softmax layer. mask: A boolean mask of the same shape as inputs. Defaults to None. The mask specifies 1 to keep and 0 to mask.

Returns

softmaxed output with the same shape as inputs.

Expand source code
class Softmax(Layer):
  """Softmax activation function.

  Example without mask:

  >>> inp = np.asarray([1., 2., 1.])
  >>> layer = tf.keras.layers.Softmax()
  >>> layer(inp).numpy()
  array([0.21194157, 0.5761169 , 0.21194157], dtype=float32)
  >>> mask = np.asarray([True, False, True], dtype=bool)
  >>> layer(inp, mask).numpy()
  array([0.5, 0. , 0.5], dtype=float32)

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    axis: Integer, or list of Integers, axis along which the softmax
      normalization is applied.
  Call arguments:
    inputs: The inputs, or logits to the softmax layer.
    mask: A boolean mask of the same shape as `inputs`. Defaults to `None`. The
      mask specifies 1 to keep and 0 to mask.

  Returns:
    softmaxed output with the same shape as `inputs`.
  """

  def __init__(self, axis=-1, **kwargs):
    super(Softmax, self).__init__(**kwargs)
    self.supports_masking = True
    self.axis = axis

  def call(self, inputs, mask=None):
    if mask is not None:
      # Since mask is 1.0 for positions we want to keep and 0.0 for
      # masked positions, this operation will create a tensor which is 0.0 for
      # positions we want to attend and -1e.9 for masked positions.
      adder = (1.0 - tf.cast(mask, inputs.dtype)) * (
          _large_compatible_negative(inputs.dtype))

      # Since we are adding it to the raw scores before the softmax, this is
      # effectively the same as removing these entirely.
      inputs += adder
    if isinstance(self.axis, (tuple, list)):
      if len(self.axis) > 1:
        return tf.exp(inputs - tf.reduce_logsumexp(
            inputs, axis=self.axis, keepdims=True))
      else:
        return backend.softmax(inputs, axis=self.axis[0])
    return backend.softmax(inputs, axis=self.axis)

  def get_config(self):
    config = {'axis': self.axis}
    base_config = super(Softmax, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class SpatialDropout1D (rate, **kwargs)

Spatial 1D version of Dropout.

This version performs the same function as Dropout, however, it drops entire 1D feature maps instead of individual elements. If adjacent frames within feature maps are strongly correlated (as is normally the case in early convolution layers) then regular dropout will not regularize the activations and will otherwise just result in an effective learning rate decrease. In this case, SpatialDropout1D will help promote independence between feature maps and should be used instead.

Args

rate
Float between 0 and 1. Fraction of the input units to drop.

Call arguments: inputs: A 3D tensor. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Input shape: 3D tensor with shape: (samples, timesteps, channels)

Output shape: Same as input.

References

Expand source code
class SpatialDropout1D(Dropout):
  """Spatial 1D version of Dropout.

  This version performs the same function as Dropout, however, it drops
  entire 1D feature maps instead of individual elements. If adjacent frames
  within feature maps are strongly correlated (as is normally the case in
  early convolution layers) then regular dropout will not regularize the
  activations and will otherwise just result in an effective learning rate
  decrease. In this case, SpatialDropout1D will help promote independence
  between feature maps and should be used instead.

  Args:
    rate: Float between 0 and 1. Fraction of the input units to drop.

  Call arguments:
    inputs: A 3D tensor.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).

  Input shape:
    3D tensor with shape:
    `(samples, timesteps, channels)`

  Output shape:
    Same as input.

  References:
    - [Efficient Object Localization Using Convolutional
      Networks](https://arxiv.org/abs/1411.4280)
  """

  def __init__(self, rate, **kwargs):
    super(SpatialDropout1D, self).__init__(rate, **kwargs)
    self.input_spec = InputSpec(ndim=3)

  def _get_noise_shape(self, inputs):
    input_shape = tf.shape(inputs)
    noise_shape = (input_shape[0], 1, input_shape[2])
    return noise_shape

Ancestors

  • Dropout
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class SpatialDropout2D (rate, data_format=None, **kwargs)

Spatial 2D version of Dropout.

This version performs the same function as Dropout, however, it drops entire 2D feature maps instead of individual elements. If adjacent pixels within feature maps are strongly correlated (as is normally the case in early convolution layers) then regular dropout will not regularize the activations and will otherwise just result in an effective learning rate decrease. In this case, SpatialDropout2D will help promote independence between feature maps and should be used instead.

Args

rate
Float between 0 and 1. Fraction of the input units to drop.
data_format
'channels_first' or 'channels_last'. In 'channels_first' mode, the channels dimension (the depth) is at index 1, in 'channels_last' mode is it at index 3. It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Call arguments: inputs: A 4D tensor. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Input shape: 4D tensor with shape: (samples, channels, rows, cols) if data_format='channels_first' or 4D tensor with shape: (samples, rows, cols, channels) if data_format='channels_last'.

Output shape: Same as input.

References

Expand source code
class SpatialDropout2D(Dropout):
  """Spatial 2D version of Dropout.

  This version performs the same function as Dropout, however, it drops
  entire 2D feature maps instead of individual elements. If adjacent pixels
  within feature maps are strongly correlated (as is normally the case in
  early convolution layers) then regular dropout will not regularize the
  activations and will otherwise just result in an effective learning rate
  decrease. In this case, SpatialDropout2D will help promote independence
  between feature maps and should be used instead.

  Args:
    rate: Float between 0 and 1. Fraction of the input units to drop.
    data_format: 'channels_first' or 'channels_last'.
      In 'channels_first' mode, the channels dimension
      (the depth) is at index 1,
      in 'channels_last' mode is it at index 3.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Call arguments:
    inputs: A 4D tensor.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).

  Input shape:
    4D tensor with shape:
    `(samples, channels, rows, cols)` if data_format='channels_first'
    or 4D tensor with shape:
    `(samples, rows, cols, channels)` if data_format='channels_last'.

  Output shape:
    Same as input.

  References:
    - [Efficient Object Localization Using Convolutional
      Networks](https://arxiv.org/abs/1411.4280)
  """

  def __init__(self, rate, data_format=None, **kwargs):
    super(SpatialDropout2D, self).__init__(rate, **kwargs)
    if data_format is None:
      data_format = K.image_data_format()
    if data_format not in {'channels_last', 'channels_first'}:
      raise ValueError('data_format must be in '
                       '{"channels_last", "channels_first"}')
    self.data_format = data_format
    self.input_spec = InputSpec(ndim=4)

  def _get_noise_shape(self, inputs):
    input_shape = tf.shape(inputs)
    if self.data_format == 'channels_first':
      return (input_shape[0], input_shape[1], 1, 1)
    elif self.data_format == 'channels_last':
      return (input_shape[0], 1, 1, input_shape[3])

Ancestors

  • Dropout
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class SpatialDropout3D (rate, data_format=None, **kwargs)

Spatial 3D version of Dropout.

This version performs the same function as Dropout, however, it drops entire 3D feature maps instead of individual elements. If adjacent voxels within feature maps are strongly correlated (as is normally the case in early convolution layers) then regular dropout will not regularize the activations and will otherwise just result in an effective learning rate decrease. In this case, SpatialDropout3D will help promote independence between feature maps and should be used instead.

Args

rate
Float between 0 and 1. Fraction of the input units to drop.
data_format
'channels_first' or 'channels_last'. In 'channels_first' mode, the channels dimension (the depth) is at index 1, in 'channels_last' mode is it at index 4. It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Call arguments: inputs: A 5D tensor. training: Python boolean indicating whether the layer should behave in training mode (adding dropout) or in inference mode (doing nothing).

Input shape: 5D tensor with shape: (samples, channels, dim1, dim2, dim3) if data_format='channels_first' or 5D tensor with shape: (samples, dim1, dim2, dim3, channels) if data_format='channels_last'.

Output shape: Same as input.

References

Expand source code
class SpatialDropout3D(Dropout):
  """Spatial 3D version of Dropout.

  This version performs the same function as Dropout, however, it drops
  entire 3D feature maps instead of individual elements. If adjacent voxels
  within feature maps are strongly correlated (as is normally the case in
  early convolution layers) then regular dropout will not regularize the
  activations and will otherwise just result in an effective learning rate
  decrease. In this case, SpatialDropout3D will help promote independence
  between feature maps and should be used instead.

  Args:
    rate: Float between 0 and 1. Fraction of the input units to drop.
    data_format: 'channels_first' or 'channels_last'.
        In 'channels_first' mode, the channels dimension (the depth)
        is at index 1, in 'channels_last' mode is it at index 4.
        It defaults to the `image_data_format` value found in your
        Keras config file at `~/.keras/keras.json`.
        If you never set it, then it will be "channels_last".

  Call arguments:
    inputs: A 5D tensor.
    training: Python boolean indicating whether the layer should behave in
      training mode (adding dropout) or in inference mode (doing nothing).

  Input shape:
    5D tensor with shape:
    `(samples, channels, dim1, dim2, dim3)` if data_format='channels_first'
    or 5D tensor with shape:
    `(samples, dim1, dim2, dim3, channels)` if data_format='channels_last'.

  Output shape:
    Same as input.

  References:
    - [Efficient Object Localization Using Convolutional
      Networks](https://arxiv.org/abs/1411.4280)
  """

  def __init__(self, rate, data_format=None, **kwargs):
    super(SpatialDropout3D, self).__init__(rate, **kwargs)
    if data_format is None:
      data_format = K.image_data_format()
    if data_format not in {'channels_last', 'channels_first'}:
      raise ValueError('data_format must be in '
                       '{"channels_last", "channels_first"}')
    self.data_format = data_format
    self.input_spec = InputSpec(ndim=5)

  def _get_noise_shape(self, inputs):
    input_shape = tf.shape(inputs)
    if self.data_format == 'channels_first':
      return (input_shape[0], input_shape[1], 1, 1, 1)
    elif self.data_format == 'channels_last':
      return (input_shape[0], 1, 1, 1, input_shape[4])

Ancestors

  • Dropout
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class StackedRNNCells (cells, **kwargs)

Wrapper allowing a stack of RNN cells to behave as a single cell.

Used to implement efficient stacked RNNs.

Args

cells
List of RNN cell instances.

Examples:

batch_size = 3
sentence_max_length = 5
n_features = 2
new_shape = (batch_size, sentence_max_length, n_features)
x = tf.constant(np.reshape(np.arange(30), new_shape), dtype = tf.float32)

rnn_cells = [tf.keras.layers.LSTMCell(128) for _ in range(2)]
stacked_lstm = tf.keras.layers.StackedRNNCells(rnn_cells)
lstm_layer = tf.keras.layers.RNN(stacked_lstm)

result = lstm_layer(x)
Expand source code
class StackedRNNCells(Layer):
  """Wrapper allowing a stack of RNN cells to behave as a single cell.

  Used to implement efficient stacked RNNs.

  Args:
    cells: List of RNN cell instances.

  Examples:

  ```python
  batch_size = 3
  sentence_max_length = 5
  n_features = 2
  new_shape = (batch_size, sentence_max_length, n_features)
  x = tf.constant(np.reshape(np.arange(30), new_shape), dtype = tf.float32)

  rnn_cells = [tf.keras.layers.LSTMCell(128) for _ in range(2)]
  stacked_lstm = tf.keras.layers.StackedRNNCells(rnn_cells)
  lstm_layer = tf.keras.layers.RNN(stacked_lstm)

  result = lstm_layer(x)
  ```
  """

  def __init__(self, cells, **kwargs):
    for cell in cells:
      if not 'call' in dir(cell):
        raise ValueError('All cells must have a `call` method. '
                         'received cells:', cells)
      if not 'state_size' in dir(cell):
        raise ValueError('All cells must have a '
                         '`state_size` attribute. '
                         'received cells:', cells)
    self.cells = cells
    # reverse_state_order determines whether the state size will be in a reverse
    # order of the cells' state. User might want to set this to True to keep the
    # existing behavior. This is only useful when use RNN(return_state=True)
    # since the state will be returned as the same order of state_size.
    self.reverse_state_order = kwargs.pop('reverse_state_order', False)
    if self.reverse_state_order:
      logging.warning('reverse_state_order=True in StackedRNNCells will soon '
                      'be deprecated. Please update the code to work with the '
                      'natural order of states if you rely on the RNN states, '
                      'eg RNN(return_state=True).')
    super(StackedRNNCells, self).__init__(**kwargs)

  @property
  def state_size(self):
    return tuple(c.state_size for c in
                 (self.cells[::-1] if self.reverse_state_order else self.cells))

  @property
  def output_size(self):
    if getattr(self.cells[-1], 'output_size', None) is not None:
      return self.cells[-1].output_size
    elif _is_multiple_state(self.cells[-1].state_size):
      return self.cells[-1].state_size[0]
    else:
      return self.cells[-1].state_size

  def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
    initial_states = []
    for cell in self.cells[::-1] if self.reverse_state_order else self.cells:
      get_initial_state_fn = getattr(cell, 'get_initial_state', None)
      if get_initial_state_fn:
        initial_states.append(get_initial_state_fn(
            inputs=inputs, batch_size=batch_size, dtype=dtype))
      else:
        initial_states.append(_generate_zero_filled_state_for_cell(
            cell, inputs, batch_size, dtype))

    return tuple(initial_states)

  def call(self, inputs, states, constants=None, training=None, **kwargs):
    # Recover per-cell states.
    state_size = (self.state_size[::-1]
                  if self.reverse_state_order else self.state_size)
    nested_states = tf.nest.pack_sequence_as(state_size, tf.nest.flatten(states))

    # Call the cells in order and store the returned states.
    new_nested_states = []
    for cell, states in zip(self.cells, nested_states):
      states = states if tf.nest.is_nested(states) else [states]
      # TF cell does not wrap the state into list when there is only one state.
      is_tf_rnn_cell = getattr(cell, '_is_tf_rnn_cell', None) is not None
      states = states[0] if len(states) == 1 and is_tf_rnn_cell else states
      if generic_utils.has_arg(cell.call, 'training'):
        kwargs['training'] = training
      else:
        kwargs.pop('training', None)
      # Use the __call__ function for callable objects, eg layers, so that it
      # will have the proper name scopes for the ops, etc.
      cell_call_fn = cell.__call__ if callable(cell) else cell.call
      if generic_utils.has_arg(cell.call, 'constants'):
        inputs, states = cell_call_fn(inputs, states,
                                      constants=constants, **kwargs)
      else:
        inputs, states = cell_call_fn(inputs, states, **kwargs)
      new_nested_states.append(states)

    return inputs, tf.nest.pack_sequence_as(state_size,
                                         tf.nest.flatten(new_nested_states))

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    if isinstance(input_shape, list):
      input_shape = input_shape[0]
    for cell in self.cells:
      if isinstance(cell, Layer) and not cell.built:
        with backend.name_scope(cell.name):
          cell.build(input_shape)
          cell.built = True
      if getattr(cell, 'output_size', None) is not None:
        output_dim = cell.output_size
      elif _is_multiple_state(cell.state_size):
        output_dim = cell.state_size[0]
      else:
        output_dim = cell.state_size
      input_shape = tuple([input_shape[0]] +
                          tf.TensorShape(output_dim).as_list())
    self.built = True

  def get_config(self):
    cells = []
    for cell in self.cells:
      cells.append(generic_utils.serialize_keras_object(cell))
    config = {'cells': cells}
    base_config = super(StackedRNNCells, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config, custom_objects=None):
    from keras.layers import deserialize as deserialize_layer  # pylint: disable=g-import-not-at-top
    cells = []
    for cell_config in config.pop('cells'):
      cells.append(
          deserialize_layer(cell_config, custom_objects=custom_objects))
    return cls(cells, **config)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Instance variables

var output_size
Expand source code
@property
def output_size(self):
  if getattr(self.cells[-1], 'output_size', None) is not None:
    return self.cells[-1].output_size
  elif _is_multiple_state(self.cells[-1].state_size):
    return self.cells[-1].state_size[0]
  else:
    return self.cells[-1].state_size
var state_size
Expand source code
@property
def state_size(self):
  return tuple(c.state_size for c in
               (self.cells[::-1] if self.reverse_state_order else self.cells))

Methods

def get_initial_state(self, inputs=None, batch_size=None, dtype=None)
Expand source code
def get_initial_state(self, inputs=None, batch_size=None, dtype=None):
  initial_states = []
  for cell in self.cells[::-1] if self.reverse_state_order else self.cells:
    get_initial_state_fn = getattr(cell, 'get_initial_state', None)
    if get_initial_state_fn:
      initial_states.append(get_initial_state_fn(
          inputs=inputs, batch_size=batch_size, dtype=dtype))
    else:
      initial_states.append(_generate_zero_filled_state_for_cell(
          cell, inputs, batch_size, dtype))

  return tuple(initial_states)

Inherited members

class Subtract (**kwargs)

Layer that subtracts two inputs.

It takes as input a list of tensors of size 2, both of the same shape, and returns a single tensor, (inputs[0] - inputs[1]), also of the same shape.

Examples:

    import keras

    input1 = keras.layers.Input(shape=(16,))
    x1 = keras.layers.Dense(8, activation='relu')(input1)
    input2 = keras.layers.Input(shape=(32,))
    x2 = keras.layers.Dense(8, activation='relu')(input2)
    # Equivalent to subtracted = keras.layers.subtract([x1, x2])
    subtracted = keras.layers.Subtract()([x1, x2])

    out = keras.layers.Dense(4)(subtracted)
    model = keras.models.Model(inputs=[input1, input2], outputs=out)

Intializes a Merge layer.

Args

**kwargs
standard layer keyword arguments.
Expand source code
class Subtract(_Merge):
  """Layer that subtracts two inputs.

  It takes as input a list of tensors of size 2,
  both of the same shape, and returns a single tensor, (inputs[0] - inputs[1]),
  also of the same shape.

  Examples:

  ```python
      import keras

      input1 = keras.layers.Input(shape=(16,))
      x1 = keras.layers.Dense(8, activation='relu')(input1)
      input2 = keras.layers.Input(shape=(32,))
      x2 = keras.layers.Dense(8, activation='relu')(input2)
      # Equivalent to subtracted = keras.layers.subtract([x1, x2])
      subtracted = keras.layers.Subtract()([x1, x2])

      out = keras.layers.Dense(4)(subtracted)
      model = keras.models.Model(inputs=[input1, input2], outputs=out)
  ```
  """

  @tf_utils.shape_type_conversion
  def build(self, input_shape):
    super(Subtract, self).build(input_shape)
    if len(input_shape) != 2:
      raise ValueError('A `Subtract` layer should be called '
                       'on exactly 2 inputs')

  def _merge_function(self, inputs):
    if len(inputs) != 2:
      raise ValueError('A `Subtract` layer should be called '
                       'on exactly 2 inputs')
    return inputs[0] - inputs[1]

Ancestors

  • keras.layers.merge._Merge
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class ThresholdedReLU (theta=1.0, **kwargs)

Thresholded Rectified Linear Unit.

It follows:

  f(x) = x for x > theta
  f(x) = 0 otherwise`

Input shape: Arbitrary. Use the keyword argument input_shape (tuple of integers, does not include the samples axis) when using this layer as the first layer in a model.

Output shape: Same shape as the input.

Args

theta
Float >= 0. Threshold location of activation.
Expand source code
class ThresholdedReLU(Layer):
  """Thresholded Rectified Linear Unit.

  It follows:

  ```
    f(x) = x for x > theta
    f(x) = 0 otherwise`
  ```

  Input shape:
    Arbitrary. Use the keyword argument `input_shape`
    (tuple of integers, does not include the samples axis)
    when using this layer as the first layer in a model.

  Output shape:
    Same shape as the input.

  Args:
    theta: Float >= 0. Threshold location of activation.
  """

  def __init__(self, theta=1.0, **kwargs):
    super(ThresholdedReLU, self).__init__(**kwargs)
    if theta is None:
      raise ValueError('Theta of a Thresholded ReLU layer cannot be '
                       'None, requires a float. Got %s' % theta)
    if theta < 0:
      raise ValueError('The theta value of a Thresholded ReLU layer '
                       'should be >=0, got %s' % theta)
    self.supports_masking = True
    self.theta = backend.cast_to_floatx(theta)

  def call(self, inputs):
    theta = tf.cast(self.theta, inputs.dtype)
    return inputs * tf.cast(tf.greater(inputs, theta), inputs.dtype)

  def get_config(self):
    config = {'theta': float(self.theta)}
    base_config = super(ThresholdedReLU, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @tf_utils.shape_type_conversion
  def compute_output_shape(self, input_shape):
    return input_shape

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class TimeDistributed (layer, **kwargs)

This wrapper allows to apply a layer to every temporal slice of an input.

Every input should be at least 3D, and the dimension of index one of the first input will be considered to be the temporal dimension.

Consider a batch of 32 video samples, where each sample is a 128x128 RGB image with channels_last data format, across 10 timesteps. The batch input shape is (32, 10, 128, 128, 3).

You can then use TimeDistributed to apply the same Conv2D layer to each of the 10 timesteps, independently:

>>> inputs = tf.keras.Input(shape=(10, 128, 128, 3))
>>> conv_2d_layer = tf.keras.layers.Conv2D(64, (3, 3))
>>> outputs = tf.keras.layers.TimeDistributed(conv_2d_layer)(inputs)
>>> outputs.shape
TensorShape([None, 10, 126, 126, 64])

Because TimeDistributed applies the same instance of Conv2D to each of the timestamps, the same set of weights are used at each timestamp.

Args

layer
a tf.keras.layers.Layer instance.

Call arguments: inputs: Input tensor of shape (batch, time, …) or nested tensors, and each of which has shape (batch, time, …). training: Python boolean indicating whether the layer should behave in training mode or in inference mode. This argument is passed to the wrapped layer (only if the layer supports this argument). mask: Binary tensor of shape (samples, timesteps) indicating whether a given timestep should be masked. This argument is passed to the wrapped layer (only if the layer supports this argument).

Raises

ValueError
If not initialized with a tf.keras.layers.Layer instance.
Expand source code
class TimeDistributed(Wrapper):
  """This wrapper allows to apply a layer to every temporal slice of an input.

  Every input should be at least 3D, and the dimension of index one of the
  first input will be considered to be the temporal dimension.

  Consider a batch of 32 video samples, where each sample is a 128x128 RGB image
  with `channels_last` data format, across 10 timesteps.
  The batch input shape is `(32, 10, 128, 128, 3)`.

  You can then use `TimeDistributed` to apply the same `Conv2D` layer to each
  of the 10 timesteps, independently:

  >>> inputs = tf.keras.Input(shape=(10, 128, 128, 3))
  >>> conv_2d_layer = tf.keras.layers.Conv2D(64, (3, 3))
  >>> outputs = tf.keras.layers.TimeDistributed(conv_2d_layer)(inputs)
  >>> outputs.shape
  TensorShape([None, 10, 126, 126, 64])

  Because `TimeDistributed` applies the same instance of `Conv2D` to each of the
  timestamps, the same set of weights are used at each timestamp.

  Args:
    layer: a `tf.keras.layers.Layer` instance.

  Call arguments:
    inputs: Input tensor of shape (batch, time, ...) or nested tensors,
      and each of which has shape (batch, time, ...).
    training: Python boolean indicating whether the layer should behave in
      training mode or in inference mode. This argument is passed to the
      wrapped layer (only if the layer supports this argument).
    mask: Binary tensor of shape `(samples, timesteps)` indicating whether
      a given timestep should be masked. This argument is passed to the
      wrapped layer (only if the layer supports this argument).

  Raises:
    ValueError: If not initialized with a `tf.keras.layers.Layer` instance.
  """

  def __init__(self, layer, **kwargs):
    if not isinstance(layer, Layer):
      raise ValueError(
          'Please initialize `TimeDistributed` layer with a '
          '`tf.keras.layers.Layer` instance. You passed: {input}'.format(
              input=layer))
    super(TimeDistributed, self).__init__(layer, **kwargs)
    self.supports_masking = True

    # It is safe to use the fast, reshape-based approach with all of our
    # built-in Layers.
    self._always_use_reshape = (
        layer_utils.is_builtin_layer(layer) and
        not getattr(layer, 'stateful', False))

  def _get_shape_tuple(self, init_tuple, tensor, start_idx, int_shape=None):
    """Finds non-specific dimensions in the static shapes.

    The static shapes are replaced with the corresponding dynamic shapes of the
    tensor.
    Args:
      init_tuple: a tuple, the first part of the output shape
      tensor: the tensor from which to get the (static and dynamic) shapes
        as the last part of the output shape
      start_idx: int, which indicate the first dimension to take from
        the static shape of the tensor
      int_shape: an alternative static shape to take as the last part
        of the output shape
    Returns:
      The new int_shape with the first part from init_tuple
      and the last part from either `int_shape` (if provided)
      or `tensor.shape`, where every `None` is replaced by
      the corresponding dimension from `tf.shape(tensor)`.
    """
    # replace all None in int_shape by backend.shape
    if int_shape is None:
      int_shape = backend.int_shape(tensor)[start_idx:]
    if isinstance(int_shape, tf.TensorShape):
      int_shape = int_shape.as_list()
    if not any(not s for s in int_shape):
      return init_tuple + tuple(int_shape)
    shape = backend.shape(tensor)
    int_shape = list(int_shape)
    for i, s in enumerate(int_shape):
      if not s:
        int_shape[i] = shape[start_idx + i]
    return init_tuple + tuple(int_shape)

  def _remove_timesteps(self, dims):
    dims = dims.as_list()
    return tf.TensorShape([dims[0]] + dims[2:])

  def build(self, input_shape):
    input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
    input_dims = tf.nest.flatten(
        tf.nest.map_structure(lambda x: x.ndims, input_shape))
    if any(dim < 3 for dim in input_dims):
      raise ValueError(
          '`TimeDistributed` Layer should be passed an `input_shape ` '
          'with at least 3 dimensions, received: ' + str(input_shape))
    # Don't enforce the batch or time dimension.
    self.input_spec = tf.nest.map_structure(
        lambda x: InputSpec(shape=[None, None] + x.as_list()[2:]), input_shape)
    child_input_shape = tf.nest.map_structure(self._remove_timesteps, input_shape)
    child_input_shape = tf_utils.convert_shapes(child_input_shape)
    super(TimeDistributed, self).build(tuple(child_input_shape))
    self.built = True

  def compute_output_shape(self, input_shape):
    input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)

    child_input_shape = tf.nest.map_structure(self._remove_timesteps, input_shape)
    child_output_shape = self.layer.compute_output_shape(child_input_shape)
    child_output_shape = tf_utils.convert_shapes(
        child_output_shape, to_tuples=False)
    timesteps = tf_utils.convert_shapes(input_shape)
    timesteps = tf.nest.flatten(timesteps)[1]

    def insert_timesteps(dims):
      dims = dims.as_list()
      return tf.TensorShape([dims[0], timesteps] + dims[1:])

    return tf.nest.map_structure(insert_timesteps, child_output_shape)

  def call(self, inputs, training=None, mask=None):
    kwargs = {}
    if generic_utils.has_arg(self.layer.call, 'training'):
      kwargs['training'] = training

    input_shape = tf.nest.map_structure(
        lambda x: tf.TensorShape(backend.int_shape(x)), inputs)
    batch_size = tf_utils.convert_shapes(input_shape)
    batch_size = tf.nest.flatten(batch_size)[0]
    if batch_size and not self._always_use_reshape:
      inputs, row_lengths = backend.convert_inputs_if_ragged(inputs)
      is_ragged_input = row_lengths is not None
      input_length = tf_utils.convert_shapes(input_shape)
      input_length = tf.nest.flatten(input_length)[1]

      # batch size matters, use rnn-based implementation
      def step(x, _):
        output = self.layer(x, **kwargs)
        return output, []

      _, outputs, _ = backend.rnn(
          step,
          inputs,
          initial_states=[],
          input_length=row_lengths[0] if is_ragged_input else input_length,
          mask=mask,
          unroll=False)
      # pylint: disable=g-long-lambda
      y = tf.nest.map_structure(
          lambda output: backend.maybe_convert_to_ragged(
              is_ragged_input, output, row_lengths), outputs)
    else:
      # No batch size specified, therefore the layer will be able
      # to process batches of any size.
      # We can go with reshape-based implementation for performance.
      is_ragged_input = tf.nest.map_structure(
          lambda x: isinstance(x, tf.RaggedTensor), inputs)
      is_ragged_input = tf.nest.flatten(is_ragged_input)
      if all(is_ragged_input):
        input_values = tf.nest.map_structure(lambda x: x.values, inputs)
        input_row_lenghts = tf.nest.map_structure(
            lambda x: x.nested_row_lengths()[0], inputs)
        y = self.layer(input_values, **kwargs)
        y = tf.nest.map_structure(tf.RaggedTensor.from_row_lengths, y,
                               input_row_lenghts)
      elif any(is_ragged_input):
        raise ValueError('All inputs has to be either ragged or not, '
                         'but not mixed. You passed: {}'.format(inputs))
      else:
        input_length = tf_utils.convert_shapes(input_shape)
        input_length = tf.nest.flatten(input_length)[1]
        if not input_length:
          input_length = tf.nest.map_structure(lambda x: tf.shape(x)[1], inputs)
          input_length = generic_utils.to_list(tf.nest.flatten(input_length))[0]

        inner_input_shape = tf.nest.map_structure(
            lambda x: self._get_shape_tuple((-1,), x, 2), inputs)
        # Shape: (num_samples * timesteps, ...). And track the
        # transformation in self._input_map.
        inputs = tf.__internal__.nest.map_structure_up_to(inputs, tf.reshape, inputs,
                                          inner_input_shape)
        # (num_samples * timesteps, ...)
        if generic_utils.has_arg(self.layer.call, 'mask') and mask is not None:
          inner_mask_shape = self._get_shape_tuple((-1,), mask, 2)
          kwargs['mask'] = backend.reshape(mask, inner_mask_shape)

        y = self.layer(inputs, **kwargs)

        # Shape: (num_samples, timesteps, ...)
        output_shape = self.compute_output_shape(input_shape)
        # pylint: disable=g-long-lambda
        output_shape = tf.nest.map_structure(
            lambda tensor, int_shape: self._get_shape_tuple(
                (-1, input_length), tensor, 1, int_shape[2:]), y, output_shape)
        y = tf.__internal__.nest.map_structure_up_to(y, tf.reshape, y, output_shape)
        if not tf.executing_eagerly():
          # Set the static shape for the result since it might be lost during
          # array_ops reshape, eg, some `None` dim in the result could be
          # inferred.
          tf.__internal__.nest.map_structure_up_to(
              y, lambda tensor, shape: tensor.set_shape(shape), y,
              self.compute_output_shape(input_shape))

    return y

  def compute_mask(self, inputs, mask=None):
    """Computes an output mask tensor for Embedding layer.

    This is based on the inputs, mask, and the inner layer.
    If batch size is specified:
    Simply return the input `mask`. (An rnn-based implementation with
    more than one rnn inputs is required but not supported in tf.keras yet.)
    Otherwise we call `compute_mask` of the inner layer at each time step.
    If the output mask at each time step is not `None`:
    (E.g., inner layer is Masking or RNN)
    Concatenate all of them and return the concatenation.
    If the output mask at each time step is `None` and the input mask is not
    `None`:(E.g., inner layer is Dense)
    Reduce the input_mask to 2 dimensions and return it.
    Otherwise (both the output mask and the input mask are `None`):
    (E.g., `mask` is not used at all)
    Return `None`.

    Args:
      inputs: Tensor with shape [batch size, timesteps, ...] indicating the
        input to TimeDistributed. If static shape information is available for
        "batch size", `mask` is returned unmodified.
      mask: Either None (indicating no masking) or a Tensor indicating the
        input mask for TimeDistributed. The shape can be static or dynamic.

    Returns:
      Either None (no masking), or a [batch size, timesteps, ...] Tensor with
      an output mask for the TimeDistributed layer with the shape beyond the
      second dimension being the value of the input mask shape(if the computed
      output mask is none), an output mask with the shape beyond the first
      dimension being the value of the mask shape(if mask is not None) or
      output mask with the shape beyond the first dimension being the
      value of the computed output shape.

    """
    # cases need to call the layer.compute_mask when input_mask is None:
    # Masking layer and Embedding layer with mask_zero
    input_shape = tf.nest.map_structure(
        lambda x: tf.TensorShape(backend.int_shape(x)), inputs)
    input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
    batch_size = tf_utils.convert_shapes(input_shape)
    batch_size = tf.nest.flatten(batch_size)[0]
    is_ragged_input = tf.nest.map_structure(
        lambda x: isinstance(x, tf.RaggedTensor), inputs)
    is_ragged_input = generic_utils.to_list(tf.nest.flatten(is_ragged_input))
    if batch_size and not self._always_use_reshape or any(is_ragged_input):
      # batch size matters, we currently do not handle mask explicitly, or if
      # the layer always uses reshape approach, or the input is a ragged tensor.
      return mask
    inner_mask = mask
    if inner_mask is not None:
      inner_mask_shape = self._get_shape_tuple((-1,), mask, 2)
      inner_mask = backend.reshape(inner_mask, inner_mask_shape)
    inner_input_shape = tf.nest.map_structure(
        lambda tensor: self._get_shape_tuple((-1,), tensor, 2), inputs)
    inner_inputs = tf.__internal__.nest.map_structure_up_to(inputs, tf.reshape, inputs,
                                            inner_input_shape)
    output_mask = self.layer.compute_mask(inner_inputs, inner_mask)
    if output_mask is None:
      if mask is None:
        return None
      # input_mask is not None, and output_mask is None:
      # we should return a not-None mask
      output_mask = mask
      for _ in range(2, len(backend.int_shape(mask))):
        output_mask = backend.any(output_mask, axis=-1)
    else:
      # output_mask is not None. We need to reshape it
      input_length = tf_utils.convert_shapes(input_shape)
      input_length = tf.nest.flatten(input_length)[1]
      if not input_length:
        input_length = tf.nest.map_structure(lambda x: backend.shape(x)[1], inputs)
        input_length = tf.nest.flatten(input_length)[0]
      output_mask_int_shape = backend.int_shape(output_mask)
      if output_mask_int_shape is None:
        # if the output_mask does not have a static shape,
        # its shape must be the same as mask's
        if mask is not None:
          output_mask_int_shape = backend.int_shape(mask)
        else:
          input_shape = generic_utils.to_list(tf.nest.flatten(input_shape))[0]
          output_mask_int_shape = backend.compute_output_shape(input_shape)[:-1]
      output_mask_shape = self._get_shape_tuple(
          (-1, input_length), output_mask, 1, output_mask_int_shape[1:])
      output_mask = backend.reshape(output_mask, output_mask_shape)
    return output_mask

Ancestors

  • Wrapper
  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Methods

def compute_mask(self, inputs, mask=None)

Computes an output mask tensor for Embedding layer.

This is based on the inputs, mask, and the inner layer. If batch size is specified: Simply return the input mask. (An rnn-based implementation with more than one rnn inputs is required but not supported in tf.keras yet.) Otherwise we call compute_mask of the inner layer at each time step. If the output mask at each time step is not None: (E.g., inner layer is Masking or RNN) Concatenate all of them and return the concatenation. If the output mask at each time step is None and the input mask is not None:(E.g., inner layer is Dense) Reduce the input_mask to 2 dimensions and return it. Otherwise (both the output mask and the input mask are None): (E.g., mask is not used at all) Return None.

Args

inputs
Tensor with shape [batch size, timesteps, …] indicating the input to TimeDistributed. If static shape information is available for "batch size", mask is returned unmodified.
mask
Either None (indicating no masking) or a Tensor indicating the input mask for TimeDistributed. The shape can be static or dynamic.

Returns

Either None (no masking), or a [batch size, timesteps, …] Tensor with an output mask for the TimeDistributed layer with the shape beyond the second dimension being the value of the input mask shape(if the computed output mask is none), an output mask with the shape beyond the first dimension being the value of the mask shape(if mask is not None) or output mask with the shape beyond the first dimension being the value of the computed output shape.

Expand source code
def compute_mask(self, inputs, mask=None):
  """Computes an output mask tensor for Embedding layer.

  This is based on the inputs, mask, and the inner layer.
  If batch size is specified:
  Simply return the input `mask`. (An rnn-based implementation with
  more than one rnn inputs is required but not supported in tf.keras yet.)
  Otherwise we call `compute_mask` of the inner layer at each time step.
  If the output mask at each time step is not `None`:
  (E.g., inner layer is Masking or RNN)
  Concatenate all of them and return the concatenation.
  If the output mask at each time step is `None` and the input mask is not
  `None`:(E.g., inner layer is Dense)
  Reduce the input_mask to 2 dimensions and return it.
  Otherwise (both the output mask and the input mask are `None`):
  (E.g., `mask` is not used at all)
  Return `None`.

  Args:
    inputs: Tensor with shape [batch size, timesteps, ...] indicating the
      input to TimeDistributed. If static shape information is available for
      "batch size", `mask` is returned unmodified.
    mask: Either None (indicating no masking) or a Tensor indicating the
      input mask for TimeDistributed. The shape can be static or dynamic.

  Returns:
    Either None (no masking), or a [batch size, timesteps, ...] Tensor with
    an output mask for the TimeDistributed layer with the shape beyond the
    second dimension being the value of the input mask shape(if the computed
    output mask is none), an output mask with the shape beyond the first
    dimension being the value of the mask shape(if mask is not None) or
    output mask with the shape beyond the first dimension being the
    value of the computed output shape.

  """
  # cases need to call the layer.compute_mask when input_mask is None:
  # Masking layer and Embedding layer with mask_zero
  input_shape = tf.nest.map_structure(
      lambda x: tf.TensorShape(backend.int_shape(x)), inputs)
  input_shape = tf_utils.convert_shapes(input_shape, to_tuples=False)
  batch_size = tf_utils.convert_shapes(input_shape)
  batch_size = tf.nest.flatten(batch_size)[0]
  is_ragged_input = tf.nest.map_structure(
      lambda x: isinstance(x, tf.RaggedTensor), inputs)
  is_ragged_input = generic_utils.to_list(tf.nest.flatten(is_ragged_input))
  if batch_size and not self._always_use_reshape or any(is_ragged_input):
    # batch size matters, we currently do not handle mask explicitly, or if
    # the layer always uses reshape approach, or the input is a ragged tensor.
    return mask
  inner_mask = mask
  if inner_mask is not None:
    inner_mask_shape = self._get_shape_tuple((-1,), mask, 2)
    inner_mask = backend.reshape(inner_mask, inner_mask_shape)
  inner_input_shape = tf.nest.map_structure(
      lambda tensor: self._get_shape_tuple((-1,), tensor, 2), inputs)
  inner_inputs = tf.__internal__.nest.map_structure_up_to(inputs, tf.reshape, inputs,
                                          inner_input_shape)
  output_mask = self.layer.compute_mask(inner_inputs, inner_mask)
  if output_mask is None:
    if mask is None:
      return None
    # input_mask is not None, and output_mask is None:
    # we should return a not-None mask
    output_mask = mask
    for _ in range(2, len(backend.int_shape(mask))):
      output_mask = backend.any(output_mask, axis=-1)
  else:
    # output_mask is not None. We need to reshape it
    input_length = tf_utils.convert_shapes(input_shape)
    input_length = tf.nest.flatten(input_length)[1]
    if not input_length:
      input_length = tf.nest.map_structure(lambda x: backend.shape(x)[1], inputs)
      input_length = tf.nest.flatten(input_length)[0]
    output_mask_int_shape = backend.int_shape(output_mask)
    if output_mask_int_shape is None:
      # if the output_mask does not have a static shape,
      # its shape must be the same as mask's
      if mask is not None:
        output_mask_int_shape = backend.int_shape(mask)
      else:
        input_shape = generic_utils.to_list(tf.nest.flatten(input_shape))[0]
        output_mask_int_shape = backend.compute_output_shape(input_shape)[:-1]
    output_mask_shape = self._get_shape_tuple(
        (-1, input_length), output_mask, 1, output_mask_int_shape[1:])
    output_mask = backend.reshape(output_mask, output_mask_shape)
  return output_mask

Inherited members

class UpSampling1D (size=2, **kwargs)

Upsampling layer for 1D inputs.

Repeats each temporal step size times along the time axis.

Examples:

>>> input_shape = (2, 2, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> print(x)
[[[ 0  1  2]
  [ 3  4  5]]
 [[ 6  7  8]
  [ 9 10 11]]]
>>> y = tf.keras.layers.UpSampling1D(size=2)(x)
>>> print(y)
tf.Tensor(
  [[[ 0  1  2]
    [ 0  1  2]
    [ 3  4  5]
    [ 3  4  5]]
   [[ 6  7  8]
    [ 6  7  8]
    [ 9 10 11]
    [ 9 10 11]]], shape=(2, 4, 3), dtype=int64)

Args

size
Integer. Upsampling factor.

Input shape: 3D tensor with shape: (batch_size, steps, features).

Output shape: 3D tensor with shape: (batch_size, upsampled_steps, features).

Expand source code
class UpSampling1D(Layer):
  """Upsampling layer for 1D inputs.

  Repeats each temporal step `size` times along the time axis.

  Examples:

  >>> input_shape = (2, 2, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> print(x)
  [[[ 0  1  2]
    [ 3  4  5]]
   [[ 6  7  8]
    [ 9 10 11]]]
  >>> y = tf.keras.layers.UpSampling1D(size=2)(x)
  >>> print(y)
  tf.Tensor(
    [[[ 0  1  2]
      [ 0  1  2]
      [ 3  4  5]
      [ 3  4  5]]
     [[ 6  7  8]
      [ 6  7  8]
      [ 9 10 11]
      [ 9 10 11]]], shape=(2, 4, 3), dtype=int64)

  Args:
    size: Integer. Upsampling factor.

  Input shape:
    3D tensor with shape: `(batch_size, steps, features)`.

  Output shape:
    3D tensor with shape: `(batch_size, upsampled_steps, features)`.
  """

  def __init__(self, size=2, **kwargs):
    super(UpSampling1D, self).__init__(**kwargs)
    self.size = int(size)
    self.input_spec = InputSpec(ndim=3)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    size = self.size * input_shape[1] if input_shape[1] is not None else None
    return tf.TensorShape([input_shape[0], size, input_shape[2]])

  def call(self, inputs):
    output = backend.repeat_elements(inputs, self.size, axis=1)
    return output

  def get_config(self):
    config = {'size': self.size}
    base_config = super(UpSampling1D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class UpSampling2D (size=(2, 2), data_format=None, interpolation='nearest', **kwargs)

Upsampling layer for 2D inputs.

Repeats the rows and columns of the data by size[0] and size[1] respectively.

Examples:

>>> input_shape = (2, 2, 1, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> print(x)
[[[[ 0  1  2]]
  [[ 3  4  5]]]
 [[[ 6  7  8]]
  [[ 9 10 11]]]]
>>> y = tf.keras.layers.UpSampling2D(size=(1, 2))(x)
>>> print(y)
tf.Tensor(
  [[[[ 0  1  2]
     [ 0  1  2]]
    [[ 3  4  5]
     [ 3  4  5]]]
   [[[ 6  7  8]
     [ 6  7  8]]
    [[ 9 10 11]
     [ 9 10 11]]]], shape=(2, 2, 2, 3), dtype=int64)

Args

size
Int, or tuple of 2 integers. The upsampling factors for rows and columns.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".
interpolation
A string, one of nearest or bilinear.

Input shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, rows, cols, channels) - If data_format is "channels_first": (batch_size, channels, rows, cols)

Output shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, upsampled_rows, upsampled_cols, channels) - If data_format is "channels_first": (batch_size, channels, upsampled_rows, upsampled_cols)

Expand source code
class UpSampling2D(Layer):
  """Upsampling layer for 2D inputs.

  Repeats the rows and columns of the data
  by `size[0]` and `size[1]` respectively.

  Examples:

  >>> input_shape = (2, 2, 1, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> print(x)
  [[[[ 0  1  2]]
    [[ 3  4  5]]]
   [[[ 6  7  8]]
    [[ 9 10 11]]]]
  >>> y = tf.keras.layers.UpSampling2D(size=(1, 2))(x)
  >>> print(y)
  tf.Tensor(
    [[[[ 0  1  2]
       [ 0  1  2]]
      [[ 3  4  5]
       [ 3  4  5]]]
     [[[ 6  7  8]
       [ 6  7  8]]
      [[ 9 10 11]
       [ 9 10 11]]]], shape=(2, 2, 2, 3), dtype=int64)

  Args:
    size: Int, or tuple of 2 integers.
      The upsampling factors for rows and columns.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".
    interpolation: A string, one of `nearest` or `bilinear`.

  Input shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, rows, cols, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, rows, cols)`

  Output shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, upsampled_rows, upsampled_cols, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, upsampled_rows, upsampled_cols)`
  """

  def __init__(self,
               size=(2, 2),
               data_format=None,
               interpolation='nearest',
               **kwargs):
    super(UpSampling2D, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    self.size = conv_utils.normalize_tuple(size, 2, 'size')
    if interpolation not in {'nearest', 'bilinear'}:
      raise ValueError('`interpolation` argument should be one of `"nearest"` '
                       'or `"bilinear"`.')
    self.interpolation = interpolation
    self.input_spec = InputSpec(ndim=4)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if self.data_format == 'channels_first':
      height = self.size[0] * input_shape[
          2] if input_shape[2] is not None else None
      width = self.size[1] * input_shape[
          3] if input_shape[3] is not None else None
      return tf.TensorShape(
          [input_shape[0], input_shape[1], height, width])
    else:
      height = self.size[0] * input_shape[
          1] if input_shape[1] is not None else None
      width = self.size[1] * input_shape[
          2] if input_shape[2] is not None else None
      return tf.TensorShape(
          [input_shape[0], height, width, input_shape[3]])

  def call(self, inputs):
    return backend.resize_images(
        inputs, self.size[0], self.size[1], self.data_format,
        interpolation=self.interpolation)

  def get_config(self):
    config = {
        'size': self.size,
        'data_format': self.data_format,
        'interpolation': self.interpolation
    }
    base_config = super(UpSampling2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class UpSampling3D (size=(2, 2, 2), data_format=None, **kwargs)

Upsampling layer for 3D inputs.

Repeats the 1st, 2nd and 3rd dimensions of the data by size[0], size[1] and size[2] respectively.

Examples:

>>> input_shape = (2, 1, 2, 1, 3)
>>> x = tf.constant(1, shape=input_shape)
>>> y = tf.keras.layers.UpSampling3D(size=2)(x)
>>> print(y.shape)
(2, 2, 4, 2, 3)

Args

size
Int, or tuple of 3 integers. The upsampling factors for dim1, dim2 and dim3.
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, dim1, dim2, dim3, channels) - If data_format is "channels_first": (batch_size, channels, dim1, dim2, dim3)

Output shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels) - If data_format is "channels_first": (batch_size, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)

Expand source code
class UpSampling3D(Layer):
  """Upsampling layer for 3D inputs.

  Repeats the 1st, 2nd and 3rd dimensions
  of the data by `size[0]`, `size[1]` and `size[2]` respectively.

  Examples:

  >>> input_shape = (2, 1, 2, 1, 3)
  >>> x = tf.constant(1, shape=input_shape)
  >>> y = tf.keras.layers.UpSampling3D(size=2)(x)
  >>> print(y.shape)
  (2, 2, 4, 2, 3)

  Args:
    size: Int, or tuple of 3 integers.
      The upsampling factors for dim1, dim2 and dim3.
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, dim1, dim2, dim3, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, dim1, dim2, dim3)`

  Output shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, upsampled_dim1, upsampled_dim2, upsampled_dim3, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, upsampled_dim1, upsampled_dim2, upsampled_dim3)`
  """

  def __init__(self, size=(2, 2, 2), data_format=None, **kwargs):
    self.data_format = conv_utils.normalize_data_format(data_format)
    self.size = conv_utils.normalize_tuple(size, 3, 'size')
    self.input_spec = InputSpec(ndim=5)
    super(UpSampling3D, self).__init__(**kwargs)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if self.data_format == 'channels_first':
      dim1 = self.size[0] * input_shape[
          2] if input_shape[2] is not None else None
      dim2 = self.size[1] * input_shape[
          3] if input_shape[3] is not None else None
      dim3 = self.size[2] * input_shape[
          4] if input_shape[4] is not None else None
      return tf.TensorShape(
          [input_shape[0], input_shape[1], dim1, dim2, dim3])
    else:
      dim1 = self.size[0] * input_shape[
          1] if input_shape[1] is not None else None
      dim2 = self.size[1] * input_shape[
          2] if input_shape[2] is not None else None
      dim3 = self.size[2] * input_shape[
          3] if input_shape[3] is not None else None
      return tf.TensorShape(
          [input_shape[0], dim1, dim2, dim3, input_shape[4]])

  def call(self, inputs):
    return backend.resize_volumes(
        inputs, self.size[0], self.size[1], self.size[2], self.data_format)

  def get_config(self):
    config = {'size': self.size, 'data_format': self.data_format}
    base_config = super(UpSampling3D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class Wrapper (layer, **kwargs)

Abstract wrapper base class.

Wrappers take another layer and augment it in various ways. Do not use this class as a layer, it is only an abstract base class. Two usable wrappers are the TimeDistributed and Bidirectional wrappers.

Args

layer
The layer to be wrapped.
Expand source code
class Wrapper(Layer):
  """Abstract wrapper base class.

  Wrappers take another layer and augment it in various ways.
  Do not use this class as a layer, it is only an abstract base class.
  Two usable wrappers are the `TimeDistributed` and `Bidirectional` wrappers.

  Args:
    layer: The layer to be wrapped.
  """

  def __init__(self, layer, **kwargs):
    assert isinstance(layer, Layer)
    self.layer = layer
    super(Wrapper, self).__init__(**kwargs)

  def build(self, input_shape=None):
    if not self.layer.built:
      self.layer.build(input_shape)
      self.layer.built = True
    self.built = True

  @property
  def activity_regularizer(self):
    if hasattr(self.layer, 'activity_regularizer'):
      return self.layer.activity_regularizer
    else:
      return None

  def get_config(self):
    config = {'layer': generic_utils.serialize_keras_object(self.layer)}
    base_config = super(Wrapper, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

  @classmethod
  def from_config(cls, config, custom_objects=None):
    from keras.layers import deserialize as deserialize_layer  # pylint: disable=g-import-not-at-top
    # Avoid mutating the input dict
    config = copy.deepcopy(config)
    layer = deserialize_layer(
        config.pop('layer'), custom_objects=custom_objects)
    return cls(layer, **config)

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Subclasses

Inherited members

class ZeroPadding1D (padding=1, **kwargs)

Zero-padding layer for 1D input (e.g. temporal sequence).

Examples:

>>> input_shape = (2, 2, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> print(x)
[[[ 0  1  2]
  [ 3  4  5]]
 [[ 6  7  8]
  [ 9 10 11]]]
>>> y = tf.keras.layers.ZeroPadding1D(padding=2)(x)
>>> print(y)
tf.Tensor(
  [[[ 0  0  0]
    [ 0  0  0]
    [ 0  1  2]
    [ 3  4  5]
    [ 0  0  0]
    [ 0  0  0]]
   [[ 0  0  0]
    [ 0  0  0]
    [ 6  7  8]
    [ 9 10 11]
    [ 0  0  0]
    [ 0  0  0]]], shape=(2, 6, 3), dtype=int64)

Args

padding
Int, or tuple of int (length 2), or dictionary. - If int: How many zeros to add at the beginning and end of the padding dimension (axis 1). - If tuple of int (length 2): How many zeros to add at the beginning and the end of the padding dimension ((left_pad, right_pad)).

Input shape: 3D tensor with shape (batch_size, axis_to_pad, features)

Output shape: 3D tensor with shape (batch_size, padded_axis, features)

Expand source code
class ZeroPadding1D(Layer):
  """Zero-padding layer for 1D input (e.g. temporal sequence).

  Examples:

  >>> input_shape = (2, 2, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> print(x)
  [[[ 0  1  2]
    [ 3  4  5]]
   [[ 6  7  8]
    [ 9 10 11]]]
  >>> y = tf.keras.layers.ZeroPadding1D(padding=2)(x)
  >>> print(y)
  tf.Tensor(
    [[[ 0  0  0]
      [ 0  0  0]
      [ 0  1  2]
      [ 3  4  5]
      [ 0  0  0]
      [ 0  0  0]]
     [[ 0  0  0]
      [ 0  0  0]
      [ 6  7  8]
      [ 9 10 11]
      [ 0  0  0]
      [ 0  0  0]]], shape=(2, 6, 3), dtype=int64)

  Args:
      padding: Int, or tuple of int (length 2), or dictionary.
          - If int:
          How many zeros to add at the beginning and end of
          the padding dimension (axis 1).
          - If tuple of int (length 2):
          How many zeros to add at the beginning and the end of
          the padding dimension (`(left_pad, right_pad)`).

  Input shape:
      3D tensor with shape `(batch_size, axis_to_pad, features)`

  Output shape:
      3D tensor with shape `(batch_size, padded_axis, features)`
  """

  def __init__(self, padding=1, **kwargs):
    super(ZeroPadding1D, self).__init__(**kwargs)
    self.padding = conv_utils.normalize_tuple(padding, 2, 'padding')
    self.input_spec = InputSpec(ndim=3)

  def compute_output_shape(self, input_shape):
    if input_shape[1] is not None:
      length = input_shape[1] + self.padding[0] + self.padding[1]
    else:
      length = None
    return tf.TensorShape([input_shape[0], length, input_shape[2]])

  def call(self, inputs):
    return backend.temporal_padding(inputs, padding=self.padding)

  def get_config(self):
    config = {'padding': self.padding}
    base_config = super(ZeroPadding1D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class ZeroPadding2D (padding=(1, 1), data_format=None, **kwargs)

Zero-padding layer for 2D input (e.g. picture).

This layer can add rows and columns of zeros at the top, bottom, left and right side of an image tensor.

Examples:

>>> input_shape = (1, 1, 2, 2)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> print(x)
[[[[0 1]
   [2 3]]]]
>>> y = tf.keras.layers.ZeroPadding2D(padding=1)(x)
>>> print(y)
tf.Tensor(
  [[[[0 0]
     [0 0]
     [0 0]
     [0 0]]
    [[0 0]
     [0 1]
     [2 3]
     [0 0]]
    [[0 0]
     [0 0]
     [0 0]
     [0 0]]]], shape=(1, 3, 4, 2), dtype=int64)

Args

padding
Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints. - If int: the same symmetric padding is applied to height and width. - If tuple of 2 ints: interpreted as two different symmetric padding values for height and width: (symmetric_height_pad, symmetric_width_pad). - If tuple of 2 tuples of 2 ints: interpreted as ((top_pad, bottom_pad), (left_pad, right_pad))
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, height, width, channels) while channels_first corresponds to inputs with shape (batch_size, channels, height, width). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, rows, cols, channels) - If data_format is "channels_first": (batch_size, channels, rows, cols)

Output shape: 4D tensor with shape: - If data_format is "channels_last": (batch_size, padded_rows, padded_cols, channels) - If data_format is "channels_first": (batch_size, channels, padded_rows, padded_cols)

Expand source code
class ZeroPadding2D(Layer):
  """Zero-padding layer for 2D input (e.g. picture).

  This layer can add rows and columns of zeros
  at the top, bottom, left and right side of an image tensor.

  Examples:

  >>> input_shape = (1, 1, 2, 2)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> print(x)
  [[[[0 1]
     [2 3]]]]
  >>> y = tf.keras.layers.ZeroPadding2D(padding=1)(x)
  >>> print(y)
  tf.Tensor(
    [[[[0 0]
       [0 0]
       [0 0]
       [0 0]]
      [[0 0]
       [0 1]
       [2 3]
       [0 0]]
      [[0 0]
       [0 0]
       [0 0]
       [0 0]]]], shape=(1, 3, 4, 2), dtype=int64)

  Args:
    padding: Int, or tuple of 2 ints, or tuple of 2 tuples of 2 ints.
      - If int: the same symmetric padding
        is applied to height and width.
      - If tuple of 2 ints:
        interpreted as two different
        symmetric padding values for height and width:
        `(symmetric_height_pad, symmetric_width_pad)`.
      - If tuple of 2 tuples of 2 ints:
        interpreted as
        `((top_pad, bottom_pad), (left_pad, right_pad))`
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, height, width, channels)` while `channels_first`
      corresponds to inputs with shape
      `(batch_size, channels, height, width)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, rows, cols, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, rows, cols)`

  Output shape:
    4D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, padded_rows, padded_cols, channels)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, channels, padded_rows, padded_cols)`
  """

  def __init__(self, padding=(1, 1), data_format=None, **kwargs):
    super(ZeroPadding2D, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    if isinstance(padding, int):
      self.padding = ((padding, padding), (padding, padding))
    elif hasattr(padding, '__len__'):
      if len(padding) != 2:
        raise ValueError('`padding` should have two elements. '
                         'Found: ' + str(padding))
      height_padding = conv_utils.normalize_tuple(padding[0], 2,
                                                  '1st entry of padding')
      width_padding = conv_utils.normalize_tuple(padding[1], 2,
                                                 '2nd entry of padding')
      self.padding = (height_padding, width_padding)
    else:
      raise ValueError('`padding` should be either an int, '
                       'a tuple of 2 ints '
                       '(symmetric_height_pad, symmetric_width_pad), '
                       'or a tuple of 2 tuples of 2 ints '
                       '((top_pad, bottom_pad), (left_pad, right_pad)). '
                       'Found: ' + str(padding))
    self.input_spec = InputSpec(ndim=4)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if self.data_format == 'channels_first':
      if input_shape[2] is not None:
        rows = input_shape[2] + self.padding[0][0] + self.padding[0][1]
      else:
        rows = None
      if input_shape[3] is not None:
        cols = input_shape[3] + self.padding[1][0] + self.padding[1][1]
      else:
        cols = None
      return tf.TensorShape(
          [input_shape[0], input_shape[1], rows, cols])
    elif self.data_format == 'channels_last':
      if input_shape[1] is not None:
        rows = input_shape[1] + self.padding[0][0] + self.padding[0][1]
      else:
        rows = None
      if input_shape[2] is not None:
        cols = input_shape[2] + self.padding[1][0] + self.padding[1][1]
      else:
        cols = None
      return tf.TensorShape(
          [input_shape[0], rows, cols, input_shape[3]])

  def call(self, inputs):
    return backend.spatial_2d_padding(
        inputs, padding=self.padding, data_format=self.data_format)

  def get_config(self):
    config = {'padding': self.padding, 'data_format': self.data_format}
    base_config = super(ZeroPadding2D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members

class ZeroPadding3D (padding=(1, 1, 1), data_format=None, **kwargs)

Zero-padding layer for 3D data (spatial or spatio-temporal).

Examples:

>>> input_shape = (1, 1, 2, 2, 3)
>>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
>>> y = tf.keras.layers.ZeroPadding3D(padding=2)(x)
>>> print(y.shape)
(1, 5, 6, 6, 3)

Args

padding
Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints. - If int: the same symmetric padding is applied to height and width. - If tuple of 3 ints: interpreted as two different symmetric padding values for height and width: (symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad). - If tuple of 3 tuples of 2 ints: interpreted as ((left_dim1_pad, right_dim1_pad), (left_dim2_pad, right_dim2_pad), (left_dim3_pad, right_dim3_pad))
data_format
A string, one of channels_last (default) or channels_first. The ordering of the dimensions in the inputs. channels_last corresponds to inputs with shape (batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels) while channels_first corresponds to inputs with shape (batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3). It defaults to the image_data_format value found in your Keras config file at ~/.keras/keras.json. If you never set it, then it will be "channels_last".

Input shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad, depth) - If data_format is "channels_first": (batch_size, depth, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad)

Output shape: 5D tensor with shape: - If data_format is "channels_last": (batch_size, first_padded_axis, second_padded_axis, third_axis_to_pad, depth) - If data_format is "channels_first": (batch_size, depth, first_padded_axis, second_padded_axis, third_axis_to_pad)

Expand source code
class ZeroPadding3D(Layer):
  """Zero-padding layer for 3D data (spatial or spatio-temporal).

  Examples:

  >>> input_shape = (1, 1, 2, 2, 3)
  >>> x = np.arange(np.prod(input_shape)).reshape(input_shape)
  >>> y = tf.keras.layers.ZeroPadding3D(padding=2)(x)
  >>> print(y.shape)
  (1, 5, 6, 6, 3)

  Args:
    padding: Int, or tuple of 3 ints, or tuple of 3 tuples of 2 ints.
      - If int: the same symmetric padding
        is applied to height and width.
      - If tuple of 3 ints:
        interpreted as two different
        symmetric padding values for height and width:
        `(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad)`.
      - If tuple of 3 tuples of 2 ints:
        interpreted as
        `((left_dim1_pad, right_dim1_pad), (left_dim2_pad,
          right_dim2_pad), (left_dim3_pad, right_dim3_pad))`
    data_format: A string,
      one of `channels_last` (default) or `channels_first`.
      The ordering of the dimensions in the inputs.
      `channels_last` corresponds to inputs with shape
      `(batch_size, spatial_dim1, spatial_dim2, spatial_dim3, channels)`
      while `channels_first` corresponds to inputs with shape
      `(batch_size, channels, spatial_dim1, spatial_dim2, spatial_dim3)`.
      It defaults to the `image_data_format` value found in your
      Keras config file at `~/.keras/keras.json`.
      If you never set it, then it will be "channels_last".

  Input shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, first_axis_to_pad, second_axis_to_pad, third_axis_to_pad,
          depth)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, depth, first_axis_to_pad, second_axis_to_pad,
          third_axis_to_pad)`

  Output shape:
    5D tensor with shape:
    - If `data_format` is `"channels_last"`:
        `(batch_size, first_padded_axis, second_padded_axis, third_axis_to_pad,
          depth)`
    - If `data_format` is `"channels_first"`:
        `(batch_size, depth, first_padded_axis, second_padded_axis,
          third_axis_to_pad)`
  """

  def __init__(self, padding=(1, 1, 1), data_format=None, **kwargs):
    super(ZeroPadding3D, self).__init__(**kwargs)
    self.data_format = conv_utils.normalize_data_format(data_format)
    if isinstance(padding, int):
      self.padding = ((padding, padding), (padding, padding), (padding,
                                                               padding))
    elif hasattr(padding, '__len__'):
      if len(padding) != 3:
        raise ValueError('`padding` should have 3 elements. '
                         'Found: ' + str(padding))
      dim1_padding = conv_utils.normalize_tuple(padding[0], 2,
                                                '1st entry of padding')
      dim2_padding = conv_utils.normalize_tuple(padding[1], 2,
                                                '2nd entry of padding')
      dim3_padding = conv_utils.normalize_tuple(padding[2], 2,
                                                '3rd entry of padding')
      self.padding = (dim1_padding, dim2_padding, dim3_padding)
    else:
      raise ValueError(
          '`padding` should be either an int, '
          'a tuple of 3 ints '
          '(symmetric_dim1_pad, symmetric_dim2_pad, symmetric_dim3_pad), '
          'or a tuple of 3 tuples of 2 ints '
          '((left_dim1_pad, right_dim1_pad),'
          ' (left_dim2_pad, right_dim2_pad),'
          ' (left_dim3_pad, right_dim2_pad)). '
          'Found: ' + str(padding))
    self.input_spec = InputSpec(ndim=5)

  def compute_output_shape(self, input_shape):
    input_shape = tf.TensorShape(input_shape).as_list()
    if self.data_format == 'channels_first':
      if input_shape[2] is not None:
        dim1 = input_shape[2] + self.padding[0][0] + self.padding[0][1]
      else:
        dim1 = None
      if input_shape[3] is not None:
        dim2 = input_shape[3] + self.padding[1][0] + self.padding[1][1]
      else:
        dim2 = None
      if input_shape[4] is not None:
        dim3 = input_shape[4] + self.padding[2][0] + self.padding[2][1]
      else:
        dim3 = None
      return tf.TensorShape(
          [input_shape[0], input_shape[1], dim1, dim2, dim3])
    elif self.data_format == 'channels_last':
      if input_shape[1] is not None:
        dim1 = input_shape[1] + self.padding[0][0] + self.padding[0][1]
      else:
        dim1 = None
      if input_shape[2] is not None:
        dim2 = input_shape[2] + self.padding[1][0] + self.padding[1][1]
      else:
        dim2 = None
      if input_shape[3] is not None:
        dim3 = input_shape[3] + self.padding[2][0] + self.padding[2][1]
      else:
        dim3 = None
      return tf.TensorShape(
          [input_shape[0], dim1, dim2, dim3, input_shape[4]])

  def call(self, inputs):
    return backend.spatial_3d_padding(
        inputs, padding=self.padding, data_format=self.data_format)

  def get_config(self):
    config = {'padding': self.padding, 'data_format': self.data_format}
    base_config = super(ZeroPadding3D, self).get_config()
    return dict(list(base_config.items()) + list(config.items()))

Ancestors

  • Layer
  • tensorflow.python.module.module.Module
  • tensorflow.python.training.tracking.tracking.AutoTrackable
  • tensorflow.python.training.tracking.base.Trackable
  • LayerVersionSelector

Inherited members